00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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;
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
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
00157
00158
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;
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