Saturday, February 15, 2014

follow up to MOLPRO ROHF convergence difficulties (optimizing a geometry using procedures)

The end result of the last post was that I found level shifts of -0.3, 0.3 worked for my system. A brief tangent for those of you who have perused the manual and saw their suggestion of -1.0,-0.5, I did try that one as well and it does not work in this particular case. Ok, back to the question at hand, how do I optimize a geometry when ROHF won't even converge for a structure that is a local minimum? One way around this is to use MCSCF with one open orbital and run the converged orbitals through ROHF using only one iteration. However, that is a story for another day, in this case I will use the level shifts I listed above. My basic thought was that I really only want to use the level shifts if they are needed, otherwise I will use the default values. These two ideas lead to using a procedure and boolean logic within said procedure.

basis=aug-cc-pvdz

proc autoshift
   rhf
   if(status.lt.0) then
     status,rhf,clear                          !make sure calc does not abort when stock rohf does not converge
     {rhf,shifta=-0.3,shiftb=0.3;        !shifts found using grid search
     start,atden}                              !start with atomic densities again, otherwise rohf will use same "bad" orbitals
  endif
  uccsd(t)
endproc

{optg,proc=autoshift,root=1,energy=1.d-11,step=1.d-5,gradient=1.d-5,displace=symm,numhess=2,hessproc=b3lyphess}

proc b3lyphess
  rhf
  if(status.lt.0) then
    status,rhf,clear                           !same as for autoshift
    {rhf,shifta=-0.3,shiftb=0.3;                                                   
    start,atden}
  endif
  ks,b3lyp
endproc

Here I have made two procedures, one for the optimization using CCSD(T) and one for the Hessian (MOLPRO does far better with frequent numerical hessians when optimizing open-shell doublet molecules) using B3LYP. I will talk about the first one because they are almost identical. Beginning with the if statement, I hate it check if the stock ROHF calculation finished properly. If it did not, then I run ROHF with the level shifts I found in the previous post, taking care to start with the atomic densities and not the orbitals from the previous ROHF calculation. I could put in several of these if statements with various values for the level shifts to be on the safe side, but I wanted to keep this example on the simple side. If this ROHF calculation fails then I still want MOLPRO to error out, so I do not have a status,rhf,clear statement in the if structure. After that I run the UCCSD(T) calculation. The only other bit to include is telling optg that I want to use a procedure, which is accomplished with the proc=autoshift. This is currently running, but it made it past the initial calculation which is progress.

Wednesday, February 12, 2014

automation of MOLPRO and ROHF convergence testing

Every now and again I run across cases where open-shell systems cause ROHF in MOLPRO to choke. Usually this is easily solved by starting out with STO-3G, stepping up to 6-31G(d), cc-pVDZ, and, finally, aug-cc-pVXZ. MOLPRO seamlessly reads the orbitals from the previous calculation, if available, and projects these onto the new basis set. However, this approach does not work on some occasions and neither does increasing the maximum number of iterations (I have never run into an example where increasing maxit past 100 has helped). This left me with wanting to try level shifts, which would be tedious for anything more than 3 or 4 tries. This leads me to use BASH scripting to automatically generate input files covering a range of level shifts.

for SHIFTA in -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 ; do for SHIFTB in -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 ; do echo $SHIFTA $SHIFTB ; cp testt-a.inp test-shift${SHIFTA}${SHIFTB}.inp ; sed -i "s/shifta=-0.5,shiftb=-0.5/shifta=${SHIFTA},shiftb=${SHIFTB}/g" test-shift${SHIFTA}${SHIFTB}.inp ; done ; done

The nested for loops generate 81 input files, each having a different set of alpha and beta shifts, ranging from -0.5 to +0.3. The echo line lets you know how far along in the process it is. The cp line creates the input file from a template, test-a.inp. Now to the most interesting line where sed replaces the shift values from the template with the values held in variables shifta and shiftb.

The next step is to run all of these calculations. I opted for simplicity and used the same nested for loops.

module load molpro/2012.1.8 ; for SHIFTA in -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 ; do for SHIFTB in -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 ; do echo $SHIFTA $SHIFTB ; molpro -n1 <./test-shift${SHIFTA}${SHIFTB}.inp >./test-shift${SHIFTA}${SHIFTB}.out; done ; done

Finally, one needs to look at the results. I echo the shift values and then the ROHF energy. The gawk bit just gets rid of the grep term I use to pull this energy from the output file.

for SHIFTA in -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 ; do for SHIFTB in -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 ; do echo $SHIFTA $SHIFTB $( grep "RHF STATE 1.1 Energy" ./test-shift${SHIFTA}${SHIFTB}.out | gawk ' { print $5 } ') ; $( grep "No convergence" ./test-shift${shifta}${shiftb}.out ) ; done ; done >./631gs-shift.txt

