00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: IMDMgr.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.43 $ $Date: 2019年01月17日 21:20:59 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * High level interactive MD simulation management and update routines. 00019 ***************************************************************************/ 00020 00021 #include "IMDMgr.h" 00022 #include "imd.h" 00023 #include "IMDSimThread.h" 00024 #include "IMDSimBlocking.h" 00025 #include "utilities.h" 00026 #include "TextEvent.h" 00027 #include "Molecule.h" 00028 00029 IMDMgr::IMDMgr(VMDApp *vmdapp) 00030 : UIObject(vmdapp) { 00031 mol = NULL; 00032 sim = NULL; 00033 host = NULL; 00034 port = 0; 00035 Trate = 1; 00036 keep_rate = 0; 00037 copy_unit_cell = 0; // copy unit cell info from first (previous) frame 00038 frames_received = 0; 00039 energies = new IMDEnergies; 00040 want_command(Command::MOL_DEL); 00041 } 00042 00043 IMDMgr::~IMDMgr() { 00044 if (mol) 00045 detach(); 00046 delete [] host; 00047 delete energies; 00048 } 00049 00050 int IMDMgr::connect(Molecule *m, const char *h, int p) { 00051 if (mol) { 00052 return 0; 00053 } 00054 00055 delete [] host; 00056 host = stringdup(h); 00057 port = p; 00058 00059 #ifdef VMDTHREADS 00060 sim = new IMDSimThread(h, p); 00061 #else 00062 sim = new IMDSimBlocking(h, p); 00063 #endif 00064 if (!sim->isConnected()) { 00065 delete sim; 00066 sim = 0; 00067 return 0; 00068 } 00069 mol = m; 00070 frames_received = 0; 00071 return 1; 00072 } 00073 00074 void IMDMgr::pause() { 00075 if (sim) sim->pause(); 00076 } 00077 00078 void IMDMgr::unpause() { 00079 if (sim) sim->unpause(); 00080 } 00081 00082 void IMDMgr::togglepause() { 00083 if (!sim) return; 00084 int state = sim->getSimState(); 00085 if (state == IMDSim::IMDRUNNING) 00086 sim->pause(); 00087 else if (state == IMDSim::IMDPAUSED) 00088 sim->unpause(); 00089 } 00090 00091 void IMDMgr::detach() { 00092 if (sim) sim->detach(); 00093 delete sim; 00094 sim = NULL; 00095 mol = NULL; 00096 } 00097 00098 void IMDMgr::kill() { 00099 if (sim) sim->kill(); 00100 delete sim; 00101 sim = NULL; 00102 mol = NULL; 00103 } 00104 00105 int IMDMgr::send_forces(int n, const int *ind, const float *force) { 00106 if (!sim) return 0; 00107 00108 // make a temporary copy because sim may byte-swap ind and force. 00109 int *tmpind = new int[n]; 00110 float *tmpforce = new float[3L*n]; 00111 memcpy(tmpind, ind, n*sizeof(int)); 00112 memcpy(tmpforce, force, 3L*n*sizeof(float)); 00113 sim->send_forces(n, tmpind, tmpforce); 00114 delete [] tmpind; 00115 delete [] tmpforce; 00116 return 1; 00117 } 00118 00119 void IMDMgr::set_trans_rate(int rate) { 00120 if (rate > 0) { 00121 Trate = rate; 00122 if (sim) sim->set_transrate(rate); 00123 } 00124 } 00125 00126 void IMDMgr::set_keep_rate(int rate) { 00127 if (rate >= 0) { 00128 keep_rate = rate; 00129 } 00130 } 00131 00132 void IMDMgr::set_copyunitcell(int onoff) { 00133 if (onoff) { 00134 copy_unit_cell = 1; 00135 } else { 00136 copy_unit_cell = 0; 00137 } 00138 } 00139 00140 int IMDMgr::check_event() { 00141 if (sim && !sim->isConnected()) { 00142 detach(); 00143 msgInfo << "IMD connection ended unexpectedly; connection terminated." 00144 << sendmsg; 00145 } 00146 if (!sim) return 0; 00147 00148 sim->update(); 00149 if (sim->next_ts_available()) { 00150 Timestep *newts = mol->get_last_frame(); 00151 int do_save = (!newts || frames_received < 1 || 00152 (keep_rate > 0 && !(frames_received % keep_rate))); 00153 if (do_save) { 00154 newts = new Timestep(mol->nAtoms); 00155 00156 // XXX Hack to enable copying cell size and shape from previous frame 00157 // since the existing IMD protocol doesn't provide a means to 00158 // transmit updates to the unit cell info. 00159 if (copy_unit_cell) { 00160 Timestep *oldts = mol->get_last_frame(); 00161 if (oldts) { 00162 newts->a_length = oldts->a_length; 00163 newts->b_length = oldts->b_length; 00164 newts->c_length = oldts->c_length; 00165 newts->alpha = oldts->alpha; 00166 newts->beta = oldts->beta; 00167 newts->gamma = oldts->gamma; 00168 } 00169 } 00170 } 00171 00172 float *pos = newts->pos; 00173 sim->get_next_ts(pos, energies); 00174 00175 newts->timesteps = energies->tstep; 00176 newts->energy[TSE_BOND] = energies->Ebond; 00177 newts->energy[TSE_ANGLE] = energies->Eangle; 00178 newts->energy[TSE_DIHE] = energies->Edihe; 00179 newts->energy[TSE_IMPR] = energies->Eimpr; 00180 newts->energy[TSE_VDW] = energies->Evdw; 00181 newts->energy[TSE_COUL] = energies->Eelec; 00182 newts->energy[TSE_HBOND] = 0; // not supported 00183 newts->energy[TSE_TEMP] = energies->T; 00184 newts->energy[TSE_PE] = energies->Epot; 00185 newts->energy[TSE_TOTAL] = energies->Etot; 00186 newts->energy[TSE_KE] = energies->Etot - energies->Epot; 00187 00188 if (do_save) { 00189 mol->append_frame(newts); 00190 } else { 00191 mol->force_recalc(DrawMolItem::MOL_REGEN); 00192 } 00193 frames_received++; 00194 runcommand(new TimestepEvent(mol->id(), mol->numframes()-1)); 00195 } 00196 return 0; 00197 } 00198 00199 int IMDMgr::act_on_command(int type, Command *cmd) { 00200 if (type == Command::MOL_DEL) { 00201 detach(); 00202 mol = NULL; 00203 } 00204 return 0; 00205 } 00206