GlobalMasterIMD Class Reference

#include <GlobalMasterIMD.h>

Inheritance diagram for GlobalMasterIMD:

GlobalMaster List of all members.

Public Member Functions

 GlobalMasterIMD ()
 ~GlobalMasterIMD ()
void send_energies (IMDEnergies *)
void send_fcoords (int, FloatVector *)

Protected Member Functions

virtual void calculate ()
void get_vmd_forces ()

Protected Attributes

int IMDwait
int IMDignore
int IMDignoreForces
void * sock
ResizeArray< void * > clients
float * coordtmp
int coordtmpsize

Friends

class IMDOutput

Detailed Description

Definition at line 16 of file GlobalMasterIMD.h.


Constructor & Destructor Documentation

GlobalMasterIMD::GlobalMasterIMD (  ) 

Definition at line 53 of file GlobalMasterIMD.C.

References coordtmp, coordtmpsize, DebugM, endi(), find_free_port(), iINFO(), Node::imd, SimParameters::IMDignore, IMDignore, SimParameters::IMDignoreForces, IMDignoreForces, SimParameters::IMDport, SimParameters::IMDwait, IMDwait, iout, iWARN(), NAMD_die(), Node::Object(), GlobalMaster::requestedGroups(), Node::simParameters, sock, IMDOutput::use_imd(), vmdsock_create(), vmdsock_destroy(), vmdsock_init(), and vmdsock_listen().

00053                                  {
00054   DebugM(3,"Constructing\n");
00055   SimParameters *simparams = Node::Object()->simParameters;
00056   int port = simparams->IMDport;
00057   IMDwait = simparams->IMDwait;
00058   IMDignore = simparams->IMDignore;
00059   IMDignoreForces = simparams->IMDignoreForces;
00060   coordtmp = NULL;
00061   coordtmpsize = 0;
00062 
00063   if ( vmdsock_init() ) {
00064     NAMD_die("Unable to initialize socket interface for IMD.\n");
00065   }
00066   sock = vmdsock_create();
00067   int newport = find_free_port(sock, port);
00068   if (newport != port) {
00069     iout << iWARN << "Interactive MD failed to bind to port "
00070                   << port << ".\n" << endi;
00071   }
00072   if (newport < 0) {
00073     vmdsock_destroy(sock);
00074     NAMD_die("Interactive MD failed to find free port.\n");
00075   }
00076   vmdsock_listen(sock); 
00077   iout << iINFO << "Interactive MD listening on port "
00078                   << newport << ".\n" << endi;
00079   DebugM(2,"Done constructing ("<<requestedGroups().size()<<" initial groups)\n");
00080 
00081   Node::Object()->imd->use_imd(this);
00082 }

GlobalMasterIMD::~GlobalMasterIMD (  ) 

Definition at line 84 of file GlobalMasterIMD.C.

References clients, coordtmp, ResizeArray< Elem >::size(), sock, and vmdsock_destroy().

00084                                   {
00085   if (sock) 
00086     vmdsock_destroy(sock);
00087   for (int i=0; i<clients.size(); i++)
00088     vmdsock_destroy(clients[i]);
00089   delete [] coordtmp;
00090 }


Member Function Documentation

void GlobalMasterIMD::calculate (  )  [protected, virtual]

Reimplemented from GlobalMaster.

Definition at line 108 of file GlobalMasterIMD.C.

References ResizeArray< Elem >::add(), clients, DebugM, endi(), get_vmd_forces(), iINFO(), IMDignore, IMDignoreForces, IMDwait, SortedArray< Elem >::index(), iout, iWARN(), GlobalMaster::modifyAppliedForces(), GlobalMaster::modifyForcedAtoms(), GlobalMaster::modifyGroupForces(), my_imd_connect(), ResizeArray< Elem >::resize(), ResizeArray< Elem >::size(), sock, vmdforces, vmdsock_accept(), vmdsock_destroy(), and vmdsock_selread().

Referenced by IMDOutput::gather_coordinates().