From here it is easier to change other aspects with one line, such as the basis set, maxit, etc. If I am trying to get the ROHF calculation to converge I should really have grep find convergence issues. On top of that I would like to know which parameters, if any, worked and which were bogus. I modified the above line to add in a grep for "No convergence" and I dump all of the results to a file, which allows me to use the BASH sort function to parse the data either by energy or by convergence. The below line sorts based upon the energy, but one could change 3,3 to 4,4 and sort by convergence.

sort -t$' ' -k 3,3 631gs-shift.txt


Monday, December 9, 2013

pulling useful information from G03/G09 calculations

A short while after I began grad school, which was years ago now, I realized that checking on the progress of a G03/G09 calculation often required sifting through massive amounts of detritus. Rather than use less and then search through the entire file, I began learning grep, sed, and awk. This post deals with the first command, grep, and how to make custom versions that can pull out specific information. Perhaps the example I use most often is checking on the progress of a geometry optimization. G03/G09 spit out the 4 convergence criteria after each iteration, as shown below.

$ grep -iA3 "maximum force" test.log
 Maximum Force            0.009759     0.000450     NO 
 RMS     Force            0.001640     0.000300     NO 
 Maximum Displacement     0.380695     0.001800     NO 
 RMS     Displacement     0.042164     0.001200     NO 
--
 Maximum Force            0.001122     0.000450     NO 
 RMS     Force            0.000200     0.000300     YES
 Maximum Displacement     0.117795     0.001800     NO 
 RMS     Displacement     0.034630     0.001200     NO 
--
 Maximum Force            0.000796     0.000450     NO 
 RMS     Force            0.000091     0.000300     YES
 Maximum Displacement     0.290041     0.001800     NO 
 RMS     Displacement     0.065495     0.001200     NO 
--
 Maximum Force            0.000462     0.000450     NO 
 RMS     Force            0.000095     0.000300     YES
 Maximum Displacement     0.245764     0.001800     NO 
 RMS     Displacement     0.018789     0.001200     NO 
--
 Maximum Force            0.000530     0.000450     NO 
 RMS     Force            0.000087     0.000300     YES
 Maximum Displacement     0.268022     0.001800     NO 
 RMS     Displacement     0.026751     0.001200     NO 
--
 Maximum Force            0.000268     0.000450     YES
 RMS     Force            0.000051     0.000300     YES
 Maximum Displacement     0.268678     0.001800     NO 
 RMS     Displacement     0.020944     0.001200     NO 

The above command grew tedious when I wanted to monitor more than a couple jobs, hence I made an alias in the .bashrc file in my home directory. This way I only had to type the alias and not the entire grep line.

# extracts geometry convergence criteria
alias grepmax='grep -A3 -i "maximum force"'

# extracts time stamps for each CCSD gradient calc
alias grepccsd='grep "Leave Link  106"'

# extracts the number of steps taken during a geometry opt, IRC, or PES scan
alias grepstep='grep "Step number"'

# extracts the rotational constants (in GHz)
alias greprot='grep "Rotational constants"'

# extracts the harmonic vibrational frequencies (3 columns)
alias grepfreq='grep "Frequencies"'

# extracts the G3 energy (at 0 K and at finite T, but not the enthalpy or free energy)
alias grepg3='grep "G3(0 K)"'

Wednesday, December 4, 2013

G03 failing with "end of file in zsymb"

I recently came across an error I had not seen before while running Gaussian03. Right after the input file is read was the line,

End of file in ZSymb.

I had deleted one too many blank lines after the geometry input (G03 needs at least one), and adding a new line back in at the end fixed this right up.

Tuesday, December 3, 2013

radeon 7xxx video cards throttling

I have several rigs with 2 x 7950 or 2 x 7970 and on some of them (m4a79t + 7950 and m5a97 r2.0 + 7950) the gpu and memory clock is throttled under high load. After some searching around I found this utility that enables the cards to increase the power consumption of each card (gcc and the amd adl-sdk are required):

https://bitcointalk.org/index.php?topic=8384.0

I have included the code here for the impatient.

#include <iostream>
#include <cstdlib>
#include <adl_sdk.h>

using namespace std;

extern "C"
{
    int ADL_Main_Control_Create (ADL_MAIN_MALLOC_CALLBACK, int);
    int ADL_Adapter_NumberOfAdapters_Get(int *);
    int ADL_Overdrive5_PowerControl_Set(int, int);
    int ADL_Overdrive5_PowerControl_Get(int, int *, int *);
}

void* __stdcall Alloc ( int iSize )
{
    void* lpBuffer = malloc ( iSize );
    return lpBuffer;
}

void __stdcall ADL_Main_Memory_Free ( void** lpBuffer )
{
    if ( NULL != *lpBuffer )
    {
        free ( *lpBuffer );
        *lpBuffer = NULL;
    }
}

