#include <deloc.h>

Public Member Functions | |
| deloc () | |
| ~deloc () | |
| Frees memory. | |
| void | optimize () |
| Delocalized internals optimization driver. | |
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.
| 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 }
1.5.4