00108                                 {
00109   /* clear out the requested forces first! */
00110   if (!IMDignore && !IMDignoreForces) {
00111     modifyAppliedForces().resize(0);
00112     modifyForcedAtoms().resize(0);
00113     modifyGroupForces().resize(0);
00114   }
00115 
00116   // check for incoming connection
00117   do {
00118   int rc;
00119   if (IMDwait && !clients.size()) {
00120     iout << iINFO << "INTERACTIVE MD AWAITING CONNECTION\n" << endi;
00121     do { rc = vmdsock_selread(sock, 3600); } while (rc <= 0);
00122   } else {
00123     rc = vmdsock_selread(sock, 0);
00124   } 
00125   if (rc > 0) {
00126     void *clientsock = vmdsock_accept(sock);
00127     if (!clientsock) {
00128       iout << iWARN << "IMD socket accept failed\n" << endi;
00129     } else {
00130       if (!my_imd_connect(clientsock)) {
00131         iout << iWARN << "IMD connection failed\n" << endi;
00132         vmdsock_destroy(clientsock);
00133       } else {
00134         iout << iINFO << "IMD connection opened\n" <<endi;      
00135         clients.add(clientsock);
00136       }
00137     }
00138   }
00139   } while (IMDwait && !clients.size());
00140 
00141   // Assume for now that the only thing we get from VMD is a set of forces.
00142   // Later we'll want to look for and implement more sophisticated control
00143   // parameters. ie have a specified protocol
00144 
00145   // Check/get new forces from VMD
00146   get_vmd_forces();
00147 
00148   // Right now I don't check to see if any new forces were obtained.
00149   // An optimization would be cache the results message.  However, there
00150   // would still be copying since it looks like the messages get deleted
00151   // by the receiver.
00152 
00153   /* set our arrays to be big enough to hold all of the forces */
00154   int num = vmdforces.size();
00155 
00156   DebugM(2,"Setting " << num << " forces.\n");
00157   
00158   if (!IMDignore && !IMDignoreForces) {
00159     modifyForcedAtoms().resize(num);
00160     modifyAppliedForces().resize(num);
00161   
00162     int i;
00163     UniqueSortedArray<vmdforce>::iterator v_i = vmdforces.begin();
00164     for ( i = 0; i < num; ++i, ++v_i) {
00165       modifyForcedAtoms().item(i) = v_i->index;
00166       modifyAppliedForces().item(i) = v_i->force;
00167     }
00168   }
00169 }

void GlobalMasterIMD::get_vmd_forces (  )  [protected]

Definition at line 171 of file GlobalMasterIMD.C.

References clients, ResizeArray< Elem >::del(), endi(), f, vmdforce::force, if(), iINFO(), Node::imd, IMD_DISCONNECT, IMD_ENERGIES, IMD_FCOORDS, IMD_IOERROR, IMD_KILL, IMD_MDCOMM, IMD_PAUSE, imd_recv_energies(), imd_recv_fcoords(), imd_recv_header(), imd_recv_mdcomm(), IMD_TRATE, IMDignore, IMDignoreForces, SimParameters::IMDwait, IMDwait, vmdforce::index, iout, iWARN(), NAMD_quit(), Node::Object(), IMDOutput::set_transrate(), Node::simParameters, ResizeArray< Elem >::size(), vmdforces, vmdsock_destroy(), vmdsock_selread(), Vector::x, Vector::y, and Vector::z.

Referenced by calculate().