int main()
{
        int adapters, a=99, b=99;
        if(ADL_Main_Control_Create (Alloc, 1) != ADL_OK)
        {
                cout << "ADL initialization error!" << endl;
                return -1;
        }
        
        if(ADL_Adapter_NumberOfAdapters_Get(&adapters) != ADL_OK)
        {
                cout << "Cannot get the number of adapters!" << endl;
                return -1;
        }
        cout << "Found " << adapters << " adapters" << endl;
        for(int i=0; i<adapters; i++)
        {
                if(ADL_Overdrive5_PowerControl_Set(i, 10) != ADL_OK)
                {
                        cout << "Failed to set " << i << " power control" << endl;
                        return -1;
                } else { cout << "Value set for " << i << endl; }
                
                if(ADL_Overdrive5_PowerControl_Get(i, &a, &b) != ADL_OK)
                {
                        cout << "Failed to get " << i << " power control" << endl;
                        return -1;
                }
                cout << "result: " << a << "%, b: " << b << endl;
        }
        return 0;
}

The key line here is if(ADL_Overdrive5_PowerControl_Set(i, 10) != ADL_OK), and you can change the 10 to any integer up to 20. In my case 5 didn't quite work, so I had to use 10. Then to compile it you use g++, and run it using the 2nd line.

# g++ -DLINUX -o powercontrol powercontrol.cpp -latiadlxx
# ./powercontrol
Found 12 adapters
Value set for 0
result: 10%, b: 0
Value set for 1
result: 10%, b: 0
Value set for 2
result: 10%, b: 0
Value set for 3
result: 10%, b: 0
Value set for 4
result: 10%, b: 0
Value set for 5
result: 10%, b: 0
Value set for 6
result: 10%, b: 0
Value set for 7
result: 10%, b: 0
Value set for 8
result: 10%, b: 0
Value set for 9
result: 10%, b: 0
Value set for 10
result: 10%, b: 0
Value set for 11
result: 10%, b: 0

Monday, November 25, 2013

When X/kdm do not start properly

These problems go into the pile labeled, "duh, I should have tried that first." Inevitably when I make changes to the graphics hardware or complete a new install of gentoo I get to the final stage of starting X and am left with a black screen (the monitor is still receiving a signal, there's just nothing there). Usually I check Xorg.0.log and kdm.log and find that there were no issues. In this case it probably means I forgot to set the opengl renderer.

# eselect opengl set ati

After a reboot the system comes right up into kde.

The second variation is an old school X cursor, but nothing else resembling a gui (black screen), and Xorg.0.log whines about fglrx_dri.so. In this case I needed to switch the order of the graphics cards in my xorg.conf. The below command spits out the graphics adapters, and the first column is the information we want to put into xorg.conf. In this case I already had the correct pci-e device numbers, but I had them in the wrong order. A simple swap of 2:0:0 and 6:0:0 in xorg.conf (NOTE the syntax change when putting these into xorg.conf) and everything was back to functional. (SIDE NOTE: removing a graphics adapter can alter these numbers, in this rig with one card it sits at 05:00.0)

# lspci | grep -i vga
02:00.0 VGA compatible controller: Advanced Micro Devices [AMD] nee ATI Tahiti XT [Radeon HD 7970]
06:00.0 VGA compatible controller: Advanced Micro Devices [AMD] nee ATI Tahiti XT [Radeon HD 7970]


xorg.conf lines
Section "Device"
        Identifier  "aticonfig-Device[0]-0"
        Driver      "fglrx"
        BusID       "PCI:6:0:0"
EndSection

Section "Device"
        Identifier  "aticonfig-Device[1]-0"
        Driver      "fglrx"
        BusID       "PCI:2:0:0"
EndSection

Friday, November 22, 2013

To give a bit of background about my Linux usage; I began with Mandrake, Suse, and Redhat back in 2001. By 2004 I decided that if I were ever to become proficient using Linux I needed to use it 24/7. At this point I had been trying Gentoo, so I loaded it on all of my boxes and have bounced around with various spin offs of Gentoo (Vidalinux and Funtoo). These days I have moved back to vanilla Gentoo and generally have a small installation of Ubuntu one each box for installing Gentoo.

I suppose if this blog has a purpose, it is primarily to list problems I've run across and fixed. The hope is that writing these solutions down will help my brain cell remember the solutions the next time around.

Now on to the fun stuff, which was udev automagically renaming ethernet devices. The standard tell comes about during system initialization, and rc screams about not being able to start eth0.

$ ifconfig -a

The above command should show the device labeled as something not eth0 (if you don't see anything promising there at all it could be the kernel does not have the driver you need). Now that we know some sort of network device exists there is hope of fixing it. In this case we need to tell udev to stop being so clever and give us back our preciously boring eth0. The solution I decided upon (there were several, I'll try to find links to the others) was adding a rule to /etc/udev/rules.d.

# ln -s /dev/null /etc/udev/rules.d/80-net-name-slot.rules
# /etc/init.d/udev restart
# /etc/init.d/net.eth0 start