00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #include "md.h"
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 void MDFrame::initparser()
00086 {
00087 char s[100];
00088
00089 INFO("MDFrame::initparser()");
00090
00091
00092 bindvar("myname",myname,STRING);
00093 bindvar("command",command,STRING);
00094 bindvar("input",input,DOUBLE);
00095 bindvar("output_dat",output_dat,DOUBLE);
00096 bindvar("output_str",output_str,STRING);
00097 bindvar("output_fmt",output_fmt,STRING);
00098
00099
00100
00101 bindvar("NP",&_NP,INT);
00102 bindvar("NP0",&_NP0,INT);
00103 bindvar("NIMAGES",&_NIMAGES,INT);
00104 bindvar("NPfree",&_NPfree,INT);
00105 bindvar("NPfixed",&_NPfixed,INT);
00106 bindvar("H",&(_H[0][0]),DOUBLE);
00107 bindvar("H0",&(_H0[0][0]),DOUBLE);
00108 bindvar("OMEGA",&_OMEGA,DOUBLE);
00109 bindvar("VIRIAL",&(_VIRIAL[0][0]),DOUBLE);
00110 bindvar("DVIRIALDexx",&(_DVIRIAL_Dexx[0][0]),DOUBLE);
00111 bindvar("Dexx",&_Dexx,DOUBLE);
00112 bindvar("VH",&(_VH[0][0]),DOUBLE);
00113 bindvar("EPOT",&_EPOT,DOUBLE);
00114 bindvar("EPBOX",&_EPOT_BOX,DOUBLE);
00115 bindvar("EPOT0",&_EPOT0,DOUBLE);
00116 bindvar("ESTRAIN",&_ESTRAIN,DOUBLE);
00117 bindvar("KATOM",&_KATOM,DOUBLE);
00118 bindvar("KBOX",&_KBOX,DOUBLE);
00119 bindvar("Tinst",&_T,DOUBLE);
00120 bindvar("zeta",&zeta,DOUBLE);
00121 bindvar("zetav",&zetav,DOUBLE);
00122 bindvar("zetaa",&zetaa,DOUBLE);
00123 bindvar("zeta2",&zeta2,DOUBLE);
00124 bindvar("zeta3",&zeta3,DOUBLE);
00125 bindvar("zeta4",&zeta4,DOUBLE);
00126 bindvar("zeta5",&zeta5,DOUBLE);
00127 bindvar("zetaNHC",zetaNHC,DOUBLE);
00128 bindvar("zetaNHCv",zetaNHCv,DOUBLE);
00129 bindvar("zetaNHCa",zetaNHCa,DOUBLE);
00130 bindvar("zetaNHC2",zetaNHC2,DOUBLE);
00131 bindvar("zetaNHC3",zetaNHC3,DOUBLE);
00132 bindvar("zetaNHC4",zetaNHC4,DOUBLE);
00133 bindvar("zetaNHC5",zetaNHC5,DOUBLE);
00134
00135
00136
00137
00138
00139
00140
00141 bindvar("HELM",&_HELM,DOUBLE);
00142 bindvar("HELMP",&_HELMP,DOUBLE);
00143 bindvar("PSTRESS",&(_PSTRESS[0][0]),DOUBLE);
00144 bindvar("TSTRESS",&(_TOTSTRESS[0][0]),DOUBLE);
00145 bindvar("TSTRESSinMPa",&(_TOTSTRESSinMPa[0][0]),DOUBLE);
00146 bindvar("PRESSURE",&_TOTPRESSURE,DOUBLE);
00147 bindvar("SIGMA",&(_SIGMA[0][0]),DOUBLE);
00148 bindvar("GH",&(_GH[0][0]),DOUBLE);
00149 bindvar("curstep",&curstep,INT);
00150 bindvar("continue_curstep",&continue_curstep,INT);
00151 bindvar("MC_accept_ratio",&MC_accept_ratio,DOUBLE);
00152 bindvar("MC_dr",&(MC_dr[0]),DOUBLE);
00153 bindvar("dH",&(dH[0][0]),DOUBLE);
00154 bindvar("dEdlambda",&dEdlambda,DOUBLE);
00155 bindvar("Wtot",&_WTOT,DOUBLE);
00156 bindvar("Wavg",&_WAVG,DOUBLE);
00157 bindvar("RLIST",&_RLIST,DOUBLE);
00158 bindvar("SKIN",&_SKIN,DOUBLE);
00159 bindvar("enable_Fext",&_ENABLE_FEXT,INT);
00160 bindvar("applyFext",&_ENABLE_FEXT,INT);
00161
00162 bindvar("TSTRESS_xx",&(_TOTSTRESS[0][0]),DOUBLE);
00163 bindvar("TSTRESS_xy",&(_TOTSTRESS[0][1]),DOUBLE);
00164 bindvar("TSTRESS_xz",&(_TOTSTRESS[0][2]),DOUBLE);
00165 bindvar("TSTRESS_yx",&(_TOTSTRESS[1][0]),DOUBLE);
00166 bindvar("TSTRESS_yy",&(_TOTSTRESS[1][1]),DOUBLE);
00167 bindvar("TSTRESS_yz",&(_TOTSTRESS[1][2]),DOUBLE);
00168 bindvar("TSTRESS_zx",&(_TOTSTRESS[2][0]),DOUBLE);
00169 bindvar("TSTRESS_zy",&(_TOTSTRESS[2][1]),DOUBLE);
00170 bindvar("TSTRESS_zz",&(_TOTSTRESS[2][2]),DOUBLE);
00171
00172 bindvar("TSTRESSinMPa_xx",&(_TOTSTRESSinMPa[0][0]),DOUBLE);
00173 bindvar("TSTRESSinMPa_xy",&(_TOTSTRESSinMPa[0][1]),DOUBLE);
00174 bindvar("TSTRESSinMPa_xz",&(_TOTSTRESSinMPa[0][2]),DOUBLE);
00175 bindvar("TSTRESSinMPa_yx",&(_TOTSTRESSinMPa[1][0]),DOUBLE);
00176 bindvar("TSTRESSinMPa_yy",&(_TOTSTRESSinMPa[1][1]),DOUBLE);
00177 bindvar("TSTRESSinMPa_yz",&(_TOTSTRESSinMPa[1][2]),DOUBLE);
00178 bindvar("TSTRESSinMPa_zx",&(_TOTSTRESSinMPa[2][0]),DOUBLE);
00179 bindvar("TSTRESSinMPa_zy",&(_TOTSTRESSinMPa[2][1]),DOUBLE);
00180 bindvar("TSTRESSinMPa_zz",&(_TOTSTRESSinMPa[2][2]),DOUBLE);
00181
00182 bindvar("H_11",&(_H[0][0]),DOUBLE);
00183 bindvar("H_12",&(_H[0][1]),DOUBLE);
00184 bindvar("H_13",&(_H[0][2]),DOUBLE);
00185 bindvar("H_21",&(_H[1][0]),DOUBLE);
00186 bindvar("H_22",&(_H[1][1]),DOUBLE);
00187 bindvar("H_23",&(_H[1][2]),DOUBLE);
00188 bindvar("H_31",&(_H[2][0]),DOUBLE);
00189 bindvar("H_32",&(_H[2][1]),DOUBLE);
00190 bindvar("H_33",&(_H[2][2]),DOUBLE);
00191
00192
00193 bindvar("conj_itmax",&conj_itmax,INT);
00194 bindvar("conj_fevalmax",&conj_fevalmax,INT);
00195 bindvar("conj_fixbox",&conj_fixbox,INT);
00196 bindvar("conj_fixboxvec",&(conj_fixboxvec[0][0]),DOUBLE);
00197 bindvar("conj_g2res",&(conj_g2res),DOUBLE);
00198 bindvar("fixbox",&conj_fixbox,INT);
00199 bindvar("fixboxvec",&(conj_fixboxvec[0][0]),DOUBLE);
00200 bindvar("conj_fixdir",&conj_fixdir,INT);
00201 bindvar("conj_fixshape",&conj_fixshape,INT);
00202 bindvar("conj_fixatoms",&conj_fixatoms,INT);
00203 bindvar("conj_ftol",&conj_ftol,DOUBLE);
00204 bindvar("conj_dfpred",&conj_dfpred,DOUBLE);
00205 bindvar("H",&(_H[0][0]),DOUBLE);
00206 bindvar("H0",&(_H0[0][0]),DOUBLE);
00207 bindvar("stress",&(_EXTSTRESS[0][0]),DOUBLE);
00208 bindvar("stressmul",&(_EXTSTRESSMUL),DOUBLE);
00209 bindvar("extforce",extforce,DOUBLE);
00210 bindvar("forcemul",&forcemul,DOUBLE);
00211 bindvar("pressureadd",&(_EXTPRESSADD),DOUBLE);
00212 bindvar("vacuumratio",&_VACUUMRATIO,DOUBLE);
00213 bindvar("hprecond",&_HPRECOND,DOUBLE);
00214 bindvar("xprecond",&_XPRECOND,DOUBLE);
00215 bindvar("yprecond",&_YPRECOND,DOUBLE);
00216 bindvar("zprecond",&_ZPRECOND,DOUBLE);
00217
00218
00219 bindvar("constrainS",&constrainS,DOUBLE);
00220 bindvar("constrainS_INST",&constrainS_inst,DOUBLE);
00221 bindvar("constrainF",&constrainF,DOUBLE);
00222 bindvar("constrainatoms",constrainatoms,INT);
00223
00224
00225 bindvar("ensemble_type",ensemble_type,STRING);
00226 bindvar("integrator_type",integrator_type,STRING);
00227 bindvar("implementation_type",&implementation_type,INT);
00228 bindvar("SAVEMEMORY",&_SAVEMEMORY,INT);
00229 bindvar("nspecies",&nspecies,INT);
00230 bindvar("totalsteps",&totalsteps,INT);
00231 bindvar("equilsteps",&equilsteps,INT);
00232 bindvar("atommass",_ATOMMASS,DOUBLE);
00233 bindvar("atomcharge",_ATOMCHARGE,DOUBLE);
00234 bindvar("wallmass",&_WALLMASS,DOUBLE);
00235 bindvar("NHMass",NHMass,DOUBLE);
00236
00237 bindvar("NHChainLen",&NHChainLen,INT);
00238
00239 bindvar("T_OBJ",&_TDES,DOUBLE);
00240 bindvar("DOUBLE_T",&_DOUBLET,INT);
00241 bindvar("allocmultiple",&allocmultiple,INT);
00242
00243
00244 bindvar("fixedatomenergypartition",&fixedatomenergypartition,INT);
00245 bindvar("vt2",&vt2,DOUBLE);
00246
00247
00248 bindvar("boxdamp",&_BOXDAMP,DOUBLE);
00249 bindvar("timestep",&_TIMESTEP,DOUBLE);
00250 bindvar("RLIST",&_RLIST,DOUBLE);
00251 bindvar("NIC",&_NIC,INT);
00252 bindvar("NNM",&_NNM,INT);
00253 bindvar("current_NIC",&_current_NIC,INT);
00254 bindvar("current_NNM",&_current_NNM,INT);
00255 bindvar("shearrate",&(_SHEARRATE[0][0]),DOUBLE);
00256 bindvar("applyshear",&applyshear,INT);
00257 bindvar("constrainedMD",&_constrainedMD,INT);
00258 bindvar("runavgCN",&runavgposition,INT);
00259
00260
00261 bindvar("mcatom",&MC_atom,INT);
00262 bindvar("lambda0",&_LAMBDA0,DOUBLE);
00263 bindvar("lambda1",&_LAMBDA1,DOUBLE);
00264 bindvar("Ecoh",&_ECOH,DOUBLE);
00265 bindvar("switchfreq",&_SWITCHFREQ,INT);
00266 bindvar("switchoffatoms",MC_switchoffatoms,INT);
00267 bindvar("switchfunc",&_SWITCHFUNC,INT);
00268 bindvar("refpotential",&_REFPOTENTIAL,INT);
00269 bindvar("ecspring",&_ECSPRING,DOUBLE);
00270 bindvar("I12_rc",&_I12_RC,DOUBLE);
00271 bindvar("I12_sigma",&_I12_SIGMA,DOUBLE);
00272 bindvar("I12_epsilon",&_I12_EPSILON,DOUBLE);
00273 bindvar("Gauss_rc",&_GAUSS_RC,DOUBLE);
00274 bindvar("Gauss_sigma",&_GAUSS_SIGMA,DOUBLE);
00275 bindvar("Gauss_epsilon",&_GAUSS_EPSILON,DOUBLE);
00276 bindvar("randseed",&_RANDSEED,INT);
00277 bindvar("MC_dV_freq",&MC_dV_freq,INT);
00278 bindvar("MC_dN_freq",&MC_dN_freq,INT);
00279 bindvar("MC_dVmax",&MC_dVmax,DOUBLE);
00280 bindvar("MC_dfrac",&MC_dfrac,DOUBLE);
00281 bindvar("MC_P_ext",&MC_P_ext,DOUBLE);
00282 bindvar("MC_mu_ext",&MC_mu_ext,DOUBLE);
00283
00284
00285 bindvar("nebspec",nebspec,INT);
00286 bindvar("readparallelnebcn",&readparallelnebcn,INT);
00287 bindvar("annealspec",annealspec,DOUBLE);
00288 bindvar("chainlength",&_CHAINLENGTH,INT);
00289
00290
00291 bindvar("L_for_QLM",&L_for_QLM,INT);
00292 bindvar("N_solid_P",&N_solid_P,INT);
00293 bindvar("Principal_Inertia",&(Principal_Inertia[0]),DOUBLE);
00294 bindvar("N_lgst_index",&N_lgst_index,DOUBLE);
00295 bindvar("N_lgst_skin",&N_lgst_skin,DOUBLE);
00296 bindvar("N_lgst_skin_index",&N_lgst_skin_index,DOUBLE);
00297 bindvar("wSKIN",&wSKIN,INT);
00298 bindvar("N_lgst_cluster",&N_lgst_cluster,INT);
00299 bindvar("Rc_for_QLM",&Rc_for_QLM,DOUBLE);
00300 bindvar("QLM_cutoff",&QLM_cutoff,DOUBLE);
00301
00302 bindvar("saveFFScn",&saveFFScn,INT);
00303 bindvar("FFSoption",&FFSoption,INT);
00304 bindvar("FFSpruning",&FFSpruning,INT);
00305 bindvar("FFScn_weight",&FFScn_weight,DOUBLE);
00306 bindvar("FFS_Pp",&FFS_Pp,DOUBLE);
00307 bindvar("FFS0_check",&FFS0_check,INT);
00308 bindvar("FFS_i",&FFS_i,INT);
00309 bindvar("FFS_i_minus",&FFS_i_minus,INT);
00310 bindvar("FFS_i_plus",&FFS_i_plus,INT);
00311
00312
00313 bindvar("VIRIAL_Ewald",&(_VIRIAL_Ewald[0][0]),DOUBLE);
00314 bindvar("VIRIAL_Ewald_Real",&(_VIRIAL_Ewald_Real[0][0]),DOUBLE);
00315 bindvar("VIRIAL_Ewald_Rec",&(_VIRIAL_Ewald_Rec[0][0]),DOUBLE);
00316 bindvar("EPOT_Ewald",&_EPOT_Ewald,DOUBLE);
00317 bindvar("EPOT_Ewald_Real",&_EPOT_Ewald_Real,DOUBLE);
00318 bindvar("EPOT_Ewald_Rec",&_EPOT_Ewald_Rec,DOUBLE);
00319 bindvar("EPOT_Ewald_Self",&_EPOT_Ewald_Self,DOUBLE);
00320 bindvar("Ewald_CE_or_PME",&Ewald_CE_or_PME,INT);
00321 bindvar("Ewald_option_Alpha",&Ewald_option_Alpha,INT);
00322 bindvar("Ewald_Alpha",&Ewald_Alpha,DOUBLE);
00323 bindvar("Ewald_precision",&Ewald_precision,DOUBLE);
00324 bindvar("Ewald_time_ratio",&Ewald_time_ratio,DOUBLE);
00325 bindvar("Ewald_Rcut",&Ewald_Rcut,DOUBLE);
00326 bindvar("CE_Kc",&CE_Kc,DOUBLE);
00327
00328 bindvar("PME_K1",&PME_K1,INT);
00329 bindvar("PME_K2",&PME_K2,INT);
00330 bindvar("PME_K3",&PME_K3,INT);
00331 bindvar("PME_bsp_n",&PME_bsp_n,INT);
00332
00333
00334 bindvar("crystalstructure",crystalstructure,STRING);
00335 bindvar("latticeconst",latticeconst,DOUBLE);
00336 bindvar("latticesize",latticesize,DOUBLE);
00337 bindvar("torsionsim",&_TORSIONSIM,INT);
00338 bindvar("torquespec",torquespec,DOUBLE);
00339 bindvar("Torque",&_TORQUE,DOUBLE);
00340 bindvar("bendsim",&_BENDSIM,INT);
00341 bindvar("bendspec",bendspec,DOUBLE);
00342 bindvar("BendMoment",&_BENDMOMENT,DOUBLE);
00343 bindvar("P_com",&(_P_COM[0]),DOUBLE);
00344 bindvar("F_com",&(_F_COM[0]),DOUBLE);
00345 bindvar("Ptheta_com",&_PTHETA_COM,DOUBLE);
00346
00347 bindvar("latticestructure",crystalstructure,STRING);
00348 bindvar("makecnspec",latticesize,DOUBLE);
00349 bindvar("mkdipole",input,DOUBLE);
00350 bindvar("mkdislspec",input,DOUBLE);
00351 bindvar("mkcylinderspec",input,DOUBLE);
00352
00353
00354 bindvar("savecn",&savecn,INT);
00355 bindvar("saveprop",&saveprop,INT);
00356 bindvar("savecfg",&savecfg,INT);
00357 bindvar("savecnfreq",&savecnfreq,INT);
00358 bindvar("savepropfreq",&savepropfreq,INT);
00359 bindvar("savecfgfreq",&savecfgfreq,INT);
00360 bindvar("printfreq",&printfreq,INT);
00361 bindvar("filecounter",&filecounter,INT);
00362 bindvar("FFSfilecounter",&FFSfilecounter,INT);
00363 bindvar("incnfile",incnfile,STRING);
00364 bindvar("finalcnfile",finalcnfile,STRING);
00365 bindvar("outpropfile",outpropfile,STRING);
00366 bindvar("intercnfile",intercnfile,STRING);
00367 bindvar("FFScnfile",FFScnfile,STRING);
00368 bindvar("intercfgfile",intercfgfile,STRING);
00369 bindvar("potfile",potfile,STRING);
00370 bindvar("writevelocity",&writevelocity,INT);
00371 bindvar("writeall",&writeall,INT);
00372 bindvar("zipfiles",&zipfiles,INT);
00373
00374
00375 bindvar("fortranpath",fortranpath,STRING);
00376 bindvar("fortranexe",fortranexe,STRING);
00377
00378
00379 bindvar("atomeyepath",atomeyepath,STRING);
00380 bindvar("atomeyerepeat",atomeyerepeat,INT);
00381 bindvar("atomeyeexe",atomeyeexe,STRING);
00382
00383
00384 bindvar("MDCASKpot",MDCASKpot,STRING);
00385
00386
00387 bindvar("win_width",&win_width,INT);
00388 bindvar("win_height",&win_height,INT);
00389 bindvar("plotfreq",&plotfreq,INT);
00390 bindvar("atomradius",atomradius,DOUBLE);
00391 bindvar("bondradius",&bondradius,DOUBLE);
00392 bindvar("bondlength",&bondlength,DOUBLE);
00393 bindvar("bondcolor",bondcolor,STRING);
00394 bindvar("highlightcolor",highlightcolor,STRING);
00395 bindvar("fixatomcolor",fixatomcolor,STRING);
00396 bindvar("backgroundcolor",backgroundcolor,STRING);
00397 bindvar("rotateangles",rotateangles,DOUBLE);
00398 bindvar("coloratoms",&coloratoms,INT);
00399
00400 bindvar("plot_limits",plot_limits,DOUBLE);
00401 bindvar("plot_atom_info",&plot_atom_info,INT);
00402 bindvar("plot_map_pbc",&plot_map_pbc,INT);
00403 bindvar("plot_color_windows",plot_color_windows,DOUBLE);
00404 bindvar("plot_color_bar",plot_color_bar,DOUBLE);
00405 bindvar("energycolorbar",plot_color_bar,DOUBLE);
00406
00407 bindvar("plot_color_axis",&plot_color_axis,INT);
00408 bindvar("NCS",&NCS,INT);
00409 bindvar("autowritegiffreq",&autowritegiffreq,INT);
00410 bindvar("NNM_plot",&_NNM_plot,INT);
00411 bindvar("rc_plot",&rc_plot,DOUBLE);
00412
00413 bindvar("L_for_QLM",&L_for_QLM,INT);
00414 bindvar("Rc_for_QLM",&Rc_for_QLM,DOUBLE);
00415
00416 for(int i=0;i<MAXSPECIES;i++)
00417 {
00418 sprintf(s,"element%d",i);
00419 bindvar(s,element[i],STRING);
00420 sprintf(s,"atomcolor%d",i);
00421 bindvar(s,atomcolor[i],STRING);
00422 }
00423 bindvar("atomcolor",atomcolor[0],STRING);
00424 for(int i=0;i<MAXCOLORS;i++)
00425 {
00426 sprintf(s,"color%02d",i);
00427 bindvar(s,colornames[i],STRING);
00428 }
00429
00430 }
00431
00432 int MDFrame::exec(char *name)
00433 {
00434 if(Organizer::exec(name)==0) return 0;
00435
00436
00437 bindcommand(name,"runcommand",runcommand());
00438
00439
00440 bindcommand_sync(name,"relax",relax());
00441 bindcommand_sync(name,"relax_by_group",relax_by_group(input));
00442 bindcommand_sync(name,"steepest_descent_relax",strelax());
00443
00444
00445 bindcommand_sync(name,"step",step());
00446 bindcommand_sync(name,"run",run());
00447 bindcommand_sync(name,"runMDSWITCH",runMDSWITCH());
00448 bindcommand_sync(name,"eval",{refreshneighborlist();eval();});
00449 bindcommand_sync(name,"multieval",multieval());
00450 bindcommand_sync(name,"eval_insertparticle",eval_insertparticle());
00451 bindcommand_sync(name,"eval_removeparticle",eval_removeparticle());
00452 bindcommand_sync(name,"refreshnnlist",refreshneighborlist());
00453 bindcommand_sync(name,"construct_plot_nnlist",NbrListPlot_reconstruct());
00454 bindcommand_sync(name,"printnnlist",NbrList_print());
00455 bindcommand_sync(name,"calphonondisp",calphonondisp());
00456 bindcommand_sync(name,"calHessian",calHessian());
00457 bindcommand_sync(name,"readHessian",readHessian());
00458 bindcommand_sync(name,"calModeHessian",calModeHessian());
00459 bindcommand_sync(name,"calmisfit",calmisfit());
00460 bindcommand_sync(name,"calmisfit2",calmisfit2());
00461 bindcommand_sync(name,"testpotential",testpotential());
00462 bindcommand_sync(name,"calcentralsymmetry",calcentralsymmetry());
00463 bindcommand_sync(name,"caldisregistry",caldisregistry());
00464 bindcommand_sync(name,"findcore",findcore());
00465 bindcommand_sync(name,"initvelocity",initvelocity());
00466 bindcommand_sync(name,"perturbevelocity",perturbevelocity());
00467 bindcommand_sync(name,"MCperturbevelocity",MCperturbevelocity());
00468 bindcommand_sync(name,"multiplyvelocity",multiplyvelocity());
00469 bindcommand_sync(name,"randomposition",randomposition());
00470
00471
00472 bindcommand_sync(name,"applyconstraint",applyconstraint());
00473
00474
00475 bindcommand_sync(name,"runMC",runMC());
00476 bindcommand_sync(name,"runMCSWITCH",runMCSWITCH());
00477 bindcommand_sync(name,"runTAMC",runTAMC());
00478 bindcommand_sync(name,"srand",srand((unsigned int)_RANDSEED));
00479 bindcommand_sync(name,"srand48",srand48((unsigned int)_RANDSEED));
00480 bindcommand_sync(name,"srandbytime",srand((unsigned int)time(NULL)));
00481 bindcommand_sync(name,"srand48bytime",srand48((unsigned int)time(NULL)));
00482
00483
00484 #ifdef _STRINGMETHOD
00485 bindcommand_sync(name,"runstringmethod",runstringmethod());
00486 #endif
00487
00488 bindcommand_sync(name,"nebrelax",nebrelax());
00489 bindcommand_sync(name,"constrainedrelax",constrainedrelax());
00490 bindcommand_sync(name,"annealpath",annealpath());
00491 bindcommand_sync(name,"statedistance",statedistance());
00492 bindcommand_sync(name,"cutpath",cutpath());
00493 bindcommand_sync(name,"initRchain",initRchain());
00494 bindcommand(name,"allocchain",AllocChain());
00495 bindcommand(name,"interpCN",interpCN(input[0]));
00496 bindcommand(name,"copyRchaintoCN",copyRchaintoCN((int)input[0]));
00497 bindcommand(name,"copyCNtoRchain",copyCNtoRchain((int)input[0]));
00498 bindcommand(name,"moveRchain",moveRchain((int)input[0],(int)input[1]));
00499
00500
00501 bindcommand(name,"calcrystalorder",calcrystalorder());
00502 bindcommand(name,"allocQLM",allocQLM());
00503 bindcommand(name,"assign_Lam",assign_Lam());
00504
00505
00506 bindcommand(name,"Ewald_init",Ewald_init());
00507 bindcommand(name,"CE",CE());
00508 bindcommand(name,"CE_clear",CE_clear());
00509
00510
00511 bindcommand(name,"PME",PME());
00512 bindcommand(name,"PME_clear",PME_clear());
00513
00514
00515 bindcommand(name,"makecrystal",makecrystal());
00516 bindcommand(name,"makecn",makecrystal());
00517 bindcommand(name,"makecut",makecut());
00518 bindcommand(name,"makedipole",makedipole());
00519 bindcommand(name,"makedislcylinder",makedislcylinder());
00520 bindcommand(name,"makecylinder",makecylinder());
00521 bindcommand(name,"makedislocation",makedislocation());
00522 bindcommand(name,"makedisloop",makedisloop());
00523 bindcommand(name,"makegrainboundary",makegrainboundary());
00524 bindcommand(name,"makegb",makegrainboundary());
00525 bindcommand(name,"makewave",makewave());
00526
00527 bindcommand(name,"scaleH",scaleH());
00528 bindcommand(name,"setH",setH());
00529 bindcommand(name,"saveH",saveH());
00530 bindcommand(name,"restoreH",restoreH());
00531 bindcommand(name,"reorientH",_H=_H.reorient());
00532 bindcommand(name,"changeH_keepR",redefinepbc());
00533 bindcommand(name,"changeH_keepS",shiftbox());
00534 bindcommand(name,"shiftbox",shiftbox());
00535 bindcommand(name,"redefinepbc",redefinepbc());
00536 bindcommand(name,"RHtoS",RHtoS());
00537 bindcommand(name,"SHtoR",SHtoR());
00538 bindcommand(name,"clearR0",clearR0());
00539 bindcommand(name,"applystrain",applystrain());
00540 bindcommand(name,"extendbox",extendbox());
00541 bindcommand(name,"scaleVel",scaleVel());
00542
00543 bindcommand(name,"cutslice",cutslice());
00544 bindcommand(name,"splicecn",splicecn());
00545 bindcommand(name,"cutpastecn",cutpastecn());
00546
00547 bindcommand(name,"setconfig1",setconfig1());
00548 bindcommand(name,"setconfig2",setconfig2());
00549 bindcommand(name,"copytoconfig1",copytoconfig1((int)input[0]));
00550 bindcommand(name,"copytoconfig2",copytoconfig2((int)input[0]));
00551 bindcommand(name,"switchconfig",switchconfig());
00552 bindcommand(name,"replacefreeatom",replacefreeatom());
00553 bindcommand(name,"relabelatom",relabelatom());
00554
00555 bindcommand(name,"moveatom",moveatom());
00556 bindcommand(name,"movegroup",movegroup());
00557 bindcommand(name,"setgroupcomvel",setgroupcomvel());
00558 bindcommand(name,"printatoms_in_sphere",printatoms_in_sphere());
00559 bindcommand(name,"pbcshiftatom",pbcshiftatom());
00560
00561 #ifdef _TORSION_OR_BENDING
00562 bindcommand(name,"maketorquehandle",maketorquehandle());
00563 bindcommand(name,"addtorque",addtorque());
00564 bindcommand(name,"copytorqueatoms",copytorqueatoms());
00565 bindcommand(name,"makebendhandle",makebendhandle());
00566 bindcommand(name,"addbend",addbend());
00567 bindcommand(name,"copybendatoms",copybendatoms());
00568 #endif
00569
00570 bindcommand(name,"fixatoms_by_ID",fixatoms_by_ID());
00571 bindcommand(name,"fixatoms_by_position",fixatoms_by_position());
00572 bindcommand(name,"fixatoms_by_group",fixatoms_by_group(input));
00573 bindcommand(name,"fixatoms_by_species",fixatoms_by_species(input));
00574 bindcommand(name,"fixatoms_by_pos_topol",fixatoms_by_pos_topol());
00575 bindcommand(name,"fixallatoms",fixallatoms());
00576 bindcommand(name,"freeallatoms",freeallatoms());
00577 bindcommand(name,"reversefixedatoms",reversefixedatoms());
00578 bindcommand(name,"constrain_fixedatoms",constrain_fixedatoms());
00579 bindcommand(name,"fix_constrainedatoms",fix_constrainedatoms());
00580
00581 bindcommand(name,"setfixedatomsspecies",setfixedatomsspecies());
00582 bindcommand(name,"setfixedatomsgroup",setfixedatomsgroup());
00583 bindcommand(name,"reversespecies",reversespecies());
00584 bindcommand(name,"movefixedatoms",movefixedatoms());
00585 bindcommand(name,"removefixedatoms",removefixedatoms());
00586 bindcommand(name,"markremovefixedatoms",markremovefixedatoms());
00587 bindcommand(name,"removeellipsoid",removeellipsoid());
00588 bindcommand(name,"removerectbox",removerectbox());
00589 bindcommand(name,"removeoverlapatoms",removeoverlapatoms());
00590 bindcommand(name,"find_com",findcenterofmass(_SR));
00591 bindcommand(name,"translate_com",translate_com());
00592 bindcommand(name,"rotate_com",rotate_com());
00593
00594 bindcommand(name,"clearFext",clearFext());
00595 bindcommand(name,"addFext_to_group",addFext_to_group());
00596
00597
00598 bindcommand(name,"writecn",writefinalcnfile(zipfiles,false));
00599 bindcommand(name,"writeavgcn",writeavgcnfile(zipfiles,false));
00600 bindcommand(name,"readcn",readcn());
00601 bindcommand(name,"readPOSCAR",readPOSCAR());
00602 bindcommand(name,"readMDCASK",readMDCASK());
00603 bindcommand(name,"readMDCASKJAIME",readMDCASKJAIME());
00604 bindcommand(name,"readXYZ",readXYZ());
00605 bindcommand(name,"writeMDCASKXYZ",writeMDCASKXYZ(finalcnfile));
00606 bindcommand(name,"readLAMMPS",readLAMMPS());
00607 bindcommand(name,"readRchain",readRchain());
00608 bindcommand(name,"convertXDATCAR",convertXDATCAR());
00609 bindcommand(name,"openintercnfile",openintercnfile());
00610 bindcommand(name,"openFFScnfile",openFFScnfile());
00611 bindcommand(name,"writeintercn",writeintercnfile(zipfiles,false));
00612 bindcommand(name,"writeFFScn",writeFFScnfile(zipfiles,false));
00613 bindcommand(name,"setfilecounter",setfilecounter());
00614 bindcommand(name,"setFFSfilecounter",setFFSfilecounter());
00615 bindcommand(name,"openpropfile",openpropfile());
00616 bindcommand(name,"closepropfile",closepropfile());
00617 bindcommand(name,"writePOSCAR",writePOSCAR());
00618 bindcommand(name,"writeMDCASK",writeMDCASK());
00619 bindcommand(name,"writePINYMD",writePINYMD(finalcnfile));
00620 bindcommand(name,"writeLAMMPS",writeLAMMPS());
00621 bindcommand(name,"writeRchain",writeRchain());
00622
00623
00624 bindcommand(name,"fortranrelax",fortranrelax());
00625
00626
00627 bindcommand(name,"atomeye",atomeye());
00628 bindcommand(name,"writeatomeyecfg",writeatomeyecfgfile(finalcnfile));
00629 bindcommand(name,"convertCNtoCFG",convertCNtoCFG());
00630 bindcommand(name,"writepovray",writepovray(finalcnfile));
00631 bindcommand(name,"writeRASMOLXYZ",writeRASMOLXYZ(finalcnfile));
00632 bindcommand(name,"readRASMOLXYZ",readRASMOLXYZ(incnfile));
00633 bindcommand(name,"writeatomtv",writeatomtv(finalcnfile));
00634
00635
00636 bindcommand(name,"writeENERGY",writeENERGY(finalcnfile));
00637 bindcommand(name,"writeFORCE",writeFORCE(finalcnfile));
00638 bindcommand(name,"writePOSITION",writePOSITION(finalcnfile));
00639 bindcommand(name,"GnuPlotHistogram",GnuPlotHistogram());
00640
00641
00642 bindcommand(name,"openwin",openwin());
00643 bindcommand(name,"plot",plot());
00644 bindcommand(name,"alloccolors",alloccolors());
00645 bindcommand(name,"alloccolorsX",alloccolorsX());
00646 bindcommand(name,"testcolor",win->testcolor());
00647 bindcommand(name,"reversergb",win->reversergb());
00648 bindcommand(name,"writeps",win->writeps());
00649 bindcommand(name,"rotate",rotate());
00650 bindcommand(name,"saverot",saverot());
00651 bindcommand(name,"wintogglepause",wintogglepause());
00652
00653 return -1;
00654 }
00655
00656 void MDFrame::runcommand()
00657 {
00658 char extcomm[400];
00659
00660 LFile::SubHomeDir(command,command);
00661 INFO("run: "<<command);
00662 if(nolog)
00663 system(command);
00664 else
00665 {
00666 if (ncom==0) system("rm -f B*.log");
00667 strcpy(extcomm,command);
00668 strcpy(extcomm+strlen(extcomm)," > B");
00669 sprintf(extcomm+strlen(extcomm),"%d.log",ncom);
00670 system(extcomm);
00671 sprintf(extcomm,"echo -- '\n'B%d.log: \"%s\"'\n' >> B.log",ncom,command);
00672 system(extcomm);
00673 sprintf(extcomm,"cat B%d.log >> B.log",ncom);
00674 system(extcomm);
00675 ncom++;
00676 }
00677 }
00678
00679 void MDFrame::initvars()
00680 {
00681 int i;
00682
00683 INFO("MDFrame::initvars()");
00684
00685 initparser();
00686 strcpy(command,"echo Hello World");
00687
00688 strcpy(incnfile,"con.cn");
00689 strcpy(intercnfile,"inter.cn");
00690 strcpy(intercfgfile,"auto.cfg");
00691 strcpy(finalcnfile,"final.cn");
00692 strcpy(potfile,"../Mo.pot");
00693
00694 strcpy(ensemble_type,"NVE");
00695 strcpy(integrator_type,"Gear6");
00696
00697 strcpy(outpropfile,"prop.out");
00698 #ifdef _CALPHONONSPECTRUM
00699 strcpy(phonondispfile,"dispersion.m");
00700 #endif
00701
00702 strcpy(bondcolor,"red");
00703 strcpy(highlightcolor,"purple");
00704
00705 for(i=0;i<MAXSPECIES;i++)
00706 {
00707 atomradius[i]=0.1;
00708 strcpy(atomcolor[i],"orange");
00709 strcpy(element[i],"Mo");
00710 }
00711 for(i=0;i<MAXCOLORS;i++)
00712 {
00713 strcpy(colornames[i],"gray50");
00714 }
00715
00716 strcpy(MDCASKpot,"SW");
00717
00718 conj_fixboxvec.clear();
00719
00720 strcpy(element[1],"Mo");
00721 strcpy(element[2],"Si");
00722 strcpy(element[3],"Cu");
00723
00724 atomeyerepeat[0]=0;
00725
00726 extforce[0] = 0;
00727 _SIGMA.clear();
00728 _H.clear();
00729 _H0.clear();
00730
00731 torquespec[0]=torquespec[1]=torquespec[2]=0;
00732 bendspec[0]=bendspec[1]=bendspec[2]=bendspec[3]=0;
00733
00734 for(i=0;i<MAXNHCLEN;i++)
00735 NHMass[i] = 0;
00736 }
00737
00738 #ifdef _USETCL
00739
00740
00741
00742 int MDFrame::Tcl_AppInit(Tcl_Interp *interp)
00743 {
00744
00745
00746
00747 if (Tcl_Init(interp) == TCL_ERROR) {
00748 return TCL_ERROR;
00749 }
00750 #ifdef _USETK
00751 if (Tk_Init(interp) == TCL_ERROR) {
00752 return TCL_ERROR;
00753 }
00754 #endif
00755
00756
00757
00758
00759 Tcl_CreateCommand(interp, "MD++", MD_Cmd,
00760 (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
00761
00762 Tcl_CreateCommand(interp, "MD++_Set", MD_SetVar,
00763 (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
00764
00765 Tcl_CreateCommand(interp, "MD++_Get", MD_GetVar,
00766 (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
00767
00768
00769
00770
00771
00772 Tcl_SetVar(interp, "tcl_rcFileName", "~/.mytcl",
00773 TCL_GLOBAL_ONLY);
00774
00775
00776
00777
00778
00779 return TCL_OK;
00780 }
00781
00782 int Tcl_Main_Wrapper(int argc, char *argv[])
00783 {
00784 int i, pid;
00785 char oldargv[1000], newargv[1000], cmd[1000], c, *p, *filename;
00786 FILE *oldfile, *newfile;
00787
00788 pid=getpid();
00789 for(i=1;i<argc;i++)
00790 {
00791 strcpy(oldargv,argv[i]);
00792
00793 p = strrchr(oldargv,'.');
00794 if(p!=NULL) p = strstr(p,".script");
00795 if(p!=NULL)
00796 {
00797
00798 filename = strrchr(oldargv,'/');
00799 if(filename==NULL)
00800 filename = oldargv;
00801 else
00802 filename ++;
00803
00804 p[0] = 0; sprintf(newargv,"/tmp/%s.tmp%d.%s",filename,pid,"tcl");
00805 p[0] = '.';
00806
00807 INFO_Printf("replace: %s -> %s\n",oldargv,newargv);
00808
00809 strcpy(argv[i],newargv);
00810
00811
00812 oldfile = fopen(oldargv,"r");
00813 newfile = fopen(newargv,"w");
00814
00815 if(oldfile==NULL) ERROR("old input file open failure");
00816 if(newfile==NULL) ERROR("new input file open failure");
00817 fprintf(newfile,"# -*-shell-script-*-\n");
00818 fprintf(newfile,"#TCL script file created from %s\n\n",oldargv);
00819 fprintf(newfile,"MD++ {\n");
00820 for(;;)
00821 {
00822 c=getc(oldfile);
00823 if(c==EOF) break;
00824 putc(c,newfile);
00825 }
00826 fprintf(newfile,"\n}\n");
00827 fclose(oldfile);
00828 fclose(newfile);
00829 }
00830 }
00831 INFO_Printf("\n");
00832
00833 setenv("TCL_LIBRARY","/usr/share/tcl8.4",0);
00834
00835 #ifdef _USETK
00836 Tcl_Interp *interp;
00837 interp = Tcl_CreateInterp();
00838 if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, (const char **)argv,
00839 0, 0) != TCL_OK) {
00840 fprintf(stderr, "%s\n", interp->result);
00841 exit(1);
00842 }
00843 Tcl_DeleteInterp(interp);
00844
00845 Tk_Main(argc, argv, Tcl_AppInit);
00846 #else
00847 Tcl_Main(argc, argv, Tcl_AppInit);
00848 #endif
00849
00850
00851 sprintf(cmd,"rm -f /tmp/*.tmp%d.tcl\n",pid);
00852
00853 system(cmd);
00854
00855 return TCL_OK;
00856 }
00857 #endif //_USETCL
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 void MDFrame::SHtoR()
00868 { for(int i=0;i<_NP;i++) _R[i]=_H*_SR[i]; }
00869 void MDFrame::RHtoS()
00870 { Matrix33 hinv=_H.inv();
00871 for(int i=0;i<_NP;i++) _SR[i]=hinv*_R[i]; }
00872 void MDFrame::RtoR0()
00873 { int i; SHtoR(); for(i=0;i<_NP;i++) _R0[i]=_R[i]; }
00874 void MDFrame::R0toR()
00875 { int i; for(i=0;i<_NP;i++) _R[i]=_R0[i]; }
00876 void MDFrame::clearR0()
00877 { int i; for(i=0;i<_NP;i++) _R0[i].clear(); }
00878
00879 bool MDFrame::Bond(int I, int J) const
00880 {
00881 return (I<=J)? ((I^J)&1) : !((I^J)&1);
00882 }
00883
00884
00885 void MDFrame::Alloc()
00886 {
00887 int size;
00888 size=_NP*allocmultiple;
00889
00890
00891 Realloc(_SR,Vector3,size);
00892 Realloc(fixed,int,size);
00893
00894 memset(fixed,0,sizeof(int)*size);
00895 bindvar("SR",_SR,DOUBLE);
00896 bindvar("fixed",fixed,INT);
00897
00898 if(_SAVEMEMORY>=9) return;
00899
00900
00901
00902 Realloc(_R,Vector3,size);
00903 Realloc(_R0,Vector3,size);
00904
00905 bindvar("R",_R,DOUBLE);
00906 bindvar("R0",_R0,DOUBLE);
00907
00908 if(_SAVEMEMORY>=8) return;
00909
00910
00911
00912 Realloc(_F,Vector3,size);
00913 Realloc(_EPOT_IND,double,size);
00914 Realloc(species,int,size);
00915
00916 memset(_EPOT_IND,0,sizeof(double)*size);
00917 memset(species,0,sizeof(int)*size);
00918
00919 bindvar("F",_F,DOUBLE);
00920 bindvar("EPOT_IND",_EPOT_IND,DOUBLE);
00921 bindvar("species",species,INT);
00922
00923 if(_SAVEMEMORY>=7) return;
00924
00925
00926
00927 Realloc(_VR,Vector3,size);
00928 Realloc(_VSR,Vector3,size);
00929
00930
00931
00932 bindvar("VR",_VR,DOUBLE);
00933 bindvar("VSR",_VSR,DOUBLE);
00934
00935 if(_SAVEMEMORY>=6) return;
00936
00937
00938
00939 Realloc(image,int,size);
00940 Realloc(_TOPOL,double,size);
00941 Realloc(group,int,size);
00942
00943 memset(image,0,sizeof(int)*size);
00944 memset(_TOPOL,0,sizeof(double)*size);
00945 memset(group,0,sizeof(int)*size);
00946
00947 bindvar("image",image,INT);
00948 bindvar("TOPOL",_TOPOL,DOUBLE);
00949 bindvar("group",group,INT);
00950
00951 if(_SAVEMEMORY>=5) return;
00952
00953
00954
00955 Realloc(_F0,Vector3,size);
00956 Realloc(_Fext,Vector3,size);
00957
00958 memset(_Fext,0,sizeof(Vector3)*size);
00959 bindvar("F0",_F0,DOUBLE);
00960 bindvar("Fext",_Fext,DOUBLE);
00961
00962 if(_SAVEMEMORY>=1) return;
00963
00964
00965
00966 Realloc(_EPOT_RMV,double,size);
00967 Realloc(_VIRIAL_IND,Matrix33,size);
00968 Realloc(_TORQUE_IND,double,size);
00969 Realloc(_BENDMOMENT_IND,double,size);
00970
00971 memset(_EPOT_RMV,0,sizeof(double)*size);
00972 memset(_VIRIAL_IND,0,sizeof(Matrix33)*size);
00973 memset(_TORQUE_IND,0,sizeof(double)*size);
00974 memset(_BENDMOMENT_IND,0,sizeof(double)*size);
00975
00976 bindvar("EPOT_RMV",_EPOT_RMV,DOUBLE);
00977 bindvar("VIRIAL_IND",_VIRIAL_IND,DOUBLE);
00978 bindvar("TORQUE_IND",_TORQUE_IND,DOUBLE);
00979 bindvar("BENDMOMENT_IND",_BENDMOMENT_IND,DOUBLE);
00980
00981 }
00982
00983
00984
00985
00986
00987
00988 void MDFrame::potential_wrapper(int *n,double x[],double *f,double df[])
00989 {
00990 int i, j, np0, np1;
00991 Matrix33 h,htran,htraninv,s,hinv,hinvtran,hsigma,sigmahtranh;
00992 double pressure,pres,vb;
00993 Vector3 gs;
00994
00995 __conj_simframe->winplot(__conj_simframe->conj_step);
00996 __conj_simframe->saveintercn(__conj_simframe->conj_step);
00997
00998 __conj_simframe->conj_step++;
00999 __conj_simframe->_H.set(x);
01000
01001
01002 __conj_simframe->_H*=__conj_simframe->_HPRECOND;
01003
01004 h=__conj_simframe->_H;
01005 htran=h.tran();
01006 htraninv=htran.inv();
01007
01008 np0=0;
01009 np1=__conj_simframe->_NP;
01010
01011 for(i=np0;i<np1;i++)
01012 {
01013 __conj_simframe->_SR[i].set(x+i*3+9);
01014 __conj_simframe->_SR[i].x*=__conj_simframe->_XPRECOND;
01015 __conj_simframe->_SR[i].y*=__conj_simframe->_YPRECOND;
01016 __conj_simframe->_SR[i].z*=__conj_simframe->_ZPRECOND;
01017 __conj_simframe->_R[i]=h*__conj_simframe->_SR[i];
01018 }
01019
01020
01021 __conj_simframe->call_potential();
01022 __conj_simframe->calcprop();
01023 vb=0;
01024
01025 if(__conj_simframe->conj_fixbox) __conj_simframe->_GH.clear();
01026 else
01027 {
01028
01029 if(__conj_simframe->conj_fixshape)
01030 {
01031 pressure=__conj_simframe->_VIRIAL.trace()/3;
01032 __conj_simframe->_GH.clear();
01033 }
01034 else
01035 {
01036
01037 pres=__conj_simframe->_EXTSTRESS.trace()/3;
01038 pres*=__conj_simframe->_EXTSTRESSMUL;
01039 pres+=__conj_simframe->_EXTPRESSADD;
01040 pres/=160.2e3;
01041 s=__conj_simframe->_VIRIAL;
01042 s[0][0]-=__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)*pres;
01043 s[1][1]-=__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)*pres;
01044 s[2][2]-=__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)*pres;
01045
01046 hinv=h.inv(); hinvtran=hinv.tran();
01047 s=s*hinvtran;
01048 hsigma=h*__conj_simframe->_SIGMA;
01049 __conj_simframe->_GH=s-hsigma;
01050 __conj_simframe->_GH*=-1;
01051 for(i=0;i<3;i++)
01052 for(j=0;j<3;j++)
01053 if(__conj_simframe->conj_fixboxvec[i][j]==1)
01054 __conj_simframe->_GH[i][j]=0;
01055 sigmahtranh=(__conj_simframe->_SIGMA*htran)*h;
01056 vb=pres*__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)+sigmahtranh.trace()*0.5;
01057 }
01058 }
01059
01060
01061 __conj_simframe->_GH*=__conj_simframe->_HPRECOND;
01062
01063 __conj_simframe->_GH.copytoarray(df);
01064
01065 for(i=np0;i<np1;i++)
01066 {
01067 if((__conj_simframe->fixed[i])
01068 ||(__conj_simframe->conj_fixatoms))
01069 gs.clear();
01070 else
01071 gs=-htran*__conj_simframe->_F[i];
01072
01073 gs.x*=__conj_simframe->_XPRECOND;
01074 gs.y*=__conj_simframe->_YPRECOND;
01075 gs.z*=__conj_simframe->_ZPRECOND;
01076 gs.copytoarray(df+i*3+9);
01077 }
01078 *f=__conj_simframe->_EPOT + vb;
01079
01080
01081 __conj_simframe->conj_g2res=0;
01082 for(i=0;i<*n;i++)
01083 __conj_simframe->conj_g2res+=df[i]*df[i];
01084 }
01085
01086 void MDFrame::potential_wrapper_c(int n,double x[],double *f,double df[])
01087 {
01088 static int ncalls=0;
01089 potential_wrapper(&n,x,f,df);
01090
01091 INFO_Printf("%10d : %22.16e\n",ncalls++,*f);
01092
01093 }
01094
01095 int MDFrame::relax()
01096 {
01097
01098
01099 int i,n,_NP0,_NP1;
01100 double *conj_space,*conj_x,*conj_g,*conj_w, pres;
01101 Matrix33 prp, hinv, hinvtran;
01102
01103 INFO("Relax");
01104 _NP0=0;
01105 _NP1=_NP;
01106 n=_NP*3+9;
01107 conj_step=0;
01108
01109 conj_space=NULL;
01110 Realloc(conj_space,double,n*8);
01111
01112 conj_x=conj_space;
01113 conj_g=conj_space+n;
01114 conj_w=conj_space+n*2;
01115
01116 _H.copytoarray(conj_x);
01117
01118
01119 for(i=0;i<9;i++) conj_x[i]/=_HPRECOND;
01120
01121 for(i=_NP0;i<_NP1;i++)
01122 _SR[i].copytoarray(conj_x+i*3+9);
01123
01124 for(i=_NP0;i<_NP1;i++)
01125 {
01126 conj_x[9+i*3] /=_XPRECOND;
01127 conj_x[9+i*3+1]/=_YPRECOND;
01128 conj_x[9+i*3+2]/=_ZPRECOND;
01129 }
01130 __conj_simframe=this;
01131
01132
01133 pres=_EXTSTRESS.trace()/3;
01134 prp=_EXTSTRESS;
01135 prp[0][0]-=pres;
01136 prp[1][1]-=pres;
01137 prp[2][2]-=pres;
01138 prp*=_EXTSTRESSMUL;
01139 pres*=_EXTSTRESSMUL;
01140 pres+=_EXTPRESSADD;
01141
01142
01143 if(fabs(_H0.det())<1e-10)
01144 {
01145 INFO("H0 has not been specified. Use current H as reference.");
01146 hinv=_H.inv();
01147 hinvtran=hinv.tran();
01148 _OMEGA=_H.det();
01149 }
01150 else
01151 {
01152 INFO("H0 has been specified as reference.");
01153 hinv=_H0.inv();
01154 hinvtran=hinv.tran();
01155 _OMEGA=_H0.det();
01156 }
01157 _SIGMA=((hinv*prp)*hinvtran)*_OMEGA*(1-_VACUUMRATIO);
01158 _SIGMA/=160.2e3;
01159
01160
01161 CGRelax(potential_wrapper_c,n,
01162 conj_ftol,conj_fevalmax,conj_dfpred,
01163 conj_x,conj_g,&conj_f,conj_w);
01164
01165 _H.set(conj_x);
01166
01167
01168 _H*=_HPRECOND;
01169
01170 for(i=_NP0;i<_NP1;i++)
01171 {
01172 _SR[i].set(conj_x+i*3+9);
01173 _SR[i].x*=_XPRECOND;
01174 _SR[i].y*=_YPRECOND;
01175 _SR[i].z*=_ZPRECOND;
01176 }
01177 INFO_Printf("\tconj_f = %24.18g\n",conj_f);
01178
01179 free(conj_space);
01180 return 0;
01181 }
01182
01183 void MDFrame::strelax()
01184 {
01185 int i;
01186 double Ediff, Eold, Edrop;
01187
01188 INFO("Run Steepest Descent Relax");
01189
01190 Edrop = input[0];
01191 Ediff = 0.0;
01192 INFO("Tolerance = "<<Edrop<<" (eV)");
01193 INFO("Time step = "<<_TIMESTEP);
01194
01195 call_potential();
01196 SHtoR();
01197
01198 RtoR0();
01199 Eold = _EPOT;
01200
01201 if(continue_curstep)
01202 step0 = curstep;
01203 else
01204 step0 = 0;
01205 INFO("curstep="<<curstep<<", Epot="<<_EPOT);
01206 for(curstep=step0;curstep<totalsteps;curstep++)
01207 {
01208 for(i=0;i<_NP;i++)
01209 _R[i] += _F[i]*_TIMESTEP;
01210
01211 RHtoS();
01212 call_potential();
01213 Ediff = _EPOT - Eold;
01214
01215 if ((curstep%plotfreq) == 0)
01216 winplot();
01217
01218 if (Ediff>0)
01219 {
01220 INFO("Energy is increasing, Delta(E)="<<Ediff<<" (eV)");
01221 _TIMESTEP/=10.0;
01222 R0toR();
01223 RHtoS();
01224 call_potential();
01225 INFO("Decrease timestep as "<<_TIMESTEP);
01226 INFO("Restore old configuration.");
01227 continue;
01228 }
01229
01230 if (fabs(Ediff) < Edrop)
01231 {
01232 INFO("Delta(E) = "<<Ediff<<" (eV)");
01233 INFO("Energy tolerance = "<<Edrop<<" (eV) achieved ");
01234 break;
01235 }
01236
01237 if (((curstep%printfreq)==0)&&(curstep>step0))
01238 INFO("curstep="<<curstep<<", Epot="<<_EPOT);
01239
01240
01241 RtoR0();
01242 Eold = _EPOT;
01243 }
01244 INFO("curstep="<<curstep<<", Epot="<<_EPOT);
01245
01246 if ((curstep>=totalsteps) && (fabs(Ediff)>=Edrop))
01247 INFO("Maximum iterations reached!!");
01248 }
01249
01250 void MDFrame::relax_by_group(double *myinput)
01251 {
01252
01253
01254
01255
01256
01257
01258
01259
01260 int i, j, NgrpID, flag;
01261 NgrpID = (int) myinput[0];
01262
01263 if (NgrpID <= 0 )
01264 {
01265 ERROR("Number of groups should be greater than zero.");
01266 return;
01267 }
01268
01269 for (i=0; i<_NP; i++)
01270 {
01271 if (fixed[i]==1)
01272 continue;
01273 else
01274 {
01275 flag = 1;
01276 for (j=0; j<NgrpID; j++)
01277 {
01278 if (group[i]==(int) myinput[j+1])
01279 {
01280 flag = 0; break;
01281 }
01282 }
01283 if (flag) fixed[i]=1;
01284 }
01285 }
01286 INFO("test");
01287 relax();
01288 }
01289
01290
01291
01292
01293
01294 void MDFrame::cstr_potential_wrapper(int *n,double x[],double *f,double df[])
01295 {
01296 int i, j, np0, np1, ipt;
01297 Matrix33 h,htran,htraninv,s,hinv,hinvtran,hsigma,sigmahtranh, G;
01298 double pressure,pres,vb, gn, dist;
01299 Vector3 gs, ds0, dF, dsstarstar, dr0;
01300 #if 0
01301 Vector3 ds; double cs;
01302 #endif
01303 __conj_simframe->winplot(__conj_simframe->conj_step);
01304 __conj_simframe->saveintercn(__conj_simframe->conj_step);
01305
01306 __conj_simframe->conj_step++;
01307 __conj_simframe->_H.set(x);
01308
01309
01310 __conj_simframe->_H*=__conj_simframe->_HPRECOND;
01311
01312 h=__conj_simframe->_H;
01313 htran=h.tran();
01314 htraninv=htran.inv();
01315
01316 np0=0;
01317 np1=__conj_simframe->_NP;
01318
01319 for(i=np0;i<np1;i++)
01320 {
01321 __conj_simframe->_SR[i].set(x+i*3+9);
01322 __conj_simframe->_SR[i].x*=__conj_simframe->_XPRECOND;
01323 __conj_simframe->_SR[i].y*=__conj_simframe->_YPRECOND;
01324 __conj_simframe->_SR[i].z*=__conj_simframe->_ZPRECOND;
01325 __conj_simframe->_R[i]=h*__conj_simframe->_SR[i];
01326 }
01327
01328
01329 __conj_simframe->call_potential();
01330 __conj_simframe->calcprop();
01331 vb=0;
01332
01333 if(__conj_simframe->conj_fixbox) __conj_simframe->_GH.clear();
01334 else
01335 {
01336
01337 if(__conj_simframe->conj_fixshape)
01338 {
01339 pressure=__conj_simframe->_VIRIAL.trace()/3;
01340 __conj_simframe->_GH.clear();
01341 }
01342 else
01343 {
01344
01345 pres=__conj_simframe->_EXTSTRESS.trace()/3;
01346 pres*=__conj_simframe->_EXTSTRESSMUL;
01347 pres+=__conj_simframe->_EXTPRESSADD;
01348 pres/=160.2e3;
01349 s=__conj_simframe->_VIRIAL;
01350 s[0][0]-=__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)*pres;
01351 s[1][1]-=__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)*pres;
01352 s[2][2]-=__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)*pres;
01353
01354 hinv=h.inv(); hinvtran=hinv.tran();
01355 s=s*hinvtran;
01356 hsigma=h*__conj_simframe->_SIGMA;
01357 __conj_simframe->_GH=s-hsigma;
01358 __conj_simframe->_GH*=-1;
01359 for(i=0;i<3;i++)
01360 for(j=0;j<3;j++)
01361 if(__conj_simframe->conj_fixboxvec[i][j]==1)
01362 __conj_simframe->_GH[i][j]=0;
01363 sigmahtranh=(__conj_simframe->_SIGMA*htran)*h;
01364 vb=pres*__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO)+sigmahtranh.trace()*0.5;
01365 }
01366 }
01367
01368
01369 __conj_simframe->_GH*=__conj_simframe->_HPRECOND;
01370
01371 __conj_simframe->_GH.copytoarray(df);
01372
01373
01374
01375 gn=0; G = htran*h; dist = 0;
01376 for(i=1;i<=__conj_simframe->constrainatoms[0];i++)
01377 {
01378 ipt=__conj_simframe->constrainatoms[i];
01379 ds0=(__conj_simframe->_SR2[ipt]-__conj_simframe->dscom12)-__conj_simframe->_SR1[ipt];
01380 dsstarstar = G*ds0;
01381 gs=htran*__conj_simframe->_F[ipt];
01382 gn+=dot(gs,dsstarstar);
01383 dist+=dot(dsstarstar,dsstarstar);
01384 }
01385
01386
01387 gn/=dist;
01388
01389
01390
01391
01392 for(i=1;i<=__conj_simframe->constrainatoms[0];i++)
01393 {
01394 ipt=__conj_simframe->constrainatoms[i];
01395 ds0=(__conj_simframe->_SR2[ipt]-__conj_simframe->dscom12)-__conj_simframe->_SR1[ipt];
01396
01397
01398 dsstarstar = h*ds0;
01399 dF=dsstarstar*gn;
01400
01401 __conj_simframe->_F[ipt]-=dF;
01402 }
01403
01404 #if 0
01405
01406
01407 gn=0;
01408 for(i=1;i<=__conj_simframe->constrainatoms[0];i++)
01409 {
01410 ipt=__conj_simframe->constrainatoms[i];
01411 ds0=__conj_simframe->_SR2[ipt]-__conj_simframe->dscom12-__conj_simframe->_SR1[ipt];
01412 dsstarstar=G*ds0;
01413 gs=-htran*__conj_simframe->_F[ipt];
01414 gn+=dot(gs,dsstarstar);
01415 }
01416 gn/=__conj_simframe->constrain_dist;
01417 #endif
01418
01419
01420
01421 for(i=np0;i<np1;i++)
01422 {
01423 if((__conj_simframe->fixed[i])
01424 ||(__conj_simframe->conj_fixatoms))
01425 gs.clear();
01426 else
01427 gs=-htran*__conj_simframe->_F[i];
01428 gs.x*=__conj_simframe->_XPRECOND;
01429 gs.y*=__conj_simframe->_YPRECOND;
01430 gs.z*=__conj_simframe->_ZPRECOND;
01431 gs.copytoarray(df+i*3+9);
01432 }
01433 *f=__conj_simframe->_EPOT + vb;
01434 }
01435
01436 void MDFrame::cstr_potential_wrapper_c(int n,double x[],double *f,double df[])
01437 {
01438 static int ncalls=0;
01439 cstr_potential_wrapper(&n,x,f,df);
01440 INFO_Printf("%10d : %22.16e\n",ncalls++,*f);
01441 }
01442
01443 int MDFrame::applyconstraint()
01444 {
01445 int i,ipt;
01446 double sumds02, ds_star2;
01447 Vector3 ds, ds0, dr0, ds_star;
01448 Matrix33 hinv, htraninv;
01449
01450 if(constrainatoms[0]<=0)
01451 {
01452 ERROR("constrainedatoms not set!");
01453 return -1;
01454 }
01455 if(constrainatoms[0]>MAXCONSTRAINATOMS)
01456 {
01457 ERROR("Number of constrained atoms is too big!");
01458 return -1;
01459 }
01460 if(_SR1 == NULL || _SR2 == NULL)
01461 {
01462 if(_SR1 == NULL)
01463 ERROR("config1 is not set!");
01464 else
01465 ERROR("config2 is not set!");
01466 return -1;
01467 }
01468
01469
01470
01471
01472
01473 dscom12.clear();
01474 for(i=1;i<=constrainatoms[0];i++)
01475 {
01476 ipt=constrainatoms[i];
01477 dscom12+=_SR2[ipt];
01478 dscom12-=_SR1[ipt];
01479 }
01480 dscom12 /= constrainatoms[0];
01481
01482
01483
01484 #if 0
01485 for(i=1;i<=constrainatoms[0];i++)
01486 {
01487 ipt=constrainatoms[i];
01488 _SR2[ipt]-=dscom;
01489 }
01490 #endif
01491 hinv=_H.inv(); htraninv=hinv.tran();
01492 constrainS_inst=0; sumds02=0; ds_star2=0;
01493
01494
01495 constrain_dist=0;
01496 for(i=1;i<=constrainatoms[0];i++)
01497 {
01498 ipt=constrainatoms[i];
01499 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
01500 ds_star=htraninv*ds0;
01501 ds =_SR[ipt]-_SR1[ipt];
01502 constrainS_inst+=dot(ds,ds0);
01503 constrain_dist+=ds0.norm2();
01504 sumds02+=ds0.norm2();
01505 ds_star2+=ds_star.norm2();
01506 }
01507 constrainS_inst/=constrain_dist;
01508 INFO_Printf("(R_B - R_A)*S^star/|S^star| = %25.18e\n",sumds02/sqrt(ds_star2));
01509 INFO_Printf("Before displacement, s=%f constrain_dist=%e\n",constrainS_inst,constrain_dist);
01510
01511
01512 for(i=1;i<=constrainatoms[0];i++)
01513 {
01514
01515
01516 ipt=constrainatoms[i];
01517 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
01518 ds0*=(constrainS-constrainS_inst);
01519
01520 _SR[ipt]+=ds0;
01521
01522
01523 }
01524
01525
01526 constrainS_inst=0;
01527 for(i=1;i<=constrainatoms[0];i++)
01528 {
01529 ipt=constrainatoms[i];
01530 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
01531 ds =_SR[ipt]-_SR1[ipt];
01532 constrainS_inst+=dot(ds,ds0);
01533 }
01534 constrainS_inst/=constrain_dist;
01535 INFO_Printf("after displacement s=%f constrain_dist=%e\n",constrainS_inst,constrain_dist);
01536
01537 return 0;
01538 }
01539
01540 int MDFrame::constrainedrelax()
01541 {
01542
01543
01544 int i,n,ipt;
01545 double *conj_space,*conj_x,*conj_g,*conj_w, pres;
01546 Matrix33 prp, htran, hinv, hinvtran, G;
01547 Vector3 ds, ds0, dsstarstar;
01548 FILE *fp;
01549 char filename[100];
01550
01551 INFO("Constrained Relax");
01552
01553 if(constrainatoms[0]<=0)
01554 {
01555 ERROR("constrainedatoms not set!");
01556 return -1;
01557 }
01558 if(constrainatoms[0]>MAXCONSTRAINATOMS)
01559 {
01560 ERROR("Number of constrained atoms is too big!");
01561 return -1;
01562 }
01563 if(_SR1 == NULL || _SR2 == NULL)
01564 {
01565 if(_SR1 == NULL)
01566 ERROR("config1 is not set!");
01567 else
01568 ERROR("config2 is not set!");
01569 return -1;
01570 }
01571
01572 caldscom12();
01573
01574 htran=_H.tran(); G=htran*_H;
01575
01576 constrain_dist=0; constrainS_inst=0;
01577 for(i=1;i<=constrainatoms[0];i++)
01578 {
01579 ipt=constrainatoms[i];
01580 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
01581 dsstarstar = G*ds0;
01582 ds =_SR[ipt]-_SR1[ipt];
01583 constrainS_inst+=dot(ds,dsstarstar);
01584 constrain_dist+=dot(ds0,dsstarstar);
01585 }
01586 constrainS_inst/=constrain_dist;
01587 INFO_Printf("before displacement s=%f constrain_dist=%e\n",constrainS_inst,constrain_dist);
01588
01589
01590 for(i=1;i<=constrainatoms[0];i++)
01591 {
01592 ipt=constrainatoms[i];
01593 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
01594 ds0*=(constrainS-constrainS_inst);
01595 _SR[ipt]+=ds0;
01596
01597
01598 }
01599
01600
01601 constrainS_inst=0;
01602 for(i=1;i<=constrainatoms[0];i++)
01603 {
01604 ipt=constrainatoms[i];
01605 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
01606 dsstarstar=G*ds0;
01607 ds =_SR[ipt]-_SR1[ipt];
01608 constrainS_inst+=dot(ds,dsstarstar);
01609 }
01610 constrainS_inst/=constrain_dist;
01611 INFO_Printf("after displacement s=%f constrain_dist=%e\n",constrainS_inst,constrain_dist);
01612
01613 n=_NP*3+9;
01614 conj_step=0;
01615
01616 conj_space=NULL;
01617 Realloc(conj_space,double,n*8);
01618
01619 conj_x=conj_space;
01620 conj_g=conj_space+n;
01621 conj_w=conj_space+n*2;
01622
01623 _H.copytoarray(conj_x);
01624
01625
01626 for(i=0;i<9;i++) conj_x[i]/=_HPRECOND;
01627
01628
01629 for(i=0;i<_NP;i++)
01630 _SR[i].copytoarray(conj_x+i*3+9);
01631
01632 for(i=0;i<_NP;i++)
01633 {
01634 conj_x[9+i*3] /=_XPRECOND;
01635 conj_x[9+i*3+1]/=_YPRECOND;
01636 conj_x[9+i*3+2]/=_ZPRECOND;
01637 }
01638 __conj_simframe=this;
01639
01640
01641 pres=_EXTSTRESS.trace()/3;
01642 prp=_EXTSTRESS;
01643 prp[0][0]-=pres;
01644 prp[1][1]-=pres;
01645 prp[2][2]-=pres;
01646 prp*=_EXTSTRESSMUL;
01647 pres*=_EXTSTRESSMUL;
01648 pres+=_EXTPRESSADD;
01649
01650 hinv=_H.inv();
01651 hinvtran=hinv.tran();
01652 _SIGMA=((hinv*prp)*hinvtran)*__conj_simframe->_OMEGA*(1-__conj_simframe->_VACUUMRATIO);
01653 _SIGMA/=160.2e3;
01654
01655
01656 CGRelax(cstr_potential_wrapper_c,n,
01657 conj_ftol,conj_fevalmax,conj_dfpred,
01658 conj_x,conj_g,&conj_f,conj_w);
01659
01660 _H.set(conj_x);
01661
01662
01663 _H*=_HPRECOND;
01664
01665 for(i=0;i<_NP;i++)
01666 {
01667 _SR[i].set(conj_x+i*3+9);
01668 _SR[i].x*=_XPRECOND;
01669 _SR[i].y*=_YPRECOND;
01670 _SR[i].z*=_ZPRECOND;
01671 }
01672 INFO_Printf("\tconj_f = %24.18g\n",conj_f);
01673
01674
01675 constrainS_inst=0;
01676 for(i=1;i<=constrainatoms[0];i++)
01677 {
01678 ipt=constrainatoms[i];
01679 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
01680 dsstarstar = G*ds0;
01681 ds =_SR[ipt]-_SR1[ipt];
01682 constrainS_inst+=dot(ds,dsstarstar);
01683 }
01684 constrainS_inst/=constrain_dist;
01685 INFO_Printf("after relaxation s=%f E=%25.15e \n",constrainS_inst,conj_f);
01686
01687
01688 sprintf(filename,"chain%5.3f.out",constrainS_inst);
01689 fp=fopen(filename,"w");
01690 for(i=1;i<=constrainatoms[0];i++)
01691 {
01692 ipt=constrainatoms[i];
01693 fprintf(fp,"%25.15e %25.15e %25.15e\n",_R[ipt].x,_R[ipt].y,_R[ipt].z);
01694 }
01695 fclose(fp);
01696
01697 free(conj_space);
01698 return 0;
01699 }
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711 void MDFrame::ECpotential()
01712 {
01713 int i;
01714 Vector3 dr, ds;
01715 double dE;
01716 if(_SR1==NULL)
01717 {
01718 FATAL("ECpotential: _SR1 == NULL");
01719 return;
01720 }
01721 _EPOT=0;
01722 for(i=0;i<_NP;i++)
01723 {
01724 ds=_SR[i]-_SR1[i];
01725 dr=_H*ds;
01726 _F[i]=dr*(-_ECSPRING);
01727 dE=dr.norm2()*_ECSPRING*0.5;
01728 _EPOT+=dE;
01729
01730 }
01731 }
01732
01733 void MDFrame::ECpotential_energyonly()
01734 {
01735 int i;
01736 Vector3 dr, ds;
01737 double dE;
01738 if(_SR1==NULL)
01739 {
01740 FATAL("ECpotential: _SR1 == NULL");
01741 return;
01742 }
01743 _EPOT=0;
01744 for(i=0;i<_NP;i++)
01745 {
01746 ds=_SR[i]-_SR1[i];
01747 dr=_H*ds;
01748 dE=dr.norm2()*_ECSPRING*0.5;
01749 _EPOT+=dE;
01750
01751 }
01752 }
01753
01754 double MDFrame::ECpotential_energyonly(int iatom)
01755 {
01756 double Eatom;
01757 Vector3 dr, ds;
01758 if(_SR1==NULL)
01759 {
01760 FATAL("ECpotential: _SR1 == NULL");
01761 return 0;
01762 }
01763 Eatom=0;
01764
01765 ds=_SR[iatom]-_SR1[iatom];
01766 dr=_H*ds;
01767 Eatom=dr.norm2()*_ECSPRING*0.5;
01768 return Eatom;
01769 }
01770
01771 void MDFrame::HApotential_energyonly()
01772 {
01773 int n, i, id, j, jd;
01774 double Lam;
01775 Vector3 dr, ds;
01776 double dE, di, dj;
01777 if(_SR1==NULL)
01778 {
01779 FATAL("HApotential: _SR1 == NULL");
01780 return;
01781 }
01782 _EPOT=0;
01783 for(n=0;n<heslen;n++)
01784 {
01785 i = hesind[n*4 ];
01786 id= hesind[n*4+1];
01787 j = hesind[n*4+2];
01788 jd= hesind[n*4+3];
01789
01790 Lam = hes[n];
01791
01792 ds=_SR[i]-_SR1[i];
01793 dr=_H*ds; di=dr[id];
01794
01795 ds=_SR[j]-_SR1[j];
01796 dr=_H*ds; dj=dr[jd];
01797
01798 dE=0.5*Lam*di*dj;
01799 _EPOT+=dE;
01800 }
01801 }
01802
01803 void MDFrame::HApotential()
01804 {
01805 int n, i, id, j, jd;
01806 double Lam;
01807 Vector3 dr, ds;
01808 double dE, di, dj;
01809 if(_SR1==NULL)
01810 {
01811 FATAL("HApotential: _SR1 == NULL");
01812 return;
01813 }
01814 _EPOT=0;
01815 for(i=0;i<_NP;i++) _F[i].clear();
01816
01817 for(n=0;n<heslen;n++)
01818 {
01819 i = hesind[n*4 ];
01820 id= hesind[n*4+1];
01821 j = hesind[n*4+2];
01822 jd= hesind[n*4+3];
01823
01824 Lam = hes[n];
01825
01826 ds=_SR[i]-_SR1[i];
01827 dr=_H*ds; di=dr[id];
01828
01829 ds=_SR[j]-_SR1[j];
01830 dr=_H*ds; dj=dr[jd];
01831
01832 dE=0.5*Lam*di*dj;
01833 _EPOT+=dE;
01834
01835 _F[i][id] -= 0.5*Lam*dj;
01836 _F[j][jd] -= 0.5*Lam*di;
01837 }
01838 }
01839
01840 void MDFrame::I12potential_energyonly()
01841 {
01842 int ipt, j, jpt;
01843 double rc2, sig2, r2, r4, ri12;
01844 Vector3 rij, sij;
01845
01846 refreshneighborlist();
01847
01848 _EPOT=0;
01849
01850 rc2 = SQR(_I12_RC);
01851 sig2= SQR(_I12_SIGMA);
01852 for(ipt=0;ipt<_NP;ipt++)
01853 {
01854 for(j=0;j<nn[ipt];j++)
01855 {
01856
01857 jpt=nindex[ipt][j];
01858 if(ipt>jpt) continue;
01859 sij=_SR[jpt]-_SR[ipt];
01860 sij.subint();
01861 rij=_H*sij;
01862 r2=rij.norm2();
01863 if(r2<=rc2)
01864 {
01865 r4=(sig2/r2);
01866 ri12=1./(r4*r4*r4);
01867 _EPOT+=ri12;
01868 }
01869 }
01870 }
01871 _EPOT *= _I12_EPSILON;
01872 }
01873
01874 void MDFrame::I12potential()
01875 {
01876 int ipt, j, jpt;
01877 double rc2, sig2, r02, r2, ri4, ri12, r, Uc, DUDRc, U, U0, K;
01878 Vector3 rij, sij, fij;
01879
01880 refreshneighborlist();
01881
01882 _EPOT=0;
01883
01884 for(ipt=0;ipt<_NP;ipt++)
01885 {_F[ipt].clear(); _EPOT_IND[ipt]=0;}
01886 _VIRIAL.clear();
01887
01888 rc2 = SQR(_I12_RC);
01889 sig2= SQR(_I12_SIGMA);
01890 ri4 = SQR(sig2/rc2);
01891
01892
01893 Uc = 0;
01894 DUDRc = 0;
01895
01896 r02 = sig2*0.1;
01897 ri4 = SQR(sig2/r02);
01898 U0 = 7*_I12_EPSILON * (ri4*ri4*ri4);
01899 K = 6*_I12_EPSILON * (ri4*ri4*ri4) / r02;
01900
01901 for(ipt=0;ipt<_NP;ipt++)
01902 {
01903 for(j=0;j<nn[ipt];j++)
01904 {
01905 jpt=nindex[ipt][j];
01906 if(ipt>jpt) continue;
01907 sij=_SR[jpt]-_SR[ipt];
01908 sij.subint();
01909 rij=_H*sij;
01910 r2=rij.norm2();
01911 if(r2<=rc2)
01912 {
01913 if(r2<r02)
01914 {
01915 r=sqrt(r2);
01916 U = U0 - K*r2 - r*DUDRc + (_I12_RC*DUDRc-Uc);
01917 fij=rij*(2*K + DUDRc/r);
01918 }
01919 else {
01920 r=sqrt(r2);
01921 ri4=SQR(sig2/r2);
01922 ri12=(ri4*ri4*ri4);
01923 U = _I12_EPSILON * ri12 - r*DUDRc + (_I12_RC*DUDRc-Uc);
01924 fij=rij*(12*_I12_EPSILON*ri12/r2 + DUDRc/r);
01925 }
01926 _EPOT+=U;
01927 _F[ipt]-=fij;
01928 _F[jpt]+=fij;
01929 _EPOT_IND[ipt]+=U*0.5;
01930 _EPOT_IND[jpt]+=U*0.5;
01931 _VIRIAL.addnvv(1.,fij,rij);
01932 }
01933 }
01934 }
01935 }
01936
01937 void MDFrame::GAUSSpotential()
01938 {
01939 int ipt, j, jpt;
01940 double rc2, sig2, r2, U;
01941 Vector3 rij, sij, fij;
01942
01943 refreshneighborlist();
01944
01945 _EPOT=0;
01946
01947 for(ipt=0;ipt<_NP;ipt++)
01948 {_F[ipt].clear(); _EPOT_IND[ipt]=0;}
01949 _VIRIAL.clear();
01950
01951
01952 rc2 = SQR(_GAUSS_RC);
01953 sig2= SQR(_GAUSS_SIGMA);
01954
01955 for(ipt=0;ipt<_NP;ipt++)
01956 {
01957 for(j=0;j<nn[ipt];j++)
01958 {
01959 jpt=nindex[ipt][j];
01960 if(ipt>jpt) continue;
01961 sij=_SR[jpt]-_SR[ipt];
01962 sij.subint();
01963 rij=_H*sij;
01964 r2=rij.norm2();
01965 if(r2<=rc2)
01966 {
01967 U = _GAUSS_EPSILON * exp(-r2/2/sig2);
01968 fij = rij * (U/sig2);
01969 _EPOT+=U;
01970 _F[ipt]-=fij;
01971 _F[jpt]+=fij;
01972 _EPOT_IND[ipt]+=U*0.5;
01973 _EPOT_IND[jpt]+=U*0.5;
01974 _VIRIAL.addnvv(1.,fij,rij);
01975 }
01976 }
01977 }
01978 }
01979
01980 void MDFrame::SWITCHpotential(double lambda)
01981 {
01982 int i, ipt;
01983 double E;
01984 Vector3 dr, ds;
01985 Matrix33 Virial_local;
01986
01987
01988 if((_SR1==NULL)&&(_SR2==NULL))
01989 {
01990 FATAL("SWITCHpotential: _SR1, _SR2 == NULL");
01991 return;
01992 }
01993 if(_SR2==NULL)
01994 {
01995 if (_REFPOTENTIAL==0)
01996 {
01997 FATAL("SWITCHpotential: Einstein crystal not implemented yet!");
01998 }
01999 else if(_REFPOTENTIAL==1)
02000 {
02001 dEdlambda=0;
02002 if(_LAMBDA0==_LAMBDA1)
02003 {
02004 if(lambda==0){ potential(); _EPOT-=_ECOH*_NP; return; }
02005 if(lambda==1){ HApotential(); return; }
02006 }
02007 HApotential();
02008 E=_EPOT;
02009 memcpy(_F0,_F,sizeof(Vector3)*_NP);
02010 potential(); _EPOT-=_ECOH*_NP;
02011 dEdlambda=E-_EPOT;
02012 _EPOT=_EPOT*(1-lambda)+E*lambda;
02013 for(i=0;i<_NP;i++)
02014 _F[i]=_F[i]*(1-lambda)+_F0[i]*lambda;
02015
02016 }
02017 else if(_REFPOTENTIAL==2)
02018 {
02019 dEdlambda=0;
02020 if(_LAMBDA0==_LAMBDA1)
02021 {
02022 if(lambda==0){ potential(); _EPOT-=_ECOH*_NP; return; }
02023 if(lambda==1){ I12potential(); return; }
02024 }
02025 I12potential();
02026 E=_EPOT;
02027 memcpy(_F0,_F,sizeof(Vector3)*_NP);
02028 potential(); _EPOT-=_ECOH*_NP;
02029 dEdlambda=E-_EPOT;
02030 _EPOT=_EPOT*(1-lambda)+E*lambda;
02031 for(i=0;i<_NP;i++)
02032 _F[i]=_F[i]*(1-lambda)+_F0[i]*lambda;
02033 }
02034 else if (_REFPOTENTIAL==3)
02035 {
02036 I12potential();
02037 dEdlambda = _EPOT;
02038 _EPOT *= lambda;
02039 for(i=0;i<_NP;i++)
02040 _F[i] *= lambda;
02041 }
02042 else if (_REFPOTENTIAL==4)
02043 {
02044 potential();
02045 dEdlambda = _EPOT;
02046 _EPOT *= lambda;
02047 for(i=0;i<_NP;i++)
02048 _F[i] *= lambda;
02049 }
02050 else if (_REFPOTENTIAL==5)
02051 {
02052 dEdlambda=0;
02053 if(_LAMBDA0==_LAMBDA1)
02054 {
02055 if(lambda==0){ potential(); _EPOT-=_ECOH*_NP; return; }
02056 if(lambda==1){ GAUSSpotential(); return; }
02057 }
02058 GAUSSpotential();
02059 E=_EPOT;
02060 memcpy(_F0,_F,sizeof(Vector3)*_NP);
02061 potential(); _EPOT-=_ECOH*_NP;
02062 dEdlambda=E-_EPOT;
02063 _EPOT=_EPOT*(1-lambda)+E*lambda;
02064 for(i=0;i<_NP;i++)
02065 _F[i]=_F[i]*(1-lambda)+_F0[i]*lambda;
02066 }
02067 else if (_REFPOTENTIAL==6)
02068 {
02069 GAUSSpotential();
02070 dEdlambda = _EPOT;
02071 _EPOT *= lambda;
02072 for(i=0;i<_NP;i++)
02073 _F[i] *= lambda;
02074 }
02075 else if(_REFPOTENTIAL==10)
02076 {
02077 SWITCHpotential_user(lambda);
02078 }
02079 else
02080 {
02081 INFO_Printf("refpotential = %d",_REFPOTENTIAL);
02082 ERROR("unknown refpotential");
02083 }
02084 }
02085 else
02086 {
02087 dEdlambda=0;
02088 memcpy(_SR3,_SR,sizeof(Vector3)*_NP);
02089
02090 for(i=1;i<=MC_switchoffatoms[0];i++)
02091 fixed[MC_switchoffatoms[i]]=-1;
02092 for(i=0;i<_NP;i++)
02093 _SR[i]=_SR[i]-_SR1[i]+_SR2[i];
02094 SHtoR();
02095 potential();
02096
02097 for(i=1;i<=MC_switchoffatoms[0];i++)
02098 {
02099 ipt=MC_switchoffatoms[i];
02100 ds=_SR[ipt]-_SR2[ipt];
02101 dr=_H*ds;
02102 _EPOT+=dr.norm2()*_ECSPRING*0.5;
02103 _F[ipt]=dr*(-_ECSPRING);
02104 }
02105
02106 for(i=1;i<=MC_switchoffatoms[0];i++)
02107 fixed[MC_switchoffatoms[i]]=0;
02108 E=_EPOT;
02109 memcpy(_F0,_F,sizeof(Vector3)*_NP);
02110 memcpy(_SR,_SR3,sizeof(Vector3)*_NP);
02111 SHtoR();
02112 potential();
02113
02114 dEdlambda=E-_EPOT;
02115
02116
02117 for(i=1;i<=MC_switchoffatoms[0];i++)
02118 fixed[MC_switchoffatoms[i]]=-1;
02119
02120 _EPOT=_EPOT*(1-lambda)+E*lambda;
02121 for(i=0;i<_NP;i++)
02122 _F[i]=_F[i]*(1-lambda)+_F0[i]*lambda;
02123 }
02124
02125 }
02126
02127 void MDFrame::SWITCHpotential_energyonly(double lambda)
02128 {
02129 int i, ipt; double E; Vector3 dr, ds;
02130 if((_SR1==NULL)&&(_SR2==NULL))
02131 {
02132 FATAL("SWITCHpotential: _SR1, _SR2 == NULL");
02133 return;
02134 }
02135 if(_SR2==NULL)
02136 {
02137 if (_REFPOTENTIAL==0)
02138 {
02139 dEdlambda=0;
02140 if(_LAMBDA0==_LAMBDA1)
02141 {
02142 if(lambda==0){ potential_energyonly(); _EPOT-=_ECOH*_NP; return; }
02143 if(lambda==1){ ECpotential_energyonly(); return; }
02144 }
02145 ECpotential_energyonly();
02146 E=_EPOT;
02147 potential_energyonly(); _EPOT-=_ECOH*_NP;
02148 dEdlambda=E-_EPOT;
02149 _EPOT=_EPOT*(1-lambda)+E*lambda;
02150 }
02151 else if(_REFPOTENTIAL==1)
02152 {
02153 dEdlambda=0;
02154 if(_LAMBDA0==_LAMBDA1)
02155 {
02156 if(lambda==0){ potential_energyonly(); _EPOT-=_ECOH*_NP; return; }
02157 if(lambda==1){ HApotential_energyonly(); return; }
02158 }
02159 HApotential_energyonly();
02160 E=_EPOT;
02161 potential_energyonly(); _EPOT-=_ECOH*_NP;
02162 dEdlambda=E-_EPOT;
02163 _EPOT=_EPOT*(1-lambda)+E*lambda;
02164 }
02165 else if(_REFPOTENTIAL==2)
02166 {
02167 dEdlambda=0;
02168 if(_LAMBDA0==_LAMBDA1)
02169 {
02170 if(lambda==0){ potential_energyonly(); _EPOT-=_ECOH*_NP; return; }
02171 if(lambda==1){ I12potential_energyonly(); return; }
02172 }
02173 I12potential_energyonly();
02174 E=_EPOT;
02175 potential_energyonly(); _EPOT-=_ECOH*_NP;
02176 dEdlambda=E-_EPOT;
02177 _EPOT=_EPOT*(1-lambda)+E*lambda;
02178 }
02179 else if(_REFPOTENTIAL==3)
02180 {
02181 I12potential_energyonly();
02182 dEdlambda = _EPOT;
02183 _EPOT *= lambda;
02184 }
02185 else if(_REFPOTENTIAL==4)
02186 {
02187 potential_energyonly();
02188 dEdlambda = _EPOT;
02189 _EPOT *= lambda;
02190 }
02191 else if(_REFPOTENTIAL==10)
02192 {
02193 SWITCHpotential_user_energyonly(lambda);
02194 }
02195 else
02196 {
02197 INFO_Printf("refpotential = %d",_REFPOTENTIAL);
02198 ERROR("unknown refpotential");
02199 }
02200 }
02201 else
02202 {
02203 dEdlambda=0;
02204 memcpy(_SR3,_SR,sizeof(Vector3)*_NP);
02205
02206 for(i=1;i<=MC_switchoffatoms[0];i++)
02207 fixed[MC_switchoffatoms[i]]=-1;
02208 for(i=0;i<_NP;i++)
02209 _SR[i]=_SR[i]-_SR1[i]+_SR2[i];
02210 SHtoR();
02211 potential_energyonly();
02212
02213 for(i=1;i<=MC_switchoffatoms[0];i++)
02214 {
02215 ipt=MC_switchoffatoms[i];
02216 ds=_SR[ipt]-_SR2[ipt];
02217 dr=_H*ds;
02218 _EPOT+=dr.norm2()*_ECSPRING*0.5;
02219 }
02220
02221 for(i=1;i<=MC_switchoffatoms[0];i++)
02222 fixed[MC_switchoffatoms[i]]=0;
02223 E=_EPOT;
02224 memcpy(_SR,_SR3,sizeof(Vector3)*_NP);
02225 SHtoR();
02226 potential_energyonly();
02227
02228 dEdlambda=E-_EPOT;
02229
02230
02231 for(i=1;i<=MC_switchoffatoms[0];i++)
02232 fixed[MC_switchoffatoms[i]]=-1;
02233
02234 _EPOT=_EPOT*(1-lambda)+E*lambda;
02235 }
02236 }
02237
02238
02239 void MDFrame::SWITCHpotential_user(double lambda)
02240 {
02241 INFO("MDFrame::SWITCHpotential_user() not implemented yet");
02242 }
02243
02244 void MDFrame::SWITCHpotential_user_energyonly(double lambda)
02245 {
02246 INFO("MDFrame::SWITCHpotential_user_energyonly() not implemented yet");
02247 }
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261 void MDFrame::call_potential()
02262 {
02263 double lambda, vn, gn, ds_star2;
02264 int i, ipt;
02265 Vector3 ds, dr, dF, ds0, dv, gs, ds_star;
02266 Matrix33 htran, htraninv;
02267
02268 #ifdef _TORSION_OR_BENDING
02269 if (_NIMAGES>0)
02270 {
02271 if (_TORSIONSIM) copytorqueatoms();
02272 if (_BENDSIM) copybendatoms();
02273 }
02274 #endif
02275
02276 if (_Dexx>0)
02277 {
02278 calDVIRIALDexx();
02279 }
02280
02281 if (_ENABLE_SWITCH)
02282 {
02283 lambda = SWITCH_Find_Lambda();
02284 SWITCHpotential(lambda);
02285 }
02286 else {
02287 potential();
02288 }
02289
02290 #ifdef _TORSION_OR_BENDING
02291 if (_NIMAGES>0)
02292 {
02293 for(i=0;i<_NIMAGES;i++)
02294 {
02295 _EPOT -= _EPOT_IND[_NP0+i];
02296 _VIRIAL = _VIRIAL - _VIRIAL_IND[_NP0+i];
02297 _TORQUE -= _TORQUE_IND[_NP0+i];
02298 _BENDMOMENT -= _BENDMOMENT_IND[_NP0+i];
02299 }
02300 }
02301 #endif
02302
02303 if (_constrainedMD)
02304 {
02305 htran = _H.tran();
02306 htraninv = htran.inv();
02307
02308 gn=0; vn=0; ds_star2=0;
02309 for(i=1;i<=constrainatoms[0];i++)
02310 {
02311 ipt=constrainatoms[i];
02312 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
02313 ds_star=htraninv*ds0;
02314 gn+=dot(_F[ipt],ds_star);
02315 vn+=dot(_VSR[ipt],ds0);
02316 ds_star2+=ds_star.norm2();
02317 }
02318
02319 gn/=ds_star2;
02320 vn/=constrain_dist;
02321
02322 constrainF = gn*sqrt(ds_star2);
02323
02324
02325
02326 for(i=1;i<=constrainatoms[0];i++)
02327 {
02328 ipt=constrainatoms[i];
02329 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
02330 ds_star=htraninv*ds0;
02331 dF = ds_star*gn;
02332 dv = ds0*vn;
02333 _F[ipt]-=dF;
02334 _VSR[ipt]-=dv;
02335 }
02336 }
02337
02338 if (_ENABLE_FEXT)
02339 {
02340 SHtoR();
02341 for(i=0;i<_NP;i++)
02342 _F[i] += _Fext[i];
02343
02344 if(_SR1==NULL)
02345 {
02346 for(i=0;i<_NP;i++)
02347 _EPOT -= dot(_Fext[i],_R[i]);
02348 }
02349 else
02350 {
02351 for(i=0;i<_NP;i++)
02352 {
02353 ds = _SR[i] - _SR1[i];
02354 dr = _H*ds;
02355 _EPOT -= dot(_Fext[i],dr);
02356 }
02357 }
02358 _EPOT += _EPOT0_ext;
02359 }
02360 }
02361
02362 void MDFrame::potential()
02363 {
02364 INFO("MDFrame::potential() not implemented yet.");
02365 }
02366
02367 void MDFrame::potential_energyonly()
02368 {
02369 INFO("MDFrame::potential_energyonly() not implemented yet.");
02370
02371 }
02372
02373 double MDFrame::potential_energyonly(int iatom)
02374 {
02375 INFO("MDFrame::potential_energyonly(int) not implemented yet.");
02376
02377
02378 return _EPOT;
02379 }
02380
02381 void MDFrame::integrator()
02382 {
02383 switch(algorithm_id) {
02384 case(10000): NVE_Gear6(); break;
02385 case(20000): NVT_Gear6(); break;
02386 case(21000): NVTC_Gear6(); break;
02387 case(30000): NPH_Gear6(); break;
02388 case(40000): NPT_Gear6(); break;
02389 case(41000): NPTC_Gear6(); break;
02390 case(10100): NVE_VVerlet(curstep); break;
02391 case(20100): NVT_VVerlet_Implicit(curstep); break;
02392 case(20101): NVT_VVerlet_Explicit_1(curstep); break;
02393 case(20102): NVT_VVerlet_Explicit_2(curstep); break;
02394 case(21100): NVTC_VVerlet_Explicit(curstep); break;
02395 case(21101): NVTC_VVerlet_Explicit(curstep); break;
02396
02397 case(30100): NPH_VVerlet_Explicit_1(curstep); break;
02398 case(30101): NPH_VVerlet_Explicit_1(curstep); break;
02399
02400 case(40100): NPT_VVerlet_Implicit(curstep); break;
02401 case(40101): NPT_VVerlet_Explicit_1(curstep); break;
02402 case(40102): NPT_VVerlet_Explicit_2(curstep); break;
02403 default: FATAL("unknown algorithm_id ("<<algorithm_id<<")"); break;
02404 }
02405 }
02406
02407
02408
02409
02410 #include "integrators.cpp"
02411
02412 int MDFrame::runMDSWITCH()
02413 {
02414 int n;
02415 n = _ENABLE_SWITCH;
02416 _ENABLE_SWITCH = 1;
02417
02418 _WTOT = _WAVG = 0;
02419
02420 run();
02421
02422 _ENABLE_SWITCH = n;
02423
02424 return 0;
02425 }
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440 void MDFrame::run()
02441 {
02442 int itmp, i, key;
02443 double pres, omega0;
02444 class Matrix33 prp, h0inv, h0invtran;
02445
02446
02447 if (strcmp(ensemble_type,"NVE")==0)
02448 algorithm_id = 10000;
02449 else if (strcmp(ensemble_type,"NVT")==0)
02450 algorithm_id = 20000;
02451 else if (strcmp(ensemble_type,"NVTC")==0)
02452 algorithm_id = 21000;
02453 else if (strcmp(ensemble_type,"NPH")==0)
02454 algorithm_id = 30000;
02455 else if (strcmp(ensemble_type,"NPT")==0)
02456 algorithm_id = 40000;
02457 else if (strcmp(ensemble_type,"NPTC")==0)
02458 algorithm_id = 41000;
02459 else
02460 {
02461 algorithm_id = 100;
02462 ERROR("unknown ensemble_type("<<ensemble_type<<" use NVE\n"
02463 "choices: NVE, NVT, NPH, NPT");
02464 }
02465 if (strcmp(integrator_type,"Gear6")==0)
02466 algorithm_id += 0;
02467 else if (strcmp(integrator_type,"VVerlet")==0)
02468 algorithm_id += 100;
02469 else
02470 {
02471 ERROR("unknown ensemble_type("<<ensemble_type<<" use Gear6\n"
02472 "choices: Gear6 VVerlet");
02473 }
02474
02475 algorithm_id += implementation_type;
02476 INFO("algorithm_id = "<<algorithm_id);
02477
02478 itmp = algorithm_id / 10000;
02479
02480 SHtoR();
02481
02482
02483 if((itmp==3)||(itmp==4))
02484 {
02485
02486 prp=_EXTSTRESS;
02487 prp*=_EXTSTRESSMUL;
02488
02489 pres=prp.trace()/3;
02490 pres+=_EXTPRESSADD;
02491 prp[0][0]-=pres;
02492 prp[1][1]-=pres;
02493 prp[2][2]-=pres;
02494
02495 if(fabs(_H0.det())<1e-10)
02496 FATAL("you need to specify H0 by calling saveH "
02497 "before using the Parrinello-Rahman method");
02498
02499 h0inv=_H0.inv();
02500 h0invtran=h0inv.tran();
02501 omega0=_H0.det()*(1-_VACUUMRATIO);
02502 _SIGMA=((h0inv*prp)*h0invtran)*omega0;
02503 _SIGMA/=160.2e3;
02504 }
02505
02506 if(runavgposition)
02507 {
02508 if(_SRA==NULL)
02509 {
02510 INFO("Running average position, _SRA allocated and initialized");
02511 Realloc(_SRA,Vector3,_NP);
02512 }
02513 else
02514 INFO("Running average position, _SRA reinitialized");
02515 memcpy(_SRA,_SR,sizeof(Vector3)*_NP);
02516 }
02517
02518 if(continue_curstep)
02519 step0 = curstep;
02520 else
02521 step0 = 0;
02522 for(curstep=step0;curstep<(step0 + totalsteps);curstep++)
02523
02524 {
02525 key=0;
02526 while(win!=NULL)
02527 {
02528 if(win->IsPaused()) sleep(1);
02529 else break;
02530 }
02531
02532 if(curstep%savepropfreq==0) INFO("curstep="<<curstep);
02533 winplot();
02534
02535 if(curstep>=equilsteps)
02536 {
02537 if(saveprop)
02538 {
02539 if((curstep%savepropfreq)==0)
02540 {
02541 call_potential();
02542 calcprop();
02543 calcoutput();
02544 pf.write(this);
02545 }
02546 }
02547
02548
02549 if (saveFFScn == 1 && (curstep!=0 && curstep!=step0))
02550 {
02551 FFS_i_minus=curstep;
02552 key=FFSprocess();
02553 if ( key==1 ) break;
02554 }
02555 }
02556
02557
02558 step();
02559 if(runavgposition)
02560 {
02561 for(i=0;i<_NP;i++)
02562 {
02563 if(fixed[i]) continue;
02564 _SRA[i]=(_SRA[i]*(curstep-step0+1)+_SR[i])/(curstep-step0+2);
02565 }
02566 }
02567
02568
02569 if(curstep>=equilsteps)
02570 {
02571 if(savecn)
02572 {
02573 if((curstep%savecnfreq)==0&&(curstep!=0))
02574 intercn.write(this,zipfiles,true);
02575 }
02576 if(savecfg)
02577 {
02578 char extname[100];
02579 if((curstep%savecfgfreq)==0&&(curstep!=0))
02580 {
02581 AUXFile::insertindex(extname,intercfgfile,savecfgcount);
02582
02583 if(plot_color_axis==2)
02584 {
02585 if(!(((curstep%plotfreq)==0)&&(conj_step%plotfreq)==0))
02586 calcentralsymmetry();
02587 }
02588 if(plot_color_axis==8)
02589 {
02590 if(!(((curstep%plotfreq)==0)&&(conj_step%plotfreq)==0))
02591 calcrystalorder();
02592 }
02593 writeatomeyecfgfile (extname); savecfgcount ++;
02594 }
02595 }
02596 }
02597
02598 if(win!=NULL)
02599 if(win->IsAlive())
02600 if(autowritegiffreq>0)
02601 if((curstep%autowritegiffreq)==0)
02602 {
02603 win->LockWritegif();
02604 }
02605 }
02606 if(saveprop)
02607 {
02608 INFO("curstep="<<curstep);
02609 call_potential();
02610 calcprop();
02611 calcoutput();
02612 pf.write(this);
02613 }
02614 }
02615
02616 void MDFrame::calcprop()
02617 {
02618 int i, j, itmp;
02619 Matrix33 dH, s, hinv, hinvtran, htran, hsigma, sigmahtranh;
02620 Vector3 r0, r, dr, f, v;
02621 double tmp, pres;
02622 #ifdef _TORSION_OR_BENDING
02623 double tmp2, tmp4, curvature, Radius;
02624 #endif
02625
02626 tmp=0.5*(_ATOMMASS[0]*MASSCONVERT)/(_TIMESTEP*_TIMESTEP);
02627 _KATOM=0; _PSTRESS.clear();
02628 _EPOT_BOX=0; _KBOX=0;
02629 _OMEGA=_H.det();
02630 _TOTPRESSURE = _TOTSTRESS.trace()/3;
02631
02632 #if 0
02633
02634 if(indenterspec[0]!=0)
02635 {
02636
02637 x0=indenterspec[1];
02638 y0=indenterspec[2];
02639 z0=indenterspec[3];
02640 R0=indenterspec[4];
02641 K =indenterspec[5];
02642 r0.set(x0,y0,z0);
02643 for(i=0;i<_NP;i++)
02644 {
02645 r=_H*_SR[i];
02646 dr=r-r0;
02647 dR=dr.norm();
02648 if(dR<R0)
02649 {
02650 phi=0.5*K*(R0-dR)*(R0-dR);
02651 f=dr*(K*(R0-dR)/R0);
02652 _F[i]+=f;
02653 _EPOT_IND[i]+=phi;
02654 _EPOT+=phi;
02655 }
02656 }
02657 }
02658 #endif
02659
02660
02661
02662 if(extforce[0] > 0)
02663 {
02664 for(i=0;i<_NP;i++)
02665 {
02666 if( (group[i]>0) && (group[i]<=extforce[0]) )
02667 {
02668 f.set(extforce+(group[i]-1)*3+1); f*=forcemul;
02669 _F[i]+=f;
02670 _R[i]=_H*_SR[i];
02671 _EPOT-=dot(f,_R[i]);
02672 }
02673 }
02674 }
02675
02676 _NPfree = 0;
02677 if(_VR!=NULL)
02678 {
02679 for(i=0;i<_NP;i++)
02680 {
02681 if(fixed[i]) continue;
02682 _NPfree ++;
02683 _VR[i]=_H*_VSR[i];
02684 if(species[i]==0)
02685 {
02686 _KATOM+=tmp*_VR[i].norm2();
02687 _PSTRESS.addnvv(2.0*tmp,_VR[i],_VR[i]);
02688 }
02689 else
02690 {
02691 if(_ATOMMASS[species[i]]<=0)
02692 {
02693 FATAL("_ATOMMASS (for species "<<species[i]<<") = "<<_ATOMMASS[species[i]]<<" is not valid");
02694 }
02695 _KATOM+=tmp*_VR[i].norm2()*_ATOMMASS[species[i]]/_ATOMMASS[0];
02696 _PSTRESS.addnvv(2.0*tmp*_ATOMMASS[species[i]]/_ATOMMASS[0],
02697 _VR[i],_VR[i]);
02698 }
02699 }
02700 }
02701
02702 _T=_KATOM/(1.5*KB*_NPfree);
02703 _TOTSTRESS=_PSTRESS+_VIRIAL;
02704 _TOTSTRESS/=_OMEGA*(1-_VACUUMRATIO);
02705 _TOTSTRESSinMPa=_TOTSTRESS*160.2e3;
02706
02707
02708
02709 if(_VR!=NULL)
02710 {
02711 _P_COM.clear();
02712 for(i=0;i<_NP;i++)
02713 {
02714 if(species[i]==0)
02715 _P_COM += _VR[i];
02716 else
02717 _P_COM += _VR[i] * _ATOMMASS[species[i]] / _ATOMMASS[0];
02718 }
02719 }
02720
02721 #ifdef _TORSION_OR_BENDING
02722 if (_TORSIONSIM)
02723 {
02724
02725 _PTHETA_COM = 0;
02726 tmp2 = tmp4 = 0;
02727 for(i=0;i<_NP0;i++)
02728 {
02729 r = _H*_SR[i];
02730 v = _H*_VSR[i];
02731 if(species[i]!=0)
02732 v *= _ATOMMASS[species[i]] / _ATOMMASS[0];
02733 tmp2 += (v.y*r.x - v.x*r.y);
02734 tmp4 += (r.x*r.x + r.y*r.y);
02735 }
02736 _PTHETA_COM = tmp2 / tmp4;
02737
02738
02739 _P_COM.clear(); _F_COM.clear();
02740 for(i=0;i<_NP0;i++)
02741 {
02742 if(species[i]==0)
02743 _P_COM += _VR[i];
02744 else
02745 _P_COM += _VR[i] * _ATOMMASS[species[i]] / _ATOMMASS[0];
02746 _F_COM += _F[i];
02747 }
02748 }
02749
02750 if (_BENDSIM)
02751 {
02752
02753 _PTHETA_COM = 0;
02754 tmp2 = tmp4 = 0;
02755 curvature = bendspec[3];
02756 Radius = 1.0/curvature;
02757 for(i=0;i<_NP0;i++)
02758 {
02759 r = _H*_SR[i];
02760 r.y += Radius;
02761 v = _H*_VSR[i];
02762 if(species[i]!=0)
02763 v *= _ATOMMASS[species[i]] / _ATOMMASS[0];
02764 tmp2 += (v.y*r.x - v.x*r.y);
02765 tmp4 += (r.x*r.x + r.y*r.y);
02766 }
02767 _PTHETA_COM = tmp2 / tmp4;
02768
02769
02770 _P_COM.clear(); _F_COM.clear();
02771 for(i=0;i<_NP0;i++)
02772 {
02773 if(species[i]==0)
02774 _P_COM += _VR[i];
02775 else
02776 _P_COM += _VR[i] * _ATOMMASS[species[i]] / _ATOMMASS[0];
02777 _F_COM += _F[i];
02778 }
02779 }
02780 #endif
02781
02782 itmp = algorithm_id / 10000;
02783
02784 if((itmp==3)||(itmp==4))
02785 {
02786
02787 pres=_EXTSTRESS.trace()/3;
02788 pres*=_EXTSTRESSMUL;
02789 pres+=_EXTPRESSADD;
02790 pres/=160.2e3;
02791 s=_TOTSTRESS;
02792 s*=_OMEGA*(1-_VACUUMRATIO);
02793 s[0][0]-=_OMEGA*(1-_VACUUMRATIO)*pres;
02794 s[1][1]-=_OMEGA*(1-_VACUUMRATIO)*pres;
02795 s[2][2]-=_OMEGA*(1-_VACUUMRATIO)*pres;
02796
02797 hinv=_H.inv(); hinvtran=hinv.tran(); htran=_H.tran();
02798 s=s*hinvtran;
02799 hsigma=_H*_SIGMA;
02800 _GH=s-hsigma;
02801
02802
02803 for(i=0;i<3;i++)
02804 for(j=0;j<3;j++)
02805 if(conj_fixboxvec[i][j]==1)
02806 _GH[i][j]=0;
02807 sigmahtranh=(_SIGMA*htran)*_H;
02808
02809
02810 _EPOT_BOX=pres*_OMEGA*(1-_VACUUMRATIO)+sigmahtranh.trace()*0.5;
02811
02812
02813 for(i=0;i<3;i++)
02814 for(j=0;j<3;j++)
02815 if(conj_fixboxvec[i][j]==0)
02816 _KBOX+=tmp*_VH[i][j]*_VH[i][j]*_WALLMASS/_ATOMMASS[0];
02817 }
02818
02819
02820
02821 itmp = algorithm_id / 1000;
02822
02823
02824 if(itmp==10)
02825 {
02826 _HELM = _EPOT + _KATOM;
02827 _HELMP = _HELM;
02828 }
02829 else if(itmp==20)
02830 {
02831 if((NHMass[0]==0)&&(vt2!=0))
02832 {
02833 _HELM = _EPOT + _KATOM +
02834 3*_NPfree*_TDES*KB*zetav*zetav/_TIMESTEP/_TIMESTEP/1e-24/2/vt2;
02835 }
02836 else
02837 {
02838 _HELM = _EPOT + _KATOM + 0.5*NHMass[0]*SQR(zetav/_TIMESTEP);
02839 }
02840 _HELMP = _HELM + 3*_NPfree*_TDES*KB*zeta;
02841 }
02842 else if(itmp==21)
02843 {
02844 _HELM = _EPOT + _KATOM;
02845 for(i=0;i<NHChainLen;i++)
02846 _HELM += 0.5*NHMass[i]*SQR(zetaNHCv[i]/_TIMESTEP);
02847 _HELMP = _HELM + 3*_NPfree*_TDES*KB*zetaNHC[0];
02848 for(i=1;i<NHChainLen;i++)
02849 _HELMP += KB*_TDES*zetaNHC[i];
02850 }
02851 else if(itmp==30)
02852 {
02853 _HELM = _EPOT + _KATOM + _KBOX;
02854 _HELMP = _HELM + _EPOT_BOX;
02855 }
02856 else if(itmp==40)
02857 {
02858 if((NHMass[0]==0)&&(vt2!=0))
02859 {
02860 _HELM = _EPOT + _KATOM + _KBOX +
02861 3*_NPfree*_TDES*KB*zetav*zetav/_TIMESTEP/_TIMESTEP/1e-24/2/vt2;
02862 }
02863 else
02864 {
02865 _HELM = _EPOT + _KATOM + _KBOX + 0.5*NHMass[0]*SQR(zetav/_TIMESTEP);
02866 }
02867 _HELMP = _HELM + _EPOT_BOX + 3*_NPfree*_TDES*KB*zeta;
02868 }
02869 else if(itmp==41)
02870 {
02871 _HELM = _EPOT + _KATOM + _KBOX;
02872 for(i=0;i<NHChainLen;i++)
02873 _HELM += 0.5*NHMass[i]*SQR(zetaNHCv[i]/_TIMESTEP);
02874 _HELMP = _HELM + _EPOT_BOX + 3*_NPfree*_TDES*KB*zetaNHC[0];
02875 for(i=1;i<NHChainLen;i++)
02876 _HELMP += KB*_TDES*zetaNHC[i];
02877 }
02878
02879
02880 if(applyshear)
02881 {
02882 dH=_H*_SHEARRATE; dH*=_TIMESTEP;
02883 _H+=dH;
02884 }
02885
02886 if(plot_color_axis==2)
02887 {
02888 if(((curstep%plotfreq)==0)&&(conj_step%plotfreq)==0)
02889 calcentralsymmetry();
02890 }
02891
02892 if(plot_color_axis==4)
02893 {
02894 if(((curstep%plotfreq)==0)&&(conj_step%plotfreq)==0)
02895 caldisregistry();
02896 }
02897
02898 if(plot_color_axis==8)
02899 {
02900 if(((curstep%plotfreq)==0)&&(conj_step%plotfreq)==0)
02901 calcrystalorder();
02902 }
02903
02904 }
02905
02906 void MDFrame::calcoutput()
02907 {
02908 char names[10000], *p, *q;
02909
02910
02911 if(strlen(output_fmt)==0)
02912 {
02913 output_str[0]=0;
02914 return;
02915 }
02916
02917 strcpy(names,output_fmt);
02918 p=names;
02919
02920 output_str[0]=0;
02921 while(strlen(p)>0)
02922 {
02923 switch(*p)
02924 {
02925 case ' ':
02926 case '\t':
02927 p++; break;
02928 default:
02929 q=strchr(p,' ');
02930 if(q!=NULL) *q=0;
02931 identify(p);
02932 if(curn>=0)
02933 switch(vartype[curn])
02934 {
02935 case(INT): sprintf(output_str+strlen(output_str),"%10d ",*((int *)varptr[curn]+shift)); break;
02936 case(LONG): sprintf(output_str+strlen(output_str),"%10ld ",*((long *)varptr[curn]+shift)); break;
02937 case(DOUBLE): sprintf(output_str+strlen(output_str),"%23.16e ",*((double *)varptr[curn]+shift)); break;
02938 case(STRING): sprintf(output_str+strlen(output_str),"%s ",(char *)varptr[curn]+shift); break;
02939 default: FATAL("unknown vartype ("<<vartype[curn]<<")");
02940 }
02941 if(q!=NULL) p=q+1;
02942 else goto it;
02943 break;
02944 }
02945 }
02946 it:
02947 sprintf(output_str+strlen(output_str),"%s","\n");
02948 }
02949
02950 void MDFrame::calDVIRIALDexx()
02951 {
02952
02953
02954
02955
02956 Matrix33 virial1, virial2, htmp;
02957
02958 htmp = _H;
02959
02960 _H[0][0]+=_H[0][0]*_Dexx;
02961 _H[0][1]+=_H[0][1]*_Dexx;
02962 _H[0][2]+=_H[0][2]*_Dexx;
02963
02964 potential();
02965
02966 virial1 = _VIRIAL;
02967
02968 _H = htmp;
02969
02970 _H[0][0]-=_H[0][0]*_Dexx;
02971 _H[0][1]-=_H[0][1]*_Dexx;
02972 _H[0][2]-=_H[0][2]*_Dexx;
02973
02974 potential();
02975
02976 virial2 = _VIRIAL;
02977
02978 _DVIRIAL_Dexx = virial1 - virial2;
02979 _DVIRIAL_Dexx /= (2*_Dexx);
02980
02981 _H = htmp;
02982 }
02983
02984 void MDFrame::calcentralsymmetry()
02985 {
02986 int i, j, k, kpt, *csflags, mk1, mk2;
02987 double mind1, mind2, d1, d2; Vector3 sik1, sik, rik;
02988
02989 csflags = (int *)malloc(sizeof(int)*_NNM);
02990
02991 for(i=0;i<_NP;i++)
02992 {
02993 _TOPOL[i]=0;
02994 }
02995 for(i=0;i<_NP;i++)
02996 {
02997 for(j=0;j<_NNM;j++)
02998 csflags[j]=0;
02999
03000
03001 if(nn[i]<NCS) {
03002 _TOPOL[i]=NCS+1.0;
03003 continue;
03004 }
03005
03006 for(j=0;j<NCS/2;j++)
03007 {
03008 mind1=1e10; mk1=-1; sik1.set(-1,-1,-1);
03009
03010 for(k=0;k<nn[i];k++)
03011 {
03012 if(csflags[k]!=0) continue;
03013 kpt=nindex[i][k];
03014 if(kpt==i) continue;
03015 sik=_SR[kpt]-_SR[i]; sik.subint();
03016 rik=_H*sik; d1=rik.norm2();
03017 if(mind1>d1)
03018 {
03019 mind1=d1; mk1=k; sik1=sik;
03020 }
03021 }
03022 csflags[mk1]=1;
03023 mind2=1e10; mk2=-1; sik.set(-1,-1,-1);
03024
03025 for(k=0;k<nn[i];k++)
03026 {
03027 if(csflags[k]!=0) continue;
03028 kpt=nindex[i][k];
03029 if(kpt==i) continue;
03030 sik=_SR[kpt]-_SR[i]; sik+=sik1; sik.subint();
03031 rik=_H*sik; d2=rik.norm2();
03032 if(mind2>d2)
03033 {
03034 mind2=d2; mk2=k;
03035 }
03036 }
03037 csflags[mk2]=1;
03038 _TOPOL[i]+=mind2;
03039
03040 }
03041 }
03042
03043 free(csflags);
03044 }
03045
03046 void MDFrame::caldisregistry()
03047 {
03048 int i, j, jpt;
03049 Vector3 r, s;
03050 double d;
03051
03052 for(i=0;i<_NP;i++)
03053 _TOPOL[i]=0;
03054
03055 for(i=0;i<_NP;i++)
03056 {
03057 d=0;
03058 for(j=0;j<nn_plot[i];j++)
03059 {
03060 jpt=nindex_plot[i][j];
03061 s=_SR[i]-_SR[jpt];
03062 s.subint();
03063 r=_H*s;
03064 d+= (r.norm() - latticeconst[0]*sqrt(3)/4.0);
03065 }
03066 _TOPOL[i]=d;
03067 }
03068 }
03069
03070 void MDFrame::findcore()
03071 {
03072
03073
03074
03075 int i, j, n, calshape;
03076 double tmin, tmax;
03077 Vector3 s0, s1, ds, savg, ravg, ri0;
03078 Matrix33 Inertia, Unit, Temp;
03079 double m,q,p;
03080 double rri0;
03081 double phi, I1, I2, I3;
03082
03083 tmin = input[0];
03084 tmax = input[1];
03085 calshape = (int) input[2];
03086
03087
03088 Inertia.clear();
03089 Unit.clear();
03090 Unit[0][0]=1.0;Unit[1][1]=1.0;Unit[2][2]=1.0;
03091
03092 n = 0; savg.clear();
03093 for(i=0;i<_NP;i++)
03094 {
03095 if(plot_limits[0]==1)
03096 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
03097 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
03098 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
03099 {
03100 continue;
03101 }
03102 if( (_TOPOL[i]>=tmin) && (_TOPOL[i]<tmax) )
03103 {
03104 if(n==0)
03105 {
03106 s0 = _SR[i];
03107 savg = s0;
03108 }
03109 else
03110 {
03111 s1 = _SR[i];
03112 ds = s1 - s0; ds.subint();
03113 s1 = s0 + ds;
03114 savg+=s1;
03115
03116
03117 if (calshape == 1)
03118 {
03119 ri0 = _H*ds; rri0=ri0.norm();
03120 Inertia[0][0]+=rri0*rri0-ri0[0]*ri0[0];
03121 Inertia[0][1]+= -ri0[0]*ri0[1];
03122 Inertia[0][2]+= -ri0[0]*ri0[2];
03123 Inertia[1][0]+= -ri0[1]*ri0[0];
03124 Inertia[1][1]+=rri0*rri0-ri0[1]*ri0[1];
03125 Inertia[1][2]+= -ri0[1]*ri0[2];
03126 Inertia[2][0]+= -ri0[2]*ri0[0];
03127 Inertia[2][1]+= -ri0[2]*ri0[1];
03128 Inertia[2][2]+=rri0*rri0-ri0[2]*ri0[2];
03129 }
03130
03131 }
03132 n++;
03133 }
03134 }
03135 if (n>0)
03136 savg /= n;
03137 else
03138 ERROR("no defect atoms found!");
03139
03140 ravg = _H*savg;
03141 INFO_Printf("findcore: avg pos = %20.10e %20.10e %20.10e %20.10e %20.10e %20.10e\n",
03142 savg.x,savg.y,savg.z, ravg.x,ravg.y,ravg.z);
03143
03144 if (calshape == 1)
03145 {
03146 m = Inertia.trace()/3;
03147 Temp = Inertia - (Unit*m);
03148 q = Temp.det()/2;
03149 p = 0;
03150 for (i=0;i<3;i++)
03151 for (j=0;j<3;j++)
03152 {
03153 p += Temp[i][j]*Temp[i][j];
03154 }
03155 p = p/6;
03156 phi = atan( sqrt(p*p*p-q*q)/q )/3;
03157 if (phi<0) phi += M_PI;
03158 I1 = m + 2*sqrt(p)*cos(phi);
03159 I2 = m - sqrt(p)*( cos(phi) + sqrt(3) * sin(phi));
03160 I3 = m - sqrt(p)*( cos(phi) - sqrt(3) * sin(phi));
03161 Principal_Inertia[0]=I1;
03162 Principal_Inertia[1]=I2;
03163 Principal_Inertia[2]=I3;
03164 INFO_Printf("Inertia Eigenvalues = %15.7e %15.7e %15.7e\n",I1,I2,I3);
03165 }
03166 }
03167
03168 void MDFrame::calHessian()
03169 {
03170 FILE *fp;
03171 int i, ind, j, ipt;
03172 Matrix33 hinv;
03173 Vector3 df, ds, dr;
03174
03175
03176 fp=fopen("hessian.out","w");
03177
03178 INFO("open hessian.out");
03179 SHtoR();
03180 call_potential();
03181 memcpy(_VR,_F,_NP*sizeof(Vector3));
03182 memcpy(_VSR,_SR,_NP*sizeof(Vector3));
03183 hinv=_H.inv();
03184 if(input[0]==0)
03185 {
03186 for(ipt=0;ipt<_NP;ipt++)
03187 {
03188 INFO("atom "<<ipt);
03189 for(ind=0;ind<3;ind++)
03190 {
03191 _R[ipt]=_H*_VSR[ipt];
03192 _R[ipt][ind]-=_TIMESTEP;
03193 _SR[ipt]=hinv*_R[ipt];
03194 call_potential();
03195 memcpy(_VR,_F,_NP*sizeof(Vector3));
03196
03197 _R[ipt]=_H*_VSR[ipt];
03198 _R[ipt][ind]+=_TIMESTEP;
03199 _SR[ipt]=hinv*_R[ipt];
03200 call_potential();
03201
03202 _R[ipt]=_H*_VSR[ipt];
03203 _SR[ipt]=_VSR[ipt];
03204
03205 for(j=0;j<_NP;j++)
03206 {
03207 df=_F[j]-_VR[j]; df/=(2*_TIMESTEP);
03208 fprintf(fp,"%20.13e %20.13e %20.13e\n",df.x,df.y,df.z);
03209 }
03210 }
03211 }
03212 }
03213 else
03214 {
03215 for(i=0;i<(int)input[0];i++)
03216 {
03217 ipt=(int)input[i+1];
03218
03219
03220
03221
03222 for(ind=0;ind<3;ind++)
03223 {
03224
03225 _R[ipt]=_H*_VSR[ipt];
03226 _R[ipt][ind]-=_TIMESTEP;
03227 _SR[ipt]=hinv*_R[ipt];
03228 call_potential();
03229 memcpy(_VR,_F,_NP*sizeof(Vector3));
03230
03231
03232
03233 _R[ipt]=_H*_VSR[ipt];
03234 _R[ipt][ind]+=_TIMESTEP;
03235 _SR[ipt]=hinv*_R[ipt];
03236 call_potential();
03237
03238
03239
03240 _R[ipt]=_H*_VSR[ipt];
03241 _SR[ipt]=_VSR[ipt];
03242
03243 for(j=0;j<_NP;j++)
03244 {
03245 df=_F[j]-_VR[j]; df/=(2*_TIMESTEP);
03246 ds=_SR[j]-_SR[ipt]; ds.subint(); dr=_H*ds;
03247 if(df.norm()>1e-10)
03248 fprintf(fp,"%6d %3d %6d %20.13e %20.13e %20.13e %20.13e %20.13e %20.13e\n",
03249 ipt,ind+1,j,df.x,df.y,df.z,dr.x,dr.y,dr.z);
03250 }
03251 }
03252 }
03253 }
03254 fclose(fp);
03255 }
03256
03257 void MDFrame::readHessian()
03258 {
03259 FILE *fp;
03260 int i, id, j;
03261 Vector3 df;
03262
03263 if(_NP<=0) FATAL("readHessian: NP="<<_NP);
03264
03265
03266 fp=fopen(incnfile,"r");
03267
03268 Realloc(hes,double,(_NP*3)*(_NNM*3));
03269 Realloc(hesind,int,(_NP*3)*(_NNM*3)*4);
03270
03271 heslen = 0;
03272 for(i=0;i<_NP;i++)
03273 {
03274 for(id=0;id<3;id++)
03275 {
03276 for(j=0;j<_NP;j++)
03277 {
03278 fscanf(fp,"%le %le %le",&df.x,&df.y,&df.z);
03279 if(df.norm2()>1e-16)
03280 {
03281 hes[heslen] = -df.x;
03282 hesind[heslen*4 ] = i;
03283 hesind[heslen*4+1] = id;
03284 hesind[heslen*4+2] = j;
03285 hesind[heslen*4+3] = 0;
03286 heslen ++;
03287
03288 hes[heslen] = -df.y;
03289 hesind[heslen*4 ] = i;
03290 hesind[heslen*4+1] = id;
03291 hesind[heslen*4+2] = j;
03292 hesind[heslen*4+3] = 1;
03293 heslen ++;
03294
03295 hes[heslen] = -df.z;
03296 hesind[heslen*4 ] = i;
03297 hesind[heslen*4+1] = id;
03298 hesind[heslen*4+2] = j;
03299 hesind[heslen*4+3] = 2;
03300 heslen ++;
03301
03302 if(heslen>(_NP*3)*(_NNM*3))
03303 {
03304 INFO_Printf("heslen = %d _NP = %d _NNM = %d\n",heslen,_NP,_NNM);
03305 FATAL("heslen too large, increase NNM");
03306 }
03307 }
03308 }
03309 }
03310 }
03311 INFO_Printf("readHessian: heslen = %d\n",heslen);
03312 fclose(fp);
03313 }
03314
03315 void MDFrame::calModeHessian()
03316 {
03317
03318 int i, ind, j, ipt, k, p;
03319 Matrix33 hinv;
03320 Vector3 df, ds, dr;
03321
03322 int *mode_atomID, natoms, groupID, n, m, nmodes, pmode;
03323 Vector3 *mode_value;
03324 double s, sum2, tmp, mag;
03325
03326
03327 groupID = (int) input[0];
03328 n = (int) input[1];
03329 m = (int) input[2];
03330 pmode = (int) input[3];
03331 mag = input[4];
03332
03333 nmodes = n*m*3;
03334
03335 natoms = 0;
03336 for(i=0;i<_NP;i++)
03337 if(group[i]==groupID)
03338 natoms++;
03339 mode_atomID = (int *) malloc(sizeof(int)*natoms);
03340 mode_value = (Vector3 *) malloc(sizeof(Vector3)*natoms*nmodes);
03341
03342 k=0;
03343 for(i=0;i<_NP;i++)
03344 if(group[i]==groupID)
03345 {
03346 mode_atomID[k]=i;
03347 k++;
03348 }
03349
03350
03351 SHtoR();
03352 for(i=0;i<n;i++)
03353 for(j=0;j<m;j++)
03354 {
03355 for(p=0;p<natoms;p++)
03356 {
03357 ipt=mode_atomID[p];
03358 s = pow(_R[ipt].x,i)*pow(_R[ipt].y,j);
03359
03360 for(k=0;k<3;k++)
03361 {
03362 ind = i*(m*3)+j*3+k;
03363 mode_value[ind*natoms+p][k] = s;
03364 }
03365 }
03366 }
03367
03368
03369 for(i=0;i<nmodes;i++)
03370 {
03371 for(j=0;j<i;j++)
03372 {
03373 sum2 = 0;
03374 for(p=0;p<natoms;p++)
03375 sum2 += dot(mode_value[i*natoms+p],mode_value[j*natoms+p]);
03376 for(p=0;p<natoms;p++)
03377 mode_value[i*natoms+p] -= mode_value[j*natoms+p]*sum2;
03378 }
03379
03380
03381 sum2 = 0;
03382 for(p=0;p<natoms;p++)
03383 sum2 += mode_value[i*natoms+p].norm2();
03384 tmp = sqrt(sum2);
03385 for(p=0;p<natoms;p++)
03386 mode_value[i*natoms+p]/=tmp;
03387 }
03388
03389 if(mag>0)
03390 {
03391 for(p=0;p<natoms;p++)
03392 _R[mode_atomID[p]] += mode_value[pmode*natoms+p]*mag;
03393 RHtoS();
03394 winplot();
03395 }
03396
03397 free(mode_atomID);
03398 free(mode_value);
03399 }
03400
03401 void MDFrame::calphonondisp()
03402 {
03403 INFO("MDFrame::calphonondisp not implemented");
03404 }
03405
03406 void MDFrame::calmisfit()
03407 {
03408 int nx, ny, nz, i, j, k, n, ind, inda, indb;
03409 double x0, y0, z0, x1, y1, z1, dx, dy, dz, area;
03410 FILE *fp;
03411 class Vector3 c1, c2, c3, ca, cb, caxcb, dc1, dc2, dc3;
03412 class Matrix33 H_origin;
03413
03414
03415 ind = (int)input[0];
03416 if(ind < 1 || ind > 3)
03417 {
03418 ERROR("Surface normal should be one of 1, 2, and 3.");
03419 return;
03420 }
03421 ind--;
03422
03423
03424 inda = (ind+1)%3; indb = (inda+1)%3;
03425
03426 x0 = input[1]; dx = input[2]; x1 = input[3];
03427 y0 = input[4]; dy = input[5]; y1 = input[6];
03428 z0 = input[7]; dz = input[8]; z1 = input[9];
03429
03430 INFO_Printf("%% x0 = %e, dx = %e, x1 = %e\n",x0,dx,x1);
03431 INFO_Printf("%% y0 = %e, dy = %e, y1 = %e\n",y0,dy,y1);
03432 INFO_Printf("%% z0 = %e, dz = %e, z1 = %e\n",z0,dz,z1);
03433
03434 if(dx!=0) nx = (int) round((x1-x0)/dx); else nx = 0;
03435 if(dy!=0) ny = (int) round((y1-y0)/dy); else ny = 0;
03436 if(dz!=0) nz = (int) round((z1-z0)/dz); else nz = 0;
03437
03438 INFO_Printf("%% nx = %d, ny = %d, nz = %d\n",nx,ny,nz);
03439
03440 fp = fopen("Emisfit.out","w");
03441 if(fp==NULL) FATAL("calmisfit: open file failure");
03442
03443 fprintf(fp,"%% Data file for misfit energy E(i,j,k) (eV/A^2)\n");
03444 fprintf(fp,"%% Format: i, j, k, E(i,j,k)\n");
03445 fprintf(fp,"%% i=1:nx, j=1:ny, k=1:nz\n");
03446 fprintf(fp,"%% nx = %d, ny = %d, nz = %d\n",nx,ny,nz);
03447 fprintf(fp,"\n");
03448 fprintf(fp,"%% x0 = %e, dx = %e, x1 = %e\n",x0,dx,x1);
03449 fprintf(fp,"%% y0 = %e, dy = %e, y1 = %e\n",y0,dy,y1);
03450 fprintf(fp,"%% z0 = %e, dz = %e, z1 = %e\n",z0,dz,z1);
03451 fprintf(fp,"\n");
03452
03453 c1.set(_H[0][0],_H[1][0],_H[2][0]);
03454 c2.set(_H[0][1],_H[1][1],_H[2][1]);
03455 c3.set(_H[0][2],_H[1][2],_H[2][2]);
03456 c1 /= latticesize[0][3];
03457 c2 /= latticesize[1][3];
03458 c3 /= latticesize[2][3];
03459
03460 ca.set(_H[0][inda],_H[1][inda],_H[2][inda]);
03461 cb.set(_H[0][indb],_H[1][indb],_H[2][indb]);
03462 caxcb = cross(ca, cb);
03463 area = caxcb.norm();
03464
03465 fprintf(fp,"%% area = %20.14e\n", area);
03466 fprintf(fp,"\n");
03467
03468 H_origin = _H;
03469 for(n=0;n<_NP;n++) _VSR[n]=_R[n];
03470
03471 call_potential();
03472
03473 fprintf(fp,"%% Epot_0/area = %20.14e (eV/A^2)\n",_EPOT/area);
03474 fprintf(fp,"\n");
03475 fprintf(fp,"%% i\t j\t k\t Epot/area (eV/A^2)\n");
03476 fprintf(fp,"%%-------------------------------------------\n");
03477
03478 SHtoR();
03479
03480 for(k=0;k<=nz;k++)
03481 for(j=0;j<=ny;j++)
03482 for(i=0;i<=nx;i++)
03483 {
03484 dc1 = c1*(x0+i*dx);
03485 dc2 = c2*(y0+j*dy);
03486 dc3 = c3*(z0+k*dz);
03487
03488 _H[0][ind]= H_origin[0][ind]+dc1.x + dc2.x + dc3.x;
03489 _H[1][ind]= H_origin[1][ind]+dc1.y + dc2.y + dc3.y;
03490 _H[2][ind]= H_origin[2][ind]+dc1.z + dc2.z + dc3.z;
03491
03492 for(n=0;n<_NP;n++) _R[n]=_VSR[n];
03493 RHtoS();
03494
03495
03496
03497 for(n=0;n<_NP;n++) _R0[n].clear();
03498 call_potential();
03499
03500 fprintf(fp, "%d\t %d\t %d\t %20.14e\n",i,j,k,_EPOT/area);
03501
03502
03503
03504 }
03505 fclose(fp);
03506
03507 }
03508
03509 void MDFrame::calmisfit2()
03510 {
03511 int nx, ny, nz, i, j, k, n, ind, inda, indb;
03512 double x0, y0, z0, x1, y1, z1, dx, dy, dz, xmin, xmax, ymin, ymax, zmin, zmax, mx, my, mz, Lx, Ly, Lz, area;
03513 FILE *fp;
03514 class Vector3 c1, c2, c3, ca, cb, caxcb;
03515
03516 WARNING("**************************************************************");
03517 WARNING(" calmisfit2() is implemented only for rectangular supercells!");
03518 WARNING(" Use calmisfit() for tilted supercells.");
03519 WARNING("**************************************************************");
03520
03521
03522 ind = (int)input[0];
03523 if(ind < 0 || ind > 3)
03524 {
03525 ERROR("Surface normal should be one of 1, 2, and 3.");
03526 return;
03527 }
03528 ind--;
03529
03530
03531 inda = (ind+1)%3; indb = (inda+1)%3;
03532
03533 x0 = input[1]; dx = input[2]; x1 = input[3];
03534 y0 = input[4]; dy = input[5]; y1 = input[6];
03535 z0 = input[7]; dz = input[8]; z1 = input[9];
03536 xmin = input[10]; xmax = input[11];
03537 ymin = input[12]; ymax = input[13];
03538 zmin = input[14]; zmax = input[15];
03539
03540 INFO_Printf("%% x0 = %e, dx = %e, x1 = %e\n",x0,dx,x1);
03541 INFO_Printf("%% y0 = %e, dy = %e, y1 = %e\n",y0,dy,y1);
03542 INFO_Printf("%% z0 = %e, dz = %e, z1 = %e\n",z0,dz,z1);
03543
03544 if(dx!=0) nx = (int) round((x1-x0)/dx); else nx = 0;
03545 if(dy!=0) ny = (int) round((y1-y0)/dy); else ny = 0;
03546 if(dz!=0) nz = (int) round((z1-z0)/dz); else nz = 0;
03547
03548 INFO_Printf("%% nx = %d, ny = %d, nz = %d\n",nx,ny,nz);
03549
03550 fp = fopen("Emisfit.out","w");
03551 if(fp==NULL) FATAL("calmisfit2: open file failure");
03552
03553 fprintf(fp,"%% Data file for misfit energy E(i,j,k) (eV/A^2)\n");
03554 fprintf(fp,"%% Format: i, j, k, E(i,j,k)\n");
03555 fprintf(fp,"%% i=1:nx, j=1:ny, k=1:nz\n");
03556 fprintf(fp,"%% nx = %d, ny = %d, nz = %d\n",nx,ny,nz);
03557 fprintf(fp,"\n");
03558 fprintf(fp,"%% x0 = %e, dx = %e, x1 = %e\n",x0,dx,x1);
03559 fprintf(fp,"%% y0 = %e, dy = %e, y1 = %e\n",y0,dy,y1);
03560 fprintf(fp,"%% z0 = %e, dz = %e, z1 = %e\n",z0,dz,z1);
03561 fprintf(fp,"\n");
03562
03563 c1.set(_H[0][0],_H[1][0],_H[2][0]);
03564 c2.set(_H[0][1],_H[1][1],_H[2][1]);
03565 c3.set(_H[0][2],_H[1][2],_H[2][2]);
03566 c1 /= latticesize[0][3];
03567 c2 /= latticesize[1][3];
03568 c3 /= latticesize[2][3];
03569
03570 ca.set(_H[0][inda],_H[1][inda],_H[2][inda]);
03571 cb.set(_H[0][indb],_H[1][indb],_H[2][indb]);
03572 caxcb = cross(ca, cb);
03573 area = caxcb.norm();
03574
03575 fprintf(fp,"%% area = %20.14e\n", area);
03576 fprintf(fp,"\n");
03577
03578 call_potential();
03579
03580 fprintf(fp,"%% Epot_0/area = %20.14e (eV/A^2)\n",_EPOT/area);
03581 fprintf(fp,"\n");
03582 fprintf(fp,"%% i\t j\t k\t Epot/area (eV/A^2)\n");
03583 fprintf(fp,"%%-------------------------------------------\n");
03584
03585 Lx = c1.norm(); if(nx!=0) mx = Lx*(x1-x0)/nx; else mx=0;
03586 Ly = c2.norm(); if(ny!=0) my = Ly*(y1-y0)/ny; else my=0;
03587 Lz = c3.norm(); if(nz!=0) mz = Lz*(z1-z0)/nz; else mz=0;
03588
03589 SHtoR();
03590 for(n=0;n<_NP;n++)
03591 {
03592 if((_SR[n].x>=xmin)&&(_SR[n].x<xmax)
03593 &&(_SR[n].y>=ymin)&&(_SR[n].y<ymax)
03594 &&(_SR[n].z>=zmin)&&(_SR[n].z<zmax))
03595 {
03596 _VSR[n].x = _R[n].x + Lx*x0;
03597 _VSR[n].y = _R[n].y + Ly*y0;
03598 _VSR[n].z = _R[n].z + Lz*z0;
03599 }
03600 }
03601 RHtoS();
03602
03603 for(k=0;k<=nz;k++)
03604 for(j=0;j<=ny;j++)
03605 for(i=0;i<=nx;i++)
03606 {
03607 SHtoR();
03608 for(n=0;n<_NP;n++)
03609 {
03610 if((_SR[n].x>=xmin)&&(_SR[n].x<xmax)
03611 &&(_SR[n].y>=ymin)&&(_SR[n].y<ymax)
03612 &&(_SR[n].z>=zmin)&&(_SR[n].z<zmax))
03613 {
03614 _R[n].x = _VSR[n].x + i*mx;
03615 _R[n].y = _VSR[n].y + j*my;
03616 _R[n].z = _VSR[n].z + k*mz;
03617 }
03618 }
03619
03620 RHtoS();
03621
03622
03623
03624
03625 call_potential();
03626
03627 fprintf(fp, "%d\t %d\t %d\t %20.14e\n",i,j,k,_EPOT/area);
03628 INFO_Printf("%d\t %d\t %d\t %20.14e\n",i,j,k,_EPOT/area);
03629 }
03630 fclose(fp);
03631 }
03632
03633 void MDFrame::testpotential()
03634 {
03635 int i, n, ipt;
03636 double E0, fx0, fy0, fz0, fx, fy, fz, dx, f2, fmax;
03637 int imax;
03638 Vector3 r0;
03639
03640 call_potential();
03641 E0=_EPOT;
03642 f2=_F[0].norm2(); imax=0; fmax=f2;
03643 for(i=0;i<_NP;i++)
03644 {
03645 f2=_F[i].norm2();
03646 if(f2>1e4) INFO_Printf("atom [%d] f=(%e %e %e)\n",i,_F[i].x,_F[i].y,_F[i].z);
03647 if(fmax<f2)
03648 {
03649 imax=i;
03650 fmax=f2;
03651 }
03652 }
03653 INFO_Printf("max force\n");
03654 INFO_Printf("atom [%d] f=(%e %e %e)\n",imax,_F[imax].x,_F[imax].y,_F[imax].z);
03655 n=(int)input[0];
03656 dx=input[1];
03657 for(i=1;i<=n;i++)
03658 {
03659 ipt=(int)input[i+1];
03660 SHtoR();
03661 call_potential();
03662 E0=_EPOT;
03663 fx0=_F[ipt].x;
03664 fy0=_F[ipt].y;
03665 fz0=_F[ipt].z;
03666
03667 r0=_R[ipt];
03668
03669 _R[ipt].x+=dx; RHtoS();
03670 call_potential();
03671 fx=(E0-_EPOT)/dx;
03672 _R[ipt]=r0; RHtoS();
03673
03674 _R[ipt].y+=dx; RHtoS();
03675 call_potential();
03676 fy=(E0-_EPOT)/dx;
03677 _R[ipt]=r0; RHtoS();
03678
03679 _R[ipt].z+=dx; RHtoS();
03680 call_potential();
03681 fz=(E0-_EPOT)/dx;
03682 _R[ipt]=r0; RHtoS();
03683
03684 INFO_Printf("atom [%d] \tf0 =(%e %e %e)\n"
03685 " \tfnum=(%e %e %e)\n",
03686 ipt, fx0, fy0, fz0, fx, fy, fz);
03687 }
03688 }
03689
03690 void MDFrame::initvelocity()
03691 {
03692 int i, n;
03693 Vector3 vavg,v2avg,r,v;
03694 Matrix33 hinv;
03695 double v2desired, totalmass, tmp;
03696 #ifdef _TORSION_OR_BENDING
03697 double tmp2, tmp4, curvature, Radius;
03698 #endif
03699
03700 v2desired = 2*(KB*_TDES)/(_ATOMMASS[0]*MASSCONVERT)
03701 *SQR(_TIMESTEP);
03702
03703 if(_DOUBLET!=1) v2desired*=.5;
03704
03705 vavg.clear(); v2avg.clear();
03706
03707 n=0; totalmass=0;
03708 for(i=0;i<_NP;i++)
03709 {
03710 if(fixed[i])
03711 {
03712 _VR[i].clear();
03713 continue;
03714 }
03715 _VR[i].x=drand48();
03716 _VR[i].y=drand48();
03717 _VR[i].z=drand48();
03718 if(species[i]!=0)
03719 {
03720 tmp = sqrt(_ATOMMASS[0]/_ATOMMASS[species[i]]);
03721 _VR[i] *= tmp;
03722 }
03723 vavg+=_VR[i]*_ATOMMASS[species[i]];
03724 totalmass+=_ATOMMASS[species[i]];
03725 n++;
03726 }
03727
03728
03729 vavg/=totalmass;
03730 for(i=0;i<_NP;i++)
03731 {
03732 if(fixed[i]) continue;
03733 _VR[i]-=vavg;
03734 }
03735
03736 #ifdef _TORSION_OR_BENDING
03737
03738 if (_TORSIONSIM)
03739 {
03740
03741 _PTHETA_COM = 0;
03742 tmp2 = tmp4 = 0;
03743 for(i=0;i<_NP0;i++)
03744 {
03745 r = _H*_SR[i];
03746 v = _H*_VSR[i];
03747 if(species[i]!=0)
03748 v *= _ATOMMASS[species[i]] / _ATOMMASS[0];
03749 tmp2 += (v.y*r.x - v.x*r.y);
03750 tmp4 += (r.x*r.x + r.y*r.y);
03751 }
03752 _PTHETA_COM = tmp2 / tmp4;
03753 for(i=0;i<_NP0;i++)
03754 {
03755 _VR[i].x += r.y*_PTHETA_COM;
03756 _VR[i].y -= r.x*_PTHETA_COM;
03757 }
03758 _PTHETA_COM = 0;
03759 }
03760
03761 if (_BENDSIM)
03762 {
03763
03764 _PTHETA_COM = 0;
03765 tmp2 = tmp4 = 0;
03766 curvature = bendspec[3];
03767 Radius = 1.0/curvature;
03768 for(i=0;i<_NP0;i++)
03769 {
03770 r = _H*_SR[i];
03771 r.y += Radius;
03772 v = _H*_VSR[i];
03773 if(species[i]!=0)
03774 v *= _ATOMMASS[species[i]] / _ATOMMASS[0];
03775 tmp2 += (v.y*r.x - v.x*r.y);
03776 tmp4 += (r.x*r.x + r.y*r.y);
03777 }
03778 _PTHETA_COM = tmp2 / tmp4;
03779 for(i=0;i<_NP0;i++)
03780 {
03781 _VR[i].x += r.y*_PTHETA_COM;
03782 _VR[i].y -= r.x*_PTHETA_COM;
03783 }
03784 _PTHETA_COM = 0;
03785 }
03786 #endif
03787
03788 if(_NIMAGES==0) _NP0=_NP;
03789
03790 for(i=0;i<_NP0;i++)
03791 {
03792 if(species[i]==0)
03793 v2avg+=_VR[i].sq();
03794 else
03795 v2avg+=_VR[i].sq() * _ATOMMASS[species[i]]/_ATOMMASS[0];
03796 }
03797 v2avg/=(n-1)*v2desired;v2avg=v2avg.sqroot();
03798
03799 for(i=0;i<_NP0;i++)
03800 {
03801 if(v2avg.x>0)_VR[i].x/=v2avg.x;
03802 if(v2avg.y>0)_VR[i].y/=v2avg.y;
03803 if(v2avg.z>0)_VR[i].z/=v2avg.z;
03804 }
03805 hinv=_H.inv();
03806 for(i=0;i<_NP0;i++)
03807 _VSR[i]=hinv*_VR[i];
03808
03809 _KATOM=3.0*BOLZ*_TDES/EV*(n-1);
03810 if(_DOUBLET!=1) _KATOM*=.5;
03811
03812 _VH.clear();
03813
03814 }
03815
03816 void MDFrame::perturbevelocity()
03817 {
03818 int i, n;
03819 double fraction ;
03820 Vector3 vavg, r, v, w, L, Rcm, scm;
03821 Matrix33 hinv,Inertia,iinv;
03822 double v2desired, totalmass, totalmass1, tmp;
03823 double rnorm;
03824
03825 fraction = input[0];
03826
03827 v2desired = 2* (KB*_TDES)/(_ATOMMASS[0]*MASSCONVERT)*SQR(_TIMESTEP);
03828 if(_DOUBLET!=1) v2desired*=.5;
03829
03830
03831
03832
03833 vavg.clear(); scm.clear(); Rcm.clear();
03834 n=0; totalmass=0; totalmass1=0;
03835 for(i=0;i<_NP;i++)
03836 {
03837 scm+=_SR[i]*_ATOMMASS[species[i]];
03838 totalmass1+=_ATOMMASS[species[i]];
03839
03840 if(fixed[i])
03841 {
03842 continue;
03843 }
03844 _VR[i]=_H*_VSR[i];
03845
03846 tmp = v2desired*sqrt(_ATOMMASS[0]/_ATOMMASS[species[i]]);
03847 _VR[i].x+= tmp * fraction*randnorm48();
03848 _VR[i].y+= tmp * fraction*randnorm48();
03849 _VR[i].z+= tmp * fraction*randnorm48();
03850
03851 vavg+=_VR[i]*_ATOMMASS[species[i]];
03852 totalmass+=_ATOMMASS[species[i]];
03853 n++;
03854 }
03855
03856 scm /= totalmass1;
03857 Rcm = _H*scm;
03858
03859 vavg/=totalmass;
03860 for(i=0;i<_NP;i++)
03861 {
03862 if(fixed[i]) continue;
03863 _VR[i]-=vavg;
03864 }
03865
03866
03867
03868
03869 hinv=_H.inv();
03870
03871 Inertia.clear();
03872 L.clear();w.clear();vavg.clear();
03873
03874 for (i=0;i<_NP;i++)
03875 {
03876 r = _H*_SR[i] - Rcm;
03877 rnorm = r.norm();
03878 v = _VR[i];
03879 vavg+=_VR[i]*_ATOMMASS[species[i]];
03880 tmp = (_ATOMMASS[species[i]]/_ATOMMASS[species[0]]);
03881 Inertia[0][0]+= (rnorm*rnorm - r[0]*r[0])*tmp;
03882 Inertia[0][1]+= ( - r[0]*r[1])*tmp;
03883 Inertia[0][2]+= ( - r[0]*r[2])*tmp;
03884 Inertia[1][0]+= ( - r[1]*r[0])*tmp;
03885 Inertia[1][1]+= (rnorm*rnorm - r[1]*r[1])*tmp;
03886 Inertia[1][2]+= ( - r[1]*r[2])*tmp;
03887 Inertia[2][0]+= ( - r[2]*r[0])*tmp;
03888 Inertia[2][1]+= ( - r[2]*r[1])*tmp;
03889 Inertia[2][2]+= (rnorm*rnorm - r[2]*r[2])*tmp;
03890 L[0] += (r[1]*v[2] - r[2]*v[1])*tmp;
03891 L[1] += (r[2]*v[0] - r[0]*v[2])*tmp;
03892 L[2] += (r[0]*v[1] - r[1]*v[0])*tmp;
03893
03894 }
03895 vavg/=totalmass;
03896 iinv=Inertia.inv();
03897 w=iinv*L;
03898
03899 L.clear(); vavg.clear();
03900 for (i=0;i<_NP;i++)
03901 {
03902 r = _H*_SR[i] - Rcm;
03903 _VR[i][0] -= (w[1]*r[2] - w[2]*r[1]);
03904 _VR[i][1] -= (w[2]*r[0] - w[0]*r[2]);
03905 _VR[i][2] -= (w[0]*r[1] - w[1]*r[0]);
03906 vavg+=_VR[i]*_ATOMMASS[species[i]];
03907 _VSR[i] = hinv * _VR[i];
03908
03909 v = _VR[i];
03910 L[0] += (r[1]*v[2] - r[2]*v[1]);
03911 L[1] += (r[2]*v[0] - r[0]*v[2]);
03912 L[2] += (r[0]*v[1] - r[1]*v[0]);
03913 }
03914 vavg/=totalmass;
03915
03916
03917 }
03918
03919 void MDFrame::MCperturbevelocity()
03920 {
03921 int i;
03922 double tmp, Ktmp;
03923 double Ko,Kn,v2;
03924 int MC_accept, MC_trial;
03925 Matrix33 hinv;
03926
03927 Ktmp=0.5*(_ATOMMASS[0]*MASSCONVERT)/(_TIMESTEP*_TIMESTEP);
03928 hinv=_H.inv();
03929 Ko=0;
03930 MC_trial=0;
03931
03932 for (i=0;i<_NP;i++)
03933 {
03934 _R[i]=_H*_VSR[i];
03935 v2=_R[i].norm2();
03936 Ko+=Ktmp*v2*_ATOMMASS[species[i]]/_ATOMMASS[0];
03937 }
03938
03939 while(1) {
03940 MC_trial++;
03941 Kn=0;
03942 perturbevelocity();
03943 for (i=0;i<_NP;i++)
03944 {
03945 v2=_VR[i].norm2();
03946 Kn+=Ktmp*v2*_ATOMMASS[species[i]]/_ATOMMASS[0];
03947 }
03948
03949 if (strcmp(ensemble_type,"NVE")==0)
03950 {
03951 tmp=sqrt(Ko/Kn);
03952 Kn=0;
03953 for (i=0;i<_NP;i++)
03954 {
03955 _R[i]=_H*_SR[i];
03956 _VR[i]*=tmp;
03957 _VSR[i]*=tmp;
03958 v2=_VR[i].norm2();
03959 Kn+=Ktmp*v2*_ATOMMASS[species[i]]/_ATOMMASS[0];
03960 }
03961
03962 break;
03963 }
03964 else
03965 {
03966 if(Kn<Ko)
03967 MC_accept=1;
03968 else
03969 {
03970 tmp=(Ko-Kn)/(KB*_TDES);
03971
03972 if (tmp<-40) MC_accept=0;
03973 else
03974 {
03975 if(drand48()<exp(tmp))
03976 MC_accept=1;
03977 else
03978 MC_accept=0;
03979 }
03980 }
03981
03982
03983 if (MC_accept==1)
03984 {
03985 for(i=0;i<_NP;i++)
03986 {
03987 _R[i]=_H*_SR[i];
03988 }
03989 INFO_Printf("MC_trial = %d\n",MC_trial);
03990 break;
03991 }
03992 else
03993 {
03994 for(i=0;i<_NP;i++)
03995 {
03996 _VR[i]=_R[i];
03997 _VSR[i]=hinv*_VR[i];
03998 }
03999 }
04000 }
04001
04002 }
04003 }
04004
04005 void MDFrame::randomposition()
04006 {
04007 int i;
04008 for(i=0;i<_NP;i++)
04009 {
04010 _SR[i].x=drand48()-0.5;
04011 _SR[i].y=drand48()-0.5;
04012 _SR[i].z=drand48()-0.5;
04013 }
04014 }
04015
04016 #if 0
04017 void MDFrame::velscaler()
04018 {
04019
04020
04021 double katomdesired,eratio,vratio; int i,n;
04022
04023 _NPfree=0;
04024 for(i=0;i<_NP;i++)
04025 {
04026 if(!fixed[i]) _NPfree++;
04027 }
04028 katomdesired=1.5*KB*_TDES*(_NPfree-1);
04029 eratio=katomdesired/_KATOM;
04030 eratio=min(eratio,1000);
04031 vratio=(eratio-1.)/_ATOMTCPL+1.;
04032
04033 for(i=0;i<_NP;i++)
04034 {
04035 _VSR[i]*=vratio;
04036 }
04037 }
04038 #endif
04039
04040 void MDFrame::scaleVel()
04041 {
04042 double vratio; int i;
04043
04044 vratio = input[0];
04045 for(i=0;i<_NP;i++)
04046 {
04047 if(!fixed[i])
04048 _VSR[i]*=vratio;
04049 }
04050 }
04051
04052
04053 void MDFrame::multiplyvelocity()
04054 {
04055 double factor; int i, itmp;
04056
04057 factor = input[0];
04058 for(i=0;i<_NP;i++)
04059 {
04060 _VSR[i]*=factor;
04061 }
04062 itmp = algorithm_id / 1000;
04063 if((itmp==20)||(itmp==40))
04064 {
04065 zetav*=factor;
04066 }
04067 if((itmp==21))
04068 for(i=0;i<NHChainLen;i++)
04069 zetaNHCv[i]*=factor;
04070
04071 if((itmp==30)||(itmp==40))
04072 {
04073 _VH*=factor;
04074 }
04075 }
04076
04077
04078
04079 void MDFrame::step()
04080 {
04081
04082 integrator();
04083
04084
04085
04086
04087
04088
04089 if (_ENABLE_SWITCH)
04090 {
04091 _WTOT += dEdlambda * dlambdadt * (_LAMBDA1-_LAMBDA0);
04092
04093 _WAVG = _WTOT / totalsteps;
04094 }
04095 }
04096
04097 void MDFrame::eval()
04098 {
04099
04100 call_potential();
04101 calcprop();
04102 printResult();
04103 }
04104
04105 void MDFrame::eval_insertparticle()
04106 {
04107 int particle_id;
04108
04109 particle_id = _NP;
04110 _SR[particle_id].x = drand48()-0.5;
04111 _SR[particle_id].y = drand48()-0.5;
04112 _SR[particle_id].z = drand48()-0.5;
04113 fixed[particle_id]=0;
04114
04115
04116 if(allocmultiple<=1)
04117 FATAL("eval_insertparticle cannot run with allocmultiple = "<<allocmultiple);
04118 NbrList_reconstruct_use_link_list();
04119 NbrList_reconstruct_use_link_list(particle_id);
04120 potential_energyonly(particle_id);
04121 INFO_Printf("EPOT_RMV[%d] = %20.12e\n",particle_id,_EPOT_RMV[particle_id]);
04122
04123 #if 0
04124 double E0, E1, dE;
04125
04126 INFO("------");
04127 _NP ++;
04128 NbrList_reconstruct_use_link_list();
04129 potential_energyonly();
04130
04131 E1 = _EPOT;
04132 INFO("------");
04133
04134 _NP --;
04135 NbrList_reconstruct_use_link_list();
04136 potential_energyonly();
04137 E0 = _EPOT;
04138
04139 INFO("------");
04140 NbrList_reconstruct_use_link_list();
04141 NbrList_reconstruct_use_link_list(particle_id);
04142 potential_energyonly(particle_id);
04143 dE = _EPOT_RMV[particle_id];
04144
04145 INFO_Printf("E1=%20.12e E0=%20.12e E1-E0=%20.12e dE=%20.12e",E1,E0,E1-E0,dE);
04146 #endif
04147 }
04148
04149 void MDFrame::eval_removeparticle()
04150 {
04151 int particle_id;
04152
04153 particle_id = (int) input[0];
04154 potential_energyonly();
04155 INFO_Printf("EPOT_RMV[%d] = %20.12e\n",particle_id,_EPOT_RMV[particle_id]);
04156
04157 #if 0
04158 double E0, E1, dE;
04159 dE = _EPOT_RMV[particle_id];
04160 E1 = _EPOT;
04161
04162 fixed[particle_id]=-1;
04163 potential_energyonly();
04164 E0 = _EPOT;
04165
04166 fixed[particle_id]=0;
04167 INFO_Printf("E1=%20.12e E0=%20.12e E1-E0=%20.12e dE=%20.12e",E1,E0,E1-E0,dE);
04168 #endif
04169 }
04170
04171 void MDFrame::printResult()
04172 {
04173 calcoutput();
04174 if(strlen(output_str)==0)
04175 {
04176 INFO_Printf("EPOT=%18.14e\n",_EPOT);
04177 INFO_Printf("KATOM=%18.14e\n",_KATOM);
04178 INFO_Printf("PRESSURE=%18.14e in eV/Angstrom^3\n",_TOTSTRESS.trace()/3.);
04179 INFO("\nVIRIAL=["<<_VIRIAL<<"]\n"
04180 "\nH=["<<_H<<"]\n");
04181 INFO("\nStress (in MPa)=\n["<<_VIRIAL/(_H.det()*(1-_VACUUMRATIO))*160.2e3<<"]\n");
04182 }
04183 else
04184 {
04185 INFO_Printf("Format: %s\n",output_fmt);
04186 INFO_Printf("Result: %s\n",output_str);
04187 }
04188 }
04189
04190 void MDFrame::multieval()
04191 {
04192 int i;
04193 for(i=0;i<totalsteps;i++)
04194 call_potential();
04195 }
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208
04209 int MDFrame::MCstep()
04210 {
04211 int ret;
04212
04213 ret = MCstep_moveatom();
04214
04215 if(ensemble_type[1]=='P')
04216 {
04217 if(drand48()<(1.0/MC_dV_freq))
04218 ret = MCstep_dV();
04219 }
04220
04221 if(ensemble_type[0]=='u')
04222 {
04223 if(drand48()<(1.0/MC_dN_freq))
04224 ret = MCstep_dN();
04225 }
04226
04227 return ret;
04228 }
04229
04230 int MDFrame::MCstep_fracatom()
04231 {
04232
04233
04234 int ret;
04235
04236 ret = MCstep_moveatom_fracatom();
04237
04238 if(ensemble_type[1]=='P')
04239 {
04240 if(drand48()<(1.0/MC_dV_freq))
04241 ret = MCstep_dV_fracatom();
04242 }
04243
04244 if(ensemble_type[0]=='u')
04245 {
04246 if(drand48()<(1.0/MC_dN_freq))
04247 ret = MCstep_dN_fracatom();
04248 }
04249
04250 return ret;
04251 }
04252
04253 int MDFrame::MCstep_moveatom()
04254 {
04255 Vector3 dr, ds, dr0, ds0;
04256 Matrix33 hinv;
04257 int i;
04258 double Eatom0,Eatom1,tmp;
04259
04260
04261
04262 hinv=_H.inv();
04263
04264
04265 if(MC_atom>=0)
04266 {
04267 MC_atom = (int)floor(drand48()*_NP);
04268 while(fixed[MC_atom]==-1) {MC_atom = (int)floor(drand48()*_NP);}
04269
04270 Eatom0=potential_energyonly(MC_atom);
04271
04272 MC_dr.x=(drand48()-0.5)*_TIMESTEP;
04273 MC_dr.y=(drand48()-0.5)*_TIMESTEP;
04274 MC_dr.z=(drand48()-0.5)*_TIMESTEP;
04275 ds=hinv*MC_dr;
04276 _SR[MC_atom]+=ds;
04277
04278 Eatom1=potential_energyonly(MC_atom);
04279 _EPOT=_EPOT0+Eatom1-Eatom0;
04280
04281
04282
04283
04284
04285
04286
04287 }
04288 else
04289 {
04290 dr0.clear();
04291 for(i=0;i<_NP;i++)
04292 {
04293 if(fixed[i]==-1) continue;
04294 dr.x=(drand48()-0.5)*_TIMESTEP;
04295 dr.y=(drand48()-0.5)*_TIMESTEP;
04296 dr.z=(drand48()-0.5)*_TIMESTEP;
04297 dr0+=dr;
04298 ds=hinv*dr;
04299 _VSR[i]=ds;
04300 }
04301
04302 dr0/=_NP;
04303 ds0=hinv*dr0;
04304 for(i=0;i<_NP;i++)
04305 {
04306 _VSR[i]-=ds0;
04307 _SR[i]+=_VSR[i];
04308 }
04309 potential_energyonly();
04310 }
04311
04312 if(_EPOT<_EPOT0)
04313 MC_accept=1;
04314 else
04315 {
04316 tmp=(_EPOT0-_EPOT)/(KB*_TDES);
04317 if(tmp<-40) MC_accept=0;
04318 else
04319 {
04320 if(drand48()<exp(tmp))
04321 MC_accept=1;
04322 else
04323 MC_accept=0;
04324 }
04325 }
04326
04327 if(MC_accept)
04328 {
04329 _EPOT0=_EPOT;
04330 MC_accept_tot++;
04331 }
04332 else
04333 {
04334 if(MC_atom>=0)
04335 {
04336 _SR[MC_atom]-=ds;
04337 }
04338 else
04339 {
04340 for(i=0;i<_NP;i++)
04341 {
04342 _SR[i]-=_VSR[i];
04343 }
04344 _EPOT=_EPOT0;
04345
04346 }
04347 }
04348 return MC_accept;
04349 }
04350
04351 int MDFrame::MCstep_dV()
04352 {
04353 double tmp, V, dV;
04354
04355
04356
04357 V = _H.det();
04358
04359 dV = MC_dVmax*(2*drand48()-1);
04360 _H0 = _H;
04361
04362 tmp = pow((V+dV)/V,1.0/3.0);
04363 _H *= tmp;
04364
04365
04366 NbrList_reconstruct_use_link_list();
04367 potential_energyonly();
04368
04369 tmp=(_EPOT0-_EPOT - MC_P_ext*dV/160.2e3)/(KB*_TDES) + _NP*log((V+dV)/V);
04370
04371 if(tmp>0)
04372 MC_accept=1;
04373 else
04374 {
04375 if(tmp<-40) MC_accept=0;
04376 else
04377 {
04378 if(drand48()<exp(tmp))
04379 MC_accept=1;
04380 else
04381 MC_accept=0;
04382 }
04383 }
04384
04385 if(MC_accept)
04386 {
04387 _EPOT0=_EPOT;
04388 MC_accept_tot++;
04389 }
04390 else
04391 {
04392 _H = _H0;
04393 _EPOT = _EPOT0;
04394
04395 NbrList_reconstruct_use_link_list();
04396 }
04397 return MC_accept;
04398 }
04399
04400 int MDFrame::MCstep_dN()
04401 {
04402 int atom_id, i;
04403 double dE,tmp,xi;
04404
04405
04406
04407 xi = drand48() - 0.5;
04408
04409
04410 if (xi < 0)
04411 {
04412 atom_id = (int) floor(drand48()*_NP);
04413 potential_energyonly();
04414 dE = -_EPOT_RMV[atom_id];
04415
04416 tmp = (-dE - MC_mu_ext)/(KB*_TDES) + log(_NP*MC_Lambda3/_H.det());
04417
04418 INFO_Printf("MC trial remove: dE = %20.12e tmp = %20.12e\n",dE,tmp);
04419
04420 if(tmp>0)
04421 MC_accept=1;
04422 else
04423 {
04424 if(tmp<-40) MC_accept=0;
04425 else
04426 {
04427 if( drand48() < exp(tmp) )
04428 MC_accept=1;
04429 else
04430 MC_accept=0;
04431 }
04432 }
04433 if(MC_accept)
04434 {
04435 _EPOT += dE;
04436 _EPOT0=_EPOT;
04437 MC_accept_tot++;
04438
04439 for(i=atom_id+1;i<_NP;i++)
04440 {
04441 _SR[i-1]=_SR[i];
04442 fixed[i-1]=fixed[i];
04443 species[i-1]=species[i];
04444 _EPOT_IND[i-1]=_EPOT_IND[i];
04445 _EPOT_RMV[i-1]=_EPOT_RMV[i];
04446 _TOPOL[i-1]=_TOPOL[i];
04447 }
04448 _NP--;
04449 }
04450 }
04451 else
04452 {
04453 atom_id = _NP;
04454
04455 _SR[atom_id].x = drand48()-0.5;
04456 _SR[atom_id].y = drand48()-0.5;
04457 _SR[atom_id].z = drand48()-0.5;
04458 fixed[atom_id] = 0;
04459
04460 _NP ++;
04461
04462
04463 NbrList_reconstruct_use_link_list();
04464
04465
04466
04467 potential_energyonly();
04468
04469 dE = _EPOT - _EPOT0;
04470
04471 tmp = (-dE + MC_mu_ext)/(KB*_TDES) - log(_NP*MC_Lambda3/_H.det());
04472 INFO_Printf("V = %20.12e -log(NP*Lambda3/V) = %20.12e\n",_H.det(), -log(_NP*MC_Lambda3/_H.det()));
04473 INFO_Printf("MC trial insert: dE = %20.12e (%20.12e) tmp = %20.12e\n",dE,_EPOT_RMV[atom_id],tmp);
04474
04475 if(tmp>0)
04476 MC_accept=1;
04477 else
04478 {
04479 if(tmp<-40) MC_accept=0;
04480 else
04481 {
04482 if( drand48() < exp(tmp) )
04483 MC_accept=1;
04484 else
04485 MC_accept=0;
04486 }
04487 }
04488
04489 if(MC_accept)
04490 {
04491 _EPOT0=_EPOT;
04492 MC_accept_tot++;
04493 }
04494 else
04495 {
04496 _EPOT=_EPOT0;
04497 _NP--;
04498
04499 NbrList_reconstruct_use_link_list();
04500
04501
04502 }
04503 }
04504
04505 return MC_accept;
04506 }
04507
04508
04509 int MDFrame::MCstep_moveatom_fracatom()
04510 {
04511
04512
04513 Vector3 dr, ds, dr0, ds0;
04514 Matrix33 hinv;
04515 int i;
04516 double tmp;
04517
04518
04519
04520 hinv=_H.inv();
04521
04522
04523 if(MC_atom>=0)
04524 {
04525 FATAL("MCstep_moveatom_fracatom only works for MC_atom = -1, i.e. move all atoms at once");
04526 }
04527 else
04528 {
04529 dr0.clear();
04530 for(i=0;i<_NP;i++)
04531 {
04532 if(fixed[i]==-1) continue;
04533 dr.x=(drand48()-0.5)*_TIMESTEP;
04534 dr.y=(drand48()-0.5)*_TIMESTEP;
04535 dr.z=(drand48()-0.5)*_TIMESTEP;
04536 dr0+=dr;
04537 ds=hinv*dr;
04538 _VSR[i]=ds;
04539 }
04540
04541 dr0/=_NP;
04542 ds0=hinv*dr0;
04543 for(i=0;i<_NP;i++)
04544 {
04545 _VSR[i]-=ds0;
04546 _SR[i]+=_VSR[i];
04547 }
04548 potential_energyonly();
04549 _EPOT-=_EPOT_RMV[_NP-1]*(1-MC_fracatom);
04550 }
04551
04552 if(_EPOT<_EPOT0)
04553 MC_accept=1;
04554 else
04555 {
04556 tmp=(_EPOT0-_EPOT)/(KB*_TDES);
04557 if(tmp<-40) MC_accept=0;
04558 else
04559 {
04560 if(drand48()<exp(tmp))
04561 MC_accept=1;
04562 else
04563 MC_accept=0;
04564 }
04565 }
04566
04567 if(MC_accept)
04568 {
04569 _EPOT0=_EPOT;
04570 MC_accept_tot++;
04571 }
04572 else
04573 {
04574 if(MC_atom>=0)
04575 {
04576 _SR[MC_atom]-=ds;
04577 }
04578 else
04579 {
04580 for(i=0;i<_NP;i++)
04581 {
04582 _SR[i]-=_VSR[i];
04583 }
04584 _EPOT=_EPOT0;
04585 }
04586 }
04587 return MC_accept;
04588 }
04589
04590 int MDFrame::MCstep_dV_fracatom()
04591 {
04592 double tmp, V, dV;
04593
04594
04595
04596 V = _H.det();
04597
04598 dV = MC_dVmax*(2*drand48()-1);
04599 _H0 = _H;
04600
04601 tmp = pow((V+dV)/V,1.0/3.0);
04602 _H *= tmp;
04603
04604
04605 NbrList_reconstruct_use_link_list();
04606 potential_energyonly();
04607 _EPOT-=_EPOT_RMV[_NP-1]*(1-MC_fracatom);
04608
04609 tmp=(_EPOT0-_EPOT - MC_P_ext*dV/160.2e3)/(KB*_TDES) + _NP*log((V+dV)/V);
04610
04611 if(tmp>0)
04612 MC_accept=1;
04613 else
04614 {
04615 if(tmp<-40) MC_accept=0;
04616 else
04617 {
04618 if(drand48()<exp(tmp))
04619 MC_accept=1;
04620 else
04621 MC_accept=0;
04622 }
04623 }
04624
04625 if(MC_accept)
04626 {
04627 _EPOT0=_EPOT;
04628 MC_accept_tot++;
04629 }
04630 else
04631 {
04632 _H = _H0;
04633 _EPOT = _EPOT0;
04634
04635 NbrList_reconstruct_use_link_list();
04636 }
04637 return MC_accept;
04638 }
04639
04640 int MDFrame::MCstep_dN_fracatom()
04641 {
04642 int atom_id;
04643 double dE,tmp,xi;
04644
04645
04646
04647 xi = drand48() - 0.5;
04648
04649 if (xi < 0)
04650 {
04651 atom_id = _NP-1;
04652 MC_fracatom -= MC_dfrac;
04653 potential_energyonly();
04654 _EPOT-=_EPOT_RMV[_NP-1]*(1-MC_fracatom);
04655 dE = _EPOT - _EPOT0;
04656
04657 if(fabs(dE+_EPOT_RMV[atom_id]*MC_dfrac)>1e-10)
04658 FATAL("MC trial remove: dE = "<<dE<<" EPOT_RMV["<<atom_id<<"] = "<<_EPOT_RMV[atom_id]
04659 <<" MC_dfrac = "<<MC_dfrac);
04660
04661 tmp = (-dE - MC_mu_ext*MC_dfrac)/(KB*_TDES) + log(_NP*MC_Lambda3/_H.det())*MC_dfrac;
04662
04663 INFO_Printf("MC trial remove: dE = %20.12e tmp = %20.12e frac=%f\n",dE,tmp,MC_fracatom);
04664
04665 if(tmp>0)
04666 MC_accept=1;
04667 else
04668 {
04669 if(tmp<-40) MC_accept=0;
04670 else
04671 {
04672 if( drand48() < exp(tmp) )
04673 MC_accept=1;
04674 else
04675 MC_accept=0;
04676 }
04677 }
04678 if(MC_accept)
04679 {
04680 _EPOT0=_EPOT;
04681 MC_accept_tot++;
04682
04683 if(MC_fracatom==0)
04684 {
04685 _NP --;
04686
04687 atom_id = (int) floor(drand48()*_NP);
04688
04689 _SR[(_NP)]=_SR[atom_id]; fixed[_NP]=fixed[atom_id]; species[_NP]=species[atom_id]; _EPOT_IND[_NP]=_EPOT_IND[atom_id]; _EPOT_RMV[_NP]=_EPOT_RMV[atom_id]; _TOPOL[_NP]=_TOPOL[atom_id];
04690 _SR[(atom_id-1)]=_SR[_NP-1]; fixed[atom_id-1]=fixed[_NP-1]; species[atom_id-1]=species[_NP-1]; _EPOT_IND[atom_id-1]=_EPOT_IND[_NP-1]; _EPOT_RMV[atom_id-1]=_EPOT_RMV[_NP-1]; _TOPOL[atom_id-1]=_TOPOL[_NP-1];
04691 _SR[(_NP-1)]=_SR[_NP]; fixed[_NP-1]=fixed[_NP]; species[_NP-1]=species[_NP]; _EPOT_IND[_NP-1]=_EPOT_IND[_NP]; _EPOT_RMV[_NP-1]=_EPOT_RMV[_NP]; _TOPOL[_NP-1]=_TOPOL[_NP];
04692
04693 MC_fracatom = 1;
04694 }
04695 _EPOT = _EPOT0;
04696 INFO_Printf("MC remove accepted: NP = %d frac = %f\n",_NP,MC_fracatom);
04697 }
04698 else
04699 {
04700 MC_fracatom += MC_dfrac;
04701 _EPOT = _EPOT0;
04702 }
04703 }
04704 else
04705 {
04706 if(MC_fracatom==1)
04707 {
04708 atom_id = _NP;
04709 _SR[atom_id].x = drand48()-0.5;
04710 _SR[atom_id].y = drand48()-0.5;
04711 _SR[atom_id].z = drand48()-0.5;
04712 fixed[atom_id] = 0;
04713 _NP ++;
04714 MC_fracatom = MC_dfrac;
04715
04716 NbrList_reconstruct_use_link_list();
04717
04718
04719 potential_energyonly();
04720 _EPOT-=_EPOT_RMV[_NP-1]*(1-MC_fracatom);
04721 dE = _EPOT - _EPOT0;
04722
04723 if(fabs((dE-_EPOT_RMV[atom_id]*MC_dfrac)/dE)>1e-10)
04724 FATAL("MC trial insert: dE = "<<dE<<" EPOT_RMV["<<atom_id<<"] = "<<_EPOT_RMV[atom_id]
04725 <<" MC_dfrac = "<<MC_dfrac);
04726 }
04727 else
04728 {
04729 atom_id = _NP-1;
04730 MC_fracatom += MC_dfrac;
04731 potential_energyonly();
04732 _EPOT-=_EPOT_RMV[atom_id]*(1-MC_fracatom);
04733 dE = _EPOT - _EPOT0;
04734
04735 if(fabs(dE-_EPOT_RMV[atom_id]*MC_dfrac)>1e-10)
04736 FATAL("MC trial insert: dE = "<<dE<<" EPOT_RMV["<<atom_id<<"] = "<<_EPOT_RMV[atom_id]
04737 <<" MC_dfrac = "<<MC_dfrac);
04738 }
04739
04740
04741 tmp = (-dE + MC_mu_ext*MC_dfrac)/(KB*_TDES) - log(_NP*MC_Lambda3/_H.det())*MC_dfrac;
04742 INFO_Printf("V = %20.12e -log(NP*Lambda3/V) = %20.12e\n",_H.det(), -log(_NP*MC_Lambda3/_H.det()));
04743 INFO_Printf("MC trial insert: dE = %20.12e (%20.12e) tmp = %20.12e frac=%f\n",dE,_EPOT_RMV[atom_id],tmp,MC_fracatom);
04744
04745 if(tmp>0)
04746 MC_accept=1;
04747 else
04748 {
04749 if(tmp<-40) MC_accept=0;
04750 else
04751 {
04752 if( drand48() < exp(tmp) )
04753 MC_accept=1;
04754 else
04755 MC_accept=0;
04756 }
04757 }
04758
04759 if(MC_accept)
04760 {
04761 INFO_Printf("MC insert accepted: NP = %d frac = %f\n",_NP,MC_fracatom);
04762 _EPOT0=_EPOT;
04763 MC_accept_tot++;
04764 }
04765 else
04766 {
04767 _EPOT=_EPOT0;
04768 if(MC_fracatom==MC_dfrac)
04769 {
04770 _NP--;
04771 MC_fracatom=1;
04772
04773 NbrList_reconstruct_use_link_list();
04774
04775
04776 }
04777 else
04778 {
04779 MC_fracatom -= MC_dfrac;
04780 }
04781 }
04782 }
04783
04784 return MC_accept;
04785 }
04786
04787
04788 int MDFrame::MCSWITCHstep(double lambda)
04789 {
04790 Vector3 dr, ds, dr0, ds0;
04791 Matrix33 hinv;
04792 int i;
04793 double Eatom0, Eatom1, ECatom0, ECatom1, tmp;
04794
04795 hinv=_H.inv();
04796 Eatom0=ECatom0=Eatom1=ECatom1=0;
04797 if(MC_atom>=0)
04798 {
04799 MC_atom = (int)floor(drand48()*_NP);
04800
04801 if(_SR2==NULL)
04802 {
04803 Eatom0 = potential_energyonly(MC_atom);
04804 ECatom0= ECpotential_energyonly(MC_atom);
04805
04806 MC_dr.x=(drand48()-0.5)*_TIMESTEP;
04807 MC_dr.y=(drand48()-0.5)*_TIMESTEP;
04808 MC_dr.z=(drand48()-0.5)*_TIMESTEP;
04809 ds=hinv*MC_dr;
04810 _SR[MC_atom]+=ds;
04811
04812 Eatom1 = potential_energyonly(MC_atom);
04813 ECatom1= ECpotential_energyonly(MC_atom);
04814
04815 _EPOT = _EPOT0 + ((1-lambda)*Eatom1+lambda*ECatom1)
04816 - ((1-lambda)*Eatom0+lambda*ECatom0) ;
04817
04818 dEdlambda += (ECatom1 - Eatom1) - (ECatom0 - Eatom0) ;
04819 }
04820 else
04821 {
04822 Eatom0 = potential_energyonly(MC_atom);
04823 memcpy(_SR3,_SR,sizeof(Vector3)*_NP);
04824 for(i=0;i<_NP;i++)
04825 _SR[i]=_SR[i]-_SR1[i]+_SR2[i];
04826 ECatom0 = potential_energyonly(MC_atom);
04827 memcpy(_SR,_SR3,sizeof(Vector3)*_NP);
04828
04829 MC_dr.x=(drand48()-0.5)*_TIMESTEP;
04830 MC_dr.y=(drand48()-0.5)*_TIMESTEP;
04831 MC_dr.z=(drand48()-0.5)*_TIMESTEP;
04832 ds=hinv*MC_dr;
04833 _SR[MC_atom]+=ds;
04834
04835 Eatom1 = potential_energyonly(MC_atom);
04836 memcpy(_SR3,_SR,sizeof(Vector3)*_NP);
04837 for(i=0;i<_NP;i++)
04838 _SR[i]=_SR[i]-_SR1[i]+_SR2[i];
04839 ECatom1 = potential_energyonly(MC_atom);
04840 memcpy(_SR,_SR3,sizeof(Vector3)*_NP);
04841
04842 _EPOT = _EPOT0 + ((1-lambda)*Eatom1+lambda*ECatom1)
04843 - ((1-lambda)*Eatom0+lambda*ECatom0) ;
04844
04845 dEdlambda += (ECatom1 - Eatom1) - (ECatom0 - Eatom0) ;
04846 }
04847 }
04848 else
04849 {
04850 dr0.clear();
04851 for(i=0;i<_NP;i++)
04852 {
04853 dr.x=(drand48()-0.5)*_TIMESTEP;
04854 dr.y=(drand48()-0.5)*_TIMESTEP;
04855 dr.z=(drand48()-0.5)*_TIMESTEP;
04856 dr0+=dr;
04857 ds=hinv*dr;
04858 _VSR[i]=ds;
04859 }
04860
04861 dr0/=_NP;
04862 ds0=hinv*dr0;
04863 for(i=0;i<_NP;i++)
04864 {
04865 _VSR[i]-=ds0;
04866 _SR[i]+=_VSR[i];
04867 }
04868 SWITCHpotential_energyonly(lambda);
04869 }
04870
04871
04872 if(_EPOT<_EPOT0)
04873 MC_accept=1;
04874 else
04875 {
04876 tmp=(_EPOT0-_EPOT)/(KB*_TDES);
04877 if(tmp<-40) MC_accept=0;
04878 else
04879 {
04880 if(drand48()<exp(tmp))
04881 MC_accept=1;
04882 else
04883 MC_accept=0;
04884 }
04885 }
04886
04887 if(MC_accept)
04888 {
04889 _EPOT0=_EPOT;
04890 MC_accept_tot++;
04891 }
04892 else
04893 {
04894 if(MC_atom>=0)
04895 {
04896 _SR[MC_atom]-=ds;
04897
04898 dEdlambda -= (ECatom1 - Eatom1) - (ECatom0 - Eatom0) ;
04899
04900 _EPOT=_EPOT0;
04901 }
04902 else
04903 {
04904 for(i=0;i<_NP;i++)
04905 {
04906 _SR[i]-=_VSR[i];
04907 }
04908 _EPOT=_EPOT0;
04909 }
04910 }
04911 return MC_accept;
04912 }
04913
04914 int MDFrame::runMC()
04915 {
04916
04917
04918
04919
04920
04921 if ( (strcmp(ensemble_type,"NVT")!=0) &&
04922 (strcmp(ensemble_type,"NPT")!=0) &&
04923 (strcmp(ensemble_type,"uVT")!=0) &&
04924 (strcmp(ensemble_type,"uPT")!=0) )
04925 {
04926 ERROR("unknown ensemble_type "<<ensemble_type<<"--> set to NVT");
04927 strcpy(ensemble_type,"NVT");
04928 }
04929
04930 if(ensemble_type[0]=='u')
04931 {
04932 double tmp;
04933 if(nspecies>1) ERROR("runMC: uVT/uPT not implemented for nspecies = "<<nspecies);
04934 tmp = PLANCK_H/sqrt(2*M_PI*_ATOMMASS[0]*1.e-3/AVO/EV*KB*_TDES)*1e10;
04935 INFO_Printf("runMC: thermal wavelength Lambda = %20.12e Angstrom",tmp);
04936 MC_Lambda3 = tmp*tmp*tmp;
04937
04938 if(allocmultiple<=1)
04939 FATAL("runMC: cannot run with allocmultiple = "<<allocmultiple);
04940 }
04941
04942 SHtoR();
04943
04944 potential_energyonly();
04945 _EPOT-=_EPOT_RMV[_NP-1]*(1-MC_fracatom);
04946 _EPOT0=_EPOT;
04947
04948 MC_accept_tot=0;
04949 MC_accept_ratio=0;
04950
04951 if(continue_curstep)
04952 step0 = curstep;
04953 else
04954 step0 = 0;
04955 for(curstep=step0;curstep<(step0 + totalsteps);curstep++)
04956
04957 {
04958 while(win!=NULL)
04959 {
04960 if(win->IsPaused()) sleep(1);
04961 else break;
04962 }
04963
04964
04965
04966 MCstep_fracatom();
04967 MC_accept_ratio = ((double) MC_accept_tot) / (curstep+1);
04968
04969 if(curstep%printfreq==0)
04970 {
04971 INFO_Printf("curstep = %d MC_atom = %d MC_accept = %d "
04972 "accept_ratio = %e\n",
04973 curstep, MC_atom, MC_accept, MC_accept_ratio);
04974 }
04975 winplot();
04976
04977 if(curstep>=equilsteps)
04978 {
04979 if(saveprop)
04980 {
04981 if((curstep%savepropfreq)==0)
04982 {
04983 potential_energyonly();
04984 _EPOT-=_EPOT_RMV[_NP-1]*(1-MC_fracatom);
04985 calcprop();
04986 calcoutput();
04987 pf.write(this);
04988 }
04989 }
04990
04991 if(savecn)
04992 if((curstep%savecnfreq)==0&&(curstep!=0))
04993 intercn.write(this,zipfiles,true);
04994 }
04995 if(win!=NULL)
04996 if(win->IsAlive())
04997 if(autowritegiffreq>0)
04998 if((curstep%autowritegiffreq)==0)
04999 {
05000 win->LockWritegif();
05001 }
05002 }
05003 if(saveprop)
05004 {
05005 potential_energyonly();
05006 _EPOT-=_EPOT_RMV[_NP-1]*(1-MC_fracatom);
05007 calcprop();
05008 calcoutput();
05009 pf.write(this);
05010 }
05011
05012 return 0;
05013 }
05014
05015 double MDFrame::SWITCH_Find_Lambda()
05016 {
05017 double lambda, t, s, t5, t4, t3, t2;
05018
05019 t = ((double) curstep)/ (totalsteps-1);
05020 if(_SWITCHFUNC == 0)
05021 {
05022 t2 = t*t;
05023 t3 = t2*t;
05024 t4 = t3*t;
05025 t5 = t4*t;
05026 s = (t5*(70.*t4-315.*t3+540.*t2-420.*t+126.));
05027 dlambdadt = (t4*(630.*t4-2520.*t3+3780.*t2-2520.*t+630.));
05028 }
05029 else if(_SWITCHFUNC == 1)
05030 {
05031 s = t;
05032 dlambdadt = 1;
05033 }
05034 else
05035 {
05036 s = t;
05037 dlambdadt = 1;
05038 ERROR("unknown switchfunc!");
05039 }
05040 lambda = _LAMBDA0 + s * (_LAMBDA1-_LAMBDA0) ;
05041 return lambda;
05042 }
05043
05044 int MDFrame::runMCSWITCH()
05045 {
05046 double lambda, lambdaprev;
05047
05048 SHtoR();
05049
05050 lambda=_LAMBDA0;
05051 lambdaprev=lambda; dlambdadt=0;
05052 SWITCHpotential_energyonly(lambda);
05053 _EPOT0=_EPOT;
05054
05055 MC_accept_tot=0;
05056 MC_accept_ratio=0;
05057 _WTOT=0;
05058
05059 if(continue_curstep)
05060 step0 = curstep;
05061 else
05062 step0 = 0;
05063 for(curstep=step0;curstep<(step0 + totalsteps);curstep++)
05064
05065 {
05066 while(win!=NULL)
05067 {
05068 if(win->IsPaused()) sleep(1);
05069 else break;
05070 }
05071
05072 if((curstep%_SWITCHFREQ)==0)
05073 lambda = SWITCH_Find_Lambda();
05074
05075 if(lambda!=lambdaprev)
05076 {
05077 lambdaprev=lambda;
05078
05079 SWITCHpotential_energyonly(lambda);
05080 _EPOT0=_EPOT;
05081 }
05082
05083 MCSWITCHstep(lambda);
05084 _WTOT += dEdlambda * dlambdadt * (_LAMBDA1-_LAMBDA0);
05085
05086 _WAVG = _WTOT / totalsteps ;
05087 MC_accept_ratio = ((double) MC_accept_tot) / (curstep+1);
05088
05089 if(curstep%printfreq==0)
05090 {
05091 INFO_Printf("curstep = %d MC_atom = %d "
05092 "accept_ratio = %e lambda = %e dEdlambda=%e E=%e\n",
05093 curstep, MC_atom, MC_accept_ratio, lambda, dEdlambda,_EPOT);
05094 }
05095 winplot();
05096
05097 if(curstep>=equilsteps)
05098 {
05099 if(saveprop)
05100 {
05101 if((curstep%savepropfreq)==0)
05102 {
05103 calcoutput();
05104 pf.write(this);
05105 }
05106 }
05107
05108 if(savecn)
05109 if((curstep%savecnfreq)==0&&(curstep!=0))
05110 intercn.write(this,zipfiles,true);
05111 }
05112 if(win!=NULL)
05113 if(win->IsAlive())
05114 if(autowritegiffreq>0)
05115 if((curstep%autowritegiffreq)==0)
05116 {
05117 win->LockWritegif();
05118 }
05119 }
05120 if(saveprop)
05121 {
05122 calcoutput();
05123 pf.write(this);
05124 }
05125
05126 INFO_Printf("dF = %20.16e\n",_WAVG);
05127 return 0;
05128 }
05129
05130 int MDFrame::runTAMC()
05131 {
05132 int i, ipt, j, n, transition, cnindex, chainindex;
05133 Vector3 ds, dr;
05134 Matrix33 hinv;
05135 double Eatom0, Eatom1, tmp, r0, r2;
05136
05137
05138
05139
05140
05141
05142
05143
05144
05145
05146
05147
05148 SHtoR();
05149 potential_energyonly();
05150 _EPOT0=_EPOT;
05151
05152 MC_accept_tot=0;
05153 MC_accept_ratio=0;
05154
05155 n=constrainatoms[0];
05156 transition=0;
05157
05158 for(j=1;j<=n;j++)
05159 {
05160 ipt=constrainatoms[j];
05161 _Rc[0][j]=_R[ipt];
05162 }
05163
05164
05165
05166
05167
05168
05169 for(curstep=1;curstep<=totalsteps;curstep++)
05170 {
05171 while(win!=NULL)
05172 {
05173 if(win->IsPaused()) sleep(1);
05174 else break;
05175 }
05176
05177 hinv=_H.inv();
05178
05179 j = (int)ceil(drand48()*n);
05180 MC_atom = constrainatoms[j];
05181
05182 Eatom0=potential_energyonly(MC_atom);
05183
05184 MC_dr.x=(drand48()-0.5)*_TIMESTEP;
05185 MC_dr.y=(drand48()-0.5)*_TIMESTEP;
05186 MC_dr.z=(drand48()-0.5)*_TIMESTEP;
05187 ds=hinv*MC_dr;
05188 _SR[MC_atom]+=ds;
05189
05190 Eatom1=potential_energyonly(MC_atom);
05191 _EPOT=_EPOT0+Eatom1-Eatom0;
05192
05193 if(_EPOT<_EPOT0)
05194 MC_accept=1;
05195 else
05196 {
05197 tmp=(_EPOT0-_EPOT)/(KB*_TDES);
05198 if(tmp<-40) MC_accept=0;
05199 else
05200 {
05201 if(drand48()<exp(tmp))
05202 MC_accept=1;
05203 else
05204 MC_accept=0;
05205 }
05206 }
05207
05208 if(MC_accept)
05209 {
05210 _EPOT0=_EPOT;
05211 MC_accept_tot++;
05212 }
05213 else
05214 {
05215 _SR[MC_atom]-=ds;
05216 }
05217
05218 if(curstep%printfreq==0)
05219 {
05220 MC_accept_ratio = ((double) MC_accept_tot) / (curstep+1);
05221 INFO_Printf("curstep = %d MC_atom = %d MC_accept = %d "
05222 "accept_ratio = %e\n",
05223 curstep, MC_atom, MC_accept, MC_accept_ratio);
05224 }
05225 winplot();
05226
05227 if(curstep%savecnfreq==0)
05228 {
05229 cnindex=curstep/savecnfreq;
05230
05231 chainindex = (cnindex-1)%_CHAINLENGTH + 1;
05232 SHtoR();
05233 for(j=1;j<=n;j++)
05234 {
05235 ipt=constrainatoms[j];
05236 _Rc[chainindex][j]=_R[ipt];
05237 }
05238
05239
05240 if(chainindex==_CHAINLENGTH)
05241 {
05242
05243
05244 for(i=0;i<_NP;i++)
05245 fixed[i]=1;
05246 for(j=1;j<=n;j++)
05247 fixed[constrainatoms[j]]=0;
05248
05249 relax();
05250 r2=0;
05251 for(j=1;j<=n;j++)
05252 {
05253 ipt=constrainatoms[j];
05254 ds=_SR1[ipt]-_SR[ipt];
05255 dr=_H*ds;
05256 r2+=dr.norm2();
05257 }
05258 r0=sqrt(r2);
05259 transition = 0;
05260 if(r0>annealspec[0]) transition=1;
05261
05262 INFO_Printf("curstep=%d r0 = %e transition = %d\n",
05263 curstep,r0,transition);
05264 if(transition)
05265 {
05266 return transition;
05267 }
05268 else
05269 {
05270 for(j=1;j<=n;j++)
05271 {
05272 _Rc[0][j]=_Rc[_CHAINLENGTH][j];
05273 ipt=constrainatoms[j];
05274 _R[ipt]=_Rc[_CHAINLENGTH][j];
05275 }
05276 RHtoS();
05277 potential_energyonly();
05278 INFO_Printf("E = %e\n",_EPOT);
05279 }
05280 }
05281 }
05282 }
05283
05284 return transition;
05285 }
05286
05287
05288
05289
05290
05291
05292
05293
05294
05295
05296
05297
05298 void MDFrame::AllocChain()
05299 {
05300 int n,size,i;
05301 void *c;
05302
05303 n=constrainatoms[0];
05304 size=sizeof(Vector3 *)*(_CHAINLENGTH+1)+sizeof(Vector3)*(_CHAINLENGTH+1)*n + 10;
05305
05306 if(n<=0)
05307 {
05308 ERROR("Constrained atoms not set! (atoms not selected)");
05309 return;
05310 }
05311 if(n>MAXCONSTRAINATOMS)
05312 {
05313 ERROR("Number of constrained atoms is too big!");
05314 return;
05315 }
05316
05317 INFO_Printf("AllocChain: malloc size = %d\n",size);
05318 c=malloc(size); memset(c,0,size);
05319 _Rc=(Vector3 **) c; _Rc[0]=(Vector3 *)(_Rc+(_CHAINLENGTH+1));
05320 for(i=1;i<=_CHAINLENGTH;i++) _Rc[i]=_Rc[i-1]+n;
05321
05322 c=malloc(size); memset(c,0,size);
05323 _Fc=(Vector3 **) c; _Fc[0]=(Vector3 *)(_Fc+(_CHAINLENGTH+1));
05324 for(i=1;i<=_CHAINLENGTH;i++) _Fc[i]=_Fc[i-1]+n;
05325
05326 _nebinterp=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05327 memset(_nebinterp,0,sizeof(double)*(_CHAINLENGTH+1));
05328
05329 INFO("Memory for _Rc and _Fc are allocated.");
05330 }
05331
05332 void MDFrame::caldscom12()
05333 {
05334
05335
05336
05337
05338 int i, n, ipt;
05339
05340 n=constrainatoms[0];
05341
05342
05343 dscom12.clear();
05344 for(i=1;i<=n;i++)
05345 {
05346 ipt=constrainatoms[i];
05347 dscom12+=_SR2[ipt];
05348 dscom12-=_SR1[ipt];
05349 }
05350 dscom12/=n;
05351
05352 #if 0
05353
05354 for(i=0;i<_NP;i++)
05355 {
05356 _SR2[i]-=dscom12;
05357 _SR2[i].subint();
05358 }
05359 dscom12.clear();
05360 #endif
05361 INFO_Printf("center-of-mass shift: [%f %f %f]\n",dscom12.x,dscom12.y,dscom12.z);
05362 }
05363
05364 int MDFrame::readRchain()
05365 {
05366 int i, j;
05367 char *buffer; char *pp, *q;
05368 char fname[300];
05369
05370 LFile::SubHomeDir(incnfile,fname);
05371 INFO("filename="<<fname);
05372 LFile::LoadToString(fname,buffer,0);
05373
05374 pp=buffer;
05375
05376 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
05377 if(readparallelnebcn)
05378 _CHAINLENGTH = 0;
05379 else
05380 sscanf(q, "%d", &_CHAINLENGTH);
05381 INFO("CHAINLEGNTH="<<_CHAINLENGTH);
05382
05383 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
05384 sscanf(q, "%d", constrainatoms);
05385
05386 INFO("constrainatoms[0]="<<constrainatoms[0]);
05387
05388 if (_Rc==NULL)
05389 {
05390 INFO("call AllocChain()");
05391 AllocChain();
05392 } else
05393 INFO("Warning: _Rc will be overwritten!!");
05394
05395 for(i=0;i<constrainatoms[0];i++)
05396 {
05397 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
05398 sscanf(q, "%d", constrainatoms+i+1);
05399 }
05400
05401 for(j=0;j<=_CHAINLENGTH;j++)
05402 {
05403 for(i=0;i<constrainatoms[0];i++)
05404 {
05405 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
05406 sscanf(q, "%lf %lf %lf",&(_Rc[j][i].x),&(_Rc[j][i].y),&(_Rc[j][i].z));
05407 }
05408 }
05409
05410 Free(buffer);
05411 DUMP("readRchain finished");
05412 return 0;
05413 }
05414
05415 int MDFrame::writeRchain()
05416 {
05417 int i, j;
05418 FILE *fp;
05419
05420 fp=fopen(finalcnfile,"w");
05421
05422 fprintf(fp,"%d\n",_CHAINLENGTH);
05423 fprintf(fp,"%d\n",constrainatoms[0]);
05424
05425 for(i=0;i<constrainatoms[0];i++)
05426 fprintf(fp,"%d\n",constrainatoms[i+1]);
05427
05428 for(j=0;j<=_CHAINLENGTH;j++)
05429 for(i=0;i<constrainatoms[0];i++)
05430 fprintf(fp,"%25.15e %25.15e %25.15e\n",_Rc[j][i].x,_Rc[j][i].y,_Rc[j][i].z);
05431
05432 fclose(fp);
05433 DUMP("writeRchain finished");
05434 return 0;
05435 }
05436
05437 void MDFrame::initRchain()
05438 {
05439 int ipt,i,j,n; double s; Vector3 ds;
05440
05441 n=constrainatoms[0];
05442
05443 for(j=0;j<=_CHAINLENGTH;j++)
05444 {
05445 s=(1.0*j)/_CHAINLENGTH;
05446 _nebinterp[j] = s;
05447 for(i=0;i<n;i++)
05448 {
05449 ipt=constrainatoms[i+1];
05450 ds=_SR2[ipt]-dscom12; ds-=_SR1[ipt]; ds.subint();
05451 ds*=s; ds+=_SR1[ipt];
05452 _Rc[j][i]=_H*ds;
05453 }
05454 }
05455 INFO("Chain _Rc is initialized");
05456 }
05457
05458 int MDFrame::interpCN(double s)
05459 {
05460 int i;
05461 Vector3 ds;
05462
05463
05464 if(_SR1 == NULL || _SR2 == NULL)
05465 {
05466 if(_SR1 == NULL)
05467 ERROR("config1 is not set!");
05468 else
05469 ERROR("config2 is not set!");
05470 return -1;
05471 }
05472
05473 #if 0
05474 if(s==0)
05475 {
05476 INFO_Printf("interpCN s=%g special case\n",s);
05477 for(i=0;i<_NP;i++)
05478 _SR[i]=_SR1[i];
05479 }
05480 else if(s==1)
05481 {
05482 INFO_Printf("interpCN s=%g special case\n",s);
05483 for(i=0;i<_NP;i++)
05484 _SR[i]=_SR2[i];
05485 }
05486 else
05487 #else
05488 if(1)
05489 #endif
05490 {
05491 for(i=0;i<_NP;i++)
05492 {
05493 ds=_SR2[i]; ds-=_SR1[i]; ds.subint();
05494 ds*=s; ds+=_SR1[i];
05495 _SR[i]=ds;
05496 }
05497 }
05498 return 0;
05499 }
05500
05501 void MDFrame::copyRchaintoCN(int j)
05502 {
05503 int i, n, ipt;
05504 Matrix33 hinv;
05505
05506 hinv = _H.inv();
05507 n=constrainatoms[0];
05508 for(i=0;i<n;i++)
05509 {
05510 ipt=constrainatoms[i+1];
05511 _SR[ipt]=hinv*_Rc[j][i];
05512 }
05513 }
05514
05515 void MDFrame::copyCNtoRchain(int j)
05516 {
05517 int i, n, ipt;
05518
05519 n=constrainatoms[0];
05520 for(i=0;i<n;i++)
05521 {
05522 ipt=constrainatoms[i+1];
05523 _Rc[j][i]= _H*_SR[ipt];
05524 }
05525 }
05526
05527 void MDFrame::moveRchain(int jdes, int jsrc)
05528 {
05529 int i, n;
05530
05531 n=constrainatoms[0];
05532 for(i=0;i<n;i++)
05533 {
05534 _Rc[jdes][i]= _Rc[jsrc][i];
05535 }
05536 }
05537
05538
05539
05540
05541
05542
05543 #ifdef _STRINGMETHOD
05544 #include "stringmethod.cpp"
05545 #endif
05546
05547 void MDFrame::nebrelax()
05548 {
05549
05550
05551
05552
05553
05554
05555
05556
05557 int i, n, j, ipt, size;
05558 Vector3 ds, ds0, dr, dt, ft, dR1, dR2, **dTang;
05559 Matrix33 hinv;
05560 double s, fr, r2, k, fm2, dR1norm, dR1norm2, dR2norm, dR2norm2;
05561 double dEmax, dEmin, minFm, Fspring, *Ec, *Lc, *Fm, *Ft, *dR, *TangMag2;
05562 void *c;
05563 FILE *fp;
05564
05565 INFO("NEB Relax");
05566
05567 if(_SR1 == NULL || _SR2 == NULL)
05568 {
05569 if(_SR1 == NULL)
05570 ERROR("config1 is not set!");
05571 else
05572 ERROR("config2 is not set!");
05573 return;
05574 }
05575
05576 if(_Rc==NULL || _Fc==NULL)
05577 {
05578 AllocChain();
05579 caldscom12();
05580 initRchain();
05581 }
05582
05583 n=constrainatoms[0];
05584 Ec=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05585 Lc=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05586 Fm=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05587 Ft=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05588 dR=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05589 TangMag2=(double *)malloc(sizeof(double)*(_CHAINLENGTH-1));
05590 size=sizeof(Vector3 *)*(_CHAINLENGTH-1)+sizeof(Vector3)*(_CHAINLENGTH-1)*n + 10;
05591 c=malloc(size); memset(c,0,size);
05592 dTang = (Vector3 **)c; dTang[0]=(Vector3 *)(dTang+(_CHAINLENGTH-1));
05593 for(i=1;i<_CHAINLENGTH-1;i++) dTang[i]=dTang[i-1]+n;
05594
05595 fp=fopen("nebeng.out","w");
05596
05597
05598 constrain_dist=0; s=0;
05599 for(i=0;i<n;i++)
05600 {
05601 ipt=constrainatoms[i+1];
05602 ds0=(_SR2[ipt]-dscom12)-_SR1[ipt];
05603 constrain_dist+=ds0.norm2();
05604 }
05605 INFO_Printf("neb: constrain_dist=%e\n",constrain_dist);
05606
05607 if(nebspec[0]==1)
05608 {
05609 for(i=0;i<n;i++)
05610 {
05611 ipt=constrainatoms[i+1];
05612 fixed[ipt]=1;
05613 }
05614 }
05615
05616 step0 = curstep;
05617 for(curstep=step0;curstep<(step0 + totalsteps);curstep++)
05618 {
05619
05620 for(j=0;j<=_CHAINLENGTH;j++)
05621 {
05622 s=_nebinterp[j];
05623
05624 interpCN(s);
05625
05626 copyRchaintoCN(j);
05627
05628 if(nebspec[0]==1)
05629 {
05630 INFO("Relaxation for the point "<<j<<" in the energy hill");
05631 relax();
05632 }
05633
05634 call_potential();
05635 Ec[j]=_EPOT;
05636
05637 for(i=0;i<n;i++)
05638 {
05639 ipt=constrainatoms[i+1];
05640 _Fc[j][i]=_F[ipt];
05641 }
05642 }
05643
05644
05645 for(j=1;j<_CHAINLENGTH;j++)
05646 {
05647 if (((Ec[j+1]-Ec[j]>0) && (Ec[j-1]-Ec[j]>0)) ||
05648 ((Ec[j+1]-Ec[j]<0) && (Ec[j-1]-Ec[j]<0)))
05649 {
05650 dEmax = max(fabs(Ec[j+1]-Ec[j]),fabs(Ec[j-1]-Ec[j]));
05651 dEmin = min(fabs(Ec[j+1]-Ec[j]),fabs(Ec[j-1]-Ec[j]));
05652
05653 if (Ec[j+1]>Ec[j-1])
05654 for(i=0;i<n;i++)
05655 {
05656 dt=(_Rc[j+1][i]-_Rc[j][i])*dEmax +
05657 (_Rc[j][i]-_Rc[j-1][i])*dEmin;
05658 dTang[j-1][i]=dt;
05659 }
05660 else
05661 for(i=0;i<n;i++)
05662 {
05663 dt=(_Rc[j+1][i]-_Rc[j][i])*dEmin +
05664 (_Rc[j][i]-_Rc[j-1][i])*dEmax;
05665 dTang[j-1][i]=dt;
05666 }
05667 }
05668 else
05669 {
05670 if (Ec[j+1]>Ec[j-1])
05671 for(i=0;i<n;i++)
05672 {
05673 dt=_Rc[j+1][i]-_Rc[j][i];
05674 dTang[j-1][i]=dt;
05675 }
05676 else
05677 for(i=0;i<n;i++)
05678 {
05679 dt=_Rc[j][i]-_Rc[j-1][i];
05680 dTang[j-1][i]=dt;
05681 }
05682 }
05683
05684 r2=0;
05685 for(i=0;i<n;i++)
05686 r2+=dTang[j-1][i].norm2();
05687 TangMag2[j-1]=r2;
05688 }
05689
05690
05691 minFm = 1.79e+300;
05692
05693 for(j=1;j<_CHAINLENGTH;j++)
05694 {
05695 fr=0;
05696 for(i=0;i<n;i++)
05697 fr+=dot(_Fc[j][i],dTang[j-1][i]);
05698
05699 Ft[j] = fr/sqrt(TangMag2[j-1]);
05700 fr/=TangMag2[j-1];
05701
05702 fm2=0;
05703 for(i=0;i<n;i++)
05704 {
05705 dt=dTang[j-1][i]*fr;
05706 _Fc[j][i]-=dt;
05707 fm2 += _Fc[j][i].norm2();
05708 }
05709 Fm[j]=sqrt(fm2);
05710 if (Fm[j]<minFm)
05711 minFm = Fm[j];
05712 }
05713 Fm[0]=Fm[_CHAINLENGTH]=0;
05714 Ft[0]=Ft[_CHAINLENGTH]=0;
05715
05716
05717
05718 k = minFm*_CHAINLENGTH;
05719 for(j=1;j<_CHAINLENGTH;j++)
05720 {
05721
05722 dR1norm2=0;
05723 for(i=0;i<n;i++)
05724 {
05725 dR1=_Rc[j+1][i]-_Rc[j][i];
05726 dR1norm2+=dR1.norm2();
05727 }
05728 dR1norm=sqrt(dR1norm2);
05729 if (j==_CHAINLENGTH-1)
05730 dR[j+1] = dR1norm;
05731
05732
05733 dR2norm2=0;
05734 for(i=0;i<n;i++)
05735 {
05736 dR2=_Rc[j][i]-_Rc[j-1][i];
05737 dR2norm2+=dR2.norm2();
05738 }
05739 dR2norm=sqrt(dR2norm2);
05740 dR[j] = dR2norm;
05741
05742 Fspring = k*(dR1norm - dR2norm);
05743
05744 for(i=0;i<n;i++)
05745 _Fc[j][i]+=dTang[j-1][i]*(Fspring/sqrt(TangMag2[j-1]));
05746 }
05747 dR[0] = 0;
05748
05749 if(curstep%printfreq==0)
05750 {
05751 INFO_Printf("curstep = %d\n",curstep);
05752 for(j=0;j<=_CHAINLENGTH;j++)
05753 INFO_Printf("%20.12e %25.15e %25.15e %25.15e %25.15e\n",_nebinterp[j],Ec[j]-Ec[0],Fm[j],Ft[j], dR[j]);
05754 fprintf(fp,"%d ",curstep);
05755 for(j=0;j<=_CHAINLENGTH;j++)
05756 fprintf(fp,"%20.12e %25.15e %25.15e %25.15e %25.15e",_nebinterp[j], Ec[j]-Ec[0], Fm[j], Ft[j], dR[j]);
05757 fprintf(fp,"\n");
05758 fflush(fp);
05759 }
05760
05761
05762 for(j=1;j<_CHAINLENGTH;j++)
05763 for(i=0;i<n;i++)
05764 _Rc[j][i]+=_Fc[j][i]*_TIMESTEP;
05765 }
05766
05767
05768 INFO_Printf("curstep = %d\n",curstep);
05769 for(j=0;j<=_CHAINLENGTH;j++)
05770 INFO_Printf("%20.12e %25.15e %25.15e %25.15e %25.15e\n",_nebinterp[j],Ec[j]-Ec[0],Fm[j],Ft[j], dR[j]);
05771 fprintf(fp,"%d ",curstep);
05772 for(j=0;j<=_CHAINLENGTH;j++)
05773 fprintf(fp,"%20.12e %25.15e %25.15e %25.15e %25.15e",_nebinterp[j], Ec[j]-Ec[0], Fm[j], Ft[j], dR[j]);
05774 fprintf(fp,"\n");
05775 fflush(fp);
05776
05777 free(Ec);
05778 free(Lc);
05779 free(Fm); free(Ft);
05780 free(dR);
05781 free(dTang); free(TangMag2);
05782 fclose(fp);
05783 }
05784
05785 void MDFrame::annealpath()
05786 {
05787
05788 int i,n,j,k, ipt, naccept, alg;
05789 Vector3 ds, dr, *Rold; Matrix33 hinv;
05790 double s, rmax, T, T0, lambda, r0, r1, r2, r02, r12, r22, rt;
05791 double Emax, Enewmax, Eold, Epen, Enewpen, Etot, Enewtot;
05792 double xi, crit, accratio, *Ec, *Lc;
05793 FILE *fp;
05794
05795 INFO("annealpath");
05796
05797 if(constrainatoms[0]<=0)
05798 {
05799 ERROR("constrainedatoms not set! (atoms not selected)");
05800 return;
05801 }
05802
05803 rmax = annealspec[0];
05804 T0 = annealspec[1];
05805 lambda= annealspec[2];
05806 alg = (int)annealspec[3];
05807
05808 if((rmax<=0)||(T0<=0)||(lambda<=0))
05809 {
05810 ERROR("Invalide annealspec !");
05811 return;
05812 }
05813
05814 fp=fopen("nebeng.out","w");
05815
05816 Ec=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05817 Lc=(double *)malloc(sizeof(double)*(_CHAINLENGTH+1));
05818 Rold=(Vector3 *)malloc(sizeof(Vector3)*constrainatoms[0]);
05819
05820 hinv=_H.inv();
05821
05822
05823 dscom12.clear();
05824 constrain_dist=0; s=0;
05825 n=constrainatoms[0];
05826 for(i=0;i<n;i++)
05827 {
05828 ipt=constrainatoms[i+1];
05829 dscom12+=_SR2[ipt];
05830 dscom12-=_SR1[ipt];
05831 }
05832 dscom12/=n;
05833
05834 #if 0
05835 for(i=0;i<n;i++)
05836 {
05837 ipt=constrainatoms[i+1];
05838 _SR2[ipt]-=dscom12;
05839 }
05840 #endif
05841
05842 INFO("find energy along the entire chain");
05843
05844 for(j=0;j<=_CHAINLENGTH;j++)
05845 {
05846 s=(1.0*j)/_CHAINLENGTH;
05847
05848 for(i=0;i<_NP;i++)
05849 {
05850 ds=_SR2[i]-dscom12; ds-=_SR1[i]; ds*=s; ds+=_SR1[i];
05851 _SR[i]=ds;
05852 }
05853
05854 for(i=0;i<n;i++)
05855 {
05856 ipt=constrainatoms[i+1];
05857 _SR[ipt]=hinv*_Rc[j][i];
05858 }
05859 potential_energyonly();
05860 Ec[j]=_EPOT;
05861 }
05862
05863 Emax=Ec[0]; Epen=0; Etot=0;
05864 for(j=1;j<=_CHAINLENGTH;j++)
05865 {
05866
05867 if(Emax<Ec[j]) Emax=Ec[j];
05868
05869 if(Ec[j]>Ec[j-1]) Epen+=Ec[j]-Ec[j-1];
05870 Etot+=Ec[j]-Ec[0];
05871 }
05872
05873 INFO("begin annealing simulation");
05874
05875 naccept = 0;
05876
05877 if(continue_curstep)
05878 step0 = curstep;
05879 else
05880 step0 = 0;
05881 for(curstep=step0;curstep<(step0 + totalsteps);curstep++)
05882
05883 {
05884 T = T0*exp(-lambda*curstep/totalsteps);
05885
05886
05887 j = (int) ceil( drand48()*(_CHAINLENGTH-1) );
05888
05889
05890 for(i=0;i<n;i++)
05891 Rold[i]=_Rc[j][i];
05892 Eold=Ec[j];
05893
05894
05895
05896 r02=0;
05897 for(i=0;i<n;i++)
05898 {
05899 dr=_Rc[j+1][i]-_Rc[j-1][i];
05900 r02+=dr.norm2();
05901 }
05902 r0=sqrt(r02);
05903 if(r0>1e-6)
05904 {
05905 xi=(2*drand48()-1)*(rmax-r0*0.5);
05906 r12=rmax*rmax-(r0*0.5+fabs(xi))*(r0*0.5+fabs(xi));
05907 if(r12<0)
05908 {
05909 WARNING("r12<0");
05910 r12=0;
05911 }
05912 r1=sqrt(r12);
05913
05914 for(i=0;i<n;i++)
05915 for(k=0;k<3;k++)
05916 _Rc[j][i][k]=2*drand48()-1;
05917
05918 rt=0;
05919 for(i=0;i<n;i++)
05920 {
05921 dr=_Rc[j+1][i]-_Rc[j-1][i];
05922 rt+=dot(_Rc[j][i],dr);
05923 }
05924 rt/=r02;
05925 for(i=0;i<n;i++)
05926 {
05927 dr=_Rc[j+1][i]-_Rc[j-1][i];
05928 dr*=rt;
05929 _Rc[j][i]-=dr;
05930 }
05931
05932 r22=0;
05933 for(i=0;i<n;i++)
05934 r22+=_Rc[j][i].norm2();
05935 r2=sqrt(r22);
05936 for(i=0;i<n;i++)
05937 _Rc[j][i]*=r1/r2;
05938
05939 for(i=0;i<n;i++)
05940 {
05941 dr=_Rc[j+1][i]-_Rc[j-1][i];
05942 dr/=r0;
05943 dr*=(r0*0.5+xi);
05944 dr+=_Rc[j-1][i];
05945 _Rc[j][i]+=dr;
05946 }
05947 }
05948 else
05949 {
05950
05951 for(i=0;i<n;i++)
05952 for(k=0;k<3;k++)
05953 _Rc[j][i][k]=2*drand48()-1;
05954
05955 r22=0;
05956 for(i=0;i<n;i++)
05957 r22+=_Rc[j][i].norm2();
05958 r2=sqrt(r22);
05959 for(i=0;i<n;i++)
05960 _Rc[j][i]*=(rmax-2e-6)/r2;
05961
05962 for(i=0;i<n;i++)
05963 {
05964 _Rc[j][i]+=(_Rc[j-1][i]+_Rc[j+1][i])*0.5;
05965 }
05966 }
05967
05968
05969
05970
05971
05972
05973
05974
05975
05976
05977
05978
05979 s=(1.0*j)/_CHAINLENGTH;
05980
05981 for(i=0;i<_NP;i++)
05982 {
05983 ds=_SR2[i]-dscom12; ds-=_SR1[i]; ds*=s; ds+=_SR1[i];
05984 _SR[i]=ds;
05985 }
05986
05987 for(i=0;i<n;i++)
05988 {
05989 ipt=constrainatoms[i+1];
05990 _SR[ipt]=hinv*_Rc[j][i];
05991 }
05992 potential_energyonly();
05993 Ec[j]=_EPOT;
05994
05995 Enewmax=Ec[0]; Enewpen=0; Enewtot=0;
05996 for(k=1;k<=_CHAINLENGTH;k++)
05997 {
05998
05999 if(Enewmax<Ec[k]) Enewmax=Ec[k];
06000
06001 if(Ec[k]>Ec[k-1]) Enewpen+=Ec[k]-Ec[k-1];
06002 Enewtot+=Ec[k]-Ec[0];
06003 }
06004
06005 switch(alg) {
06006 case(0): crit=exp((Emax-Enewmax)/T); break;
06007 case(1): crit=exp((Epen-Enewpen)/T); break;
06008 case(2): crit=exp((Etot-Enewtot)/T); break;
06009 default: crit=0; ERROR("annealpath: MC alg not set!"); break;
06010 }
06011 xi = drand48();
06012 if(xi<crit)
06013 {
06014 Emax=Enewmax;
06015 Epen=Enewpen;
06016 Etot=Enewtot;
06017 naccept ++;
06018 }
06019 else
06020 {
06021 for(i=0;i<n;i++)
06022 _Rc[j][i]=Rold[i];
06023 Ec[j]=Eold;
06024 }
06025 accratio = 1.0*naccept/(curstep+1);
06026
06027 if(curstep%printfreq==0)
06028 {
06029 INFO_Printf("curstep = %d\n",curstep);
06030 for(k=0;k<=_CHAINLENGTH;k++)
06031 INFO_Printf("%e %25.15e\n",1.0*k/_CHAINLENGTH,Ec[k]-Ec[0]);
06032 INFO_Printf("alg=%d Emax=%e Epen=%e Etot=%e T=%e j=%d acceptance ratio = %d/%d = %e\n",
06033 alg,Emax-Ec[0],Epen,Etot,T,j,naccept,curstep+1,accratio);
06034 fprintf(fp,"%d ",curstep);
06035 for(k=0;k<=_CHAINLENGTH;k++)
06036 fprintf(fp," %25.15e ",Ec[k]-Ec[0]);
06037 fprintf(fp,"\n");
06038 }
06039 }
06040
06041 free(Ec);
06042 free(Lc);
06043 free(Rold);
06044 fclose(fp);
06045 }
06046
06047 void MDFrame::cutpath()
06048 {
06049
06050 int i,n,j,n0,n1,step,jnew;
06051
06052 INFO("cutpath");
06053
06054 if(constrainatoms[0]<=0)
06055 {
06056 ERROR("constrainedatoms not set! (atoms not selected)");
06057 return;
06058 }
06059
06060 step = (int) annealspec[0];
06061 n0 = (int) annealspec[1];
06062 n1 = (int) annealspec[2];
06063
06064 if(n0<=0) n0=1;
06065 if(n1>=_CHAINLENGTH) n1=_CHAINLENGTH-1;
06066 n=constrainatoms[0];
06067 jnew=1;
06068 for(j=n0;j<=n1;j+=step)
06069 {
06070
06071 for(i=0;i<n;i++)
06072 _Rc[jnew][i]=_Rc[j][i];
06073 jnew++;
06074 }
06075 for(i=0;i<n;i++)
06076 _Rc[jnew][i]=_Rc[_CHAINLENGTH][i];
06077 _CHAINLENGTH=jnew;
06078 }
06079
06080 int MDFrame::statedistance()
06081 {
06082 int i, n, j, k, ipt;
06083 Vector3 ds, dr;
06084 double r, r2, rinf, dx;
06085
06086 n=constrainatoms[0];
06087 if(n<=0)
06088 {
06089 INFO_Printf("distance involving all %d atoms\n",_NP);
06090 r2=0; rinf=0;
06091 for(i=0;i<_NP;i++)
06092 {
06093 ds=_SR[i]-_SR1[i];
06094 dr=_H*ds;
06095 r2+=dr.norm2();
06096 for(k=0;k<3;k++)
06097 {
06098 dx=fabs(dr[k]);
06099 if(dx>rinf) rinf=dx;
06100 }
06101 }
06102 r=sqrt(r2);
06103 }
06104 else
06105 {
06106 INFO_Printf("distance involving %d constrain atoms\n",n);
06107 r2=0; rinf=0;
06108 for(j=1;j<=n;j++)
06109 {
06110 ipt=constrainatoms[j];
06111 ds=_SR[ipt]-_SR1[ipt];
06112 dr=_H*ds;
06113 r2+=dr.norm2();
06114 for(k=0;k<3;k++)
06115 {
06116 dx=fabs(dr[k]);
06117 if(dx>rinf) rinf=dx;
06118 }
06119 }
06120 r=sqrt(r2);
06121 }
06122 INFO_Printf("2-norm r = %20.12e infinite-norm r = %20.12e\n",r,rinf);
06123 return 0;
06124 }
06125
06126
06127
06128
06129
06130
06131 #include "ffs.cpp"
06132
06133
06134
06135
06136
06137 #include "ewald.cpp"
06138
06139
06140
06141
06142
06143
06144
06145 #include "lattice.h"
06146
06147 void MDFrame::makecrystal()
06148 {
06149 UnitCell my_unitcell,my_unitcell2;
06150 Matrix33 myorient, lattice;
06151 Vector3 tmpv;
06152 int i,j,k,m,n;
06153
06154 INFO("makecrystal");
06155 myorient.set(latticesize[0][0],latticesize[0][1],latticesize[0][2],
06156 latticesize[1][0],latticesize[1][1],latticesize[1][2],
06157 latticesize[2][0],latticesize[2][1],latticesize[2][2]);
06158
06159 if(strcmp(crystalstructure,"simple-cubic")==0)
06160 {
06161 latticeconst[1]=latticeconst[2]=latticeconst[0];
06162 my_unitcell.set(1,sc_basis);
06163 nspecies=1;
06164 }
06165 else if(strcmp(crystalstructure,"body-centered-cubic")==0)
06166 {
06167 latticeconst[1]=latticeconst[2]=latticeconst[0];
06168 my_unitcell.set(2,bcc_basis);
06169 nspecies=1;
06170 }
06171 else if(strcmp(crystalstructure,"face-centered-cubic")==0)
06172 {
06173 latticeconst[1]=latticeconst[2]=latticeconst[0];
06174 my_unitcell.set(4,fcc_basis);
06175 nspecies=1;
06176 }
06177 else if(strcmp(crystalstructure,"NaCl")==0)
06178 {
06179 latticeconst[1]=latticeconst[2]=latticeconst[0];
06180 my_unitcell.set(8,nacl_basis,nacl_species);
06181 nspecies=2;
06182 }
06183 else if(strcmp(crystalstructure,"CsCl")==0)
06184 {
06185 latticeconst[1]=latticeconst[2]=latticeconst[0];
06186 my_unitcell.set(2,bcc_basis,cscl_species);
06187 nspecies=2;
06188 }
06189 else if(strcmp(crystalstructure,"L1_2")==0)
06190 {
06191 latticeconst[1]=latticeconst[2]=latticeconst[0];
06192 my_unitcell.set(4,fcc_basis,l12_species);
06193 nspecies=2;
06194 }
06195 else if(strcmp(crystalstructure,"L1_0")==0)
06196 {
06197 latticeconst[1]=latticeconst[2]=latticeconst[0];
06198 my_unitcell.set(4,fcc_basis,l10_species);
06199 nspecies=2;
06200 }
06201 else if(strcmp(crystalstructure,"diamond-cubic")==0)
06202 {
06203 latticeconst[1]=latticeconst[2]=latticeconst[0];
06204 my_unitcell.set(8,dc_basis);
06205 nspecies=1;
06206 }
06207 else if(strcmp(crystalstructure,"beta-tin")==0)
06208 {
06209 if(latticeconst[1]<=0) latticeconst[1]=latticeconst[0];
06210 if(latticeconst[2]<=0) latticeconst[2]=latticeconst[0];
06211
06212
06213 my_unitcell.set(4,betatin_basis);
06214 nspecies=1;
06215 }
06216 else if(strcmp(crystalstructure,"beta-tin-2")==0)
06217 {
06218 if(latticeconst[1]<=0) latticeconst[1]=latticeconst[0];
06219 if(latticeconst[2]<=0) latticeconst[2]=latticeconst[0];
06220 my_unitcell.set(4,betatin_basis,betatin_2_species);
06221 nspecies=2;
06222 }
06223 else if(strcmp(crystalstructure,"zinc-blende")==0)
06224 {
06225 latticeconst[1]=latticeconst[2]=latticeconst[0];
06226 my_unitcell.set(8,dc_basis,zb_species);
06227 nspecies=2;
06228 }
06229 else if(strcmp(crystalstructure,"wurtzite")==0)
06230 {
06231 latticeconst[1]=latticeconst[0]*M_SQRT3;
06232 my_unitcell.set(8,wurtzite_basis,wurtzite_species);
06233 nspecies=2;
06234 }
06235 else if(strcmp(crystalstructure,"CaF2")==0)
06236 {
06237 latticeconst[1]=latticeconst[2]=latticeconst[0];
06238 my_unitcell.set(12,caf2_basis,caf2_species);
06239 nspecies=2;
06240 }
06241 else if(strcmp(crystalstructure,"hexagonal-ortho")==0)
06242 {
06243 latticeconst[1]=latticeconst[0]*M_SQRT3;
06244 my_unitcell.set(4,hex_ortho_basis);
06245 nspecies=1;
06246 }
06247 else if(strcmp(crystalstructure,"rhombohedral-Si-Ge")==0)
06248 {
06249 latticeconst[1]=latticeconst[0]*M_SQRT3;
06250 latticeconst[2]=latticeconst[0]*4.89897948556636;
06251 my_unitcell.set(24,rhsige_basis,rhsige_species);
06252 nspecies=2;
06253 }
06254 else if(strcmp(crystalstructure,"bc8")==0)
06255 {
06256 latticeconst[1]=latticeconst[2]=latticeconst[0];
06257 my_unitcell.set(16,bc8_basis);
06258 nspecies=1;
06259 }
06260 else if(strcmp(crystalstructure,"alpha-quartz")==0)
06261 {
06262 latticeconst[1]=latticeconst[0]*M_SQRT3;
06263 my_unitcell.set(18,alpha_quartz_basis,alpha_quartz_species);
06264 nspecies = 2;
06265 }
06266 else if(strcmp(crystalstructure,"beta-quartz")==0)
06267 {
06268 latticeconst[1]=latticeconst[0]*M_SQRT3;
06269 my_unitcell.set(18,beta_quartz_basis,beta_quartz_species);
06270 nspecies = 2;
06271 }
06272 else if(strcmp(crystalstructure,"tridymite")==0)
06273 {
06274 latticeconst[1]=latticeconst[0]*M_SQRT3;
06275 my_unitcell.set(24,tridymite_basis,tridymite_species);
06276 nspecies = 2;
06277 }
06278 else if(strcmp(crystalstructure,"cristobalite")==0)
06279 {
06280 latticeconst[1]=latticeconst[0];
06281 my_unitcell.set(12,cristobalite_basis,cristobalite_species);
06282 nspecies = 2;
06283 }
06284 else if(strcmp(crystalstructure,"ice-Ih-O")==0)
06285 {
06286 latticeconst[1]=latticeconst[0]*M_SQRT3;
06287 my_unitcell.set(8,ice_Ih_O_basis);
06288 nspecies=1;
06289 }
06290 else if(strcmp(crystalstructure,"ice-Ih")==0)
06291 {
06292 latticeconst[1]=latticeconst[0]*M_SQRT3;
06293 my_unitcell.set(24,ice_Ih_basis,ice_Ih_species);
06294 nspecies=2;
06295 }
06296 else if(strcmp(crystalstructure,"A11")==0)
06297 {
06298 if(latticeconst[1]==0) latticeconst[1]=latticeconst[0];
06299 if(latticeconst[2]==0) latticeconst[2]=latticeconst[0];
06300 my_unitcell.set(8,A11_basis);
06301
06302 nspecies=1;
06303 }
06304 else
06305 {
06306 ERROR("unknown lattice structure :"<<crystalstructure
06307 <<" for makecn");
06308 }
06309 my_unitcell=my_unitcell*myorient.tran();
06310
06311 INFO("my_unitcell\n"<<my_unitcell);
06312 n=0;
06313 _NP=(int)(latticesize[0][3]*latticesize[1][3]
06314 *latticesize[2][3]*my_unitcell.n);
06315
06316 printf("%f %f %f %d\n",latticesize[0][3],latticesize[1][3],
06317 latticesize[2][3],my_unitcell.n);
06318
06319 INFO("makecn: _NP="<<_NP);
06320
06321
06322 Alloc();
06323
06324 for(i=0;i<(int)latticesize[0][3];i++)
06325 for(j=0;j<(int)latticesize[1][3];j++)
06326 for(k=0;k<(int)latticesize[2][3];k++)
06327 {
06328 for(m=0;m<my_unitcell.n;m++)
06329 {
06330 tmpv.set(i,j,k);
06331 _SR[n+m]=my_unitcell.basis[m]+tmpv;
06332
06333 if(_SAVEMEMORY<8)
06334 species[n+m]=my_unitcell.species[m];
06335 }
06336 n+=my_unitcell.n;
06337 }
06338 for(i=0;i<_NP;i++)
06339 {
06340 _SR[i].x/=latticesize[0][3];
06341 _SR[i].y/=latticesize[1][3];
06342 _SR[i].z/=latticesize[2][3];
06343 }
06344 for(i=0;i<_NP;i++)
06345 {
06346 _SR[i]-=0.5;
06347 fixed[i]=0;
06348
06349
06350 if(_SAVEMEMORY<7)
06351 _VSR[i].clear();
06352 }
06353
06354 lattice.set(latticeconst[0],0.,0., 0.,latticeconst[1],0., 0.,0.,latticeconst[2]);
06355 _H=lattice*myorient.tran();
06356 lattice.set(latticesize[0][3],0.,0., 0.,latticesize[1][3],0., 0.,0.,latticesize[2][3]);
06357 _H=_H*lattice;
06358
06359 _H=_H.reorient();
06360
06361
06362 if(_SAVEMEMORY<9)
06363 {
06364 for(i=0;i<_NP;i++)
06365 _R[i] = _H*_SR[i];
06366 }
06367 }
06368
06369
06370 void MDFrame::makecut()
06371 {
06372
06373
06374 int i, ind, nx, ny, nz;
06375 double x0, y0, z0, rdotn;
06376 Vector3 a, b, c, r, n;
06377 Matrix33 M;
06378
06379 ind = (int) input[0];
06380 nx = (int) input[1];
06381 ny = (int) input[2];
06382 nz = (int) input[3];
06383 x0 = input[4];
06384 y0 = input[5];
06385 z0 = input[6];
06386
06387 a.set(latticesize[0][0],latticesize[0][1],latticesize[0][2]);
06388 b.set(latticesize[1][0],latticesize[1][1],latticesize[1][2]);
06389 c.set(latticesize[2][0],latticesize[2][1],latticesize[2][2]);
06390
06391 n.set(nx,ny,nz);
06392
06393 a/=a.norm();
06394 b/=b.norm();
06395 c/=c.norm();
06396
06397 M.setcol(a,b,c);
06398
06399 SHtoR();
06400 for(i=0;i<_NP;i++)
06401 {
06402 r = M*_R[i];
06403 r.x -= x0; r.y -= y0; r.z -= z0;
06404 rdotn = dot(r,n);
06405
06406 if(rdotn*ind>0) fixed[i]=1;
06407 }
06408 }
06409
06410 void MDFrame::makedipole()
06411 {
06412
06413
06414
06415 int i,j,k,minx,maxx,miny,maxy;
06416 int xind,yind,zind;
06417 double theta[50], pre, frac, x, y, r21, r22, bx, by, nu, nua, nub;
06418 class Vector3 sr0,sr1,r0,r1,ds,dr,sb,b,du,st,due;
06419 class Vector3 sra,srb,src,ra,rb,rc,dua,dub,duc,ux,uy;
06420 class Vector3 px, py, pz, pa, pb, pc;
06421 double pxpa, pxpb, pypa, pypb;
06422 int removenum,n,insertnum;
06423 double dx, dy, dxc, dyc;
06424 int store, gcut;
06425
06426 if(input[0]==0)
06427 {
06428 ERROR("makedipole(): no dipole geometry set");
06429 return;
06430 }
06431 store = (int) input[17];
06432 gcut = (int) input[18];
06433
06434
06435 zind=(int)input[0];
06436 yind=(int)input[1];
06437 xind=zind+yind;if(xind==5)xind=1;if(xind==4)xind=2;
06438 xind--;yind--;zind--;
06439 sb.set(input[2],input[3],input[4]);
06440 b=_H*sb;
06441 if(fabs(b.x)<1e-8) b.x=0;
06442 if(fabs(b.y)<1e-8) b.y=0;
06443 if(fabs(b.z)<1e-8) b.z=0;
06444 INFO("sb="<<sb<<"\nb="<<b);
06445 if(!gcut)
06446 {
06447 sr0[xind]=input[5];sr0[yind]=input[6];sr0[zind]=0;
06448 sr1[xind]=input[5];sr1[yind]=input[7];sr1[zind]=0;
06449 }
06450 else
06451 {
06452 sr0[xind]=input[5];sr0[yind]=input[6];sr0[zind]=0;
06453 sr1[xind]=input[7];sr1[yind]=input[8];sr1[zind]=0;
06454 INFO("sr0="<<sr0);
06455 INFO("sr1="<<sr1);
06456 }
06457 r0=_H*sr0;r1=_H*sr1;
06458 pz.set(_H[0][zind],_H[1][zind],_H[2][zind]);
06459 pz/=pz.norm();
06460 py=r1-r0;
06461 py.orth(pz); py/=py.norm();
06462 px=cross(py,pz);
06463 INFO("px="<<px);
06464 INFO("py="<<py);
06465 INFO("pz="<<pz);
06466 pa.set(_H[0][xind],_H[1][xind],_H[2][xind]);
06467 pb.set(_H[0][yind],_H[1][yind],_H[2][yind]);
06468 pc.set(_H[0][zind],_H[1][zind],_H[2][zind]);
06469 pxpa=px*pa; pxpb=px*pb; pypb=py*pb; pypa=py*pa;
06470 bx=b*px; by=b*py;
06471 INFO("bx="<<bx<<" by="<<by);
06472 if(fabs(pxpa)<1e-8) pxpa=0;
06473 if(fabs(pxpb)<1e-8) pxpb=0;
06474 if(fabs(pypb)<1e-8) pypb=0;
06475 if(fabs(pypa)<1e-8) pypa=0;
06476 if(pxpa<0) { pxpa=-pxpa; pxpb=-pxpb; px*=-1; INFO("redefine x");}
06477 INFO_Printf("pxpa=%e pxpb=%e pypb=%e pypa=%e\n",pxpa,pxpb,pypb,pypa);
06478
06479
06480 sra[xind]=-0.5;sra[yind]=-0.5;sra[zind]=0;
06481 srb[xind]= 0.5;srb[yind]=-0.5;srb[zind]=0;
06482 src[xind]=-0.5;src[yind]= 0.5;src[zind]=0;
06483 ra=_H*sra;rb=_H*srb;rc=_H*src;
06484 nu=input[8]; nua=1.0/4/(1-nu)/2/M_PI; nub=(1.0-2*nu)*nua;
06485 minx=(int)input[9]; maxx=(int)input[10];
06486 miny=(int)input[11];maxy=(int)input[12];
06487 #define getdu_sav(SR) protect(\
06488 ds[xind]=j; ds[yind]=k; ds[zind]=0;\
06489 ds+=SR; ds-=sr0; \
06490 x=ds[xind]*pxpa+ds[yind]*pxpb;\
06491 y=ds[xind]*pypa+ds[yind]*pypb; r21=x*x+y*y;\
06492 theta[0]=atan2(-x,y);\
06493 ds[xind]=j; ds[yind]=k; ds[zind]=0;\
06494 ds+=SR; ds-=sr1; \
06495 x=ds[xind]*pxpa+ds[yind]*pxpb;\
06496 y=ds[xind]*pypa+ds[yind]*pypb; r22=x*x+y*y;\
06497 theta[1]=atan2(-x,y);\
06498 pre=0.5/M_PI*(theta[1]-theta[0]);\
06499 du=b*pre; if((fabs(bx)>1e-8)||(fabs(by)>1e-8)){due.clear();\
06500 due-=px*(-bx*sin(theta[0]*2)*nua+by*(log(r21)*nub+cos(theta[0]*2)*nua));\
06501 due-=py*( by*sin(theta[0]*2)*nua-bx*(log(r21)*nub-cos(theta[0]*2)*nua));\
06502 due+=px*(-bx*sin(theta[1]*2)*nua+by*(log(r22)*nub+cos(theta[1]*2)*nua));\
06503 due+=py*( by*sin(theta[1]*2)*nua-bx*(log(r22)*nub-cos(theta[1]*2)*nua));\
06504 du+=due;} \
06505 )
06506 #define getdu_s(SR) protect(\
06507 ds[xind]=j; ds[yind]=k; ds[zind]=0;\
06508 ds+=SR; ds-=sr0; \
06509 theta[0]=atan2(-ds[xind],ds[yind]);\
06510 ds[xind]=j; ds[yind]=k; ds[zind]=0;\
06511 ds+=SR; ds-=sr1; \
06512 theta[1]=atan2(-ds[xind],ds[yind]);\
06513 pre=0.5/M_PI*(theta[1]-theta[0]);\
06514 du=b*pre;)
06515 #define getdu getdu_sav
06516
06517 if(storedr==NULL)
06518 {
06519 INFO("allocate storedr");
06520 Realloc(storedr,Vector3,_NP*allocmultiple);
06521 bindvar("storedr",storedr,DOUBLE);
06522
06523 SHtoR();
06524 for(i=0;i<_NP;i++) storedr[i]=_R[i];
06525 }
06526
06527
06528 removenum=insertnum=0;
06529 if(fabs(b*px)>1e-8)
06530 {
06531 if((b*px)>0)
06532 {
06533 INFO("Need to remove atoms");
06534 removenum=0;
06535 dr=r1-r0; dyc=dr*py; dxc=b*px;
06536 for(i=0;i<_NP;i++)
06537 {
06538
06539 if((int)input[14])
06540 if((_SR[i][zind]<input[15])||(_SR[i][zind]>=input[16]))
06541 continue;
06542 ds=_SR[i]; ds-=sr0; ds.subint();
06543 dr=_H*ds; dx=dr*px; dy=dr*py;
06544 if((dx>=-dxc*0.5)&&(dx<dxc*0.5)&&(dy>=0)&&(dy<dyc))
06545 {
06546 INFO_Printf("need remove atom %d\n",i);
06547 fixed[i] = -1;
06548 removenum++;
06549 }
06550 }
06551 INFO("need removenum="<<removenum);
06552 }
06553 else
06554 {
06555 INFO("Need to insert atoms");
06556 insertnum=0;
06557 dr=r1-r0; dyc=dr*py; dxc=b*px; dxc=dxc*(-1.0);
06558 for(i=0;i<_NP;i++)
06559 {
06560
06561 if((int)input[14])
06562 if((_SR[i][zind]<input[15])||(_SR[i][zind]>=input[16]))
06563 continue;
06564 ds=_SR[i]; ds-=sr0; ds.subint();
06565 dr=_H*ds; dx=dr*px; dy=dr*py;
06566 if((dx>=-dxc*0.5)&&(dx<dxc*0.5)&&(dy>=0)&&(dy<dyc))
06567 {
06568 INFO_Printf("need replicate atom %d\n",i);
06569 _SR[insertnum+_NP] = _SR[i];
06570 _R[insertnum+_NP] = _R[i];
06571 storedr[insertnum+_NP]=storedr[i];
06572 insertnum++;
06573 }
06574 }
06575 INFO("need insertnum="<<insertnum);
06576 }
06577 }
06578
06579 dua.clear(); dub.clear(); duc.clear();
06580
06581 if((minx!=maxx)||(miny!=maxy))
06582 {
06583 for(j=minx;j<=maxx;j++)
06584 for(k=miny;k<=maxy;k++)
06585 {
06586 getdu(sra); dua+=du;
06587 getdu(srb); dub+=du;
06588 getdu(src); duc+=du;
06589 }
06590 }
06591 ux=dub-dua;
06592 uy=duc-dua;
06593 INFO("overall tilt ux="<<ux<<" uy="<<uy);
06594
06595 SHtoR();
06596 for(i=0;i<_NP;i++)
06597 {
06598 if(fixed[i]) continue;
06599
06600 if((int)input[14])
06601 if((_SR[i][zind]<input[15])||(_SR[i][zind]>=input[16]))
06602 continue;
06603 for(j=minx;j<=maxx;j++)
06604 for(k=miny;k<=maxy;k++)
06605 {
06606 st=_SR[i]; st[zind]=0; getdu(st);
06607 storedr[i]+=du;
06608 }
06609 storedr[i]-=ux*_SR[i][xind];
06610 storedr[i]-=uy*_SR[i][yind];
06611 if(i==0) INFO("storedr[0]="<<storedr[0]);
06612 }
06613 INFO("originally "<<_NP<<" atoms");
06614 INFO("insert "<<insertnum<<" atoms");
06615 _NP+=insertnum;
06616 INFO("now "<<_NP<<" atoms");
06617
06618
06619
06620 if(input[13])
06621 {
06622 INFO("shiftbox to accommodate plastic strain");
06623 frac=-(input[7]-input[6]);
06624 dH[0][xind]+=(_H[0][0]*input[2]+_H[0][1]*input[3]
06625 +_H[0][2]*input[4])*frac;
06626 dH[1][xind]+=(_H[1][0]*input[2]+_H[1][1]*input[3]
06627 +_H[1][2]*input[4])*frac;
06628 dH[2][xind]+=(_H[2][0]*input[2]+_H[2][1]*input[3]
06629 +_H[2][2]*input[4])*frac;
06630 }
06631
06632 INFO_Printf("makedipole: store=%d\n",store);
06633 if(!store)
06634 {
06635
06636 SHtoR();
06637 for(i=0;i<_NP;i++)
06638 {
06639
06640 _R[i]=storedr[i];
06641 }
06642 RHtoS();
06643 INFO("free storedr");
06644 free(storedr);
06645 storedr = NULL;
06646
06647
06648 n=0; SHtoR();
06649 removenum=0;
06650 for(i=0;i<_NP;i++)
06651 {
06652 if(fixed[i]!=-1)
06653 {
06654 _R0[n]=_R[i];
06655 fixed[n]=fixed[i];
06656 n++;
06657 }
06658 else
06659 {
06660 removenum++;
06661 }
06662 }
06663 INFO("originally "<<_NP<<" atoms");
06664 INFO("remove "<<removenum<<" atoms");
06665 _NP-=removenum;
06666 INFO("now "<<_NP<<" atoms");
06667 R0toR(); RHtoS();
06668 INFO("NP="<<_NP<<" n="<<n);
06669
06670
06671
06672 _H+=dH;
06673 dH.clear();
06674 }
06675 }
06676
06677 void MDFrame::makedislocation()
06678 {
06679
06680
06681
06682
06683
06684
06685
06686
06687
06688
06689
06690
06691
06692
06693
06694
06695
06696
06697 double a, nu, nua, nub, bx, by, bz, x, y, r2, theta, pre;
06698 Vector3 b, l, n, r0, e1, e2, e3, b0, du, due;
06699 Vector3 sra, srb, src, srd, ra, rb, rc, rd, dua, dub, duc, dud;
06700 Matrix33 M;
06701 int store, cut, i, k, removenum, insertnum;
06702
06703 if(input[0]==0)
06704 {
06705 INFO_Printf("input = [%f %f %f ]\n",
06706 input[0],input[1],input[2]);
06707 ERROR("makedislocation(): no dislocation geometry set");
06708 return;
06709 }
06710 a = input[1];
06711 b.set(input[2],input[3],input[4]);
06712 l.set(input[5],input[6],input[7]);
06713 n.set(input[8],input[9],input[10]);
06714 r0.set(input[11],input[12],input[13]);
06715 nu = input[14];
06716 store = (int) input[15];
06717 cut = (int) input[16];
06718
06719
06720 b*=a;
06721 if(fabs(b.x)<1e-8) b.x=0;
06722 if(fabs(b.y)<1e-8) b.y=0;
06723 if(fabs(b.z)<1e-8) b.z=0;
06724
06725
06726
06727 e3=l;
06728 e3/=e3.norm();
06729 e2=n;
06730 e2/=e2.norm();
06731 e1=cross(e2,e3);
06732 M.setcol(e1,e2,e3);
06733
06734 bx=b*e1; by=b*e2; bz=b*e3;
06735 b0.set(bx,by,bz);
06736 nu=input[7]; nua=1.0/4/(1-nu)/2/M_PI; nub=(1.0-2*nu)*nua;
06737
06738 if((storedr==NULL))
06739 {
06740 INFO("allocate storedr");
06741 Realloc(storedr,Vector3,_NP*allocmultiple);
06742
06743 SHtoR();
06744 for(i=0;i<_NP;i++) storedr[i]=_R[i];
06745 }
06746
06747
06748 removenum=insertnum=0;
06749 if(fabs(by)>1e-8)
06750 {
06751 INFO("Remove/insert atoms not implemented yet");
06752 if((by)>0)
06753 {
06754 INFO("Need to remove atoms");
06755 removenum=0;
06756 INFO("need removenum="<<removenum);
06757 }
06758 else
06759 {
06760 INFO("Need to insert atoms");
06761 insertnum=0;
06762 INFO("need insertnum="<<insertnum);
06763 }
06764 return;
06765 }
06766
06767 #define getdu_r(R) protect(\
06768 x = (R-r0)*e1;\
06769 y = (R-r0)*e2;\
06770 if(cut)\
06771 {\
06772 if(y>0)\
06773 du=b0*0.5;\
06774 else\
06775 du=b0*(-0.5);\
06776 }\
06777 else\
06778 {\
06779 r2 = x*x + y*y;\
06780 theta = atan2(y, x);\
06781 pre = 0.5/M_PI*theta;\
06782 du = b0*pre;\
06783 if ((fabs(bx)>1e8)||(fabs(by)>1e8))\
06784 {\
06785 due.clear();\
06786 due-=x*(-bx*sin(theta*2)*nua+by*(log(r2)*nub+cos(theta*2)*nua));\
06787 due-=y*( by*sin(theta*2)*nua-bx*(log(r2)*nub-cos(theta*2)*nua));\
06788 du += due;\
06789 }\
06790 }\
06791 du = M*du;)
06792
06793 sra.set(-0.5,-0.5,-0.5);
06794 srb.set( 0.5,-0.5,-0.5);
06795 src.set(-0.5, 0.5,-0.5);
06796 srd.set(-0.5,-0.5, 0.5);
06797
06798 ra=_H*sra;rb=_H*srb;rc=_H*src;rd=_H*srd;
06799 getdu_r(ra); dua=du;
06800 getdu_r(rb); dub=du;
06801 getdu_r(rc); duc=du;
06802 getdu_r(rd); dud=du;
06803 dub -= dua; duc -= dua; dud -= dua;
06804 output_dat[0] = dub.x; output_dat[1] = dub.y; output_dat[2] = dub.z;
06805 output_dat[3] = duc.x; output_dat[4] = duc.y; output_dat[5] = duc.z;
06806 output_dat[6] = dud.x; output_dat[7] = dud.y; output_dat[8] = dud.z;
06807
06808 SHtoR();
06809 for(i=0;i<_NP;i++)
06810 {
06811 getdu_r(_R[i]);
06812 storedr[i]+=du;
06813 if(i==0) INFO("storedr[0]="<<storedr[0]);
06814 }
06815 RHtoS();
06816
06817 if(!store)
06818 {
06819
06820 SHtoR();
06821 for(i=0;i<_NP;i++)
06822 {
06823
06824 _R[i]=storedr[i];
06825 }
06826 RHtoS();
06827
06828
06829
06830
06831 k=0; SHtoR();
06832 removenum=0;
06833 for(i=0;i<_NP;i++)
06834 {
06835 if(fixed[i]!=-1)
06836 {
06837 _R0[k]=_R[i];
06838 fixed[k]=fixed[i];
06839 k++;
06840 }
06841 else
06842 {
06843 removenum++;
06844 }
06845 }
06846 INFO("originally "<<_NP<<" atoms");
06847 INFO("remove "<<removenum<<" atoms");
06848 _NP-=removenum;
06849 INFO("now "<<_NP<<" atoms");
06850 R0toR(); RHtoS();
06851 INFO("NP="<<_NP<<" n="<<n);
06852 }
06853
06854
06855 if (fixedatomenergypartition) setfixbufferatoms();
06856 }
06857
06858
06859 void MDFrame::makecylinder()
06860 {
06861
06862
06863
06864
06865
06866
06867
06868
06869
06870
06871
06872
06873 int i, xind, yind, zind, flag;
06874 double r, rrem;
06875 double x, y, bx, by;
06876 class Vector3 sr0,r0,ds,dr,sb,b,du,st,due;
06877 class Vector3 ux,uy;
06878 class Vector3 px, py, pz, pa, pb, pc;
06879 double pxpa, pxpb, pypa, pypb, szmin, szmax;
06880 int removenum,n;
06881
06882 if(input[0]==0)
06883 {
06884 INFO_Printf("input = [%f %f %f ]\n",
06885 input[0],input[1],input[2]);
06886 ERROR("makecylinder(): no dislocation geometry set");
06887 return;
06888 }
06889
06890
06891 zind=(int)input[0];
06892 yind=(int)input[1];
06893 xind=zind+yind;if(xind==5)xind=1;if(xind==4)xind=2;
06894 xind--;yind--;zind--;
06895
06896
06897 sr0[xind]=input[2];sr0[yind]=input[3];sr0[zind]=0;
06898
06899 r0=_H*sr0;
06900 pz.set(_H[0][zind],_H[1][zind],_H[2][zind]);
06901 pz/=pz.norm();
06902 py.set(_H[0][yind],_H[1][yind],_H[2][yind]);
06903 py.orth(pz); py/=py.norm();
06904 px=cross(py,pz);
06905 INFO("px="<<px);
06906 INFO("py="<<py);
06907 INFO("pz="<<pz);
06908 pa.set(_H[0][xind],_H[1][xind],_H[2][xind]);
06909 pb.set(_H[0][yind],_H[1][yind],_H[2][yind]);
06910 pc.set(_H[0][zind],_H[1][zind],_H[2][zind]);
06911 pxpa=px*pa; pxpb=px*pb; pypb=py*pb; pypa=py*pa;
06912 bx=b*px; by=b*py;
06913 INFO("bx="<<bx<<" by="<<by);
06914 if(fabs(pxpa)<1e-8) pxpa=0;
06915 if(fabs(pxpb)<1e-8) pxpb=0;
06916 if(fabs(pypb)<1e-8) pypb=0;
06917 if(fabs(pypa)<1e-8) pypa=0;
06918 if(pxpa<0) { pxpa=-pxpa; pxpb=-pxpb; px*=-1; INFO("redefine x");}
06919 INFO_Printf("pxpa=%e pxpb=%e pypb=%e pypa=%e\n",pxpa,pxpb,pypb,pypa);
06920
06921 rrem=input[4];
06922 flag=(int) input[5];
06923 szmin = input[6];
06924 szmax = input[7];
06925
06926 if(szmax>szmin)
06927 {
06928 INFO_Printf("only atoms with r[%d] between %e and %e will be cut\n",
06929 zind,szmin,szmax);
06930 }
06931
06932 #define getdr(SR) protect(\
06933 ds=SR; ds-=sr0; ds[zind]=0; \
06934 x=ds[xind]*pxpa+ds[yind]*pxpb;\
06935 y=ds[xind]*pypa+ds[yind]*pypb; r=sqrt(x*x+y*y);)
06936
06937 SHtoR();
06938 for(i=0;i<_NP;i++)
06939 {
06940 getdr(_SR[i]);
06941
06942 if(szmax<=szmin)
06943 {
06944 if(r>rrem)
06945 {
06946 if(flag==1)
06947 fixed[i]=1;
06948 else
06949 fixed[i]=-1;
06950 }
06951 }
06952 else
06953 {
06954 if((_SR[i][zind]>=szmin)&&(_SR[i][zind]<szmax))
06955 {
06956 if(r>rrem)
06957 {
06958 if(flag==1)
06959 fixed[i]=1;
06960 else
06961 fixed[i]=-1;
06962 }
06963 }
06964 }
06965 }
06966
06967
06968 n=0; SHtoR();
06969 removenum=0;
06970 for(i=0;i<_NP;i++)
06971 {
06972 if(fixed[i]!=-1)
06973 {
06974 _R0[n]=_R[i];
06975 fixed[n]=fixed[i];
06976
06977
06978 if(_SAVEMEMORY<8) species[n]=species[i];
06979 n++;
06980 }
06981 else
06982 {
06983 removenum++;
06984 }
06985 }
06986 INFO("originally "<<_NP<<" atoms");
06987 INFO("remove "<<removenum<<" atoms");
06988 _NP-=removenum;
06989 INFO("now "<<_NP<<" atoms");
06990 R0toR(); RHtoS();
06991 INFO("NP="<<_NP<<" n="<<n);
06992
06993
06994 if (fixedatomenergypartition) setfixbufferatoms();
06995 }
06996
06997 void MDFrame::setfixbufferatoms()
06998 {
06999
07000
07001
07002 int i, j, jpt, ninter, nfree, nfixed;
07003 Vector3 sij, rij;
07004 double r;
07005
07006 INFO("setfixbufferatoms");
07007 refreshneighborlist();
07008
07009 for(i=0;i<_NP;i++)
07010 {
07011 if(!fixed[i]) continue;
07012 fixed[i]=1;
07013 for(j=0;j<nn[i];j++)
07014 {
07015 jpt=nindex[i][j];
07016 if(fixed[jpt]) continue;
07017 sij=_SR[jpt]-_SR[i];
07018 sij.subint();
07019 rij=_H*sij;
07020 r=rij.norm();
07021 if(r<_RLIST-_SKIN) fixed[i]=2;
07022 }
07023 }
07024 ninter=0; nfree=0; nfixed=0;
07025 for(i=0;i<_NP;i++)
07026 {
07027 if(fixed[i]!=1) ninter++;
07028 if(fixed[i]==0) nfree++;
07029 if(fixed[i]) nfixed++;
07030 }
07031 INFO("number of interacting atoms: ninter="<<ninter);
07032 INFO("number of free atoms: nfree ="<<nfree);
07033 INFO("number of fixed atoms: nfixed="<<nfixed);
07034 }
07035
07036 void MDFrame::makedislcylinder()
07037 {
07038
07039
07040 int i, xind, yind, zind;
07041 double r, rfix, rgfbc, rrem;
07042
07043
07044 double theta[2], pre, x, y, r21, bx, by, nu, nua, nub;
07045 class Vector3 sr0,r0,ds,dr,sb,b,du,st,due;
07046 class Vector3 ux,uy;
07047 class Vector3 px, py, pz, pa, pb, pc;
07048 double pxpa, pxpb, pypa, pypb;
07049 int removenum,n,insertnum;
07050 double dx, dxc;
07051 static class Vector3 *storedr;
07052 int store;
07053
07054 INFO("outdated function, use makecylinder and makedislocation instead");
07055 INFO("see Computer Simulations of Dislocations, Section 3.1, ta-screw.script");
07056
07057 if(input[0]==0)
07058 {
07059 INFO_Printf("input = [%f %f %f ]\n",
07060 input[0],input[1],input[2]);
07061 ERROR("makedislocation(): no dislocation geometry set");
07062 return;
07063 }
07064 store = (int) input[11];
07065
07066
07067 zind=(int)input[0];
07068 yind=(int)input[1];
07069 xind=zind+yind;if(xind==5)xind=1;if(xind==4)xind=2;
07070 xind--;yind--;zind--;
07071
07072 sb.set(input[2],input[3],input[4]);
07073 b=_H*sb;
07074 if(fabs(b.x)<1e-8) b.x=0;
07075 if(fabs(b.y)<1e-8) b.y=0;
07076 if(fabs(b.z)<1e-8) b.z=0;
07077
07078
07079 sr0[xind]=input[5];sr0[yind]=input[6];sr0[zind]=0;
07080
07081 r0=_H*sr0;
07082 pz.set(_H[0][zind],_H[1][zind],_H[2][zind]);
07083 pz/=pz.norm();
07084 py.set(_H[0][yind],_H[1][yind],_H[2][yind]);
07085 py.orth(pz); py/=py.norm();
07086 px=cross(py,pz);
07087 INFO("px="<<px);
07088 INFO("py="<<py);
07089 INFO("pz="<<pz);
07090 pa.set(_H[0][xind],_H[1][xind],_H[2][xind]);
07091 pb.set(_H[0][yind],_H[1][yind],_H[2][yind]);
07092 pc.set(_H[0][zind],_H[1][zind],_H[2][zind]);
07093 pxpa=px*pa; pxpb=px*pb; pypb=py*pb; pypa=py*pa;
07094 bx=b*px; by=b*py;
07095 INFO("bx="<<bx<<" by="<<by);
07096 if(fabs(pxpa)<1e-8) pxpa=0;
07097 if(fabs(pxpb)<1e-8) pxpb=0;
07098 if(fabs(pypb)<1e-8) pypb=0;
07099 if(fabs(pypa)<1e-8) pypa=0;
07100 if(pxpa<0) { pxpa=-pxpa; pxpb=-pxpb; px*=-1; INFO("redefine x");}
07101 INFO_Printf("pxpa=%e pxpb=%e pypb=%e pypa=%e\n",pxpa,pxpb,pypb,pypa);
07102
07103 nu=input[7]; nua=1.0/4/(1-nu)/2/M_PI; nub=(1.0-2*nu)*nua;
07104 rfix=input[8]; rgfbc=input[9]; rrem=input[10];
07105
07106 if(storedr==NULL)
07107 {
07108 INFO("allocate storedr");
07109 storedr = (Vector3 *)malloc(sizeof(Vector3)*_NP*allocmultiple);
07110 bindvar("storedr",storedr,DOUBLE);
07111 for(i=0;i<_NP;i++) storedr[i].clear();
07112 }
07113
07114
07115 removenum=insertnum=0;
07116 if(fabs(b*px)>1e-8)
07117 {
07118 if((b*px)>0)
07119 {
07120 INFO("Need to remove atoms");
07121 removenum=0;
07122 dxc=b*px;
07123 for(i=0;i<_NP;i++)
07124 {
07125 ds=_SR[i]; ds-=sr0; ds.subint();
07126 dr=_H*ds; dx=dr*px;
07127 if((dx>=-dxc*0.5)&&(dx<dxc*0.5))
07128 {
07129 INFO_Printf("need remove atom %d\n",i);
07130 fixed[i] = -1;
07131 removenum++;
07132 }
07133 }
07134 INFO("need removenum="<<removenum);
07135 }
07136 else
07137 {
07138 INFO("Need to insert atoms");
07139 insertnum=0;
07140 dxc=b*px; dxc=dxc*(-1.0);
07141 for(i=0;i<_NP;i++)
07142 {
07143 ds=_SR[i]; ds-=sr0; ds.subint();
07144 dr=_H*ds; dx=dr*px;
07145 if((dx>=-dxc*0.5)&&(dx<dxc*0.5))
07146 {
07147 INFO_Printf("need replicate atom %d\n",i);
07148 _SR[insertnum+_NP] = _SR[i];
07149 _R[insertnum+_NP] = _R[i];
07150 storedr[insertnum+_NP]=storedr[i];
07151 insertnum++;
07152 }
07153 }
07154 INFO("need insertnum="<<insertnum);
07155 }
07156 }
07157
07158 #define getdu_single(SR) protect(\
07159 ds=SR; ds-=sr0; ds[zind]=0; \
07160 x=ds[xind]*pxpa+ds[yind]*pxpb;\
07161 y=ds[xind]*pypa+ds[yind]*pypb; r21=x*x+y*y;\
07162 theta[0]=atan2(-x,y);\
07163 pre=0.5/M_PI*(theta[0]);\
07164 du=b*pre; if((fabs(bx)>1e-8)||(fabs(by)>1e-8)){due.clear();\
07165 due-=px*(-bx*sin(theta[0]*2)*nua+by*(log(r21)*nub+cos(theta[0]*2)*nua));\
07166 due-=py*( by*sin(theta[0]*2)*nua-bx*(log(r21)*nub-cos(theta[0]*2)*nua));\
07167 \
07168 \
07169 du+=due;} \
07170 )
07171
07172 SHtoR();
07173 for(i=0;i<_NP;i++)
07174 {
07175 getdr(_SR[i]);
07176 if(r>rrem) fixed[i]=-1;
07177 else if(r>rfix) fixed[i]=1;
07178 if(fixed[i]==-1) continue;
07179 st=_SR[i]; st[zind]=0; getdu_single(st);
07180 storedr[i]+=du;
07181
07182 storedr[i]-=ux*_SR[i][xind];
07183 storedr[i]-=uy*_SR[i][yind];
07184 if(i==0) INFO("storedr[0]="<<storedr[0]);
07185 }
07186 INFO("originally "<<_NP<<" atoms");
07187 INFO("insert "<<insertnum<<" atoms");
07188 _NP+=insertnum;
07189 INFO("now "<<_NP<<" atoms");
07190
07191
07192 if(!store)
07193 {
07194
07195 SHtoR();
07196 for(i=0;i<_NP;i++)
07197 {
07198 _R[i]+=storedr[i];
07199 }
07200 RHtoS();
07201 free(storedr);
07202 storedr = NULL;
07203
07204
07205 n=0; SHtoR();
07206 removenum=0;
07207 for(i=0;i<_NP;i++)
07208 {
07209 if(fixed[i]!=-1)
07210 {
07211 _R0[n]=_R[i];
07212 fixed[n]=fixed[i];
07213 n++;
07214 }
07215 else
07216 {
07217 removenum++;
07218 }
07219 }
07220 INFO("originally "<<_NP<<" atoms");
07221 INFO("remove "<<removenum<<" atoms");
07222 _NP-=removenum;
07223 INFO("now "<<_NP<<" atoms");
07224 R0toR(); RHtoS();
07225 INFO("NP="<<_NP<<" n="<<n);
07226
07227 }
07228
07229
07230 if (fixedatomenergypartition) setfixbufferatoms();
07231 }
07232
07233 void MDFrame::makedisloop()
07234 {
07235
07236
07237
07238
07239
07240
07241
07242 class Vector3 normal, sb, b, du, sr, rt;
07243 double radius, height, V;
07244 int minx, maxx, miny, maxy, minz, maxz, i, j, k, m, n;
07245 int removenum, store;
07246 Matrix33 epsilon;
07247 static class Vector3 *storedr;
07248 static Matrix33 dH;
07249
07250 if(input[0]==0)
07251 {
07252 ERROR("makedisloop(): no dipole geometry set");
07253 return;
07254 }
07255 store = (int) input[16];
07256
07257
07258 normal.set(input[0],input[1],input[2]);
07259 normal/=normal.norm();
07260 INFO("normal="<<normal);
07261 radius=input[3];
07262 height=input[4];
07263 sb.set(input[5],input[6],input[7]);
07264 b=_H*sb;
07265 if(fabs(b.x)<1e-8) b.x=0;
07266 if(fabs(b.y)<1e-8) b.y=0;
07267 if(fabs(b.z)<1e-8) b.z=0;
07268 INFO("sb="<<sb<<"\nb="<<b);
07269
07270
07271 minx=(int)input[9]; maxx=(int)input[10];
07272 miny=(int)input[11];maxy=(int)input[12];
07273 minz=(int)input[13];maxz=(int)input[14];
07274
07275
07276 if(storedr==NULL)
07277 {
07278 INFO("allocate storedr");
07279 storedr = (Vector3 *)malloc(sizeof(Vector3)*_NP*allocmultiple);
07280 bindvar("storedr",storedr,DOUBLE);
07281 for(i=0;i<_NP;i++) storedr[i].clear();
07282 }
07283
07284
07285 removenum=0;
07286 if(fabs(b*normal)>1e-4)
07287 {
07288 INFO("b*normal="<<b*normal);
07289 if((b*normal)>0)
07290 {
07291 INFO("Need to remove atoms: not implemented!");
07292 return;
07293 }
07294 else
07295 {
07296 INFO("Need to insert atoms: not implemented!");
07297 return;
07298 }
07299 }
07300
07301
07302
07303
07304
07305 SHtoR();
07306 for(i=0;i<_NP;i++)
07307 {
07308 if(fixed[i]) continue;
07309 for(j=minx;j<=maxx;j++)
07310 for(k=miny;k<=maxy;k++)
07311 for(m=minz;m<=maxz;m++)
07312 {
07313
07314 sr=_SR[i]; sr.x+=j; sr.y+=k; sr.z+=m;
07315 rt=_H*sr;
07316 calloopdisp(&normal,radius,height,&b,&rt,&du);
07317
07318 storedr[i]+=du;
07319 }
07320 if(i==0) INFO("storedr[0]="<<storedr[0]);
07321 }
07322
07323
07324 if(input[15])
07325 {
07326 INFO("shiftbox");
07327 epsilon.clear();
07328 V=_H.det();
07329 INFO("V="<<V);
07330 epsilon.addnvv
07331 (M_PI*radius*radius/(sqrt(3.0)*_H[0][0]*_H[0][0]),
07332 b,normal);
07333 INFO("epsilon="<<epsilon);
07334
07335 dH=epsilon;
07336 }
07337
07338 if(!store)
07339 {
07340
07341 SHtoR();
07342 for(i=0;i<_NP;i++)
07343 {
07344 _R[i]+=storedr[i];
07345 }
07346 RHtoS();
07347 free(storedr);
07348 storedr = NULL;
07349
07350
07351 n=0; SHtoR();
07352 removenum=0;
07353 for(i=0;i<_NP;i++)
07354 {
07355 if(fixed[i]!=-1)
07356 {
07357 _R0[n]=_R[i];
07358 fixed[n]=0;
07359 n++;
07360 }
07361 else
07362 {
07363 removenum++;
07364 }
07365 }
07366 INFO("originally "<<_NP<<" atoms");
07367 INFO("remove "<<removenum<<" atoms");
07368 _NP-=removenum;
07369 INFO("now "<<_NP<<" atoms");
07370 R0toR(); RHtoS();
07371 INFO("NP="<<_NP<<" n="<<n);
07372
07373
07374
07375 _H+=dH;
07376 }
07377 }
07378
07379 void MDFrame::calloopdisp
07380 (Vector3 *normal,double radius,double height,
07381 Vector3 *b, Vector3 *rt,Vector3 *du)
07382 {
07383
07384
07385
07386 double hr, dx, x, y, z, r, r2, R, Omega;
07387 Vector3 rr;
07388 int Ns, i, j;
07389
07390 hr=height/radius;
07391 rr=*rt; rr/=radius;
07392 z=rr*(*normal);
07393 r2=(rr.norm2()-z*z);
07394 if(r2>0) r=sqrt(r2);
07395 else r=0;
07396
07397
07398 if(r<1.0/5.5)
07399 Ns=5;
07400 else
07401 Ns=(int)(1.0/r-0.5);
07402
07403 dx=2.0/(2*Ns+1);
07404
07405 if(fabs(z*radius)<3)
07406 {
07407 if(r>1)
07408 Omega=0;
07409 else
07410 if(z>0)
07411 Omega=-2*M_PI;
07412 else
07413 Omega=2*M_PI;
07414 *du = *b;
07415 *du *= (-Omega/4/M_PI);
07416 return;
07417 }
07418 Omega=0;
07419 for(i=-Ns;i<=Ns;i++)
07420 for(j=-Ns;j<=Ns;j++)
07421 {
07422
07423 x=dx*i;
07424 y=dx*j;
07425 if(x*x+y*y<=1)
07426 {
07427 R=sqrt((x-r)*(x-r)+y*y+z*z);
07428 Omega+=1./(R*R*R);
07429 }
07430 }
07431 Omega*=(-z*dx*dx);
07432 *du = *b;
07433 *du *= (-Omega/4/M_PI);
07434 return;
07435 }
07436
07437 void MDFrame::makegrainboundary()
07438 {
07439
07440 int i,n,imgx,imgy;
07441 int gbtype;
07442 double sx0,sy0,p,q,shift[3], alpha;
07443 Matrix33 rot1, rot2, hnew, hinv;
07444 Vector3 r0, sr0, r1,dr,drr,s1,sr;
07445
07446 gbtype = (int)input[0];
07447 sx0=input[1];
07448 sy0=input[2];
07449 p=input[3];
07450 q=input[4];
07451 shift[0]=input[5];
07452 shift[1]=input[6];
07453 shift[2]=input[7];
07454
07455 if(gbtype==0)
07456 {
07457 ERROR("makegb(): no gb geometry set");
07458 return;
07459 }
07460
07461 alpha=atan2(p,q);
07462 rot1.set(cos(alpha),-sin(alpha),0,
07463 sin(alpha),cos(alpha),0,
07464 0,0,1);
07465 rot2.set(cos(alpha),sin(alpha),0,
07466 -sin(alpha),cos(alpha),0,
07467 0,0,1);
07468 hnew=_H;
07469 hnew[0][0]/=cos(alpha);
07470 hnew[0][1]/=cos(alpha);
07471 hnew[0][2]/=cos(alpha);
07472 hnew[1][0]/=cos(alpha);
07473 hnew[1][1]/=cos(alpha);
07474 hnew[1][2]/=cos(alpha);
07475 hinv=hnew.inv();
07476 sr0.set(sx0,sy0,0);
07477 r0=_H*sr0;
07478 n=0;
07479 for(i=0;i<_NP;i++)
07480 {
07481 {
07482
07483 for(imgx=-1;imgx<=1;imgx++)
07484 for(imgy=-1;imgy<=1;imgy++)
07485 {
07486 sr=_SR[i]; sr.x+=imgx; sr.y+=imgy;
07487 r1=_H*sr;
07488 dr=r1-r0;
07489 drr=rot1*dr;
07490 _R[i]=r0+drr;
07491 s1=hinv*_R[i];
07492 if((s1.x>sx0)&&(s1.x<0.5)
07493 &&(s1.y>=-0.5)&&(s1.y<0.5))
07494 {
07495 INFO("atom "<<i<<" "<<s1);
07496 _R0[n]=s1;
07497 n++;
07498 if(n>_NP)
07499 INFO("number of atoms "<<n<<" exceed "<<_NP);
07500 }
07501 }
07502 }
07503 {
07504
07505 for(imgx=-1;imgx<=1;imgx++)
07506 for(imgy=-1;imgy<=1;imgy++)
07507 {
07508 sr=_SR[i]; sr.x+=imgx; sr.y+=imgy;
07509 r1=_H*sr;
07510 dr=r1-r0;
07511 drr=rot2*dr;
07512 _R[i]=r0+drr;
07513 s1=hinv*_R[i];
07514 if((s1.x<=sx0)&&(s1.x>=-0.5)
07515 &&(s1.y>=-0.5)&&(s1.y<0.5))
07516 {
07517 INFO("atom "<<i<<" "<<s1);
07518 _R0[n]=s1;
07519 n++;
07520 if(n>_NP)
07521 INFO("number of atoms "<<n<<" exceed "<<_NP);
07522 }
07523 }
07524 }
07525 }
07526 INFO("makegb: old NP="<<_NP<<" new NP="<<n);
07527 _NP=n;
07528 for(i=0;i<_NP;i++)
07529 {
07530 _SR[i]=_R0[i];
07531 _R[i]=_H*_SR[i];
07532 _R0[i]=_R[i];
07533 }
07534 }
07535
07536 void MDFrame::makewave()
07537 {
07538
07539
07540
07541
07542
07543
07544
07545
07546
07547
07548
07549 double amp;
07550 Vector3 dr, kvec;
07551 int i, vel;
07552
07553 if(input[0]==0)
07554 {
07555 INFO_Printf("mkwavespec = [%f %f %f ]\n",
07556 input[0],input[1],input[2]);
07557 ERROR("makewave(): no geometry set");
07558 return;
07559 }
07560
07561 amp = input[1];
07562 dr.set(input[2],input[3],input[4]);
07563 dr/=dr.norm();
07564 dr*=amp;
07565 kvec.set(input[5],input[6],input[7]);
07566 vel = (int)input[8];
07567
07568 SHtoR();
07569 for(i=0;i<_NP;i++)
07570 {
07571 _R[i]+=dr*cos(kvec*_SR[i]*2*M_PI);
07572 }
07573 RHtoS();
07574 if(vel!=0)
07575 {
07576 INFO_Printf("makewave(): vel=%d not implemented\n",vel);
07577 ERROR("makewave()");
07578 }
07579 }
07580
07581 #ifdef _TORSION_OR_BENDING
07582 #include "../cookies/src/md_torsion.cpp"
07583 #include "../cookies/src/md_bending.cpp"
07584 #endif
07585
07586
07587 void MDFrame::scaleH()
07588 {
07589
07590 INFO(_H);
07591 _H*=input[0];
07592 INFO(_H);
07593 }
07594 void MDFrame::saveH()
07595 {
07596
07597 INFO(_H);
07598 _H0=_H;
07599 INFO(_H);
07600 }
07601 void MDFrame::setH()
07602 {
07603
07604
07605
07606 int i,j;
07607 double h;
07608 i=(int)input[0];
07609 j=(int)input[1];
07610 h=input[2];
07611 _H[i][j]=h;
07612 }
07613 void MDFrame::restoreH()
07614 {
07615
07616 INFO(_H);
07617 _H=_H0;
07618 INFO(_H);
07619 }
07620
07621
07622
07623
07624
07625
07626 void MDFrame::shiftbox()
07627 {
07628
07629
07630
07631
07632
07633 int xind, yind;
07634 double frac;
07635 if(input[0]==0)
07636 {
07637 ERROR("input(): no shift geometry set");
07638 return;
07639 }
07640 xind=(int)input[0];
07641 yind=(int)input[1];
07642 xind--;yind--;
07643 frac=input[2];
07644
07645 INFO("The old H=\n"<<_H);
07646
07647 _H[0][xind]+=_H[0][yind]*frac;
07648 _H[1][xind]+=_H[1][yind]*frac;
07649 _H[2][xind]+=_H[2][yind]*frac;
07650
07651 INFO("The new H=\n"<<_H);
07652 SHtoR();
07653 }
07654
07655 void MDFrame::redefinepbc()
07656 {
07657
07658
07659
07660
07661
07662 int xind, yind;
07663 double frac;
07664 if(input[0]==0)
07665 {
07666 ERROR("input(): no shift geometry set");
07667 return;
07668 }
07669 xind=(int)input[0];
07670 yind=(int)input[1];
07671 xind--;yind--;
07672 frac=input[2];
07673
07674 INFO("The old H=\n"<<_H);
07675
07676 SHtoR();
07677
07678 _H[0][xind]+=_H[0][yind]*frac;
07679 _H[1][xind]+=_H[1][yind]*frac;
07680 _H[2][xind]+=_H[2][yind]*frac;
07681
07682 INFO("The new H=\n"<<_H);
07683 RHtoS();
07684 }
07685
07686 void MDFrame::applystrain()
07687 {
07688
07689
07690
07691
07692
07693
07694
07695 class Matrix33 rot, rotv, strain, rstrain; double tmp;
07696
07697 rot.set(input);
07698
07699 tmp=sqrt(rot[0][0]*rot[0][0]+rot[0][1]*rot[0][1]+rot[0][2]*rot[0][2]);
07700 rot[0][0]/=tmp;rot[0][1]/=tmp;rot[0][2]/=tmp;
07701 tmp=sqrt(rot[1][0]*rot[1][0]+rot[1][1]*rot[1][1]+rot[1][2]*rot[1][2]);
07702 rot[1][0]/=tmp;rot[1][1]/=tmp;rot[1][2]/=tmp;
07703 tmp=sqrt(rot[2][0]*rot[2][0]+rot[2][1]*rot[2][1]+rot[2][2]*rot[2][2]);
07704 rot[2][0]/=tmp;rot[2][1]/=tmp;rot[2][2]/=tmp;
07705 rotv=rot.tran();
07706
07707 strain.set(input+9);
07708 strain*=input[19];
07709 rstrain=rot*strain;
07710 rstrain=rstrain*rotv;
07711
07712 INFO("applystrain rstrain="<<rstrain);
07713 _H0=_H;
07714 _H+=rstrain*_H;
07715 }
07716
07717 void MDFrame::extendbox()
07718 {
07719
07720
07721
07722
07723
07724
07725
07726 int dir, n;
07727 int i,j;
07728
07729 dir=(int)input[0]; n=(int)input[1];
07730 if((dir<=0)||(dir>=4)) return;
07731 if(n<=1) return;
07732 dir--;
07733
07734 for(i=0;i<_NP;i++)
07735 {
07736 for(j=1;j<n;j++)
07737 {
07738 _SR[i+_NP*j]=_SR[i];
07739 _SR[i+_NP*j][dir]+=j;
07740 fixed[i+_NP*j]=fixed[i];
07741 _EPOT_IND[i+_NP*j]=_EPOT_IND[i];
07742 _TOPOL[i+_NP*j]=_TOPOL[i];
07743 }
07744 }
07745 for(i=0;i<_NP*n;i++)
07746 {
07747 _SR[i][dir]=(_SR[i][dir]+0.5)/n-0.5;
07748 }
07749 _H[0][dir]*=n;
07750 _H[1][dir]*=n;
07751 _H[2][dir]*=n;
07752 _NP*=n;
07753 SHtoR();
07754 INFO("extenbox: new NP="<<_NP);
07755 }
07756
07757
07758
07759
07760 void MDFrame::cutslice()
07761 {
07762
07763
07764
07765
07766
07767
07768 int dir, n;
07769 int i;
07770
07771 dir=(int)input[0]; n=(int)input[1];
07772 if((dir<=0)||(dir>=4)) return;
07773 if(n<=1) return;
07774 dir--;
07775
07776 INFO("dir = "<<dir<<" n = "<<n);
07777 for(i=0;i<_NP/n;i++)
07778 {
07779 INFO_Printf("_SR: %20.17e -> %20.17e\n",
07780 _SR[i][dir],(_SR[i][dir]+0.5)*n-0.5);
07781 _SR[i][dir]=(_SR[i][dir]+0.5)*n-0.5;
07782 }
07783 _H[0][dir]/=n;
07784 _H[1][dir]/=n;
07785 _H[2][dir]/=n;
07786 _NP/=n;
07787 SHtoR();
07788 INFO("extenbox: new NP="<<_NP);
07789 }
07790
07791
07792 void MDFrame::splicecn()
07793 {
07794 int i, dir, np0, np1;
07795 double ratio;
07796 double w;
07797 char cmd[1000], tmpfile[200];
07798 Matrix33 h0, h1; Vector3 c0,c1;
07799
07800 INFO("splicecn");
07801 dir=(int)input[0];
07802 w=input[1];
07803 if((dir<=0)||(dir>=4)) return;
07804 dir--;
07805
07806
07807 np0=_NP; h0=_H;
07808 writefinalcnfile(zipfiles,false);
07809
07810
07811 readcn();
07812 np1=_NP; h1=_H;
07813
07814 sprintf(tmpfile,"tmp.cn");
07815
07816 sprintf(cmd,"echo %d > %s",np0+np1,tmpfile);
07817 INFO_Printf("%s\n",cmd); system(cmd);
07818 sprintf(cmd,"head -%d %s | tail -%d >> %s",np0+1,finalcnfile,np0,tmpfile);
07819 INFO_Printf("%s\n",cmd); system(cmd);
07820 sprintf(cmd,"head -%d %s | tail -%d >> %s",np1+4,incnfile, np1+3,tmpfile);
07821 INFO_Printf("%s\n",cmd); system(cmd);
07822
07823 sprintf(cmd,"echo %d ", nspecies);
07824 for(i=0;i<nspecies;i++)
07825 sprintf(cmd,"%s %s ",cmd,element[i]);
07826 sprintf(cmd,"%s >> %s",cmd,tmpfile);
07827 INFO_Printf("%s\n",cmd); system(cmd);
07828
07829 strcpy(incnfile,tmpfile);
07830 readcn();
07831
07832 c0.set(h0[0][dir],h0[1][dir],h0[2][dir]);
07833 c1.set(h1[0][dir],h1[1][dir],h1[2][dir]);
07834 ratio=c0.norm()/c1.norm();
07835
07836 _NP = np0 + np1;
07837
07838 for(i=0;i<np0;i++)
07839 _SR[i][dir]=(_SR[i][dir]+0.5)*ratio/(ratio+1)-0.5;
07840
07841 for(i=np0;i<_NP;i++)
07842 _SR[i][dir]=(_SR[i][dir]-0.5)/(ratio+1)+0.5;
07843
07844 _H[0][dir]=c0[0]+c1[0];
07845 _H[1][dir]=c0[1]+c1[1];
07846 _H[2][dir]=c0[2]+c1[2];
07847
07848 SHtoR();
07849
07850 writefinalcnfile(zipfiles,false);
07851 }
07852
07853 #if 0
07854 void MDFrame::splicecn()
07855 {
07856
07857
07858
07859
07860
07861
07862
07863
07864
07865 int i, dir;
07866 int *species0, *group0;
07867 Matrix33 h0; int np0; double ratio;
07868 Vector3 c,c0;
07869 double w;
07870 double alpha;
07871
07872 INFO("splicecn");
07873 dir=(int)input[0];
07874 w=input[1];
07875 if((dir<=0)||(dir>=4)) return;
07876 dir--;
07877
07878 species0 = (int *) malloc(sizeof(int)*_NP*allocmultiple);
07879 group0 = (int *) malloc(sizeof(int)*_NP*allocmultiple);
07880
07881 for(i=0;i<_NP;i++)
07882 {
07883
07884 _R0[i]=_SR[i];
07885 species0[i]=species[i];
07886 group0[i]=group[i];
07887 }
07888 h0=_H; np0=_NP;
07889 readcn();
07890
07891 c.set(_H[0][dir],_H[1][dir],_H[2][dir]);
07892 c0.set(h0[0][dir],h0[1][dir],h0[2][dir]);
07893 ratio=c0.norm()/c.norm();
07894
07895 for(i=0;i<_NP;i++)
07896 {
07897
07898 _R0[i+np0]=_SR[i];
07899 species0[i+np0]=species[i];
07900 group0[i+np0]=group[i];
07901 }
07902
07903 for(i=0;i<np0;i++)
07904 {
07905 if(w<0.001)
07906 alpha=1;
07907 else
07908 {
07909 if(_R0[i][dir]<(-0.5+w/2))
07910 {
07911 alpha=(0.5+_R0[i][dir])/w+0.5;
07912 }
07913 else if(_R0[i][dir]>(0.5-w/2))
07914 {
07915 alpha=(0.5-_R0[i][dir])/w+0.5;
07916 }
07917 else
07918 alpha=1;
07919 }
07920
07921 _SR[i]=_R0[i]*alpha+_R0[i+np0]*(1-alpha);
07922 _SR[i][dir]=(_R0[i][dir]+0.5)*ratio/(ratio+1)-0.5;
07923 species[i]=species0[i];
07924 group[i]=group0[i];
07925 }
07926 for(i=np0;i<np0+_NP;i++)
07927 {
07928 if(w<0.001)
07929 alpha=1;
07930 else
07931 {
07932 if(_R0[i][dir]<(-0.5+w/2))
07933 {
07934 alpha=(0.5+_R0[i][dir])/w+0.5;
07935 }
07936 else if(_R0[i][dir]>(0.5-w/2))
07937 {
07938 alpha=(0.5-_R0[i][dir])/w+0.5;
07939 }
07940 else
07941 alpha=1;
07942 }
07943
07944 _SR[i]=_R0[i]*alpha+_R0[i-np0]*(1-alpha);
07945 _SR[i][dir]=(_R0[i][dir]-0.5)/(ratio+1)+0.5;
07946 species[i]=species0[i];
07947 group[i]=group0[i];
07948 }
07949
07950 _H[0][dir]=c[0]+c0[0];
07951 _H[1][dir]=c[1]+c0[1];
07952 _H[2][dir]=c[2]+c0[2];
07953 _NP+=np0;
07954 SHtoR();
07955
07956 free(species0);
07957 free(group0);
07958
07959 INFO("splicecn: new NP="<<_NP);
07960 }
07961 #endif
07962
07963
07964 void MDFrame::cutpastecn()
07965 {
07966
07967
07968
07969
07970
07971
07972
07973
07974
07975
07976 int i,j,jpt,minj,dir,dirx,diry; double s0, s1, ds, mind, dis;
07977 Matrix33 h0; Vector3 sij;
07978
07979 dir=(int)input[0];
07980 if((dir<1)||(dir>3)) return;
07981 dir--;
07982 dirx=(dir+1)%3; diry=(dir+2)%3;
07983 s0=input[1];
07984 s1=input[2];
07985 ds=input[3];
07986
07987
07988 for(i=0;i<_NP;i++)
07989 {
07990 _VSR[i]=_SR[i];
07991 }
07992 h0=_H;
07993
07994 initcn.open(incnfile,LFile::O_Read);
07995 initcn.read(this);
07996 for(i=0;i<_NP;i++)
07997 {
07998 _R0[i]=_SR[i];
07999 }
08000 _H=h0;
08001 for(i=0;i<_NP;i++)
08002 {
08003 _SR[i]=_VSR[i];
08004 }
08005 for(i=0;i<_NP;i++)
08006 {
08007 if(fixed[i]) continue;
08008 if((_R0[i][dir]<s0)||(_R0[i][dir]>=s1)) continue;
08009 mind=100; minj=-1;
08010 for(j=0;j<nn[i];j++)
08011 {
08012 jpt=nindex[i][j];
08013 sij=_R0[i]-_R0[jpt]; sij[dir]-=ds; sij.subint();
08014 dis=sij.norm();
08015 if(dis<mind)
08016 {
08017 mind=dis;
08018 minj=jpt;
08019 }
08020 }
08021 if(mind>1e-4)
08022 {
08023 ERROR("cutpastecn: mind("<<mind<<") > 1e-4");
08024 }
08025 _SR[i][dirx]=_VSR[minj][dirx];
08026 _SR[i][diry]=_VSR[minj][diry];
08027 _SR[i][dir]=_VSR[minj][dir]+ds;
08028 }
08029 SHtoR();
08030 }
08031
08032 void MDFrame::setconfig1()
08033 {
08034
08035
08036 Realloc(_SR1,Vector3,_NP);
08037 memcpy(_SR1, _SR, sizeof(Vector3)*_NP);
08038 }
08039
08040 void MDFrame::setconfig2()
08041 {
08042
08043
08044 Realloc(_SR2,Vector3,_NP);
08045 memcpy(_SR2, _SR, sizeof(Vector3)*_NP);
08046
08047
08048 Realloc(_SR3,Vector3,_NP);
08049 memset(_SR3, 0, sizeof(Vector3)*_NP);
08050 }
08051
08052 void MDFrame::copytoconfig1(int ind)
08053 {
08054 int i;
08055 for(i=0;i<_NP;i++)
08056 _SR1[i][ind] = _SR[i][ind];
08057 }
08058
08059 void MDFrame::copytoconfig2(int ind)
08060 {
08061 int i;
08062 for(i=0;i<_NP;i++)
08063 _SR2[i][ind] = _SR[i][ind];
08064 }
08065
08066 void MDFrame::switchconfig()
08067 {
08068
08069 int i;
08070 if((_SR1!=NULL)&&(_SR2!=NULL))
08071 {
08072 for(i=0;i<_NP;i++)
08073 {
08074 _SR[i]-=_SR1[i];
08075 _SR[i]+=_SR2[i];
08076 }
08077 }
08078 else
08079 {
08080 ERROR("MDFrame::switchconfig _SR1 _SR2 not loaded");
08081 }
08082 }
08083
08084 void MDFrame::replacefreeatom()
08085 {
08086 int i;
08087 Matrix33 h0;
08088
08089 for(i=0;i<_NP;i++)
08090 {
08091 _R0[i]=_SR[i];
08092 }
08093 h0=_H;
08094 readcn();
08095
08096 for(i=0;i<_NP;i++)
08097 {
08098 if(fixed[i])
08099 {
08100 _SR[i]=_R0[i];
08101 }
08102 }
08103 _H=h0;
08104
08105 SHtoR();
08106 }
08107
08108 void MDFrame::relabelatom()
08109 {
08110
08111
08112
08113 int n0, n1;
08114 Vector3 s0;
08115 n0=(int)input[0];
08116 n1=(int)input[1];
08117 if(n0==n1) return;
08118 if((n0<0)||(n0>_NP)) {FATAL("relabelatom n0 out of range");}
08119 if((n1<0)||(n1>_NP)) {FATAL("relabelatom n0 out of range");}
08120 s0=_SR[n0];
08121 if(n1<n0)
08122 memmove(_SR+n1+1,_SR+n1,sizeof(Vector3)*(n0-n1));
08123 else
08124 memmove(_SR+n0,_SR+n0+1,sizeof(Vector3)*(n0-n1));
08125 _SR[n1]=s0;
08126 }
08127
08128
08129 void MDFrame::moveatom()
08130 {
08131
08132
08133
08134
08135
08136
08137
08138
08139
08140 int i, n, id, fix;
08141 double mx, my, mz;
08142 double x0, y0, z0, r, r2, dmin, dmax;
08143 Vector3 s0, ds, dr;
08144
08145 n=(int)input[0];
08146
08147 INFO_Printf("n=%d\n",n);
08148
08149 if(n>0)
08150 {
08151 mx=input[1];
08152 my=input[2];
08153 mz=input[3];
08154
08155 SHtoR();
08156 for(i=0;i<n;i++)
08157 {
08158 id=(int)input[4+i];
08159 _R[id].x+=mx;
08160 _R[id].y+=my;
08161 _R[id].z+=mz;
08162 }
08163 RHtoS();
08164 }
08165 else if(n==-2)
08166 {
08167
08168 }
08169 if(n==0)
08170 {
08171 INFO("move atoms in circular plate");
08172 x0=input[1];
08173 y0=input[2];
08174 z0=input[3];
08175 r =input[4];
08176 dmin=input[5];
08177 dmax=input[6];
08178 mx=input[7];
08179 my=input[8];
08180 mz=input[9];
08181 fix=(int)input[10];
08182
08183 r2=r*r;
08184 s0.set(x0,y0,z0);
08185 for(i=0;i<_NP;i++)
08186 {
08187 if((_SR[i].y>=dmax)||(_SR[i].y<dmin)) continue;
08188 if(fix)
08189 {
08190 fixed[i]=1;
08191 INFO_Printf("fix atom %d in plane\n",i);
08192 }
08193 ds=_SR[i]-s0;
08194 ds.subint();
08195
08196 dr=_H*ds;
08197 if(dr.norm2()>r2) continue;
08198
08199 _SR[i].x+=mx;
08200 _SR[i].y+=my;
08201 _SR[i].z+=mz;
08202 INFO_Printf("move atom %d\n",i);
08203 }
08204
08205 SHtoR();
08206 }
08207 return;
08208 }
08209
08210 void MDFrame::movegroup()
08211 {
08212
08213
08214
08215
08216
08217
08218
08219
08220
08221 int i, n, id, ip;
08222 double mx, my, mz;
08223
08224 n=(int)input[0];
08225
08226 INFO_Printf("n=%d\n",n);
08227
08228 if(n>0)
08229 {
08230 SHtoR();
08231 mx=input[1];
08232 my=input[2];
08233 mz=input[3];
08234
08235 SHtoR();
08236 for(i=0;i<n;i++)
08237 {
08238 id=(int)input[4+i];
08239 for(ip=0;ip<_NP;ip++)
08240 {
08241 if(group[ip]==id)
08242 {
08243 _R[ip].x+=mx;
08244 _R[ip].y+=my;
08245 _R[ip].z+=mz;
08246 }
08247 }
08248 }
08249 RHtoS();
08250 }
08251 return;
08252 }
08253
08254 void MDFrame::setgroupcomvel()
08255 {
08256
08257
08258
08259
08260
08261
08262
08263
08264
08265 int i, n, id, ip;
08266 double vx, vy, vz, totmass;
08267 Vector3 vcom; Matrix33 hinv;
08268
08269 n=(int)input[0];
08270
08271 INFO_Printf("n=%d\n",n);
08272
08273 if(n>0)
08274 {
08275 SHtoR();
08276 vx=input[1];
08277 vy=input[2];
08278 vz=input[3];
08279
08280 totmass=0;
08281 for(ip=0;ip<_NP;ip++)
08282 _VR[ip]=_H*_VSR[ip];
08283
08284 for(i=0;i<n;i++)
08285 {
08286 id=(int)input[4+i];
08287 for(ip=0;ip<_NP;ip++)
08288 {
08289 if(fixed[ip]) continue;
08290 if(group[ip]==id)
08291 {
08292 vcom+=_VR[ip]*_ATOMMASS[species[ip]];
08293 totmass+=_ATOMMASS[species[ip]];
08294 }
08295 }
08296 }
08297 INFO("totmass="<<totmass<<" vcom="<<vcom);
08298 if(totmass==0)
08299 WARNING("no atoms have the specified group(s)");
08300 else
08301 {
08302 vcom/=totmass;
08303 vcom.x-=vx; vcom.y-=vy; vcom.z-=vz;
08304 for(i=0;i<n;i++)
08305 {
08306 id=(int)input[4+i];
08307 for(ip=0;ip<_NP;ip++)
08308 {
08309 if(fixed[ip]) continue;
08310 if(group[ip]==id)
08311 {
08312 _VR[ip]-=vcom;
08313 }
08314 }
08315 }
08316 }
08317
08318 hinv=_H.inv();
08319 for(ip=0;ip<_NP;ip++)
08320 _VSR[ip]=hinv*_VR[ip];
08321 }
08322 return;
08323 }
08324
08325 void MDFrame::printatoms_in_sphere()
08326 {
08327
08328
08329
08330
08331
08332
08333
08334 int i, n; double r2; Vector3 r0, s0, ds, dr; Matrix33 hinv;
08335 hinv=_H.inv();
08336 r0.set(input[0],input[1],input[2]);
08337 r2=input[3]*input[3];
08338 s0=hinv*r0;
08339 n=0;
08340 for(i=0;i<_NP;i++)
08341 {
08342 ds=_SR[i]-s0;
08343 ds.subint();
08344 dr=_H*ds;
08345 if(dr.norm2()<r2)
08346 {
08347 n++;
08348 }
08349 }
08350 INFO_Printf("\n%d ",n);
08351 for(i=0;i<_NP;i++)
08352 {
08353 ds=_SR[i]-s0;
08354 ds.subint();
08355 dr=_H*ds;
08356 if(dr.norm2()<r2)
08357 {
08358 INFO_Printf("%d ",i);
08359 }
08360 }
08361 INFO_Printf("\n");
08362 }
08363
08364 void MDFrame::pbcshiftatom()
08365 {
08366 int i;
08367 double dx,dy,dz;
08368 dx=input[0];
08369 dy=input[1];
08370 dz=input[2];
08371
08372 for(i=0;i<_NP;i++)
08373 {
08374 _SR[i].x+=dx;_SR[i].y+=dy;_SR[i].z+=dz;
08375 _SR[i].subint();
08376 }
08377 SHtoR();
08378 }
08379
08380
08381
08382
08383 void MDFrame::fixatoms_by_ID()
08384 {
08385
08386
08387
08388
08389
08390
08391 int i, n;
08392 n=(int)input[0];
08393
08394
08395
08396
08397 for(i=1;i<=n;i++)
08398 {
08399 fixed[(int)input[i]]=1;
08400 }
08401 _NPfixed=_NPfree=0;
08402 for(i=0;i<_NP;i++)
08403 {
08404 if(fixed[i]==1) _NPfixed++;
08405 if(fixed[i]==0) _NPfree++;
08406 }
08407 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08408 }
08409
08410 void MDFrame::fixatoms_by_position()
08411 {
08412
08413
08414
08415
08416
08417
08418
08419
08420
08421
08422
08423
08424
08425
08426 int i, enable, nfixed, ind, inda, indb;
08427 double xmin, xmax, ymin, ymax, zmin, zmax;
08428 double x0, y0, z0, rmin, rmax, ra0, rb0, sqrra, sqrrb, sqrr;
08429
08430 enable=(int)input[0];
08431 nfixed=0;
08432
08433 if(enable == 1)
08434 {
08435 xmin=input[1];
08436 xmax=input[2];
08437 ymin=input[3];
08438 ymax=input[4];
08439 zmin=input[5];
08440 zmax=input[6];
08441
08442 INFO_Printf("setfixedatoms = [\n");
08443 nfixed=0;
08444 for(i=0;i<_NP;i++)
08445 {
08446 if((_SR[i].x>=xmin)&&(_SR[i].x<xmax)
08447 &&(_SR[i].y>=ymin)&&(_SR[i].y<ymax)
08448 &&(_SR[i].z>=zmin)&&(_SR[i].z<zmax))
08449 {
08450 fixed[i]=1;
08451 nfixed++;
08452 }
08453 }
08454 INFO_Printf("%d\n",nfixed);
08455 for(i=0;i<_NP;i++)
08456 {
08457 if((_SR[i].x>=xmin)&&(_SR[i].x<xmax)
08458 &&(_SR[i].y>=ymin)&&(_SR[i].y<ymax)
08459 &&(_SR[i].z>=zmin)&&(_SR[i].z<zmax))
08460 {
08461 INFO_Printf("%d ",i);
08462 }
08463 }
08464 }
08465 else if(enable == 2)
08466 {
08467 ind = (int)input[1]; ind--;
08468 x0 = input[2];
08469 y0 = input[3];
08470 z0 = input[4];
08471 rmin = input[5];
08472 rmax = input[6];
08473
08474
08475 inda = (ind+1)%3; indb = (inda+1)%3;
08476 ra0 = input[(inda+2)]; rb0 = input[(indb+2)];
08477
08478 switch (ind)
08479 {
08480 case 0: INFO_Printf("Cylindrical axis: x\n"); break;
08481 case 1: INFO_Printf("Cylindrical axis: y\n"); break;
08482 case 2: INFO_Printf("Cylindrical axis: z\n"); break;
08483 }
08484 INFO_Printf("Atoms whose radial distance between "
08485 "%f and %f will be fixed.\n", rmin, rmax);
08486 INFO_Printf("setfixedatoms = [\n");
08487
08488 for(i=0;i<_NP;i++)
08489 {
08490 sqrra = (_SR[i][inda] - ra0)*(_SR[i][inda] - ra0);
08491 sqrrb = (_SR[i][indb] - rb0)*(_SR[i][indb] - rb0);
08492
08493 sqrr = sqrra + sqrrb;
08494
08495
08496
08497
08498
08499
08500 if ((sqrr >= rmin*rmin) && (sqrr < rmax*rmax))
08501 {
08502 INFO_Printf("%d ",i);
08503 fixed[i]=1;
08504 nfixed++;
08505 }
08506 }
08507 }
08508 INFO_Printf("\n]\n");
08509 INFO_Printf("%d atoms fixed\n",nfixed);
08510 _NPfixed=_NPfree=0;
08511 for(i=0;i<_NP;i++)
08512 {
08513 if(fixed[i]==1) _NPfixed++;
08514 if(fixed[i]==0) _NPfree++;
08515 }
08516 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08517 }
08518
08519 void MDFrame::fixatoms_by_group(double *myinput)
08520 {
08521
08522
08523
08524
08525
08526
08527
08528 int i, j, NgrpID, nfixed;
08529 NgrpID = (int) myinput[0];
08530
08531 INFO("Number of groups to be fixed: "<<NgrpID);
08532
08533 if (NgrpID <= 0 )
08534 {
08535 ERROR("Number of groups to be fixed should be greater than zero.");
08536 return;
08537 }
08538
08539 INFO_Printf("fixedatomID = [\n");
08540 nfixed = 0;
08541 for (i=0;i<_NP;i++)
08542 {
08543 if (fixed[i]==1)
08544 continue;
08545 else
08546 {
08547 for (j=0; j<NgrpID; j++)
08548 {
08549 if (group[i]==(int) myinput[j+1])
08550 {
08551 fixed[i] = 1; nfixed++;
08552 INFO_Printf("%d ",i);
08553 break;
08554 }
08555 }
08556 }
08557 }
08558 INFO_Printf("\n]\n");
08559 INFO("Number of fixed atoms: "<<nfixed);
08560 _NPfixed=_NPfree=0;
08561 for(i=0;i<_NP;i++)
08562 {
08563 if(fixed[i]==1) _NPfixed++;
08564 if(fixed[i]==0) _NPfree++;
08565 }
08566 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08567 }
08568
08569 void MDFrame::fixatoms_by_species(double *myinput)
08570 {
08571
08572
08573
08574
08575
08576
08577
08578 int i, j, N_species, nfixed;
08579 N_species = (int) myinput[0];
08580
08581 INFO("Number of species to be fixed: "<<N_species);
08582
08583 if (N_species <= 0 )
08584 {
08585 ERROR("Number of species to be fixed should be greater than zero.");
08586 return;
08587 }
08588
08589 INFO_Printf("fixedatomID = [\n");
08590 nfixed = 0;
08591 for (i=0;i<_NP;i++)
08592 {
08593 if (fixed[i]==1)
08594 continue;
08595 else
08596 {
08597 for (j=0; j<N_species; j++)
08598 {
08599 if (species[i]==(int) myinput[j+1])
08600 {
08601 fixed[i] = 1; nfixed++;
08602 INFO_Printf("%d ",i);
08603 break;
08604 }
08605 }
08606 }
08607 }
08608 INFO_Printf("\n]\n");
08609 INFO("Number of fixed atoms: "<<nfixed);
08610 _NPfixed=_NPfree=0;
08611 for(i=0;i<_NP;i++)
08612 {
08613 if(fixed[i]==1) _NPfixed++;
08614 if(fixed[i]==0) _NPfree++;
08615 }
08616 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08617 }
08618
08619 void MDFrame::fixatoms_by_pos_topol()
08620 {
08621
08622
08623
08624
08625
08626
08627
08628
08629
08630
08631
08632
08633 int i, n, nfixed;
08634 double xmin, xmax, ymin, ymax, zmin, zmax, tmin, tmax;
08635 n=(int)input[0];
08636 xmin=input[1];
08637 xmax=input[2];
08638 ymin=input[3];
08639 ymax=input[4];
08640 zmin=input[5];
08641 zmax=input[6];
08642 tmin=input[7];
08643 tmax=input[8];
08644
08645 INFO_Printf("setfixedatoms = [\n");
08646 nfixed=0;
08647 for(i=0;i<_NP;i++)
08648 {
08649
08650 if((_SR[i].x>=xmin)&&(_SR[i].x<xmax)
08651 &&(_SR[i].y>=ymin)&&(_SR[i].y<ymax)
08652 &&(_SR[i].z>=zmin)&&(_SR[i].z<zmax)
08653 &&(_TOPOL[i]>=tmin)&&(_TOPOL[i]<tmax))
08654 {
08655 fixed[i]=1;
08656 nfixed++;
08657 }
08658 }
08659 INFO_Printf("%d\n",nfixed);
08660 for(i=0;i<_NP;i++)
08661 {
08662 if((_SR[i].x>=xmin)&&(_SR[i].x<xmax)
08663 &&(_SR[i].y>=ymin)&&(_SR[i].y<ymax)
08664 &&(_SR[i].z>=zmin)&&(_SR[i].z<zmax)
08665 &&(_TOPOL[i]>=tmin)&&(_TOPOL[i]<tmax))
08666 {
08667 INFO_Printf("%d ",i);
08668 }
08669 }
08670 INFO_Printf("\n]\n");
08671 INFO_Printf("%d atoms fixed\n",nfixed);
08672 _NPfixed=_NPfree=0;
08673 for(i=0;i<_NP;i++)
08674 {
08675 if(fixed[i]==1) _NPfixed++;
08676 if(fixed[i]==0) _NPfree++;
08677 }
08678 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08679 }
08680
08681 void MDFrame::fixallatoms()
08682 {
08683 int i;
08684
08685 for(i=0;i<_NP;i++)
08686 {
08687 fixed[i]=1;
08688 }
08689 _NPfixed=_NPfree=0;
08690 for(i=0;i<_NP;i++)
08691 {
08692 if(fixed[i]==1) _NPfixed++;
08693 if(fixed[i]==0) _NPfree++;
08694 }
08695 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08696 }
08697
08698 void MDFrame::freeallatoms()
08699 {
08700 int i;
08701
08702 for(i=0;i<_NP;i++)
08703 {
08704 fixed[i]=0;
08705 }
08706 _NPfixed=_NPfree=0;
08707 for(i=0;i<_NP;i++)
08708 {
08709 if(fixed[i]==1) _NPfixed++;
08710 if(fixed[i]==0) _NPfree++;
08711 }
08712 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08713 }
08714
08715 void MDFrame::reversefixedatoms()
08716 {
08717 int i;
08718
08719 for(i=0;i<_NP;i++)
08720 {
08721 if(fixed[i]==0) fixed[i]=1;
08722 else if(fixed[i]==1) fixed[i]=0;
08723 }
08724 _NPfixed=_NPfree=0;
08725 for(i=0;i<_NP;i++)
08726 {
08727 if(fixed[i]==1) _NPfixed++;
08728 if(fixed[i]==0) _NPfree++;
08729 }
08730 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08731 }
08732
08733 void MDFrame::constrain_fixedatoms()
08734 {
08735 int i, nc;
08736
08737 nc=0;
08738 for(i=0;i<_NP;i++)
08739 {
08740 if(fixed[i]==1)
08741 {
08742 nc++;
08743 if (nc>=MAXCONSTRAINATOMS)
08744 {
08745 ERROR("MAXCONSTRAINATOMS exceeded. You need to change the defined value in md.h");
08746 continue;
08747 }
08748 constrainatoms[nc]=i;
08749 }
08750 }
08751 constrainatoms[0]=nc;
08752 }
08753
08754 void MDFrame::fix_constrainedatoms()
08755 {
08756 int i, nc;
08757
08758 nc=constrainatoms[0];
08759 for(i=1;i<=nc;i++)
08760 {
08761 fixed[constrainatoms[i]]=1;
08762 }
08763 INFO_Printf("%d atoms fixed\n",nc);
08764 _NPfixed=_NPfree=0;
08765 for(i=0;i<_NP;i++)
08766 {
08767 if(fixed[i]==1) _NPfixed++;
08768 if(fixed[i]==0) _NPfree++;
08769 }
08770 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08771 }
08772
08773 void MDFrame::setfixedatomsspecies()
08774 {
08775
08776 int i;
08777 for(i=0;i<_NP;i++)
08778 {
08779 if(fixed[i]==1)
08780 species[i]=(int)input[0];
08781 }
08782 }
08783
08784 void MDFrame::setfixedatomsgroup()
08785 {
08786
08787 int i;
08788 for(i=0;i<_NP;i++)
08789 {
08790 if(fixed[i]==1)
08791 group[i]=(int)input[0];
08792 }
08793 }
08794
08795 void MDFrame::reversespecies()
08796 {
08797
08798 int i;
08799 for(i=0;i<_NP;i++)
08800 {
08801 if(species[i]==0)
08802 species[i]=1;
08803 else if(species[i]==1)
08804 species[i]=0;
08805 }
08806 }
08807
08808 void MDFrame::removefixedatoms()
08809 {
08810 int i, j;
08811
08812 j=0;
08813 for(i=0;i<_NP;i++)
08814 {
08815 if(fixed[i]==0)
08816 {
08817 _SR[j]=_SR[i];
08818 fixed[j]=fixed[i];
08819 species[j]=species[i];
08820 _EPOT_IND[j]=_EPOT_IND[i];
08821 _TOPOL[j]=_TOPOL[i];
08822 j++;
08823 }
08824 }
08825 _NP=j;
08826 SHtoR();
08827 _NPfixed=_NPfree=0;
08828 for(i=0;i<_NP;i++)
08829 {
08830 if(fixed[i]==1) _NPfixed++;
08831 if(fixed[i]==0) _NPfree++;
08832 }
08833 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08834 }
08835
08836 void MDFrame::markremovefixedatoms()
08837 {
08838 int i;
08839
08840 for(i=0;i<_NP;i++)
08841 {
08842 if(fixed[i]==1)
08843 {
08844 fixed[i]=-1;
08845 }
08846 }
08847 _NPfixed=_NPfree=0;
08848 for(i=0;i<_NP;i++)
08849 {
08850 if(fixed[i]==1) _NPfixed++;
08851 if(fixed[i]==0) _NPfree++;
08852 }
08853 INFO_Printf("NPfixed = %d, NPfree = %d\n",_NPfixed,_NPfree);
08854 }
08855
08856 void MDFrame::movefixedatoms()
08857 {
08858 int i;
08859
08860 for(i=0;i<_NP;i++)
08861 {
08862 if(fixed[i]==1)
08863 {
08864 _SR[i].x+=input[0];
08865 _SR[i].y+=input[1];
08866 _SR[i].z+=input[2];
08867 }
08868 }
08869 }
08870
08871 void MDFrame::removeellipsoid()
08872 {
08873
08874
08875
08876
08877
08878
08879
08880
08881
08882 int i, n, removenum;
08883 double x0, y0, z0, arem, brem, crem;
08884 Vector3 r0, dr;
08885
08886 if(input[0]==0)
08887 {
08888 INFO_Printf("input = [%f %f %f ]\n",
08889 input[0],input[1],input[2]);
08890 ERROR("removeellipsoid(): no geometry set");
08891 return;
08892 }
08893
08894
08895 x0=input[1];
08896 y0=input[2];
08897 z0=input[3];
08898 arem=input[4];
08899 brem=input[5];
08900 crem=input[6];
08901
08902 r0.set(x0,y0,z0);
08903
08904
08905 SHtoR();
08906 for(i=0;i<_NP;i++)
08907 {
08908 dr = _R[i]-r0;
08909 dr.x/=arem;
08910 dr.y/=brem;
08911 dr.z/=crem;
08912 if(dr.norm2()<=1)
08913 fixed[i]=-1;
08914 }
08915
08916
08917 n=0; SHtoR();
08918 removenum=0;
08919 for(i=0;i<_NP;i++)
08920 {
08921 if(fixed[i]!=-1)
08922 {
08923 _R0[n]=_R[i];
08924 fixed[n]=fixed[i];
08925 n++;
08926 }
08927 else
08928 {
08929 removenum++;
08930 }
08931 }
08932 INFO("originally "<<_NP<<" atoms");
08933 INFO("remove "<<removenum<<" atoms");
08934 _NP-=removenum;
08935 INFO("now "<<_NP<<" atoms");
08936 R0toR(); RHtoS();
08937 INFO("NP="<<_NP<<" n="<<n);
08938 }
08939
08940 void MDFrame::removerectbox()
08941 {
08942
08943
08944
08945
08946 int i, j, assist, plotonly, outside;
08947 Vector3 ds, dss, sa, sb, sc, s0;
08948 Vector3 ha, hb, hc;
08949 Matrix33 sh, shinv, latt, lattinv;
08950
08951 ha.set(latticesize[0][0],latticesize[0][1],latticesize[0][2]);
08952 hb.set(latticesize[1][0],latticesize[1][1],latticesize[1][2]);
08953 hc.set(latticesize[2][0],latticesize[2][1],latticesize[2][2]);
08954 ha*=latticesize[0][3];
08955 hb*=latticesize[1][3];
08956 hc*=latticesize[2][3];
08957 latt.setcol(ha,hb,hc);
08958 lattinv=latt.inv();
08959
08960 sa.set(input[0],input[1],input[2]);
08961 sb.set(input[4],input[5],input[6]);
08962 sc.set(input[8],input[9],input[10]);
08963 sa*=input[3];
08964 sb*=input[7];
08965 sc*=input[11];
08966 s0.set(input[12],input[13],input[14]);
08967 assist=(int)input[15];
08968 plotonly=(int)input[16];
08969 outside=(int)input[17];
08970
08971 sa=lattinv*sa;
08972 sb=lattinv*sb;
08973 sc=lattinv*sc;
08974 s0=lattinv*s0;
08975
08976 INFO("assist="<<assist);
08977 INFO("plotonly="<<plotonly);
08978
08979 sh.setcol(sa,sb,sc);
08980 shinv=sh.inv();
08981 INFO("vol="<<sh.det());
08982 INFO("s0="<<s0);
08983
08984 for(i=0;i<_NP;i++)
08985 {
08986 ds=_SR[i]-s0;
08987
08988 dss=shinv*ds;
08989 if(assist&&(!plotonly))
08990 {
08991 if((dss.x>=-0.5)&&(dss.x<0.5)&&
08992 (dss.y>=-0.5)&&(dss.y<0.5))
08993 {
08994 if(fabs(dss.z)<2)
08995 {
08996 if((dss.z>=-0.5)&&(dss.z<0.5))
08997 {
08998 fixed[i]=-1;
08999 }
09000 else if(dss.z>0.5)
09001 {
09002 dss.z=(dss.z-0.5)/(2-0.5)*(2-0.1)+0.1-dss.z;
09003 dss.x=0; dss.y=0;
09004 INFO("dss="<<dss);
09005 _SR[i]+=sh*dss;
09006 }
09007 else
09008 {
09009 dss.z=(dss.z+0.5)/(-2+0.5)*(-2+0.1)-0.1-dss.z;
09010 dss.x=0; dss.y=0;
09011 INFO("dss="<<dss);
09012 _SR[i]+=sh*dss;
09013 }
09014 }
09015 }
09016 }
09017 else
09018 {
09019 if((dss.x>=-0.5)&&(dss.x<0.5)&&
09020 (dss.y>=-0.5)&&(dss.y<0.5)&&
09021 (dss.z>=-0.5)&&(dss.z<0.5))
09022 {
09023 fixed[i]=-1;
09024 }
09025 }
09026 }
09027 if(outside)
09028 {
09029 for(i=0;i<_NP;i++)
09030 {
09031 if(fixed[i]==-1)
09032 {
09033 fixed[i]=0;
09034 }
09035 else if(fixed[i]==0)
09036 {
09037 fixed[i]=-1;
09038 }
09039 }
09040 }
09041 if(!plotonly)
09042 {
09043 j=0;
09044 for(i=0;i<_NP;i++)
09045 {
09046 if(fixed[i]!=-1)
09047 {
09048 _SR[j]=_SR[i];
09049 fixed[j]=0;
09050 if(_SAVEMEMORY<8)
09051 _EPOT_IND[j]=_EPOT_IND[i];
09052 if(_SAVEMEMORY<6)
09053 _TOPOL[j]=_TOPOL[i];
09054 j++;
09055 }
09056 }
09057 INFO("removerectbox: "<<_NP-j<<" of atoms removed");
09058 _NP=j;
09059 INFO("new number of atoms "<<_NP);
09060 if(_SAVEMEMORY<9)
09061 SHtoR();
09062 }
09063 }
09064
09065 void MDFrame::removeoverlapatoms()
09066 {
09067
09068
09069
09070
09071 int i, j, jpt;
09072 double removerc, rc2;
09073 Vector3 ds, dr;
09074
09075 refreshneighborlist();
09076
09077 removerc = input[0];
09078
09079 rc2=removerc*removerc;
09080 for(i=0;i<_NP;i++)
09081 {
09082 for(j=0;j<nn[i];j++)
09083 {
09084 jpt=nindex[i][j];
09085 ds=_SR[i]-_SR[jpt];
09086 ds.subint();
09087 dr=_H*ds;
09088 if(dr.norm2()<rc2)
09089 {
09090 fixed[i]=-1;
09091 if(fixed[jpt]==-1) fixed[i]=0;
09092 }
09093 }
09094 }
09095 j=0;
09096 for(i=0;i<_NP;i++)
09097 {
09098 if(fixed[i]!=-1)
09099 {
09100 _SR[j]=_SR[i];
09101 fixed[j]=0;
09102 j++;
09103 }
09104 }
09105 _NP=j;
09106 SHtoR();
09107 }
09108
09109 void MDFrame::findcenterofmass(class Vector3 *sr)
09110 {
09111
09112 int i;
09113 double totalmass;
09114
09115 _COM.clear();
09116 totalmass=0;
09117
09118 if(nspecies==1)
09119 {
09120 for(i=0;i<_NP;i++)
09121 _COM+=sr[i];
09122 _COM/=_NP;
09123 }
09124 else if (nspecies > 1)
09125 {
09126 for(i=0;i<_NP;i++)
09127 {
09128 _COM+=sr[i]*_ATOMMASS[species[i]];
09129 totalmass+=_ATOMMASS[species[i]];
09130 }
09131 _COM/=totalmass;
09132 }
09133 else
09134 ERROR("Number of species("<<nspecies<<") must be positive integer!!");
09135
09136 INFO("_COM = ("<<_COM<<")");
09137 }
09138
09139 void MDFrame::translate_com()
09140 {
09141 int i;
09142 Vector3 com, com1, dcom;
09143
09144
09145
09146
09147
09148
09149
09150
09151 com.clear();
09152 com1.clear();
09153
09154 INFO("In config1, ");
09155 findcenterofmass(_SR1); com1=_COM;
09156 INFO("In current config, ");
09157 findcenterofmass(_SR); com=_COM;
09158
09159 dcom = com1 - com;
09160 INFO("dcom = ("<<dcom<<")");
09161
09162 for(i=0;i<_NP;i++)
09163 _SR[i]+=dcom;
09164 }
09165
09166
09167 void MDFrame::rotate_com()
09168 {
09169 int index, i;
09170 Vector3 r, r1, dr, ds;
09171 Vector3 com, com1, dcom;
09172 double J, R2, alpha;
09173 Matrix33 hinv;
09174
09175
09176 index = (int) input[0] - 1;
09177
09178 if(index<0)
09179 FATAL("rotate_com: index ("<<index<<") is not valid!");
09180
09181 if(index!=2)
09182 FATAL("rotate_com: index ("<<index<<") is not valid!");
09183
09184
09185
09186
09187 com.clear(); com1.clear();
09188
09189 if(nspecies==1)
09190 {
09191 INFO("In config1, ");
09192 findcenterofmass(_SR1); com1=_COM;
09193 INFO("In current config, ");
09194 findcenterofmass(_SR); com=_COM;
09195 }
09196 else
09197 {
09198 FATAL("rotate_com not implemented for multiple species yet");
09199 }
09200
09201 J = 0; R2 = 0;
09202 for(i=0;i<_NP;i++)
09203 {
09204 r = _H*(_SR[i]-com);
09205 r1 = _H*(_SR1[i]-com1);
09206
09207 J += r.x*r1.y - r.y*r1.x;
09208 R2 += r.y*r1.y + r.x*r1.x;
09209 }
09210 alpha = atan2(J,R2);
09211
09212 INFO_Printf("amount of rotation needed: alpha = %20.12e (degree)\n",alpha*180/M_PI);
09213
09214 hinv = _H.inv();
09215 for(i=0;i<_NP;i++)
09216 {
09217 r = _H*(_SR[i]-com);
09218 dr.x = r.x*cos(alpha) - r.y*sin(alpha);
09219 dr.y = r.x*sin(alpha) + r.y*cos(alpha);
09220 dr.z = r.z;
09221 ds = hinv*dr;
09222 _SR[i]=(ds+com);
09223 }
09224 }
09225
09226 void MDFrame::clearFext()
09227 {
09228 int i;
09229 if(_Fext!=NULL)
09230 {
09231 for(i=0;i<_NP;i++)
09232 _Fext[i].clear();
09233 }
09234 }
09235
09236 void MDFrame::addFext_to_group()
09237 {
09238 int i, groupID;
09239 double fx, fy, fz;
09240
09241 if(_Fext==NULL)
09242 {
09243 ERROR("addFext_to_group: _Fext == NULL !");
09244 return;
09245 }
09246 groupID = (int) input[0];
09247 fx = input[1];
09248 fy = input[2];
09249 fz = input[3];
09250 for(i=0;i<_NP;i++)
09251 {
09252 if(group[i]==groupID)
09253 {
09254 _Fext[i].x = fx;
09255 _Fext[i].y = fy;
09256 _Fext[i].z = fz;
09257 }
09258 }
09259 }
09260
09261
09262
09263
09264 void MDFrame::NbrList_reconstruct(int iatom)
09265 {
09266
09267 NbrList_reconstruct_use_link_list(iatom);
09268 }
09269
09270 void MDFrame::NbrList_reconstruct_use_link_list(int iatom)
09271 {
09272
09273
09274
09275
09276 int i, j, k, cell_ind, ncell, ineigh, ncx, ncy, ncz, itmp;
09277 int head1, head2, ipt, jpt, i1, j1, k1, i2, j2, k2;
09278 int max_nnm, num_neigh_cell, neigh_cell_ind[27];
09279 double rsmax2;
09280 Vector3 s,sij,rij,h;
09281
09282
09283 if(iatom==-1)
09284 NbrList_init(_NP*allocmultiple,_NNM);
09285
09286 rsmax2=_RLIST*_RLIST;
09287 h=_H.height();
09288
09289
09290 ncx=(int)floor(h[0]/((_RLIST)*1.05));if(ncx==0)ncx=1;
09291 ncy=(int)floor(h[1]/((_RLIST)*1.05));if(ncy==0)ncy=1;
09292 ncz=(int)floor(h[2]/((_RLIST)*1.05));if(ncz==0)ncz=1;
09293
09294
09295
09296
09297 ncell = ncx*ncy*ncz;
09298 NbrList_initlinklist(ncell);
09299
09300
09301 for(ipt=0;ipt<_NP;ipt++)
09302 {
09303 s=_SR[ipt]; s.subint();
09304 i=(int)floor((s.x+0.5)*ncx);i=(i+2*ncx)%ncx;
09305 j=(int)floor((s.y+0.5)*ncy);j=(j+2*ncy)%ncy;
09306 k=(int)floor((s.z+0.5)*ncz);k=(k+2*ncz)%ncz;
09307
09308 cell_ind = (i*ncy + j)*ncz + k;
09309
09310
09311 link_list[ipt] = link_head[cell_ind];
09312 link_head[cell_ind] = ipt;
09313 }
09314
09315
09316
09317
09318
09319
09320
09321
09322
09323
09324
09325
09326
09327
09328
09329
09330 if(iatom==-1)
09331 {
09332 for(ipt=0;ipt<_NP;ipt++)
09333 {
09334 nn[ipt]=0;
09335 for(itmp=0;itmp<_NNM;itmp++)
09336 nindex[ipt][itmp]=0;
09337 }
09338 }
09339 else
09340 {
09341 ipt=iatom;
09342 nn[ipt]=0;
09343 for(itmp=0;itmp<_NNM;itmp++)
09344 nindex[ipt][itmp]=0;
09345 }
09346 max_nnm = 0;
09347
09348 if(iatom==-1)
09349 {
09350 for(cell_ind=0;cell_ind<ncell;cell_ind++)
09351 {
09352
09353
09354
09355 k = cell_ind % ncz;
09356 j = ((cell_ind - k)/ncz) % ncy;
09357 i = (((cell_ind - k)/ncz) - j) / ncy;
09358
09359 neigh_cell_ind[0] = cell_ind;
09360 num_neigh_cell = 1;
09361 for(i1=((ncx==1)?i:(i-1));i1<=((ncx<=2)?i:(i+1));i1++)
09362 for(j1=((ncy==1)?j:(j-1));j1<=((ncy<=2)?j:(j+1));j1++)
09363 for(k1=((ncz==1)?k:(k-1));k1<=((ncz<=2)?k:(k+1));k1++)
09364 {
09365 i2=(i1+2*ncx)%ncx;
09366 j2=(j1+2*ncy)%ncy;
09367 k2=(k1+2*ncz)%ncz;
09368 if((i==i2)&&(j==j2)&&(k==k2)) continue;
09369 neigh_cell_ind[num_neigh_cell] = (i2*ncy + j2)*ncz + k2;
09370 num_neigh_cell ++;
09371 }
09372
09373
09374
09375
09376
09377
09378
09379 head1 = link_head[cell_ind];
09380
09381 max_nnm = 0;
09382
09383 for(ineigh=0;ineigh<num_neigh_cell;ineigh++)
09384 {
09385 head2 = link_head[neigh_cell_ind[ineigh]];
09386
09387
09388 ipt = head1;
09389 while(ipt!=-1)
09390 {
09391 jpt = head2;
09392 while(jpt!=-1)
09393 {
09394
09395
09396
09397 if(ipt<jpt)
09398 {
09399 sij=_SR[ipt]-_SR[jpt];
09400 sij.subint();
09401 rij=_H*sij;
09402 if(rij.norm2()<rsmax2)
09403 {
09404 nindex[ipt][nn[ipt]]=jpt;
09405 nn[ipt]++;
09406 if(nn[ipt]>=_NNM)
09407 FATAL("reconstruct: index["<<ipt<<"] ("
09408 <<nn[ipt]<<") >= NNM("<<_NNM<<")"
09409 " increase NNM in script");
09410 if(max_nnm<nn[ipt]) max_nnm=nn[ipt];
09411
09412 nindex[jpt][nn[jpt]]=ipt;
09413 nn[jpt]++;
09414 if(nn[jpt]>=_NNM)
09415 FATAL("reconstruct: index["<<jpt<<"] ("
09416 <<nn[ipt]<<") >= NNM("<<_NNM<<")"
09417 " increase NNM in script");
09418 if(max_nnm<nn[jpt]) max_nnm=nn[jpt];
09419 }
09420 }
09421
09422 if(jpt==link_list[jpt])
09423 FATAL("jpt="<<jpt<<" link_list["<<jpt<<"]="<<link_list[jpt]);
09424 jpt = link_list[jpt];
09425 }
09426
09427 if(ipt==link_list[ipt])
09428 FATAL("ipt="<<ipt<<" link_list["<<ipt<<"]="<<link_list[ipt]);
09429 ipt = link_list[ipt];
09430 }
09431 }
09432 }
09433 }
09434 else
09435 {
09436 s=_SR[iatom]; s.subint();
09437 i=(int)floor((s.x+0.5)*ncx);i=(i+2*ncx)%ncx;
09438 j=(int)floor((s.y+0.5)*ncy);j=(j+2*ncy)%ncy;
09439 k=(int)floor((s.z+0.5)*ncz);k=(k+2*ncz)%ncz;
09440
09441 cell_ind = (i*ncy + j)*ncz + k;
09442
09443
09444 neigh_cell_ind[0] = cell_ind;
09445 num_neigh_cell = 1;
09446 for(i1=((ncx==1)?i:(i-1));i1<=((ncx<=2)?i:(i+1));i1++)
09447 for(j1=((ncy==1)?j:(j-1));j1<=((ncy<=2)?j:(j+1));j1++)
09448 for(k1=((ncz==1)?k:(k-1));k1<=((ncz<=2)?k:(k+1));k1++)
09449 {
09450 i2=(i1+2*ncx)%ncx;
09451 j2=(j1+2*ncy)%ncy;
09452 k2=(k1+2*ncz)%ncz;
09453 if((i==i2)&&(j==j2)&&(k==k2)) continue;
09454 neigh_cell_ind[num_neigh_cell] = (i2*ncy + j2)*ncz + k2;
09455 num_neigh_cell ++;
09456 }
09457 max_nnm = 0;
09458
09459 for(ineigh=0;ineigh<num_neigh_cell;ineigh++)
09460 {
09461 head2 = link_head[neigh_cell_ind[ineigh]];
09462
09463
09464 ipt = iatom;
09465 jpt = head2;
09466 while(jpt!=-1)
09467 {
09468 if(ipt!=jpt)
09469 {
09470 sij=_SR[ipt]-_SR[jpt];
09471 sij.subint();
09472 rij=_H*sij;
09473 if(rij.norm2()<rsmax2)
09474 {
09475 nindex[ipt][nn[ipt]]=jpt;
09476 nn[ipt]++;
09477 if(nn[ipt]>=_NNM)
09478 FATAL("reconstruct: index["<<ipt<<"] ("
09479 <<nn[ipt]<<") >= NNM("<<_NNM<<")"
09480 "increase NNM in script");
09481 if(max_nnm<nn[ipt]) max_nnm=nn[ipt];
09482
09483 nindex[jpt][nn[jpt]]=ipt;
09484 nn[jpt]++;
09485 if(nn[jpt]>=_NNM)
09486 FATAL("reconstruct: index["<<jpt<<"] ("
09487 <<nn[ipt]<<") >= NNM("<<_NNM<<")"
09488 "increase NNM in script");
09489 if(max_nnm<nn[jpt]) max_nnm=nn[jpt];
09490 }
09491
09492 if(jpt==link_list[jpt])
09493 FATAL("jpt="<<jpt<<" link_list["<<jpt<<"]="<<link_list[jpt]);
09494 jpt = link_list[jpt];
09495 }
09496 }
09497 }
09498 }
09499
09500 if(iatom==-1)
09501 {
09502 for(i=0;i<_NP;i++)
09503 {
09504 _R[i]=_H*_SR[i];
09505 _R0[i]=_R[i];
09506 }
09507
09508
09509 iatom=_NP-1;
09510 _R[iatom]=_H*_SR[iatom];
09511 _R0[iatom]=_R[iatom];
09512
09513
09514
09515
09516
09517
09518 }
09519 else
09520 {
09521 _R[iatom]=_H*_SR[iatom];
09522 _R0[iatom]=_R[iatom];
09523
09524
09525
09526
09527
09528
09529 }
09530 _current_NNM=max_nnm;
09531
09532
09533
09534 }
09535
09536 void MDFrame::NbrList_reconstruct_use_cell_list(int iatom)
09537 {
09538
09539 int ncx,ncy,ncz;
09540 int ncx0,ncx1,ncy0,ncy1,ncz0,ncz1,np0,np1;
09541 int i,j,k,n,i1,j1,k1,n1,i2,j2,k2;
09542 int ipt,jpt, itmp;
09543 double rsmax2;
09544 Vector3 s,sij,rij,h;
09545 int m_nic, m_nnm;
09546
09547 if(iatom!=-1)
09548 {
09549 FATAL("NbrList_reconstruct_use_cell_list iatom="<<iatom<<" not implemented! use link_list");
09550 }
09551
09552 NbrList_init(_NP*allocmultiple,_NNM);
09553
09554 rsmax2=_RLIST*_RLIST;
09555 h=_H.height();
09556
09557 INFO("reconstruct neighborlist");
09558 DUMP("reconstruct_cell() ");
09559 INFO("H="<<_H<<" _RLIST="<<_RLIST);
09560
09561 ncx=(int)floor(h[0]/((_RLIST)*1.05));if(ncx==0)ncx=1;
09562 ncy=(int)floor(h[1]/((_RLIST)*1.05));if(ncy==0)ncy=1;
09563 ncz=(int)floor(h[2]/((_RLIST)*1.05));if(ncz==0)ncz=1;
09564
09565 NbrList_initcell(ncx,ncy,ncz,_NIC);
09566
09567 ncx0=0; ncx1=ncx; ncy0=0; ncy1=ncy; ncz0=0; ncz1=ncz;
09568
09569 np0=0;
09570 np1=_NP;
09571
09572 for(i=ncx0;i<ncx1;i++)
09573 for(j=ncy0;j<ncy1;j++)
09574 for(k=ncz0;k<ncz1;k++)
09575 celllist[i][j][k][0]=0;
09576
09577 m_nic = 0;
09578 for(ipt=0;ipt<_NP;ipt++)
09579 {
09580 s=_SR[ipt];
09581 s.subint();
09582 i=(int)floor((s.x+0.5)*ncx);i=(i+2*ncx)%ncx;
09583 j=(int)floor((s.y+0.5)*ncy);j=(j+2*ncy)%ncy;
09584 k=(int)floor((s.z+0.5)*ncz);k=(k+2*ncz)%ncz;
09585 if((i>=ncx0)&&(i<ncx1)&&(j>=ncy0)&&(j<ncy1)&&(k>=ncz0)&&(k<ncz1))
09586 {
09587
09588 celllist[i][j][k][0]++;
09589 if(celllist[i][j][k][0]>_NIC-1)
09590 FATAL("reconstruct(): too many atoms per cell "
09591 <<celllist[i][j][k][0]<<" > limit("<<(_NIC-1)<<")"
09592 <<"increase NIC in script");
09593 celllist[i][j][k][celllist[i][j][k][0]]=ipt;
09594 if(m_nic<celllist[i][j][k][0]) m_nic=celllist[i][j][k][0];
09595 }
09596 }
09597 _current_NIC=m_nic;
09598
09599 for(ipt=np0;ipt<np1;ipt++)
09600 {
09601 nn[ipt]=0;
09602 for(itmp=0;itmp<_NNM;itmp++)
09603 nindex[ipt][itmp]=0;
09604 }
09605 DUMP("list cleared");
09606
09607 m_nnm=0;
09608 for(i=ncx0;i<ncx1;i++)
09609 for(j=ncy0;j<ncy1;j++)
09610 for(k=ncz0;k<ncz1;k++)
09611 for(n=1;n<=celllist[i][j][k][0];n++)
09612 {
09613 ipt=celllist[i][j][k][n];
09614
09615 #if 1
09616 {
09617 i2=i;
09618 j2=j;
09619 k2=k;
09620
09621 for(n1=1;n1<=celllist[i2][j2][k2][0];n1++)
09622 {
09623 jpt=celllist[i2][j2][k2][n1];
09624 if(ipt==jpt) continue;
09625 sij=_SR[ipt]-_SR[jpt];
09626 sij.subint();
09627 rij=_H*sij;
09628 if(rij.norm2()<rsmax2)
09629 {
09630 nindex[ipt][nn[ipt]]=jpt;
09631 nn[ipt]++;
09632 if(nn[ipt]>=_NNM)
09633 FATAL("reconstruct: index["<<ipt<<"] ("
09634 <<nn[ipt]<<") >= NNM("<<_NNM<<")"
09635 "increase NNM in script");
09636 if(m_nnm<nn[ipt]) m_nnm=nn[ipt];
09637 }
09638 }
09639 }
09640 #endif
09641 #if 1
09642 for(i1=((ncx==1)?i:(i-1));i1<=((ncx<=2)?i:(i+1));i1++)
09643 for(j1=((ncy==1)?j:(j-1));j1<=((ncy<=2)?j:(j+1));j1++)
09644 for(k1=((ncz==1)?k:(k-1));k1<=((ncz<=2)?k:(k+1));k1++)
09645 {
09646 i2=(i1+2*ncx)%ncx;
09647 j2=(j1+2*ncy)%ncy;
09648 k2=(k1+2*ncz)%ncz;
09649 if((i==i2)&&(j==j2)&&(k==k2)) continue;
09650
09651 for(n1=1;n1<=celllist[i2][j2][k2][0];n1++)
09652 {
09653 jpt=celllist[i2][j2][k2][n1];
09654 if(ipt==jpt) continue;
09655 sij=_SR[ipt]-_SR[jpt];
09656 sij.subint();
09657 rij=_H*sij;
09658 if(rij.norm2()<rsmax2)
09659 {
09660 nindex[ipt][nn[ipt]]=jpt;
09661 nn[ipt]++;
09662 if(nn[ipt]>=_NNM)
09663 FATAL("reconstruct: index["<<ipt<<"] ("
09664 <<nn[ipt]<<") >= NNM("<<_NNM<<")"
09665 "increase NNM in script");
09666 if(m_nnm<nn[ipt]) m_nnm=nn[ipt];
09667 }
09668 }
09669 }
09670 #endif
09671 }
09672
09673 _current_NNM=m_nnm;
09674
09675
09676 for(i=np0;i<np1;i++)
09677 {
09678 _R[i]=_H*_SR[i];
09679 _R0[i]=_R[i];
09680 }
09681
09682
09683 }
09684
09685 void MDFrame::NbrList_print()
09686 {
09687 int i, j, n, ipt, jpt;
09688
09689 n = (int) input[0];
09690 for(i=0;i<n;i++)
09691 {
09692 ipt = (int) input[i+1];
09693
09694 INFO_Printf("atom [%d] has %d neighbors ( ",ipt,nn[ipt]);
09695
09696 for(j=0;j<nn[i];j++)
09697 {
09698 jpt = nindex[ipt][j];
09699 INFO_Printf(" %d",jpt);
09700 }
09701 INFO_Printf(")\n");
09702 }
09703 }
09704
09705 bool MDFrame::NbrList_needrefresh()
09706 {
09707
09708 double maxd;
09709 int i, need;
09710 Vector3 dR;
09711 if (firsttime)
09712 {
09713 firsttime=false;
09714 return true;
09715 }
09716 maxd=0;
09717 SHtoR();
09718 for(i=0;i<_NP;i++)
09719 {
09720
09721
09722 dR = _R[i] - _R0[i];
09723 maxd=max(dR.norm2(),maxd);
09724
09725
09726
09727 }
09728 need=(maxd>_SKIN*_SKIN/4.0);
09729
09730
09731 return (need!=0);
09732 }
09733
09734 void MDFrame::NbrList_init(int mx,int mz)
09735 {
09736
09737
09738 int shft1,shft2;
09739 int i;
09740
09741 DUMP("initlist("<<mx<<","<<mz<<")");
09742 shft1=mx*mz*sizeof(int);
09743 shft2=mx*sizeof(int *);
09744 if(shft1+shft2==0) return;
09745
09746 Realloc(nindex_mem,char,(shft1+shft2));
09747
09748 nindex=(int **)(nindex_mem+shft1);
09749
09750 memset(nindex_mem,0,shft1+shft2);
09751 for(i=0;i<mx;i++)
09752 {
09753 nindex[i]=(int *)(nindex_mem+i*mz*sizeof(int));
09754 }
09755
09756 Realloc(nn,int,mx);
09757 }
09758
09759 void MDFrame::NbrList_initlinklist(int ncell)
09760 {
09761 int i;
09762
09763 Realloc(link_head,int,ncell);
09764 Realloc(link_list,int,_NP);
09765
09766 for(i=0;i<ncell;i++) link_head[i]=-1;
09767 for(i=0;i<_NP;i++) link_list[i]=-1;
09768 }
09769
09770 void MDFrame::NbrList_freelinklist()
09771 {
09772 free(link_head);
09773 free(link_list);
09774 }
09775
09776 void MDFrame::NbrList_initcell(int mx, int my, int mz, int mc)
09777 {
09778
09779 int shft1,shft2,shft3,shft4;
09780 int i, j, k;
09781
09782
09783
09784 shft1=mx*my*mz*mc*sizeof(int);
09785 shft2=mx*my*mz*sizeof(int *);
09786 shft3=mx*my*sizeof(int **);
09787 shft4=mx*sizeof(int ***);
09788 if(shft1+shft2+shft3+shft4==0) return;
09789
09790 INFO("initcell("<<mx<<","<<my<<","<<mz<<","<<mc<<") cell list size "<<shft1+shft2+shft3+shft4);
09791 Realloc(cell_mem,char,(shft1+shft2+shft3+shft4));
09792 celllist=(int ****)(cell_mem+shft1+shft2+shft3);
09793
09794 memset(cell_mem,0,shft1+shft2+shft3+shft4);
09795 for(i=0;i<mx;i++)
09796 {
09797 celllist[i]=(int ***)(cell_mem+shft1+shft2+i*my*sizeof(int **));
09798 for(j=0;j<my;j++)
09799 {
09800 celllist[i][j]=(int **)(cell_mem+shft1+(i*my*mz+j*mz)*sizeof(int *));
09801 for(k=0;k<mz;k++)
09802 {
09803 celllist[i][j][k]=
09804 (int *)(cell_mem+(i*my*mz*mc+j*mz*mc+k*mc)*sizeof(int));
09805 }
09806 }
09807 }
09808 }
09809
09810 void MDFrame::NbrList_free()
09811 {
09812 free(nindex_mem);
09813 nindex_mem=NULL;
09814 nn=NULL;
09815 nindex=NULL;
09816 }
09817
09818 void MDFrame::NbrList_freecell()
09819 {
09820 free(cell_mem);
09821 cell_mem=NULL;
09822 celllist=NULL;
09823 }
09824
09825 void MDFrame::NbrList_refresh()
09826 {
09827 if(NbrList_needrefresh()) NbrList_reconstruct();
09828 }
09829
09830 void MDFrame::NbrListPlot_reconstruct()
09831 {
09832 int ipt, j, jpt;
09833 Vector3 s, r;
09834 double rsmax2;
09835
09836 if (nn_plot == NULL)
09837 {
09838 INFO("NBR test");
09839 NbrListPlot_init(_NP,_NNM_plot);
09840 }
09841
09842 rsmax2=rc_plot*rc_plot;
09843
09844 INFO("reconstruct neighborlist_plot");
09845 for(ipt=0;ipt<_NP;ipt++)
09846 {
09847 nn_plot[ipt]=0;
09848 for(j=0;j<nn[ipt];j++)
09849 {
09850
09851
09852 jpt=nindex[ipt][j];
09853 s=_SR[ipt]-_SR[jpt];
09854 s.subint();
09855 r = _H*s;
09856
09857 if(r.norm2()<rsmax2)
09858 {
09859 nindex_plot[ipt][nn_plot[ipt]]=jpt;
09860 nn_plot[ipt]++;
09861 }
09862
09863
09864 }
09865 }
09866 INFO_Printf("reconstruct_plot() finished\n");
09867 }
09868
09869 void MDFrame::NbrListPlot_init(int mx,int mz)
09870 {
09871
09872 int shft1,shft2;
09873 int i;
09874
09875 DUMP("initlist("<<mx<<","<<mz<<")");
09876 shft1=mx*mz*sizeof(int);
09877 shft2=mx*sizeof(int *);
09878 if(shft1+shft2==0) return;
09879
09880 Realloc(nindex_plot_mem,char,(shft1+shft2));
09881
09882 nindex_plot=(int **)(nindex_plot_mem+shft1);
09883
09884 memset(nindex_plot_mem,0,shft1+shft2);
09885 for(i=0;i<mx;i++)
09886 {
09887
09888 nindex_plot[i]=(int *)(nindex_plot_mem+i*mz*sizeof(int));
09889 }
09890
09891 Realloc(nn_plot,int,mx);
09892 }
09893
09894
09895
09896
09897
09898 int MDFrame::readcn()
09899 {
09900 initcn.open(incnfile,LFile::O_Read);
09901 return initcn.read(this);
09902 }
09903
09904 int MDFrame::readPOSCAR()
09905 {
09906 initposcar.open(incnfile,LFile::O_Read);
09907 return initposcar.read(this);
09908 }
09909
09910 int MDFrame::readMDCASK()
09911 {
09912 initmdcaskcon.open(incnfile,LFile::O_Read);
09913 initmdcaskcon.read(this);
09914 initmdcaskinput.open("mold.in",LFile::O_Read);
09915 return initmdcaskinput.read(this);
09916 }
09917
09918 int MDFrame::readLAMMPS()
09919 {
09920 initlammps.open(incnfile,LFile::O_Read);
09921 return initlammps.read(this);
09922 }
09923
09924 int MDFrame::writeLAMMPS()
09925 {
09926 finallammps.open(finalcnfile);
09927 return finallammps.write(this);
09928 }
09929
09930 int MDFrame::setfilecounter()
09931 {
09932 intercn.setcount(filecounter);
09933 return 0;
09934 }
09935
09936 int MDFrame::setFFSfilecounter()
09937 {
09938 FFScn.setcount(FFSfilecounter);
09939 return 0;
09940 }
09941
09942 int MDFrame::convertXDATCAR()
09943 {
09944 int i, j;
09945 char *buffer; char *pp, *q;
09946 int np, nframe;
09947 char fname[200];
09948
09949 strcpy(fname,incnfile);
09950 LFile::SubHomeDir(fname,fname);
09951 LFile::LoadToString(fname,buffer,0);
09952
09953 pp=buffer;
09954
09955 q=pp; pp=strchr(pp, '\n'); if(pp) *(char *)pp++=0;
09956 sscanf(q,"%d %d %d",&np, &j, &nframe);
09957
09958 q=pp; pp=strchr(pp, '\n'); if(pp) *(char *)pp++=0;
09959 q=pp; pp=strchr(pp, '\n'); if(pp) *(char *)pp++=0;
09960 q=pp; pp=strchr(pp, '\n'); if(pp) *(char *)pp++=0;
09961 q=pp; pp=strchr(pp, '\n'); if(pp) *(char *)pp++=0;
09962
09963 for(j=0;j<nframe;j++)
09964 {
09965 q=pp; pp=strchr(pp, '\n'); if(pp) *(char *)pp++=0;
09966
09967 for(i=0;i<_NP;i++)
09968 {
09969 q=pp; pp=strchr(pp, '\n'); if(pp) *(char *)pp++=0;
09970 sscanf(q,"%lf %lf %lf",
09971 &(_SR[i].x),&(_SR[i].y),&(_SR[i].z));
09972 }
09973 INFO("frame "<<j);
09974 writeintercnfile(zipfiles,false);
09975 }
09976 Free(buffer);
09977 return 0;
09978 }
09979
09980
09981 int MDFrame::writefinalcnfile(int zip, bool bg)
09982 {
09983 finalcn.open(finalcnfile);
09984 return finalcn.write(this,zip,bg);
09985
09986 }
09987
09988 int MDFrame::writeavgcnfile(int zip, bool bg)
09989 {
09990 avgcn.open(finalcnfile);
09991 return avgcn.write(this,zip,bg);
09992 }
09993
09994 void MDFrame::saveintercn(int step)
09995 {
09996 if(savecn)
09997 if((step%savecnfreq)==0&&(step!=0))
09998 writeintercnfile(zipfiles,false);
09999 }
10000
10001 int MDFrame::writeintercnfile(int zip,bool bg)
10002 {
10003 return intercn.write(this,zip,bg);
10004 }
10005
10006 int MDFrame::writeFFScnfile(int zip, bool bg)
10007 {
10008 return FFScn.write(this,zip,bg);
10009 }
10010
10011 int MDFrame::writePOSCAR()
10012 {
10013 finalposcar.open(finalcnfile);
10014 return finalposcar.write(this);
10015 }
10016
10017 int MDFrame::writeMDCASK()
10018 {
10019 finalmdcaskcon.open(finalcnfile);
10020 finalmdcaskcon.write(this,0);
10021 finalmdcaskinput.open("mold.in");
10022 return finalmdcaskinput.write(this,0);
10023 }
10024
10025 int MDFrame::openintercnfile()
10026 {
10027 return intercn.open(intercnfile);
10028 }
10029
10030 int MDFrame::openFFScnfile()
10031 {
10032 return FFScn.open(FFScnfile);
10033 }
10034
10035 int MDFrame::openpropfile()
10036 {
10037 return pf.open(outpropfile);
10038 }
10039
10040 int MDFrame::closepropfile()
10041 {
10042 pf.close(zipfiles,true);
10043 return 0;
10044 }
10045
10046
10047 char * CNFile::describe()
10048 {
10049 static char tmp[500];
10050 sprintf(tmp,"%s","Configuration File for Atom Positions, Format:\n"
10051 "sx1 sy1 sz1; ... ; sxn syn szn; H(3x3)");
10052 return tmp;
10053 }
10054
10055 int CNFile::writeblock(void *p)
10056 {
10057 int i;
10058 MDFrame &d=*((MDFrame *)p);
10059 f->Printf("%d\n",d._NP);
10060 for(i=0;i<d._NP;i++)
10061 {
10062 if (d.writeall)
10063 f->Printf("%25.17E %25.17E %25.17E %25.17E %25.17E %25.17E"
10064 " %25.17E %2d %25.17E %2d %2d %2d\n",
10065 d._SR[i].x,d._SR[i].y,d._SR[i].z,
10066 d._VSR[i].x,d._VSR[i].y,d._VSR[i].z,
10067 d._EPOT_IND[i],d.fixed[i],d._TOPOL[i],
10068 d.species[i],d.group[i],d.image[i]);
10069 else if (d.writevelocity)
10070 f->Printf("%25.17E %25.17E %25.17E %25.17E %25.17E %25.17E\n",
10071 d._SR[i].x,d._SR[i].y,d._SR[i].z,
10072 d._VSR[i].x,d._VSR[i].y,d._VSR[i].z);
10073 else
10074 f->Printf("%25.17E %25.17E %25.17E\n",
10075 d._SR[i].x,d._SR[i].y,d._SR[i].z);
10076 }
10077 f->Printf("%25.17E %25.17E %25.17E\n"
10078 "%25.17E %25.17E %25.17E\n"
10079 "%25.17E %25.17E %25.17E\n",
10080 d._H[0][0],d._H[0][1],d._H[0][2],
10081 d._H[1][0],d._H[1][1],d._H[1][2],
10082 d._H[2][0],d._H[2][1],d._H[2][2]);
10083 f->Printf("%d ",d.nspecies);
10084 for(i=0;i<d.nspecies;i++) f->Printf("%s ",d.element[i]);
10085 f->Printf("\n");
10086
10087
10088
10089 f->Printf("%25.17E %25.17E\n", d.zeta, d.zetav);
10090
10091
10092 return 0;
10093 }
10094
10095 int CNFile::readblock(void *p)
10096 {
10097 int i;
10098 char *buffer, *pp, *q;
10099 MDFrame &d=*((MDFrame *)p);
10100
10101 LFile::LoadToString(fname,buffer,0);
10102
10103 pp=buffer;
10104 sscanf(pp, "%d", &d._NP);
10105 INFO("readblock: NP="<<d._NP);
10106
10107 d.Alloc();
10108
10109 pp=strchr(pp, '\n');
10110 pp++;
10111 for(i=0;i<d._NP;i++)
10112 {
10113 q=pp;
10114 pp=strchr(pp,'\n');
10115 if(pp) *(char *)pp++=0;
10116
10117
10118 sscanf(q, "%lf %lf %lf %lf %lf %lf %lf %d %lf %d %d %d",
10119 &(d._SR[i].x),&(d._SR[i].y),&(d._SR[i].z),
10120 &(d._VSR[i].x),&(d._VSR[i].y),&(d._VSR[i].z),
10121 &(d._EPOT_IND[i]),&(d.fixed[i]),&(d._TOPOL[i]),
10122 &(d.species[i]),&(d.group[i]),&(d.image[i]));
10123
10124
10125 }
10126
10127
10128 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10129 sscanf(q, "%lf %lf %lf",&d._H[0][0],&d._H[0][1],&d._H[0][2]);
10130 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10131 sscanf(q, "%lf %lf %lf",&d._H[1][0],&d._H[1][1],&d._H[1][2]);
10132 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10133 sscanf(q, "%lf %lf %lf",&d._H[2][0],&d._H[2][1],&d._H[2][2]);
10134
10135
10136 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0; else {Free(buffer); return 0;}
10137
10138 sscanf(q, "%d %s %s %s %s %s %s %s %s %s %s",
10139 &(d.nspecies),
10140 d.element[0],d.element[1],d.element[2],d.element[3],d.element[4],
10141 d.element[5],d.element[6],d.element[7],d.element[8],d.element[9]);
10142
10143
10144
10145
10146 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0; else {Free(buffer); return 0;}
10147 sscanf(q, "%lf %lf",&d.zeta, &d.zetav);
10148
10149 Free(buffer);
10150 DUMP("readblock finished");
10151 return 0;
10152 }
10153
10154 int AVGCNFile::readblock(void *p)
10155 {
10156 return 0;
10157 }
10158
10159 int AVGCNFile::writeblock(void *p)
10160 {
10161 int i;
10162 MDFrame &d=*((MDFrame *)p);
10163 f->Printf("%d\n",d._NP);
10164
10165 if(d._SRA == NULL)
10166 {
10167 ERROR("No _SRA to be written!!!");
10168 return -1;
10169 }
10170
10171 for(i=0;i<d._NP;i++)
10172 f->Printf("%25.17E %25.17E %25.17E\n",
10173 d._SRA[i].x,d._SRA[i].y,d._SRA[i].z);
10174
10175 f->Printf("%25.17E %25.17E %25.17E\n"
10176 "%25.17E %25.17E %25.17E\n"
10177 "%25.17E %25.17E %25.17E\n",
10178 d._H[0][0],d._H[0][1],d._H[0][2],
10179 d._H[1][0],d._H[1][1],d._H[1][2],
10180 d._H[2][0],d._H[2][1],d._H[2][2]);
10181 f->Printf("%d ",d.nspecies);
10182 for(i=0;i<d.nspecies;i++) f->Printf("%s ",d.element[i]);
10183 f->Printf("\n");
10184
10185 return 0;
10186 }
10187
10188
10189 char * POSCARFile::describe()
10190 {
10191 static char tmp[500];
10192 sprintf(tmp,"%s","Ionic positions in POSCAR (VASP) format");
10193 return tmp;
10194 }
10195
10196 int POSCARFile::writeblock(void *p)
10197 {
10198 int i;
10199
10200 MDFrame &d=*((MDFrame *)p);
10201
10202 f->Printf("POSCAR by MD++ [%s]\n",d.dirname);
10203 f->Printf(" 1.0\n");
10204 f->Printf(" %25.17e %25.17e %25.17e\n"
10205 " %25.17e %25.17e %25.17e\n"
10206 " %25.17e %25.17e %25.17e\n",
10207 d._H[0][0],d._H[1][0],d._H[2][0],
10208 d._H[0][1],d._H[1][1],d._H[2][1],
10209 d._H[0][2],d._H[1][2],d._H[2][2] );
10210 f->Printf(" %d\n",d._NP);
10211 f->Printf("direct (relative coordinates s)\n");
10212 for(i=0;i<d._NP;i++)
10213 {
10214 f->Printf("%25.17e %25.17e %25.17e\n",
10215 d._SR[i].x,d._SR[i].y,d._SR[i].z);
10216 }
10217 return 0;
10218 }
10219
10220 int POSCARFile::readblock(void *p)
10221 {
10222 int i;
10223 char *buffer; char *pp, *q, s[100];
10224 double scale;
10225 Matrix33 h, hinv;
10226
10227 MDFrame &d=*((MDFrame *)p);
10228
10229 LFile::LoadToString(fname,buffer,0);
10230
10231 INFO("readPOSCAR:: read into string");
10232
10233 pp=buffer;
10234 pp=strchr(pp, '\n');
10235 pp++;
10236
10237 q=pp;
10238 pp=strchr(pp,'\n');
10239 if(pp) *(char *)pp++=0;
10240
10241 sscanf(q, "%lf", &scale);
10242
10243 for(i=0;i<3;i++)
10244 {
10245 q=pp;
10246 pp=strchr(pp,'\n');
10247 if(pp) *(char *)pp++=0;
10248
10249 sscanf(q, "%lf %lf %lf", &h[0][i], &h[1][i], &h[2][i]);
10250 h[0][i]*=scale;h[1][i]*=scale;h[2][i]*=scale;
10251 }
10252
10253 q=pp;
10254 pp=strchr(pp,'\n');
10255 if(pp) *(char *)pp++=0;
10256 printf("read line : %s\n",q);
10257 sscanf(q, "%d", &d._NP);
10258 INFO("readblock: NP="<<d._NP);
10259
10260 d.Alloc();
10261 d._H=h;
10262 INFO("readPOSCAR:: alloced");
10263
10264 q=pp;
10265 pp=strchr(pp,'\n');
10266 if(pp) *(char *)pp++=0;
10267 sscanf(q, "%s", s);
10268 INFO("readblock: s="<<s);
10269
10270 if((s[0]=='C')||(s[0]=='c')||(s[0]=='K')||(s[0]=='k'))
10271 {
10272 hinv = h.inv();
10273 for(i=0;i<d._NP;i++)
10274 {
10275 q=pp;
10276 pp=strchr(pp,'\n');
10277 if(pp) *(char *)pp++=0;
10278 sscanf(q, "%lf %lf %lf",
10279 &(d._R[i].x),&(d._R[i].y),&(d._R[i].z));
10280 d._R[i]*=scale;
10281 d._SR[i]=hinv*d._R[i];
10282 d.fixed[i]=0;
10283 }
10284 }
10285 else
10286 {
10287 for(i=0;i<d._NP;i++)
10288 {
10289 q=pp;
10290 pp=strchr(pp,'\n');
10291 if(pp) *(char *)pp++=0;
10292 sscanf(q, "%lf %lf %lf",
10293 &(d._SR[i].x),&(d._SR[i].y),&(d._SR[i].z));
10294 }
10295 }
10296 Free(buffer);
10297 return 0;
10298 }
10299
10300
10301 char * MDCASKconFile::describe()
10302 {
10303 static char tmp[500];
10304 sprintf(tmp,"%s","Ionic positions in MDCASK (mdyn.con) format");
10305 return tmp;
10306 }
10307
10308 int MDCASKconFile::writeblock(void *p)
10309 {
10310 int i;
10311 MDFrame &d=*((MDFrame *)p);
10312
10313 for(i=0;i<d._NP;i++)
10314 {
10315 #if 0
10316 f->Printf("%8d %4d %13.6E %13.6E %13.6E %8.5E %13.6E %8.5E\n",
10317 i+1,1,d._SR[i].x,d._SR[i].y,d._SR[i].z,
10318 0.0,d._EPOT_IND[i],0.0);
10319 #else
10320 f->Printf("%13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E\n",
10321 d._SR[i].x,d._SR[i].y,d._SR[i].z,
10322 0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0,
10323 1.0,i+1.0,0.0,0.0);
10324
10325 #endif
10326
10327 }
10328 return 0;
10329 }
10330
10331 int MDCASKconFile::readblock(void *p)
10332 {
10333 int i;
10334 char *buffer; char *pp, *q;
10335 double tmp1, tmp2; int i1, i2;
10336
10337 MDFrame &d=*((MDFrame *)p);
10338
10339 LFile::LoadToString(fname,buffer,0);
10340
10341 pp=buffer;
10342 sscanf(pp, "%d", &d._NP);
10343 INFO("readblock: NP="<<d._NP);
10344
10345 d.Alloc();
10346
10347 pp=strchr(pp, '\n');
10348 pp++;
10349 for(i=0;i<d._NP;i++)
10350 {
10351 q=pp;
10352 pp=strchr(pp,'\n');
10353 if(pp) *(char *)pp++=0;
10354 sscanf(q, "%d %d %lf %lf %lf %lf %lf %lf",
10355 &i1,&i2,&(d._SR[i].x),&(d._SR[i].y),&(d._SR[i].z),
10356 &tmp1,&(d._EPOT_IND[i]),&tmp2);
10357 d.fixed[i]=0;
10358 }
10359 Free(buffer);
10360 DUMP("readblock finished");
10361 return 0;
10362 }
10363
10364 char * MDCASKinputFile::describe()
10365 {
10366 static char tmp[500];
10367 sprintf(tmp,"%s","Input File in MDCASK (mold.in) format");
10368 return tmp;
10369 }
10370
10371 int MDCASKinputFile::writeblock(void *p)
10372 {
10373 MDFrame &d=*((MDFrame *)p);
10374
10375
10376 f->Printf("MOLDY - Input file by MD++ (orthongonal cell only)\n");
10377 f->Printf("EAM Cu Potential\n");
10378
10379
10380 f->Printf("%10.6f %10.6f %10.6f\tALATT (IN ANGSTROMS) BLATT CLATT\n",
10381 d._H[0][0],d._H[1][1],d._H[2][2]);
10382
10383 f->Printf(" .T .T .T PBCX PBCY PBCZ\n");
10384 f->Printf(" .F LATOUT\n");
10385 f->Printf(" .F 0.0000000 0.00 Shift xshift yshift\n");
10386
10387 if(strcasecmp(d.MDCASKpot,"TERSOFF")==0)
10388 f->Printf(" .T .F .F .F .F .F .F TERSOFF ROCKETT SW ZBL EAM EDIP MEAM\n");
10389 else if(strcasecmp(d.MDCASKpot,"ROCKETT")==0)
10390 f->Printf(" .F .T .F .F .F .F .F TERSOFF ROCKETT SW ZBL EAM EDIP MEAM\n");
10391 else if(strcasecmp(d.MDCASKpot,"SW")==0)
10392 f->Printf(" .F .F .T .F .F .F .F TERSOFF ROCKETT SW ZBL EAM EDIP MEAM\n");
10393 else if(strcasecmp(d.MDCASKpot,"ZBL")==0)
10394 f->Printf(" .F .F .F .T .F .F .F TERSOFF ROCKETT SW ZBL EAM EDIP MEAM\n");
10395 else if(strcasecmp(d.MDCASKpot,"EAM")==0)
10396 f->Printf(" .F .F .F .F .T .F .F TERSOFF ROCKETT SW ZBL EAM EDIP MEAM\n");
10397 else if(strcasecmp(d.MDCASKpot,"EDIP")==0)
10398 f->Printf(" .F .F .F .F .F .T .F TERSOFF ROCKETT SW ZBL EAM EDIP MEAM\n");
10399 else if(strcasecmp(d.MDCASKpot,"MEAM")==0)
10400 f->Printf(" .F .F .F .F .F .F .T TERSOFF ROCKETT SW ZBL EAM EDIP MEAM\n");
10401
10402 f->Printf(" .F TWOCOMP\n");
10403 f->Printf(" .F 1000 0.8 TEMPCONT NLANGEVIN TEMPFACT \n");
10404 f->Printf(" .F .F .F 10 ISOKBOT ZTC XYTC NTCLAYERS\n");
10405 f->Printf(" 3.0e-14 BETAL(eV.S/A)\n");
10406 f->Printf(" .F 1 .F FREESURF NSURFLUS DIMER(2X1) \n");
10407 f->Printf(" .F 1 STLAY Nstatl\n");
10408 f->Printf(" .F 0 150.000 INTERFACE NTEMPLUS TEMPUP\n");
10409 f->Printf("2 NELEM\n");
10410 f->Printf("283.0 283.0 MASS (Si) MASS (Si)\n");
10411 f->Printf("94.0 94.0 CHARGE(Si) CHARGE(Si) \n");
10412 f->Printf("0.0855 .F ATOMIC DENSITY (atoms/A**3) IEL(T/F)\n");
10413 f->Printf("1.0E-15 DELTA (TIMESTEP IN SECONDS)\n");
10414 f->Printf("0 0 0 NST NPR NSC \n");
10415 f->Printf("600.0001 0.0 TEMPRQ PRESS\n");
10416 f->Printf("1.0 0.0 0.0 B0\n"
10417 "0.0 1.0 0.0 B0\n"
10418 "0.0 0.0 1.0 B0\n");
10419 f->Printf("0 1 Interstitial, Vacancy\n");
10420 f->Printf("1 0.0 0.0 0.0\n");
10421 f->Printf("1 1 100000 0 7 NSTEPS NPRINT NSCALE NIN IOU\n");
10422 f->Printf(" .T CONFIGFILE \n");
10423 f->Printf(" .F 4 2.75 XMOLNEIGHBORS NCOORD CUTOFFNEIGH\n");
10424 f->Printf(" .F DAMPIN\n");
10425 f->Printf(" .F CLUSTER\n");
10426 f->Printf(" 1234.56 SEED\n");
10427 f->Printf("0.0 178.0 47.5 4 1000000000 EPKA THETA PHIANG NPKA INPKA\n");
10428 f->Printf("0.00 0.00 0.00\n");
10429 f->Printf(" 63.55 2 PKAMASS IDNPKA\n");
10430 f->Printf(" 1 .F NPARPKA REPEAT\n");
10431 f->Printf(".T ConjG\n");
10432 f->Printf("0.0008 500 0.1 GRADTL MAXFN DFPRED\n");
10433 f->Printf("0 IQUEN\n");
10434 f->Printf("0.1e-14 0.5E-16 1.0 0.1 DTMAX DTMIN DEMAX DXMAX\n");
10435 f->Printf(" .F CHNGDT\n");
10436 f->Printf(" -1 NCRYS \n");
10437 f->Printf(" Si C\n");
10438 f->Printf("1830.8 471.18 AIJ BIJ (Si)\n");
10439 f->Printf("2.4799 1.7322 XLIJ XMUI (Si)\n");
10440 f->Printf("2.7 3.0 ARIJ SIJ (Si)\n");
10441 f->Printf("1.1e-6 0.78734 100390.0 16.217 -0.59825 BETAI XNI CI DI H (Si)\n");
10442 f->Printf("1393.6 346.7 AIJ BIJ (C)\n");
10443 f->Printf("3.4879 2.2119 XLIJ XMUI (C)\n");
10444 f->Printf("1.8 2.1 ARIJ SIJ (C)\n");
10445 f->Printf("1.5724e-7 0.72751 38049.0 4.384 -0.57058 BETAI XNI CI DI H (C)\n");
10446 f->Printf(" 3.25 0.2\n");
10447 f->Printf(" 1.7322\n");
10448 f->Printf(" 7.049556277 0.6022245584 1.80 ASI BSI ACUTSI\n");
10449 f->Printf(" 2.1685 2.0951 1.20 21.0 EPS SIGM GAMSI LAMBSI\n");
10450 f->Printf("-30.0 30.0 -30.0 30.0 -30.0 30.0 XMINP XMAXP YMINP YMAXP ZMINP ZMAXP\n");
10451 return 0;
10452 }
10453
10454 int MDCASKinputFile::readblock(void *p)
10455 {
10456 int i;
10457 char *buffer; char *pp, *q;
10458 Matrix33 h;
10459
10460 MDFrame &d=*((MDFrame *)p);
10461
10462 LFile::LoadToString(fname,buffer,0);
10463
10464
10465 pp=buffer;
10466 pp=strchr(pp, '\n');
10467 pp++;
10468
10469
10470 pp=strchr(pp, '\n');
10471 pp++;
10472
10473 q=pp;
10474 pp=strchr(pp, '\n');
10475 if(pp) *(char *) pp++=0;
10476 d._H.clear();
10477 sscanf(q, "%lf %lf %lf",
10478 &d._H[0][0],&d._H[1][1],&d._H[2][2]);
10479 INFO("_H="<<d._H);
10480
10481
10482 for(i=0;i<18;i++)
10483 {
10484 pp=strchr(pp, '\n');
10485 pp++;
10486 }
10487
10488
10489 for(i=0;i<3;i++)
10490 {
10491 q=pp;
10492 pp=strchr(pp, '\n');
10493 if(pp) *(char *) pp++=0;
10494 sscanf(q, "%lf %lf %lf",&(h[i][0]),&(h[i][1]),&(h[i][2]));
10495 }
10496 INFO("h="<<h);
10497
10498 d._H[0][0]*=h[0][0];
10499 d._H[1][1]*=h[1][1];
10500 d._H[2][2]*=h[2][2];
10501 for(i=0;i<d._NP;i++)
10502 {
10503 d._SR[i].x/=h[0][0];
10504 d._SR[i].y/=h[1][1];
10505 d._SR[i].z/=h[2][2];
10506 }
10507
10508 Free(buffer);
10509 DUMP("readblock finished");
10510 return 0;
10511 }
10512
10513
10514 int MDFrame::readMDCASKJAIME()
10515 {
10516 int i;
10517 char *buffer; char *pp, *q;
10518 int i1, i2;
10519 char fname[300];
10520
10521 LFile::SubHomeDir(incnfile,fname);
10522 LFile::LoadToString(fname,buffer,0);
10523
10524 pp=buffer;
10525
10526 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10527 sscanf(q, "%d", &_NP);
10528 INFO("readMDCASKJAIME: NP="<<_NP);
10529
10530 Alloc();
10531
10532 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10533 for(i=0;i<_NP;i++)
10534 {
10535 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10536 sscanf(q, "%d %d %lf %lf %lf",
10537 &i1,&i2,&(_SR[i].z),&(_SR[i].y),&(_SR[i].x));
10538 _SR[i].z/=100.0;
10539 _SR[i].y/=-8.0;
10540 _SR[i].x/=12.0;
10541 }
10542 Free(buffer);
10543 DUMP("readMDCASKJAIME finished");
10544 return 0;
10545 }
10546
10547 int MDFrame::readXYZ()
10548 {
10549 int i, j, nel, isatom;
10550 char *buffer; char *pp, *q;
10551 char el[5], fname[300];
10552
10553 Matrix33 hinv;
10554
10555 LFile::SubHomeDir(incnfile,fname);
10556 LFile::LoadToString(fname,buffer,0);
10557
10558 pp=buffer;
10559
10560 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10561 sscanf(q, "%d", &_NP);
10562 INFO("readXYZ: NP="<<_NP);
10563
10564 Alloc();
10565
10566 hinv = _H.inv();
10567
10568 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10569
10570 nel = 0;
10571 isatom = 1;
10572 for(i=0;i<_NP;i++)
10573 {
10574 q=pp; pp=strchr(pp,'\n'); if(pp) *(char *)pp++=0;
10575 sscanf(q, "%s %lf %lf %lf",
10576 el,&(_R[i].x),&(_R[i].y),&(_R[i].z));
10577
10578 _SR[i] = hinv*_R[i];
10579
10580 if (i==0)
10581 {
10582 strcpy(element[nel],el); species[i]=nel; nel=1;
10583 }
10584 else
10585 {
10586 for(j=0;j<nel;j++)
10587 {
10588 isatom = strcmp(el, element[j]);
10589 if (!isatom)
10590 {
10591 species[i]=j; break;
10592 }
10593 }
10594 if (isatom)
10595 {
10596 strcpy(element[nel],el); species[i]=nel; nel++;
10597 }
10598 }
10599 }
10600 nspecies = nel;
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619 Free(buffer);
10620 DUMP("readXYZ finished");
10621 return 0;
10622 }
10623
10624
10625 char * LAMMPSFile::describe()
10626 {
10627 static char tmp[500];
10628 sprintf(tmp,"%s","data file MD++ -> LAMMPS\n"
10629 "dump file LAMMPS --> MD++");
10630 return tmp;
10631 }
10632
10633
10634 int LAMMPSFile::readblock(void *p)
10635 {
10636 int i, stepnum, readstepnum, match, atomID, scale;
10637 char *buffer; char *pp, *q;
10638 double xmin, xmax, ymin, ymax, zmin, zmax, xshift, yshift, zshift;
10639 Matrix33 hinv;
10640
10641 MDFrame &d=*((MDFrame *)p);
10642
10643 readstepnum = (int) d.input[0];
10644 scale = (int) d.input[1];
10645
10646 LFile::LoadToString(fname,buffer,0);
10647
10648 INFO("readLAMMPS:: read into string");
10649 pp = buffer;
10650
10651
10652
10653
10654 match = 0;
10655 while (1)
10656 {
10657
10658 pp=strchr(pp, '\n'); if (pp==NULL) break; pp++;
10659
10660
10661 q=pp; pp=strchr(pp,'\n'); if (pp==NULL) break; if(pp) *(char *)pp++=0;
10662 sscanf(q, "%d", &stepnum);
10663
10664
10665 pp=strchr(pp, '\n'); pp++;
10666
10667
10668 q=pp; pp=strchr(pp,'\n'); if (pp==NULL) break; if(pp) *(char *)pp++=0;
10669 sscanf(q, "%d", &d._NP);
10670
10671 if(stepnum!=readstepnum)
10672 {
10673 for(i=0;i<d._NP+5;i++)
10674 {
10675
10676 pp=strchr(pp, '\n'); pp++;
10677 }
10678 INFO_Printf("%d, %d Skip %d lines\n",stepnum, readstepnum, d._NP+5);
10679 }
10680 else
10681 {
10682 match = 1;
10683 INFO_Printf("stepnum = %d matches readstepnum %d\n",stepnum,readstepnum);
10684 INFO("readblock: NP="<<d._NP);
10685 d.Alloc();
10686 INFO("readLAMMPS:: allocated");
10687
10688
10689 pp=strchr(pp, '\n'); pp++;
10690
10691 q=pp; pp=strchr(pp,'\n'); if (pp==NULL) break; if(pp) *(char *)pp++=0;
10692 sscanf(q, "%lf %lf", &xmin, &xmax);
10693 q=pp; pp=strchr(pp,'\n'); if (pp==NULL) break; if(pp) *(char *)pp++=0;
10694 sscanf(q, "%lf %lf", &ymin, &ymax);
10695 q=pp; pp=strchr(pp,'\n'); if (pp==NULL) break; if(pp) *(char *)pp++=0;
10696 sscanf(q, "%lf %lf", &zmin, &zmax);
10697
10698 d._H.clear();
10699 d._H.set(xmax-xmin, 0, 0,
10700 0, ymax-ymin, 0,
10701 0, 0, zmax-zmin);
10702 hinv = d._H.inv();
10703
10704 xshift = (xmax+xmin)/2;
10705 yshift = (ymax+ymin)/2;
10706 zshift = (zmax+zmin)/2;
10707
10708
10709 pp=strchr(pp, '\n'); pp++;
10710 if (scale == 0)
10711 {
10712 for(i=0;i<d._NP;i++)
10713 {
10714 q=pp; pp=strchr(pp,'\n'); if (pp==NULL) break; if(pp) *(char *)pp++=0;
10715 sscanf(q, "%d ", &atomID);
10716 q=strchr(q,' '); q++;
10717
10718
10719
10720 sscanf(q, "%d %lf %lf %lf %lf %lf %lf",
10721 &(d.species[atomID-1]),
10722 &(d._R[atomID-1].x),&(d._R[atomID-1].y),&(d._R[atomID-1].z),
10723 &(d._VR[atomID-1].x),&(d._VR[atomID-1].y),&(d._VR[atomID-1].z));
10724 d.species[atomID-1]-=1;
10725
10726 d._VR[atomID-1].x *= d._TIMESTEP;
10727 d._VR[atomID-1].y *= d._TIMESTEP;
10728 d._VR[atomID-1].z *= d._TIMESTEP;
10729
10730
10731
10732
10733 d._R[atomID-1].x -= xshift;
10734 d._R[atomID-1].y -= yshift;
10735 d._R[atomID-1].z -= zshift;
10736 d._SR[atomID-1]=hinv*d._R[atomID-1];
10737 d._VSR[atomID-1] = hinv*d._VR[atomID-1];
10738 d.fixed[atomID-1]=0;
10739 }
10740 }
10741 else
10742 {
10743 for(i=0;i<d._NP;i++)
10744 {
10745 q=pp; pp=strchr(pp,'\n'); if (pp==NULL) break; if(pp) *(char *)pp++=0;
10746 sscanf(q, "%d ", &atomID);
10747 q=strchr(q,' '); q++;
10748 sscanf(q, "%d %lf %lf %lf %lf %lf %lf",
10749 &(d.species[atomID-1]),
10750 &(d._SR[atomID-1].x),&(d._SR[atomID-1].y),&(d._SR[atomID-1].z),
10751 &(d._VR[atomID-1].x),&(d._VR[atomID-1].y),&(d._VR[atomID-1].z));
10752 d.species[atomID-1]-=1;
10753
10754
10755 d._VR[atomID-1].x *= d._TIMESTEP;
10756 d._VR[atomID-1].y *= d._TIMESTEP;
10757 d._VR[atomID-1].z *= d._TIMESTEP;
10758 d._VSR[atomID-1] = hinv*d._VR[atomID-1];
10759
10760
10761
10762
10763 d._SR[atomID-1].x -= 0.5;
10764 d._SR[atomID-1].y -= 0.5;
10765 d._SR[atomID-1].z -= 0.5;
10766
10767 d.fixed[atomID-1]=0;
10768 }
10769 }
10770 break;
10771 }
10772 }
10773 if(!match)
10774 ERROR("No match stepnum found!");
10775
10776 Free(buffer);
10777 return 0;
10778 }
10779
10780 int LAMMPSFile::writeblock(void *p)
10781 {
10782 int i;
10783 double xmag, ymag, zmag;
10784 class Vector3 c1, c2, c3;
10785 MDFrame &d=*((MDFrame *)p);
10786
10787 c1.set(d._H[0][0],d._H[1][0],d._H[2][0]);
10788 c2.set(d._H[0][1],d._H[1][1],d._H[2][1]);
10789 c3.set(d._H[0][2],d._H[1][2],d._H[2][2]);
10790 xmag = c1.norm(); ymag = c2.norm(); zmag = c3.norm();
10791
10792 f->Printf("LAMMPS data file by MD++ [%s]\n",d.dirname);
10793 f->Printf("%d atoms\n",d._NP);
10794 f->Printf("%d atom types\n",d.nspecies);
10795
10796
10797
10798 f->Printf("0 %25.17e xlo xhi\n",xmag);
10799 f->Printf("0 %25.17e ylo yhi\n",ymag);
10800 f->Printf("0 %25.17e zlo zhi\n\n",zmag);
10801
10802
10803 f->Printf("Masses\n\n");
10804
10805
10806
10807 for(i=0;i<d.nspecies;i++)
10808 f->Printf("%d %12.9e \n",i+1,d._ATOMMASS[i]);
10809 f->Printf("\n");
10810
10811 f->Printf("Atoms \n\n");
10812
10813
10814 for(i=0;i<d._NP;i++)
10815 {
10816 d._SR[i].x += 0.5;
10817 d._SR[i].y += 0.5;
10818 d._SR[i].z += 0.5;
10819 }
10820
10821 d.SHtoR();
10822 for(i=0;i<d._NP;i++)
10823 {
10824 f->Printf("%d %d %25.17e %25.17e %25.17e\n",
10825 i+1, d.species[i]+1, d._R[i].x,d._R[i].y,d._R[i].z);
10826 }
10827
10828 INFO("writevelocity="<<d.writevelocity);
10829 if (d.writevelocity)
10830 {
10831 f->Printf("\nVelocities \n\n");
10832
10833
10834 for(i=0;i<d._NP;i++)
10835 {
10836 d._VR[i] = d._H*d._VSR[i];
10837 f->Printf("%d %25.17e %25.17e %25.17e\n",
10838 i+1, d._VR[i].x/d._TIMESTEP,d._VR[i].y/d._TIMESTEP,d._VR[i].z/d._TIMESTEP);
10839 }
10840 }
10841 return 0;
10842 }
10843
10844
10845
10846
10847
10848 char * PropFile::describe()
10849 {
10850 static char tmp[500];
10851
10852
10853 sprintf(tmp,"property at every %d time steps",MDFrame().savepropfreq);
10854 return tmp;
10855 }
10856
10857 int PropFile::writeentry(void *p)
10858 {
10859 char tmp[500];
10860 MDFrame &d=*((MDFrame *)p);
10861 if(strlen(d.output_str)>0)
10862 {
10863 *f<<d.output_str;
10864
10865 }
10866 else
10867 {
10868 sprintf(tmp,"%12d %20.13e %20.13e %20.13e "
10869 "%20.13e %20.13e %20.13e %20.13e "
10870 "%20.13e %20.13e %20.13e %20.13e %20.13e\n",
10871 d.curstep,
10872 d._KATOM,
10873 d._EPOT,
10874 d._TOTSTRESS.trace()/3,
10875 d._TOTSTRESS[0][1],
10876 d._TOTSTRESS[1][2],
10877 d._TOTSTRESS[2][0],
10878 d._HELM,
10879 d._HELMP,
10880 d._T,
10881 d.zeta,
10882 d.dEdlambda,
10883 d._OMEGA
10884 );
10885 *f<<tmp;
10886 }
10887 return 0;
10888 }
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905 void MDFrame::writefortraninifile(char *fname)
10906 {
10907 FILE *fp;
10908 char extpath[200];
10909
10910 INFO("MDFrame::writefortraninifile "<<fname);
10911 LFile::SubHomeDir(fortranpath,extpath);
10912 INFO("fortranpath "<<fortranpath<<" extpath "<<extpath<<" potfile"<<potfile);
10913 fp=fopen(fname,"w");
10914 if(fp==NULL)
10915 {
10916 FATAL("writefortraniinfile: open file failure");
10917 }
10918 fprintf(fp,"#1 Settings for F90 Relax BCC Code (generated by MD++)\n");
10919 fprintf(fp,"#2 Potential file name: (Note that there is a Tab before the file name!\n");
10920 fprintf(fp,"\t%s/%s\n",extpath,potfile);
10921 fprintf(fp,"#4 Initial configuration file name(*.cn):\n");
10922 fprintf(fp,"\tinit.cn\n");
10923 fprintf(fp,"#6 Final output configuration file name (*.cn):\n");
10924 fprintf(fp,"\tfrelaxed.cn\n");
10925 fprintf(fp,"\n");
10926 fprintf(fp,"#9 Stress components: (In GPa)\n");
10927 fprintf(fp,"#10 pr(1,1), pr(2,2), pr(3,3):\n");
10928 fprintf(fp,"\t%E\t%E\t%E\n",
10929 _EXTSTRESS[0][0]*1e-3*_EXTSTRESSMUL+_EXTPRESSADD*1e-3,
10930 _EXTSTRESS[1][1]*1e-3*_EXTSTRESSMUL+_EXTPRESSADD*1e-3,
10931 _EXTSTRESS[2][2]*1e-3*_EXTSTRESSMUL+_EXTPRESSADD*1e-3);
10932 fprintf(fp,"#12 pr(1,2), pr(2,3), pr(3,1):\n");
10933 fprintf(fp,"\t%E\t%E\t%E\n",
10934 _EXTSTRESS[0][1]*1e-3*_EXTSTRESSMUL,
10935 _EXTSTRESS[1][2]*1e-3*_EXTSTRESSMUL,
10936 _EXTSTRESS[2][0]*1e-3*_EXTSTRESSMUL);
10937 fprintf(fp,"\n");
10938 fprintf(fp,"#15 Conjugate gradient search settings:\n");
10939 fprintf(fp,"#16 The first trial step in optimization (dfpred):\n");
10940 fprintf(fp,"\t%e\n",conj_dfpred);
10941 fprintf(fp,"#18 Tolerance on the residual gradient (gradtl / np):\n");
10942 fprintf(fp,"\t%e\n",conj_ftol);
10943 fprintf(fp,"#20 Max number of force calls (maxfn):\n");
10944 fprintf(fp,"\t%d\n",conj_fevalmax);
10945 fprintf(fp,"\n");
10946 fprintf(fp,"#23 Allow box vector to relax? ('1' for yes, '0' for no.) \n");
10947 fprintf(fp,"\t%d\n",!conj_fixbox);
10948 fprintf(fp,"#25 Write the configuration sequence to files? ('1' for yes, '0' for no.)\n");
10949 fprintf(fp,"\t%d\n",savecn);
10950 fprintf(fp,"#27 If yes, frequency of saving configuration? (per how many timesteps)\n");
10951 fprintf(fp,"\t%d\n",savecnfreq);
10952 fprintf(fp,"\n");
10953 fprintf(fp,"#30 Set fixed atoms specification (iffixed, sy0, sy1, sy2, sy3)\n");
10954 fprintf(fp,"\t0 0.0 0.0 0.0 0.0\n");
10955 fprintf(fp,"#32 CN format 1: sx,sy,sz, 2: sx,sy,sz, 3: sx,sy,sz,vx,vy,vz,pot,iffixed\n");
10956 if(writeall) fprintf(fp,"\t3\n");
10957 else if(writevelocity) fprintf(fp,"\t2\n");
10958 else fprintf(fp,"\t1\n");
10959
10960 fclose(fp);
10961 }
10962
10963 void MDFrame::fortranrelax()
10964 {
10965 char extpath[200], comsav[200];
10966
10967 LFile::SubHomeDir(fortranpath,extpath);
10968
10969 writefortraninifile("Relax.ini");
10970 strcpy(comsav,command);
10971
10972 sprintf(finalcnfile,"init.cn");
10973 writefinalcnfile(zipfiles,false);
10974
10975 sprintf(command,"%s/%s",extpath,fortranexe);
10976 runcommand();
10977
10978 sprintf(incnfile,"frelaxed.cn");
10979 readcn();
10980
10981
10982
10983 sprintf(command,"gzip -f frelaxed.cn");
10984 runcommand();
10985
10986
10987 sprintf(command,"gzip -f init.cn");
10988 runcommand();
10989
10990 strcpy(command,comsav);
10991 }
10992
10993
10994
10995 void MDFrame::writeatomeyecfgfile(char *fname)
10996 {
10997 FILE *fp;
10998 int i, nplot, nr, n1, n2, n3, nn, ix, iy, iz, k;
10999 Matrix33 h; Vector3 s;
11000 int nw, cind; double Emin, Emax;
11001
11002 INFO("MDFrame::writeatomeyecfgfile "<<fname);
11003
11004 switch(plot_color_axis){
11005 case(0): color_ind=_EPOT_IND; break;
11006 case(1): color_ind=_EPOT_IND; break;
11007 case(2): color_ind=_TOPOL; break;
11008 case(4): color_ind=_TOPOL; break;
11009 case(8): color_ind=_TOPOL; break;
11010 default: ERROR("plot() unknown coloraxis "<<plot_color_axis); return;
11011 }
11012
11013 fp=fopen(fname,"w");
11014 if(fp==NULL)
11015 {
11016 FATAL("writeatomeyecfgfile: open file failure");
11017 }
11018
11019 nplot = 0;
11020 nr = atomeyerepeat[0];
11021 if(nr!=0)
11022 {
11023 n1=atomeyerepeat[1];
11024 n2=atomeyerepeat[2];
11025 n3=atomeyerepeat[3];
11026 if(n1<=0) n1=1;
11027 if(n2<=0) n2=1;
11028 if(n3<=0) n3=1;
11029 nn = n1*n2*n3;
11030 INFO_Printf("atomeyerepeat ( %d %d %d )\n",
11031 n1, n2, n3);
11032 }
11033 else
11034 {
11035 nn = n1 = n2 = n3 = 1;
11036 }
11037
11038 nw = (int)plot_color_windows[0];
11039 for(i=0;i<_NP;i++)
11040 {
11041 if(nw>0)
11042 {
11043 if(plot_limits[0]==1)
11044 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11045 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11046 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11047 {
11048 continue;
11049 }
11050 for(k=0;k<nw;k++)
11051 {
11052 Emin = plot_color_windows[k*3+1];
11053 Emax = plot_color_windows[k*3+2];
11054 cind = (int) plot_color_windows[k*3+3];
11055
11056 if((color_ind[i]>=Emin)&&
11057 (color_ind[i]<=Emax))
11058 {
11059 nplot ++;
11060 continue;
11061 }
11062 }
11063 }
11064 else
11065 {
11066 if(plot_limits[0]==1)
11067 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11068 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11069 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11070 {
11071
11072 continue;
11073 }
11074 nplot ++;
11075 }
11076 }
11077 h=_H.tran();
11078 fprintf(fp,"Number of particles = %d\n",nplot*nn);
11079 fprintf(fp,"A = 1.0 Angstrom (basic length-scale)\n");
11080 fprintf(fp,"H0(1,1) = %f A\n",h[0][0]*n1);
11081 fprintf(fp,"H0(1,2) = %f A\n",h[0][1]*n1);
11082 fprintf(fp,"H0(1,3) = %f A\n",h[0][2]*n1);
11083 fprintf(fp,"H0(2,1) = %f A\n",h[1][0]*n2);
11084 fprintf(fp,"H0(2,2) = %f A\n",h[1][1]*n2);
11085 fprintf(fp,"H0(2,3) = %f A\n",h[1][2]*n2);
11086 fprintf(fp,"H0(3,1) = %f A\n",h[2][0]*n3);
11087 fprintf(fp,"H0(3,2) = %f A\n",h[2][1]*n3);
11088 fprintf(fp,"H0(3,3) = %f A\n",h[2][2]*n3);
11089 #define ATOMEYE_EXTCFG
11090 #ifdef ATOMEYE_EXTCFG
11091 fprintf(fp,".NO_VELOCITY.\n");
11092 fprintf(fp,"entry_count = 4\n");
11093 fprintf(fp,"auxiliary[0] = pote [eV]\n");
11094
11095
11096 for(i=0;i<_NP;i++)
11097 {
11098 s=_SR[i];
11099 if(plot_map_pbc==1) s.subint();
11100 if(plot_limits[0]==1)
11101 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11102 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11103 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11104 {
11105 continue;
11106 }
11107
11108 if(nw>0)
11109 {
11110 for(k=0;k<nw;k++)
11111 {
11112 Emin = plot_color_windows[k*3+1];
11113 Emax = plot_color_windows[k*3+2];
11114 cind = (int) plot_color_windows[k*3+3];
11115
11116 if((color_ind[i]>=Emin)&&
11117 (color_ind[i]<=Emax))
11118 {
11119 for(ix=0;ix<n1;ix++)
11120 for(iy=0;iy<n2;iy++)
11121 for(iz=0;iz<n3;iz++)
11122 {
11123 fprintf(fp,"%f\n%s\n %f %f %f %f \n",
11124 _ATOMMASS[species[i]],element[species[i]],
11125 (s.x+0.5+ix)/n1,
11126 (s.y+0.5+iy)/n2,
11127 (s.z+0.5+iz)/n3,
11128 color_ind[i]);
11129 }
11130
11131 continue;
11132 }
11133 }
11134 }
11135 else
11136 {
11137 if(plot_limits[0]==1)
11138 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11139 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11140 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11141 {
11142 continue;
11143 }
11144 for(ix=0;ix<n1;ix++)
11145 for(iy=0;iy<n2;iy++)
11146 for(iz=0;iz<n3;iz++)
11147 {
11148 fprintf(fp,"%f\n%s\n%f %f %f %f \n",
11149 _ATOMMASS[species[i]],element[species[i]],
11150 (s.x+0.5+ix)/n1,
11151 (s.y+0.5+iy)/n2,
11152 (s.z+0.5+iz)/n3,
11153 color_ind[i]);
11154 }
11155 }
11156 }
11157 #else
11158 for(i=0;i<_NP;i++)
11159 {
11160 for(ix=0;ix<n1;ix++)
11161 for(iy=0;iy<n2;iy++)
11162 for(iz=0;iz<n3;iz++)
11163 {
11164 fprintf(fp,"%f %s %f %f %f %f %f %f\n",
11165 _ATOMMASS[species[i]],element[species[i]],
11166 (s.x+0.5+ix)/n1,
11167 (s.y+0.5+iy)/n2,
11168 (s.z+0.5+iz)/n3,
11169 _VSR[i].x/n1,
11170 _VSR[i].y/n2,
11171 _VSR[i].z/n3);
11172 }
11173 }
11174 #endif
11175 fclose(fp);
11176 }
11177
11178 void MDFrame::convertCNtoCFG()
11179 {
11180 int i, istart, iend;
11181 char cfgfname[100];
11182
11183 istart = (int) input [0];
11184 iend = (int) input [1];
11185
11186 for(i=istart;i<=iend;i++)
11187 {
11188 if(strlen(incnfile)>=12)
11189 {
11190 sprintf(incnfile + strlen(incnfile)-12,"inter%04d.cn",i);
11191 strcpy(cfgfname,incnfile);
11192 sprintf(cfgfname + strlen(cfgfname)-12,"inter%04d.cfg",i);
11193 }
11194 else
11195 {
11196 sprintf(incnfile,"inter%04d.cn",i);
11197 sprintf(cfgfname,"inter%04d.cfg",i);
11198 }
11199 readcn();
11200 writeatomeyecfgfile(cfgfname);
11201 }
11202
11203 }
11204
11205
11206 void MDFrame::writepovray(char *fname)
11207 {
11208 FILE *fp;
11209 int i, nplot, nr, n1, n2, n3, nn, ix, iy, iz, k, ipt, jpt;
11210 Vector3 r, sr;
11211 int nw, cind; double Emin, Emax;
11212
11213 INFO("MDFrame::writepovray "<<fname);
11214
11215 switch(plot_color_axis){
11216 case(0): color_ind=_EPOT_IND; break;
11217 case(1): color_ind=_EPOT_IND; break;
11218 case(2): color_ind=_TOPOL; break;
11219 case(4): color_ind=_TOPOL; break;
11220 case(8): color_ind=_TOPOL; break;
11221 default: ERROR("plot() unknown coloraxis "<<plot_color_axis); return;
11222 }
11223
11224 fp=fopen(fname,"w");
11225 if(fp==NULL)
11226 {
11227 FATAL("writepovray: open file failure");
11228 }
11229
11230 nplot = 0;
11231 nr = atomeyerepeat[0];
11232 if(nr!=0)
11233 {
11234 n1=atomeyerepeat[1];
11235 n2=atomeyerepeat[2];
11236 n3=atomeyerepeat[3];
11237 if(n1<=0) n1=1;
11238 if(n2<=0) n2=1;
11239 if(n3<=0) n3=1;
11240 nn = n1*n2*n3;
11241 INFO_Printf("povraypeat ( %d %d %d )\n",
11242 n1, n2, n3);
11243 }
11244 else
11245 {
11246 nn = n1 = n2 = n3 = 1;
11247 }
11248
11249 fprintf(fp,"#include \"../viewpoint.pov\"\n");
11250 fprintf(fp,"\n");
11251 fprintf(fp,"union {\n");
11252 fprintf(fp," union {\n");
11253 fprintf(fp,"\n");
11254
11255 nw = (int) plot_color_windows[0];
11256 for(i=0;i<_NP;i++)
11257 {
11258 if(plot_limits[0]==1)
11259 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11260 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11261 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11262 {
11263 continue;
11264 }
11265 if(plot_limits[0]==2)
11266 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11267 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11268 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11269 {
11270 sr.set( (_SR[i].x)/n1,
11271 (_SR[i].y)/n2,
11272 (_SR[i].z)/n3 );
11273 r = _H*sr;
11274 fprintf(fp,"sphere { <%f, %f, %f>, radiusbc "
11275 "pigment { color colorbc "
11276 "transmit transmitbc } "
11277 "finish { phong 1 metallic }"
11278 " }\n",
11279
11280 r.x, r.y, r.z);
11281 continue;
11282 }
11283
11284 if(nw>0)
11285 {
11286 for(k=0;k<nw;k++)
11287 {
11288 Emin = plot_color_windows[k*3+1];
11289 Emax = plot_color_windows[k*3+2];
11290 cind = (int) plot_color_windows[k*3+3];
11291
11292 if((color_ind[i]>=Emin)&&
11293 (color_ind[i]<=Emax))
11294 {
11295 for(ix=0;ix<n1;ix++)
11296 for(iy=0;iy<n2;iy++)
11297 for(iz=0;iz<n3;iz++)
11298 {
11299 sr.set( (_SR[i].x+ix)/n1,
11300 (_SR[i].y+iy)/n2,
11301 (_SR[i].z+iz)/n3 );
11302 r = _H*sr;
11303 fprintf(fp,"sphere { <%f, %f, %f>, radius%02d "
11304 "pigment { color color%02d "
11305 "transmit transmit%02d } "
11306 "finish { phong 1 metallic }"
11307 " }\n",
11308
11309 r.x, r.y, r.z, cind, cind, cind);
11310
11311 }
11312
11313 continue;
11314 }
11315 }
11316 }
11317 else
11318 {
11319 if(plot_limits[0]==1)
11320 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11321 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11322 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11323 {
11324 continue;
11325 }
11326 for(ix=0;ix<n1;ix++)
11327 for(iy=0;iy<n2;iy++)
11328 for(iz=0;iz<n3;iz++)
11329 {
11330 sr.set( (_SR[i].x+ix)/n1,
11331 (_SR[i].y+iy)/n2,
11332 (_SR[i].z+iz)/n3 );
11333 r = _H*sr;
11334
11335
11336
11337 fprintf(fp,"sphere { <%f, %f, %f>, radius%02d "
11338 "pigment { color color%02d "
11339 "transmit transmit%02d } "
11340 "finish { phong 1 metallic }"
11341 " }\n",
11342 r.x, r.y, r.z,species[i],species[i],species[i]);
11343
11344 }
11345 }
11346 }
11347
11348 for(i=0;i<input[0];i++)
11349 {
11350 ipt=(int)input[2*i+1];
11351 jpt=(int)input[2*i+2];
11352 _R[ipt]=_H*_SR[ipt];
11353 _R[jpt]=_H*_SR[jpt];
11354 fprintf(fp,"cylinder{ <%f,%f,%f>, <%f,%f,%f>, radiuscy "
11355 "pigment { color colorcy "
11356 "transmit transmitcy } "
11357 "finish { phong 1 metallic }"
11358 " }\n",
11359 _R[ipt].x,_R[ipt].y,_R[ipt].z,
11360 _R[jpt].x,_R[jpt].y,_R[jpt].z);
11361 }
11362
11363 fprintf(fp,"\n");
11364 fprintf(fp,"\n");
11365 fprintf(fp," }\n");
11366 fprintf(fp," AdditionItems01\n");
11367 fprintf(fp," no_shadow\n");
11368 fprintf(fp," rotate rot01\n");
11369 fprintf(fp," rotate rot02\n");
11370 fprintf(fp," rotate rot03\n");
11371 fprintf(fp,"}\n");
11372
11373 fclose(fp);
11374 }
11375
11376 void MDFrame::atomeye()
11377 {
11378 char extpath[200], comsav[200];
11379
11380 LFile::SubHomeDir(atomeyepath,extpath);
11381
11382 writeatomeyecfgfile("atomeye.cfg");
11383 strcpy(comsav,command);
11384
11385 #if 1
11386 sprintf(command,"gzip -f atomeye.cfg");
11387 runcommand();
11388
11389 sprintf(command,"\"%s/%s\" atomeye.cfg.gz &",extpath,atomeyeexe);
11390 runcommand();
11391 #else
11392 sprintf(command,"\"%s/%s\" atomeye.cfg &",extpath,atomeyeexe);
11393 runcommand();
11394 #endif
11395 strcpy(command,comsav);
11396 }
11397
11398
11399
11400
11401 void MDFrame::writeENERGY(char *fname)
11402 {
11403 FILE *fp;
11404 int i;
11405
11406 INFO("MDFrame::writeENERGY "<<fname);
11407
11408 switch(plot_color_axis){
11409 case(0): color_ind=_EPOT_IND; break;
11410 case(1): color_ind=_EPOT_IND; break;
11411 case(2): color_ind=_TOPOL; break;
11412 case(4): color_ind=_TOPOL; break;
11413 case(8): color_ind=_TOPOL; break;
11414 default: ERROR("writeENERGY() unknown coloraxis "<<plot_color_axis); return;
11415 }
11416
11417 fp=fopen(fname,"w");
11418 if(fp==NULL)
11419 {
11420 FATAL("writeENERGY: open file failure");
11421 }
11422
11423 for(i=0;i<_NP;i++)
11424 {
11425 fprintf(fp," %20.16e\n",color_ind[i]);
11426 }
11427
11428 fclose(fp);
11429 }
11430
11431 void MDFrame::writeFORCE(char *fname)
11432 {
11433 FILE *fp;
11434 int i;
11435
11436 INFO("MDFrame::writeFORCE "<<fname);
11437
11438 fp=fopen(fname,"w");
11439 if(fp==NULL)
11440 {
11441 FATAL("writeFORCE: open file failure");
11442 }
11443
11444 if(input[0]==1) INFO("only write forces on fixed atoms");
11445 for(i=0;i<_NP;i++)
11446 {
11447 if(input[0]==1)
11448 {
11449 if(fixed[i]!=0)
11450 fprintf(fp,"%6d %20.12e %20.12e %20.12e %4d\n",
11451 i,_F0[i].x,_F0[i].y,_F0[i].z,fixed[i]);
11452 }
11453 else
11454 {
11455 fprintf(fp,"%6d %20.12e %20.12e %20.12e %4d\n",
11456 i,_F[i].x,_F[i].y,_F[i].z,fixed[i]);
11457 }
11458 }
11459 fclose(fp);
11460 }
11461
11462 void MDFrame::writePOSITION(char *fname)
11463 {
11464 FILE *fp;
11465 int i;
11466
11467 INFO("MDFrame::writePOSITION "<<fname);
11468
11469 SHtoR();
11470 fp=fopen(fname,"w");
11471 if(fp==NULL)
11472 {
11473 FATAL("writePOSITION: open file failure");
11474 }
11475
11476 if(input[0]==1) INFO("only write positions of fixed atoms");
11477 for(i=0;i<_NP;i++)
11478 {
11479 if(input[0]==1)
11480 {
11481 if(fixed[i]!=0)
11482 fprintf(fp,"%6d %20.12e %20.12e %20.12e %4d\n",
11483 i,_R[i].x,_R[i].y,_R[i].z,fixed[i]);
11484 }
11485 else
11486 {
11487 fprintf(fp,"%6d %20.12e %20.12e %20.12e %4d\n",
11488 i,_R[i].x,_R[i].y,_R[i].z,fixed[i]);
11489 }
11490 }
11491 fclose(fp);
11492 }
11493
11494 void MDFrame::writeMDCASKXYZ(char *fname)
11495 {
11496 FILE *fp;
11497 int i;
11498 char extname[200];
11499 Vector3 r;
11500
11501 LFile::SubHomeDir(fname,extname);
11502
11503 INFO("MDFrame::writeMDCASKXYZ "<<extname);
11504
11505 fp=fopen(extname,"w");
11506 if(fp==NULL)
11507 {
11508 FATAL("writeMDCASKXYZ: open file failure");
11509 }
11510
11511 fprintf(fp,"%d\n",_NP);
11512 if(_SAVEMEMORY==9)
11513 {
11514 for(i=0;i<_NP;i++)
11515 {
11516 r=_H*_SR[i];
11517 fprintf(fp,"%20.16e %20.16e %20.16e\n",
11518 r.x,r.y,r.z);
11519 }
11520 }
11521 else
11522 {
11523 SHtoR();
11524 for(i=0;i<_NP;i++)
11525 {
11526 fprintf(fp,"%20.16e %20.16e %20.16e\n",
11527 _R[i].x,_R[i].y,_R[i].z);
11528 }
11529 }
11530 fclose(fp);
11531 }
11532
11533 void MDFrame::writeatomtv(char *fname)
11534 {
11535 FILE *fp;
11536 int i, k, nw, cind, nplot;
11537 double Emin, Emax;
11538 char extname[200];
11539
11540 LFile::SubHomeDir(fname,extname);
11541
11542 INFO("MDFrame::writeatomtv "<<extname);
11543
11544 fp=fopen(extname,"w");
11545 if(fp==NULL)
11546 {
11547 FATAL("writeatomtv: open file failure");
11548 }
11549
11550 fprintf(fp,"%d\n",2);
11551
11552
11553 fprintf(fp," %d 0 \" box \"\n",8);
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564 fprintf(fp," %lf %lf %lf %lf %lf\n",-_H[2][2]/2,-_H[1][1]/2,-_H[0][0]/2,0.,0.);
11565 fprintf(fp," %lf %lf %lf %lf %lf\n",-_H[2][2]/2,-_H[1][1]/2, _H[0][0]/2,0.,0.);
11566 fprintf(fp," %lf %lf %lf %lf %lf\n",-_H[2][2]/2, _H[1][1]/2,-_H[0][0]/2,0.,0.);
11567 fprintf(fp," %lf %lf %lf %lf %lf\n",-_H[2][2]/2, _H[1][1]/2, _H[0][0]/2,0.,0.);
11568 fprintf(fp," %lf %lf %lf %lf %lf\n", _H[2][2]/2,-_H[1][1]/2,-_H[0][0]/2,0.,0.);
11569 fprintf(fp," %lf %lf %lf %lf %lf\n", _H[2][2]/2,-_H[1][1]/2, _H[0][0]/2,0.,0.);
11570 fprintf(fp," %lf %lf %lf %lf %lf\n", _H[2][2]/2, _H[1][1]/2,-_H[0][0]/2,0.,0.);
11571 fprintf(fp," %lf %lf %lf %lf %lf\n", _H[2][2]/2, _H[1][1]/2, _H[0][0]/2,0.,0.);
11572 SHtoR();
11573 switch(plot_color_axis){
11574 case(0): color_ind=_EPOT_IND; break;
11575 case(1): color_ind=_EPOT_IND; break;
11576 case(2): color_ind=_TOPOL; break;
11577 case(4): color_ind=_TOPOL; break;
11578 case(8): color_ind=_TOPOL; break;
11579 default: ERROR("plot() unknown coloraxis "<<plot_color_axis); return;
11580 }
11581 nw = (int) plot_color_windows[0];
11582 nplot = 0;
11583 for(i=0;i<_NP;i++)
11584 {
11585 if(nw>0)
11586 {
11587 if(plot_limits[0]==1)
11588 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11589 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11590 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11591 {
11592 continue;
11593 }
11594 for(k=0;k<nw;k++)
11595 {
11596 Emin = plot_color_windows[k*3+1];
11597 Emax = plot_color_windows[k*3+2];
11598 cind = (int) plot_color_windows[k*3+3];
11599
11600 if((color_ind[i]>=Emin)&&
11601 (color_ind[i]<=Emax))
11602 {
11603 nplot++;
11604 continue;
11605 }
11606 }
11607 }
11608 }
11609
11610 fprintf(fp," %d 0 \" real frame 1 \"\n",nplot);
11611 for(i=0;i<_NP;i++)
11612 {
11613 if(nw>0)
11614 {
11615 if(plot_limits[0]==1)
11616 if((_SR[i].x<plot_limits[1])||(_SR[i].x>plot_limits[2])
11617 ||(_SR[i].y<plot_limits[3])||(_SR[i].y>plot_limits[4])
11618 ||(_SR[i].z<plot_limits[5])||(_SR[i].z>plot_limits[6]))
11619 {
11620 continue;
11621 }
11622 for(k=0;k<nw;k++)
11623 {
11624 Emin = plot_color_windows[k*3+1];
11625 Emax = plot_color_windows[k*3+2];
11626 cind = (int) plot_color_windows[k*3+3];
11627
11628 if((color_ind[i]>=Emin)&&
11629 (color_ind[i]<=Emax))
11630 {
11631 fprintf(fp,"%f %f %f %f %f\n",
11632
11633 _R[i].z,_R[i].y,-_R[i].x,_EPOT_IND[i],_TOPOL[i]);
11634 continue;
11635 }
11636 }
11637 }
11638 }
11639 fclose(fp);
11640 }
11641
11642 void MDFrame::readRASMOLXYZ(char *fname)
11643 {
11644 int i;
11645 char *buffer; char *pp; char extname[200];
11646
11647 LFile::SubHomeDir(fname,extname);
11648
11649 LFile::LoadToString(extname,buffer,0);
11650
11651 pp=buffer;
11652 sscanf(pp, "%d", &_NP);
11653 INFO("readRASMOLXYZ: NP="<<_NP);
11654
11655 Alloc();
11656
11657 pp=strchr(pp, '\n'); pp++;
11658
11659
11660 pp=strchr(pp, '\n'); pp++;
11661 for(i=0;i<_NP;i++)
11662 {
11663 char *q;
11664 q=pp;
11665 pp=strchr(pp,'\n');
11666 if(pp) *(char *)pp++=0;
11667 _VSR[i].clear();
11668 fixed[i]=0;
11669 sscanf(q, "%s %lf %lf %lf %lf %lf",
11670 element[0],
11671 &(_R[i].x),&(_R[i].y),&(_R[i].z),
11672 &(_EPOT_IND[i]),&(_TOPOL[i]));
11673
11674 }
11675
11676 sscanf(pp, "%lf %lf %lf %lf %lf %lf %lf %lf %lf",
11677 &_H[0][0],&_H[0][1],&_H[0][2],
11678 &_H[1][0],&_H[1][1],&_H[1][2],
11679 &_H[2][0],&_H[2][1],&_H[2][2]);
11680 Free(buffer);
11681 RHtoS();
11682 INFO("readRASMOLXYZ finished");
11683 }
11684
11685 void MDFrame::writeRASMOLXYZ(char *fname)
11686 {
11687 FILE *fp;
11688 int i;
11689 char extname[200];
11690
11691 LFile::SubHomeDir(fname,extname);
11692
11693 INFO("MDFrame::writeRASMOLXYZ "<<extname);
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706 fp=fopen(extname,"w");
11707 if(fp==NULL)
11708 {
11709 FATAL("writeRASMOLXYZ: open file failure");
11710 }
11711
11712 fprintf(fp,"%d\n",_NP);
11713 fprintf(fp,"RASMOL XYZ file prepared by MD++\n");
11714 SHtoR();
11715 for(i=0;i<_NP;i++)
11716 {
11717
11718
11719
11720
11721 fprintf(fp,"%s %20.16e %20.16e %20.16e %20.16e %20.16e\n",
11722 element[0],_R[i].x,_R[i].y,_R[i].z,
11723 _EPOT_IND[i], _TOPOL[i]);
11724 }
11725 fprintf(fp," %20.16e %20.16e %20.16e\n"
11726 " %20.16e %20.16e %20.16e\n"
11727 " %20.16e %20.16e %20.16e\n",
11728 _H[0][0],_H[0][1],_H[0][2],
11729 _H[1][0],_H[1][1],_H[1][2],
11730 _H[2][0],_H[2][1],_H[2][2]);
11731
11732 fclose(fp);
11733 }
11734
11735 void MDFrame::writePINYMD(char *fname)
11736 {
11737 FILE *fp;
11738 int i;
11739 char extname[200];
11740
11741 LFile::SubHomeDir(fname,extname);
11742
11743 INFO("MDFrame::writePINYMD "<<extname);
11744
11745 fp=fopen(extname,"w");
11746 if(fp==NULL)
11747 {
11748 FATAL("writePINYMD: open file failure");
11749 }
11750
11751 fprintf(fp,"natm_tot restart_typ itime pi_beads (from MD++)\n");
11752 fprintf(fp,"%d restart_all %d %d\n",_NP,totalsteps,1);
11753 fprintf(fp,"atm pos, atm_typ, mol_typ mol_num\n");
11754 SHtoR();
11755 for(i=0;i<_NP;i++)
11756 {
11757 fprintf(fp,"%20.16e %20.16e %20.16e a%s %s %s %d %d\n",
11758 _R[i].x,_R[i].y,_R[i].z,
11759 element[species[i]],
11760 element[species[i]],
11761 element[species[i]],
11762 i+1, 1);
11763 }
11764 fprintf(fp,"h matrix\n");
11765 fprintf(fp," %20.16e %20.16e %20.16e\n"
11766 " %20.16e %20.16e %20.16e\n"
11767 " %20.16e %20.16e %20.16e\n",
11768 _H[0][0],_H[0][1],_H[0][2],
11769 _H[1][0],_H[1][1],_H[1][2],
11770 _H[2][0],_H[2][1],_H[2][2]);
11771 fprintf(fp,"h matrix for Ewald setup\n");
11772 fprintf(fp," %20.16e %20.16e %20.16e\n"
11773 " %20.16e %20.16e %20.16e\n"
11774 " %20.16e %20.16e %20.16e\n",
11775 _H[0][0],_H[0][1],_H[0][2],
11776 _H[1][0],_H[1][1],_H[1][2],
11777 _H[2][0],_H[2][1],_H[2][2]);
11778 fprintf(fp,"1/3 log(Vol)\n%20.16e\n",log(_H.det())/3.0);
11779
11780 fprintf(fp,"atm vel\n");
11781 for(i=0;i<_NP;i++)
11782 {
11783 fprintf(fp,"%20.16e %20.16e %20.16e\n",
11784 _VR[i].x,_VR[i].y,_VR[i].z);
11785 }
11786 fprintf(fp,"number of atm nhc, length of nhc\n%d %d\n",
11787 _NP,2);
11788 fprintf(fp,"atm nhc velocities\n");
11789 for(i=0;i<_NP;i++)
11790 {
11791 fprintf(fp,"%20.16e\n%20.16e\n",0.,0.);
11792 }
11793 fprintf(fp,"vol velocities\n");
11794 fprintf(fp," %20.16e %20.16e %20.16e\n"
11795 " %20.16e %20.16e %20.16e\n"
11796 " %20.16e %20.16e %20.16e\n",
11797 0.,0.,0.,0.,0.,0.,0.,0.,0.);
11798 fprintf(fp,"log(vol) velocity\n%20.16e\n",0.);
11799 fprintf(fp,"vol nhc velocities\n%20.16e\n%20.16e\n",0.,0.);
11800
11801 fclose(fp);
11802 }
11803
11804 void MDFrame::GnuPlotHistogram()
11805 {
11806
11807
11808
11809
11810
11811
11812
11813 FILE *fp;
11814 int i, nbin, *counts, n;
11815 double Emin, Emax, *Ebin, dE;
11816 char comsav[200];
11817
11818 INFO("MDFrame::GnuPlotEnergyHistogram");
11819
11820 switch(plot_color_axis){
11821 case(0): color_ind=_EPOT_IND; break;
11822 case(1): color_ind=_EPOT_IND; break;
11823 case(2): color_ind=_TOPOL; break;
11824 case(4): color_ind=_TOPOL; break;
11825 case(8): color_ind=_TOPOL; break;
11826 default: ERROR("plot() unknown coloraxis "<<plot_color_axis); return;
11827 }
11828
11829
11830 Emin = input[0];
11831 Emax = input[1];
11832 nbin = (int)input[2];
11833
11834 if(Emin==Emax)
11835 {
11836 Emin=Emax=color_ind[0];
11837 for(i=1;i<_NP;i++)
11838 {
11839 if(Emin>color_ind[i]) Emin=color_ind[i];
11840 if(Emax<color_ind[i]) Emax=color_ind[i];
11841 }
11842 }
11843 if(fabs(Emin-Emax)<2e-8)
11844 {
11845 Emin-=1e-8;
11846 Emax+=1e-8;
11847 }
11848 if(nbin<=0) nbin=20;
11849 dE=(Emax-Emin)/nbin;
11850
11851
11852 counts=(int *)malloc(sizeof(double)*nbin);
11853 Ebin =(double *)malloc(sizeof(double)*nbin);
11854 for(i=0;i<nbin;i++)
11855 {
11856 Ebin[i]=dE*(i+0.5)+Emin;
11857 counts[i]=0;
11858 }
11859
11860 for(i=0;i<_NP;i++)
11861 {
11862 n=(int)floor((color_ind[i]-Emin)/dE);
11863 if((n>=0)&&(n<nbin))
11864 counts[n]++;
11865 }
11866
11867 writeENERGY("eng.out");
11868
11869 fp=fopen("enghist.out","w");
11870 if(fp==NULL)
11871 {
11872 FATAL("GnuPlotEnergyHistogram: open file failure");
11873 }
11874
11875 for(i=0;i<nbin;i++)
11876 {
11877 fprintf(fp," %20.16e %d\n",Ebin[i],counts[i]);
11878 }
11879 fclose(fp);
11880
11881 free(counts);
11882 free(Ebin);
11883
11884
11885
11886 fp=fopen("plotenghist.gp","w");
11887 if(fp==NULL)
11888 {
11889 FATAL("GnuPlotEnergyHistogram: open file failure");
11890 }
11891 fprintf(fp,"plot 'enghist.out' with histeps\n");
11892 fclose(fp);
11893
11894 fp=fopen("gpw","w");
11895 if(fp==NULL)
11896 {
11897 FATAL("GnuPlotEnergyHistogram: open file failure");
11898 }
11899 fprintf(fp,
11900 "#!/bin/bash\n"
11901
11902
11903
11904
11905 "gnuplot plotenghist.gp -\n");
11906 fclose(fp);
11907
11908 strcpy(comsav,command);
11909 sprintf(command,"chmod u+x gpw"); runcommand();
11910 sprintf(command,"xterm -fn 7x13 -sb -e ./gpw &\n");
11911 runcommand();
11912 strcpy(command,comsav);
11913 }
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935 void MDFrame::openwin()
11936 {
11937 openwindow(win_width,win_height,dirname);
11938 }
11939
11940 int MDFrame::openwindow(int w,int h,const char *n)
11941 {
11942 if(win!=NULL)
11943 if(win->alive) return -1;
11944 win=new YWindow(w,h,n,true,true,false);
11945 if(win==NULL) return -1;
11946 else
11947 {
11948 win->setinterval(100);
11949 win->Run();
11950 return 0;
11951 }
11952 }
11953
11954 void MDFrame::closewindow() {delete(win);}
11955
11956 void MDFrame::winplot()
11957 {
11958 if(win!=NULL)
11959 if(win->alive)
11960 if((curstep%plotfreq)==0)
11961 {
11962 plot();
11963 }
11964 }
11965
11966 void MDFrame::winplot(int step)
11967 {
11968 if(win!=NULL)
11969 if(win->alive)
11970 if((step%plotfreq)==0)
11971 {
11972 plot();
11973 }
11974 }
11975
11976 void MDFrame::wintogglepause()
11977 {
11978 if(win!=NULL)
11979 if(win->IsAlive())
11980 win->TogglePause();
11981 }
11982
11983 #include "namecolor.c"
11984 void MDFrame::alloccolors()
11985 {
11986 int r,g,b;
11987 if(win!=NULL)
11988 {
11989 if(win->alive)
11990 {
11991 for(int i=0;i<MAXCOLORS;i++)
11992 {
11993 Str2RGB(colornames[i],&r,&g,&b);
11994 colors[i]=win->AllocShortRGBColor(r,g,b);
11995 }
11996
11997 Str2RGB(atomcolor[0],&r,&g,&b);
11998 colors[MAXCOLORS+0]=win->AllocShortRGBColor(r,g,b);
11999 Str2RGB(bondcolor,&r,&g,&b);
12000 colors[MAXCOLORS+1]=win->AllocShortRGBColor(r,g,b);
12001 Str2RGB(highlightcolor,&r,&g,&b);
12002 colors[MAXCOLORS+2]=win->AllocShortRGBColor(r,g,b);
12003 Str2RGB(fixatomcolor,&r,&g,&b);
12004 colors[MAXCOLORS+3]=win->AllocShortRGBColor(r,g,b);
12005 Str2RGB(backgroundcolor,&r,&g,&b);
12006 win->bgcolor=win->AllocShortRGBColor(r,g,b);
12007
12008 for(int i=0;i<MAXSPECIES;i++)
12009 {
12010 Str2RGB(atomcolor[i],&r,&g,&b);
12011 colors[MAXCOLORS+5+i]=win->AllocShortRGBColor(r,g,b);
12012 }
12013 }
12014 else
12015 {
12016 WARNING("No window to allocate color for!");
12017 }
12018 }
12019 else
12020 {
12021 WARNING("No window to allocate color for!");
12022 }
12023 }
12024 void MDFrame::alloccolorsX()
12025 {
12026 if(win!=NULL)
12027 {
12028 if(win->alive)
12029 {
12030 colors[0]=win->AllocNamedColor(atomcolor[0]);
12031 colors[1]=win->AllocNamedColor(bondcolor);
12032 colors[2]=win->AllocNamedColor(highlightcolor);
12033 colors[3]=win->AllocNamedColor(fixatomcolor);
12034 win->bgcolor=win->AllocNamedColor(backgroundcolor);
12035 }
12036 else
12037 {
12038 WARNING("No window to allocate color for!");
12039 }
12040 }
12041 else
12042 {
12043 WARNING("No window to allocate color for!");
12044 }
12045 }
12046
12047 void MDFrame::rotate()
12048 {
12049 if(win!=NULL)
12050 {
12051 if(win->alive)
12052 {
12053 win->horizontalRot(rotateangles[0]*M_PI/180);
12054 win->verticalRot(rotateangles[1]*M_PI/180);
12055 win->spinRot(rotateangles[2]*M_PI/180);
12056 if(rotateangles[3]!=0) win->zoom(rotateangles[3]);
12057 if(rotateangles[4]!=0) win->project(rotateangles[4]);
12058 }
12059 else
12060 {
12061 WARNING("No window to rotate for!");
12062 }
12063 }
12064 else
12065 {
12066 WARNING("No window to rotate for!");
12067 }
12068 }
12069
12070 void MDFrame::saverot()
12071 {
12072 if(win!=NULL)
12073 {
12074 if(win->alive)
12075 {
12076
12077 win->saveView();
12078 }
12079 else
12080 {
12081 WARNING("No window to rotate for!");
12082 }
12083 }
12084 else
12085 {
12086 WARNING("No window to rotate for!");
12087 }
12088 }
12089
12090 #include "colormap.h"
12091
12092 void MDFrame::plot()
12093 {
12094 int i,jp,j,k;
12095 double L,r2;
12096 char s[100]; bool high;
12097 double x1,y1,z1,x2,y2,z2,dx,dy,dz,dr;
12098 int r,g,b; double alpha; unsigned ce;
12099 Vector3 s1, s2, vr1, vr2, sri, srj, ri, rj;
12100 int nw, cind, show; double Emin, Emax;
12101
12102 if(win==NULL) return;
12103 if(!(win->alive)) return;
12104
12105 L=max(_H[0][0],_H[1][1]);
12106 L=max(L,_H[2][2])*.5;
12107
12108 switch(plot_color_axis){
12109 case(0): color_ind=_EPOT_IND; break;
12110 case(1): color_ind=_EPOT_IND; break;
12111 case(2): color_ind=_TOPOL; break;
12112
12113 case(4): color_ind=_TOPOL; break;
12114 case(8): color_ind=_TOPOL; break;
12115 default: ERROR("plot() unknown coloraxis "<<plot_color_axis); return;
12116 }
12117
12118 SHtoR();
12119 win->Lock();
12120 win->Clear();
12121
12122
12123 for(i=0;i<_NP;i++)
12124 {
12125 sri=_SR[i];
12126 if(plot_map_pbc==1) sri.subint();
12127 ri = _H*sri;
12128
12129
12130
12131
12132
12133
12134
12135
12136 if(plot_limits[0]==1)
12137 if((sri.x<plot_limits[1])||(sri.x>plot_limits[2])
12138 ||(sri.y<plot_limits[3])||(sri.y>plot_limits[4])
12139 ||(sri.z<plot_limits[5])||(sri.z>plot_limits[6]))
12140 {
12141 continue;
12142 }
12143 if(plot_limits[0]==2)
12144 if((sri.x<plot_limits[1])||(sri.x>plot_limits[2])
12145 ||(sri.y<plot_limits[3])||(sri.y>plot_limits[4])
12146 ||(sri.z<plot_limits[5])||(sri.z>plot_limits[6]))
12147 {
12148 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12149 atomradius[species[i]]/L,colors[MAXCOLORS+3],s,2);
12150 continue;
12151 }
12152
12153 if (!plot_atom_info) s[0]=0;
12154 else
12155 {
12156 if(plot_atom_info==1)
12157 sprintf(s,"%d,%6.4f,%6.4f,%6.4f",
12158 i,sri.x,sri.y,sri.z);
12159 else if(plot_atom_info==2)
12160 sprintf(s,"%d,%6.4f,%6.4f,%6.4f",
12161 i,ri.x,ri.y,ri.z);
12162 else if(plot_atom_info==3)
12163 sprintf(s,"%d,%8.6e %d %d",
12164 i,color_ind[i], fixed[i], species[i]);
12165 else if(plot_atom_info==4)
12166 sprintf(s,"%d,%6.4f,%6.4f,%6.4f",
12167 i,_F[i].x,_F[i].y,_F[i].z);
12168 else
12169 s[0]=0;
12170 }
12171
12172 nw = (int)plot_color_windows[0];
12173 if(nw>0)
12174 {
12175 for(k=0;k<nw;k++)
12176 {
12177 Emin = plot_color_windows[k*3+1];
12178 Emax = plot_color_windows[k*3+2];
12179 cind = (int) plot_color_windows[k*3+3];
12180
12181 if((color_ind[i]>=Emin)&&(color_ind[i]<=Emax))
12182 {
12183
12184 if(plot_color_bar[0]==0)
12185 {
12186 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12187 atomradius[species[i]]/L,colors[cind],s,2);
12188 }
12189 else
12190 {
12191
12192
12193
12194
12195 alpha=(color_ind[i]-plot_color_bar[1])
12196 /(plot_color_bar[2]-plot_color_bar[1]);
12197 if(plot_color_bar[0]==1)
12198 colormap1(alpha,&r,&g,&b);
12199 else colormap2(alpha,&r,&g,&b);
12200
12201 ce=win->AllocShortRGBColor(r,g,b);
12202 if(plot_atom_info==5)
12203 sprintf(s,"%d,%d,%d,%d,%x",i,r,g,b,ce);
12204 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12205 atomradius[species[i]]/L,ce,s,2);
12206 }
12207 }
12208 }
12209 if(plot_color_windows[nw*3+1])
12210 if(fixed[i])
12211 {
12212
12213 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12214 atomradius[species[i]]/L,colors[MAXCOLORS+3],s,2);
12215 }
12216
12217 }
12218 else
12219 {
12220 high=false;
12221 for(j=1;j<=plot_highlight_atoms[0];j++)
12222 if(i==plot_highlight_atoms[j])
12223 {
12224 high=true;
12225 break;
12226 }
12227
12228 if(fixed[i])
12229 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12230 atomradius[species[i]]/L,colors[MAXCOLORS+3],s,2);
12231 else if (high)
12232 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12233 atomradius[species[i]]/L,colors[MAXCOLORS+2],s,2);
12234
12235 else if(plot_color_bar[0]!=0)
12236 {
12237
12238
12239
12240
12241 alpha=(color_ind[i]-plot_color_bar[1])
12242 /(plot_color_bar[2]-plot_color_bar[1]);
12243 if(plot_color_bar[0]==1)
12244 colormap1(alpha,&r,&g,&b);
12245 else colormap2(alpha,&r,&g,&b);
12246
12247 ce=win->AllocShortRGBColor(r,g,b);
12248 if(plot_atom_info==5)
12249 sprintf(s,"%d,%d,%d,%d,%x",i,r,g,b,ce);
12250 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12251 atomradius[species[i]]/L,ce,s,2);
12252 }
12253 else
12254 {
12255 if (coloratoms == 0)
12256 {
12257 ce=colors[MAXCOLORS+5+species[i]];
12258 if(plot_atom_info==5)
12259 sprintf(s,"%d,%d,%x",i,species[i],ce);
12260 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12261 atomradius[species[i]]/L,ce,s,2);
12262 }
12263 else if (coloratoms == 1)
12264 {
12265 ce=colors[MAXCOLORS+5+group[i]];
12266 if(plot_atom_info==5)
12267 sprintf(s,"%d,%d,%x",i,group[i],ce);
12268 win->DrawPoint(ri.x/L,ri.y/L,ri.z/L,
12269 atomradius[species[i]]/L,ce,s,2);
12270 }
12271 }
12272 }
12273 }
12274
12275
12276 if(bondlength>1e-3)
12277 {
12278 for(i=0;i<_NP;i++)
12279 {
12280 sri=_SR[i];
12281 if(plot_map_pbc==1) sri.subint();
12282 ri = _H*sri;
12283
12284 show = 0;
12285 nw = (int)plot_color_windows[0];
12286 if(nw>0)
12287 {
12288 for(k=0;k<nw;k++)
12289 {
12290 Emin = plot_color_windows[k*3+1];
12291 Emax = plot_color_windows[k*3+2];
12292 cind = (int) plot_color_windows[k*3+3];
12293
12294 if((color_ind[i]>=Emin)&&
12295 (color_ind[i]<=Emax))
12296 {
12297 show = 1;
12298 break;
12299 }
12300 }
12301 }
12302 else
12303 {
12304 show = 1;
12305 }
12306 if(!show) continue;
12307
12308 for(jp=0;jp<nn[i];jp++)
12309 {
12310 j=nindex[i][jp];
12311 srj=_SR[j];
12312 if(plot_map_pbc==1) srj.subint();
12313 rj = _H*srj;
12314
12315 show = 0;
12316 nw = (int)plot_color_windows[0];
12317 if(nw>0)
12318 {
12319 for(k=0;k<nw;k++)
12320 {
12321 Emin = plot_color_windows[k*3+1];
12322 Emax = plot_color_windows[k*3+2];
12323 cind = (int) plot_color_windows[k*3+3];
12324
12325 if((color_ind[j]>=Emin)&&
12326 (color_ind[j]<=Emax))
12327 {
12328 show = 1;
12329 break;
12330 }
12331 }
12332 }
12333 else
12334 {
12335 show = 1;
12336 }
12337 if(!show) continue;
12338
12339 if(plot_limits[0])
12340 if((sri.x<plot_limits[1])||(sri.x>plot_limits[2])
12341 ||(sri.y<plot_limits[3])||(sri.y>plot_limits[4])
12342 ||(sri.z<plot_limits[5])||(sri.z>plot_limits[6])
12343 ||(srj.x<plot_limits[1])||(srj.x>plot_limits[2])
12344 ||(srj.y<plot_limits[3])||(srj.y>plot_limits[4])
12345 ||(srj.z<plot_limits[5])||(srj.z>plot_limits[6]))
12346 continue;
12347 r2=(ri-rj).norm2();
12348
12349 if(r2<bondlength*bondlength)
12350 {
12351
12352
12353
12354 x1=ri.x/L;y1=ri.y/L;z1=ri.z/L;
12355 x2=rj.x/L;y2=rj.y/L;z2=rj.z/L;
12356 dx=x2-x1;dy=y2-y1;dz=z2-z1;dr=sqrt(dx*dx+dy*dy+dz*dz);
12357 dx/=dr;dy/=dr;dz/=dr;
12358 win->DrawLine(x1+dx*atomradius[species[i]]/L,
12359 y1+dy*atomradius[species[i]]/L,
12360 z1+dz*atomradius[species[i]]/L,
12361 x2-dx*atomradius[species[j]]/L,
12362 y2-dy*atomradius[species[j]]/L,
12363 z2-dz*atomradius[species[j]]/L,
12364 colors[MAXCOLORS+1],bondradius/L,1);
12365 }
12366 }
12367 }
12368 }
12369
12370 #define drawsline(a,b,c,d,e,f,g,h,i) s1.set(a,b,c); s2.set(d,e,f);\
12371 vr1=_H*s1; vr2=_H*s2; vr1/=2*L; vr2/=2*L;\
12372 win->DrawLine(vr1.x,vr1.y,vr1.z,vr2.x,vr2.y,vr2.z,g,h,i);
12373
12374 drawsline(-1,-1,-1,-1,-1, 1,colors[MAXCOLORS+2],0,0);
12375 drawsline(-1,-1, 1,-1, 1, 1,colors[MAXCOLORS+2],0,0);
12376 drawsline(-1, 1, 1,-1, 1,-1,colors[MAXCOLORS+2],0,0);
12377 drawsline(-1, 1,-1,-1,-1,-1,colors[MAXCOLORS+2],0,0);
12378 drawsline( 1,-1,-1, 1,-1, 1,colors[MAXCOLORS+2],0,0);
12379 drawsline( 1,-1, 1, 1, 1, 1,colors[MAXCOLORS+2],0,0);
12380 drawsline( 1, 1, 1, 1, 1,-1,colors[MAXCOLORS+2],0,0);
12381 drawsline( 1, 1,-1, 1,-1,-1,colors[MAXCOLORS+2],0,0);
12382 drawsline(-1,-1,-1, 1,-1,-1,colors[MAXCOLORS+2],0,0);
12383 drawsline(-1,-1, 1, 1,-1, 1,colors[MAXCOLORS+2],0,0);
12384 drawsline(-1, 1, 1, 1, 1, 1,colors[MAXCOLORS+2],0,0);
12385 drawsline(-1, 1,-1, 1, 1,-1,colors[MAXCOLORS+2],0,0);
12386
12387 win->Unlock();
12388 win->Refresh();
12389 }
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405 #ifdef _TEST
12406
12407 class TESTMD : public MDFrame
12408 {
12409 public:
12410 virtual void potential()
12411 {
12412 if(_REFPOTENTIAL == 2)
12413 {
12414 I12potential();
12415 }
12416 else
12417 {
12418 INFO("Empty potential");
12419 }
12420 }
12421 virtual void potential_energyonly()
12422 {
12423 if(_REFPOTENTIAL == 2)
12424 {
12425 I12potential_energyonly();
12426 }
12427 else
12428 {
12429 INFO("Empty potential_energyonly");
12430 }
12431 }
12432 virtual double potential_energyonly(int iatom)
12433 {
12434 INFO("Empty potential");
12435 return 0;
12436 }
12437 virtual void initvars()
12438 {
12439 MDFrame::initvars();
12440 _RLIST=3.8;
12441 }
12442
12443 };
12444
12445 class TESTMD sim;
12446
12447
12448 #include "main.cpp"
12449
12450 #endif//_TEST