psi::extrema::deloc Class Reference

Derived class for delocalized internal coordinates. More...

#include <deloc.h>

Inheritance diagram for psi::extrema::deloc:

psi::extrema::internals psi::extrema::coord_base psi::extrema::coord_base_carts psi::extrema::math_tools

Public Member Functions

 deloc ()
 ~deloc ()
 Frees memory.
void optimize ()
 Delocalized internals optimization driver.

Detailed Description

Derived class for delocalized internal coordinates.

A top level class which allows delocalized internal coordinate manipulations by driving member functions of the abstract classes.

Definition at line 20 of file deloc.h.


Constructor & Destructor Documentation

deloc::deloc (  ) 

Constructor for the top-level delocalized internals derived class. /*---------------------------------------------------------------------------

Definition at line 26 of file deloc.cc.

References psi::extrema::internals::B, chkpt_rd_felement(), chkpt_rd_rottype(), chkpt_rd_sym_label(), psi::extrema::internals::compute_G(), psi::extrema::coord_base::coords, psi::extrema::coord_base::do_deriv, psi::extrema::coord_base::do_opt, psi::extrema::coord_base::felement, ffile_noexit(), psi::extrema::internals::fnum_coords, free_matrix(), psi::extrema::internals::G, init_array(), init_int_array(), init_matrix(), ip_exist(), psi::extrema::coord_base::iteration, psi::extrema::coord_base_carts::masses, psi::extrema::internals::mem_alloc(), mmult(), NORMAL_PRINT, psi::extrema::coord_base_carts::num_atoms, psi::extrema::coord_base::num_coords, psi::extrema::coord_base_carts::num_entries, psi::extrema::internals::print_B(), psi::extrema::coord_base::print_lvl, print_mat(), RIDICULOUS_PRINT, sq_rsp(), and psi::extrema::internals::u.

00026                : internals() {
00027 
00028   int i,j,pos;
00029 
00030   deloc::parse_input();  
00031 
00032   felement = chkpt_rd_felement();
00033   point_group = chkpt_rd_sym_label();
00034 
00035   FILE *opt_ptr;
00036   ffile_noexit(&opt_ptr,"opt.dat",2);
00037   int form_deloc=0;
00038   if( opt_ptr == NULL ) {
00039       form_deloc=1;
00040       if( do_opt )
00041           do_deriv=0;
00042       iteration = 1;
00043   }
00044   
00045   else {
00046       ip_done();
00047       ip_set_uppercase(1);
00048       ip_initialize(opt_ptr,outfile);
00049       ip_cwk_add(":OPT_INFO");
00050       if(ip_exist("DO_DERIV",0)) {
00051           do_deriv=1;
00052           punt("Can't do derivatives yet");
00053       }
00054       else
00055           do_deriv=0;
00056       iteration = 2; /* proper number set in read_opt */
00057       read_bonds();
00058   }
00059   
00060   deloc::init_simples(); 
00061   if(print_lvl > NORMAL_PRINT)
00062       deloc::print_simples();
00063 
00064   /* form B matrix */
00065   deloc::compute_B_simple();
00066 
00067   if(print_lvl >= RIDICULOUS_PRINT) {
00068       fprintf(outfile,"\n  B matrix in simples representation:\n");
00069       fnum_coords = num_simples;
00070       print_B();
00071   }
00072 
00073   if(form_deloc) {
00074 
00075       fprintf(outfile,"\n\n  Forming delocalized internal coordinates\n"); 
00076    
00077       iteration = 1;
00078       
00079       /* form and diagonalize G */
00080       fnum_coords = num_simples; /* for now */
00081       G = init_matrix(num_simples,num_simples);
00082       internals::compute_G();
00083             
00084       double **temp_mat, *evals, **evects;
00085       evals = init_array(num_simples);
00086       evects = init_matrix(num_simples,num_simples);
00087       temp_mat = init_matrix(num_simples,num_simples);
00088       sq_rsp(num_simples,num_simples, G, evals, 1, evects, 1.0e-14);
00089       mmult(G,0,evects,0,temp_mat,0,num_simples,num_simples,num_simples,0);
00090       for (j=0;j<num_simples;++j) {
00091           error = 0;
00092           for (i=0;i<num_simples;++i) {
00093               if ( fabs(temp_mat[i][j] - evals[j]*evects[i][j]) > 1.0e-13)  
00094                   error=1;
00095               if (error == 1) { 
00096                   fprintf(outfile,
00097                           "\n  WARNING error detected in evect %d\n",j); 
00098                   error = 0;
00099               }
00100           }
00101       }      
00102       free_matrix(temp_mat,num_simples);
00103       
00104       if(print_lvl>NORMAL_PRINT) {
00105           pos=0;
00106           fprintf(outfile,"\n  Eigenvalues of G:\n");
00107           for(i=(num_simples-1);i>-1;--i) {
00108               if(pos==4) {
00109                   fprintf(outfile,"\n");
00110                   pos=0;
00111               }
00112               fprintf(outfile,"   % 15.10lf",evals[i]);
00113               ++pos;
00114           }
00115       }
00116 
00117       num_nonzero = 0;
00118       for (i=0;i<num_simples;++i)
00119           if( evals[i] > ev_tol ) ++num_nonzero;
00120       fprintf(outfile,
00121               "\n  %d nonzero eigenvalues of G (non-redundant coordinates)\n",
00122               num_nonzero);
00123 
00124       /* check for proper number of non-redundant coordinates */
00125       int rotor_type;
00126       rotor_type = chkpt_rd_rottype();
00127       switch (rotor_type) {
00128       case 3:
00129           if(num_atoms==2)
00130               degrees_of_freedom = 3*num_atoms -5;
00131           else punt("Use z-matrix for linear molecules");
00132           break;
00133       case 6:
00134           degrees_of_freedom = 0;
00135           break;
00136       default:
00137           degrees_of_freedom = 3 * num_atoms - 6;
00138           break;
00139       }
00140       
00141       if(num_nonzero == degrees_of_freedom) {
00142           fprintf(outfile,
00143                   "  Non-zero eigenvalues of G equal degrees of freedom");
00144           fprintf(outfile,"(%d)\n",num_nonzero);
00145       }
00146        else if(num_nonzero > degrees_of_freedom) {
00147           fprintf(outfile,"  Only %d degrees of freedom",degrees_of_freedom);
00148           fprintf(outfile,"\n  Symmetry projection and orthogonalization");
00149           fprintf(outfile," will be performed\n");
00150       }
00151       if (num_nonzero < degrees_of_freedom) {
00152           fprintf(outfile,"\n  Not enough non-redundant coordinates,");
00153           fprintf(outfile,
00154                   "\n  try reducing 'ev_tol' and check atom connectivity\n");
00155           punt("Not enough non-redundant coordinates");
00156       }
00157       
00158       /* define delocalized internal coordinates */
00159       deloc_define = init_matrix(num_nonzero, num_simples);
00160       pos=0;
00161       for(i=0;i<num_simples;++i)
00162           if(evals[i] > ev_tol) {
00163               for(j=0;j<num_simples;++j) 
00164                   deloc_define[pos][j] = evects[j][i];
00165               ++pos;
00166           }
00167       free_matrix(evects,num_simples);
00168       
00169       if(print_lvl>=RIDICULOUS_PRINT) {
00170       fprintf(outfile,"\n  Initial coordinates:\n");
00171       print_mat(deloc_define,num_nonzero,num_simples,outfile);
00172       }
00173 
00174       /* clean up coordinate symmetry */
00175       deloc::ir_project();
00176 
00177       if(num_coords!=degrees_of_freedom) 
00178           punt("number of coordinates != degrees of freedom");
00179   
00180       for(i=0;i<num_coords;++i)
00181           for(j=0;j<num_simples;++j)
00182               deloc_define[i][j] *= fabs(deloc_define[i][j]);
00183 
00184       if(!do_deriv) {
00185           
00186           /* coordinates look good, allocate memory */
00187 
00188           /* save old B_mat first */
00189           free_matrix(B,num_simples);
00190 
00191           fnum_coords = num_coords;
00192 
00193           free_matrix(u,3*num_entries);
00194 
00195           /* keep only symmetric coordinates for optimization */
00196           int *irrep_temp;
00197           irrep_temp = init_int_array(num_nonzero);
00198           for(i=0;i<num_coords;++i) {
00199               irrep_temp[i] = deloc_irrep[i];
00200           }           
00201           free(deloc_irrep);
00202           deloc_irrep = init_int_array(num_coords);
00203 
00204           double **define_temp;
00205           int temp_num_coords=0;
00206           define_temp = init_matrix(num_coords,num_simples);
00207           for(i=0;i<num_coords;++i)
00208               for(j=0;j<num_simples;++j)
00209                   define_temp[i][j] = deloc_define[i][j];
00210           free_matrix(deloc_define,num_coords);
00211           deloc_define = init_matrix(num_coords,num_simples);
00212           int p=0;
00213           for(i=0;i<num_coords;++i) 
00214               if(irrep_temp[i]==0) {
00215                   ++temp_num_coords;
00216                   for(j=0;j<num_simples;++j)
00217                       deloc_define[p][j] = define_temp[i][j];
00218                   deloc_irrep[p] = irrep_temp[i];
00219                   ++p;
00220               }
00221 
00222           num_coords = fnum_coords = temp_num_coords;
00223         
00224           internals::mem_alloc();
00225           
00226           p = -1;
00227           /* compute coordinate values */
00228           double sum;
00229           for(i=0;i<num_coords;++i) 
00230               if(deloc_irrep[i]==0) {
00231                   sum=0;
00232                   for(j=0;j<num_simples;++j)
00233                       sum += deloc_define[i][j] * simples[j].get_val();
00234                   coords[++p] = sum;
00235               }         
00236 
00237 
00238           
00239           fprintf(outfile,"\n  Delocalized internal coordinate values:\n");
00240           for(i=0;i<num_coords;++i) 
00241               fprintf(outfile,"  %d: %lf\n",i+1,coords[i]);
00242           
00243           fflush(outfile);
00244           
00245       }    
00246   }
00247   
00248   /* reform u */
00249   for(i=0;i<num_atoms;++i) {
00250       u[3*i][3*i] = 1/masses[i];
00251       u[3*i+1][3*i+1] = 1/masses[i];
00252       u[3*i+2][3*i+2] = 1/masses[i];
00253   }
00254   
00255   return;
00256 }


The documentation for this class was generated from the following files:
Generated on Wed Feb 13 16:36:15 2008 for PSI by  doxygen 1.5.4