00171                                      {
00172   IMDType type;
00173   int32 length;
00174   int32 *vmd_atoms;
00175   float *vmd_forces;
00176   int paused = 0;
00177   int warned = 0;
00178   vmdforce *vtest, vnew;
00179 
00180   // Loop through each socket one at a time.  By doing this, rather than 
00181   // polling all sockets at once, NAMD only has to keep up with one IMD
00182   // connection; if it tried to read from all of them, it could more easily
00183   // fall behind and never finish draining all the sockets.
00184   // It would be better to have a system where VMD couldn't DOS NAMD by 
00185   // spamming it with messages, but in practice NAMD is able to keep up with 
00186   // VMD's send rate.
00187   for (int i_client=0; i_client<clients.size(); i_client++) {
00188     void *clientsock = clients[i_client];
00189     while (vmdsock_selread(clientsock,0) > 0 || paused) {  // Drain the socket
00190       type = imd_recv_header(clientsock, &length);
00191       switch (type) {
00192         case IMD_MDCOMM:
00193           // Expect the msglength to give number of indicies, and the data
00194           // message to consist of first the indicies, then the coordinates
00195           // in xyz1 xyz2... format.
00196           vmd_atoms = new int32[length];
00197           vmd_forces = new float[3*length];
00198           if (imd_recv_mdcomm(clientsock, length, vmd_atoms, vmd_forces)) {
00199             iout << iWARN <<
00200               "Error reading IMD forces, killing connection\n" << endi;
00201             goto vmdDestroySocket;
00202           } 
00203           if (IMDignore || IMDignoreForces)  {
00204             if ( ! warned ) {
00205               warned = 1;
00206               char option[16];
00207               if (IMDignore) strcpy(option, "IMDignore");
00208               else strcpy(option, "IMDignoreForces");  
00209               iout << iWARN << "Ignoring IMD forces due to " << option << "\n" << endi;
00210             }
00211           } else {
00212             for (int i=0; i<length; i++) {
00213               vnew.index = vmd_atoms[i];
00214               if ( (vtest=vmdforces.find(vnew)) != NULL) {
00215                 // find was successful, so overwrite the old force values
00216                 if (vmd_forces[3*i] != 0.0f || vmd_forces[3*i+1] != 0.0f
00217                     || vmd_forces[3*i+2] != 0.0f) {
00218                   vtest->force.x = vmd_forces[3*i];
00219                   vtest->force.y = vmd_forces[3*i+1];
00220                   vtest->force.z = vmd_forces[3*i+2];
00221                 } else {
00222                   // or delete it from the list if the new force is ZERO
00223                   vmdforces.del(vnew);
00224                 }
00225               }
00226               else {
00227                 // Create a new entry in the table if the new force isn't ZERO
00228                 if (vmd_forces[3*i] != 0.0f || vmd_forces[3*i+1] != 0.0f
00229                     || vmd_forces[3*i+2] != 0.0f) {
00230                   vnew.force.x = vmd_forces[3*i];
00231                   vnew.force.y = vmd_forces[3*i+1];
00232                   vnew.force.z = vmd_forces[3*i+2];
00233                   vmdforces.add(vnew);
00234                 }
00235               }
00236             } 
00237           }
00238           delete [] vmd_atoms;
00239           delete [] vmd_forces;
00240           break;
00241         case IMD_TRATE:
00242           iout << iINFO << "Setting transfer rate to " << length<<'\n'<<endi;   
00243           Node::Object()->imd->set_transrate(length);
00244           break;
00245         case IMD_PAUSE:
00246           if (IMDignore) {
00247             iout << iWARN << "Ignoring IMD pause due to IMDignore\n" << endi;
00248             break;
00249           }
00250           if ( paused ) {
00251             iout << iINFO << "Resuming IMD\n" << endi;
00252             IMDwait = Node::Object()->simParameters->IMDwait;
00253           }
00254           paused = ! paused;
00255           if ( paused ) {
00256             iout << iINFO << "Pausing IMD\n" << endi;
00257             IMDwait = 1;
00258           }
00259           break;
00260         case IMD_IOERROR:
00261           iout << iWARN << "IMD connection lost\n" << endi;
00262         case IMD_DISCONNECT:
00263           iout << iINFO << "IMD connection detached\n" << endi;
00264           vmdDestroySocket:
00265           vmdsock_destroy(clientsock);
00266           clients.del(i_client);
00267           // Enable the MD to continue after detach
00268           if (IMDwait) IMDwait = 0;
00269           goto vmdEnd;
00270         case IMD_KILL:
00271           if (IMDignore) {
00272             iout << iWARN << "Ignoring IMD kill due to IMDignore\n" << endi;
00273             break;
00274           }
00275           NAMD_quit("Received IMD kill from client\n");
00276           break;
00277         case IMD_ENERGIES:
00278           IMDEnergies junk;
00279           imd_recv_energies(clientsock, &junk);
00280           break;
00281         case IMD_FCOORDS:
00282           vmd_forces = new float[3*length];
00283           imd_recv_fcoords(clientsock, length, vmd_forces);
00284           delete [] vmd_forces;
00285           break;
00286         default: ;
00287       }
00288     }
00289   vmdEnd: ;
00290   }
00291 }

void GlobalMasterIMD::send_energies ( IMDEnergies  ) 

Definition at line 293 of file GlobalMasterIMD.C.

References clients, imd_send_energies(), ResizeArray< Elem >::size(), and vmdsock_selwrite().

Referenced by IMDOutput::gather_energies().

00293                                                          {
00294   for (int i=0; i<clients.size(); i++) {
00295     void *clientsock = clients[i];
00296     if (!clientsock || !vmdsock_selwrite(clientsock,0)) continue;
00297     imd_send_energies(clientsock, energies);
00298   }
00299 }

void GlobalMasterIMD::send_fcoords ( int  ,
FloatVector  
)

Definition at line 301 of file GlobalMasterIMD.C.

References clients, coords, coordtmp, coordtmpsize, imd_send_fcoords(), ResizeArray< Elem >::size(), vmdsock_selwrite(), and x.

Referenced by IMDOutput::gather_coordinates().

00301                                                              {
00302   for (int i=0; i<clients.size(); i++) {
00303     void *clientsock = clients[i];
00304     if (!clientsock || !vmdsock_selwrite(clientsock,0)) continue;
00305     if (sizeof(FloatVector) == 3*sizeof(float)) {
00306       imd_send_fcoords(clientsock, N, (float *)coords);
00307     } else {
00308       if (coordtmpsize < N) {
00309         delete [] coordtmp;
00310         coordtmp = new float[3*N];
00311         coordtmpsize = N;
00312       }
00313       for (int i=0; i<N; i++) {
00314         coordtmp[3*i] = coords[i].x; 
00315         coordtmp[3*i+1] = coords[i].y; 
00316         coordtmp[3*i+2] = coords[i].z; 
00317       } 
00318       imd_send_fcoords(clientsock, N, coordtmp);
00319     }
00320   }
00321 }


Friends And Related Function Documentation

friend class IMDOutput [friend]

Definition at line 27 of file GlobalMasterIMD.h.


Member Data Documentation

ResizeArray<void *> GlobalMasterIMD::clients [protected]

Definition at line 47 of file GlobalMasterIMD.h.

Referenced by calculate(), get_vmd_forces(), send_energies(), send_fcoords(), and ~GlobalMasterIMD().

float* GlobalMasterIMD::coordtmp [protected]

Definition at line 50 of file GlobalMasterIMD.h.

Referenced by GlobalMasterIMD(), send_fcoords(), and ~GlobalMasterIMD().

int GlobalMasterIMD::coordtmpsize [protected]

Definition at line 51 of file GlobalMasterIMD.h.

Referenced by GlobalMasterIMD(), and send_fcoords().

int GlobalMasterIMD::IMDignore [protected]

Definition at line 38 of file GlobalMasterIMD.h.

Referenced by calculate(), get_vmd_forces(), GlobalMasterIMD(), and IMDOutput::use_imd().

int GlobalMasterIMD::IMDignoreForces [protected]

Definition at line 41 of file GlobalMasterIMD.h.

Referenced by calculate(), get_vmd_forces(), GlobalMasterIMD(), and IMDOutput::use_imd().

int GlobalMasterIMD::IMDwait [protected]

Definition at line 35 of file GlobalMasterIMD.h.

Referenced by calculate(), get_vmd_forces(), and GlobalMasterIMD().

void* GlobalMasterIMD::sock [protected]

Definition at line 44 of file GlobalMasterIMD.h.

Referenced by calculate(), GlobalMasterIMD(), and ~GlobalMasterIMD().


The documentation for this class was generated from the following files:
Generated on Sat Sep 23 01:17:19 2017 for NAMD by  doxygen 1.4.7