Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Molecule.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 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: Molecule.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.87 $       $Date: 2010/12/16 04:08:24 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * Main Molecule objects, which contains all the capabilities necessary to
00020  * store, draw, and manipulate a molecule.  This adds to the functions of
00021  * DrawMolecule and BaseMolecule by adding routines to read and write various
00022  * coordinate files.
00023  *
00024  * Note: Other capabilities, such as writing structure files, mutations, etc.
00025  * should go into this level.
00026  *
00027  ***************************************************************************/
00028 
00029 #include "Molecule.h"
00030 #include "Inform.h"
00031 #include "DisplayDevice.h"
00032 #include "TextEvent.h"
00033 #include "VMDApp.h"
00034 #include "CommandQueue.h"
00035 #include "CoorData.h"
00036 
00038 
00039 Molecule::Molecule(const char *src, VMDApp *vmdapp, Displayable *d) 
00040   : DrawMolecule(vmdapp, d), coorIOFiles(8) {
00041 
00042   char *strPath = NULL, *strName = NULL;
00043   breakup_filename(src, &strPath, &strName);
00044   if (!strName) strName = stringdup("unknown");
00045 
00046   // set the molecule name
00047   moleculename = stringdup(strName);
00048   delete [] strPath;
00049   delete [] strName;
00050 }
00051 
00053 Molecule::~Molecule(void) {
00054   int i;
00055 
00056   // Disconnect this molecule from IMD, if it's active
00057   app->imd_disconnect(id());
00058 
00059   while(coorIOFiles.num() > 0) {
00060     delete coorIOFiles[0];
00061     coorIOFiles.remove(0);
00062   }
00063 
00064   if (moleculename)
00065     delete [] moleculename;
00066 
00067   for (i=0; i<fileList.num(); i++) {
00068     delete [] fileList[i];
00069   } 
00070   for (i=0; i<fileSpecList.num(); i++) {
00071     delete [] fileSpecList[i];
00072   } 
00073   for (i=0; i<typeList.num(); i++) {
00074     delete [] typeList[i];
00075   } 
00076   for (i=0; i<dbList.num(); i++) {
00077     delete [] dbList[i];
00078   } 
00079   for (i=0; i<accessionList.num(); i++) {
00080     delete [] accessionList[i];
00081   } 
00082   for (i=0; i<remarksList.num(); i++) {
00083     delete [] remarksList[i];
00084   } 
00085 }
00086 
00088 
00089 int Molecule::rename(const char *newname) {
00090   delete [] moleculename;
00091   moleculename = stringdup(newname);
00092   return 1;
00093 }
00094 
00095 void Molecule::add_coor_file(CoorData *data) {
00096   coorIOFiles.append(data);
00097 }
00098 
00099 void Molecule::close_coor_file(CoorData *data) {
00100   // remove file from list
00101   msgInfo << "Finished with coordinate file " << data->name << "." << sendmsg;
00102 
00103   // Must be appended, not run, because callbacks could delete the molecule!
00104   app->commandQueue->append(
00105     new TrajectoryReadEvent(id(), data->name)
00106   );
00107 
00108   delete data;
00109 }
00110 
00111 // cancel load/save of coordinate files
00112 // return number canceled
00113 int Molecule::cancel() {
00114   int retval = 0;
00115   while(coorIOFiles.num() > 0) {
00116     msgInfo << "Canceling load/save of file: " << coorIOFiles[0]->name 
00117             << sendmsg;
00118     delete coorIOFiles[0];
00119     coorIOFiles.remove(0);
00120     retval++;
00121   }
00122   return retval;
00123 }
00124 
00125 int Molecule::get_new_frames() {
00126   int newframes = 0;
00127 
00128   // add a new frame if there are frames available in the I/O queue
00129   if (next_frame())
00130     newframes = 1; 
00131 
00132   // If an IMD simulation is in progress, store the forces in the current
00133   // timestep and send them to the simulation.  Otherwise, just toss them.
00134   if (app->imd_connected(id())) {
00135     // Add persistent forces to regular forces
00136     int ii;
00137     for (ii=0; ii<persistent_force_indices.num(); ii++) 
00138       force_indices.append(persistent_force_indices[ii]);
00139     for (ii=0; ii<persistent_force_vectors.num(); ii++) 
00140       force_vectors.append(persistent_force_vectors[ii]);
00141 
00142     // Clear old forces out of the timestep
00143     Timestep *ts = current();
00144     if (ts && ts->force) {
00145       memset(ts->force, 0, 3*nAtoms*sizeof(float));
00146     }
00147 
00148     // Check for atoms forced last time that didn't show up this time.
00149     // XXX order N^2 in number of applied forces; could be easily improved.
00150     // But N now is usually 1 or 2.
00151     ResizeArray<int> zero_force_indices;
00152     ResizeArray<float> zero_forces;
00153     for(ii=0; ii<last_force_indices.num(); ii++) {
00154       int j;
00155       int index_missing=1;
00156       for (j=0; j<force_indices.num(); j++) {
00157         if (force_indices[j]==last_force_indices[ii]) {
00158           index_missing=0;
00159           break;
00160         }
00161       }
00162       if (index_missing) {
00163         // this one didn't show up this time
00164         zero_force_indices.append(force_indices[j]);
00165         zero_forces.append(0);
00166         zero_forces.append(0);
00167         zero_forces.append(0);
00168       }
00169     }
00170 
00171     if (zero_force_indices.num()) {
00172       // There some atoms forced last time that didn't show up this time.
00173       app->imd_sendforces(zero_force_indices.num(), &(zero_force_indices[0]),
00174                           &(zero_forces[0]));
00175     }
00176 
00177     // now clear the last forces so we don't send them again
00178     last_force_indices.clear();
00179 
00180     // Set/send forces if we got any
00181     if (force_indices.num()) {
00182       if (ts) {
00183         if (!ts->force) {
00184           ts->force = new float[3*nAtoms];
00185           memset(ts->force, 0, 3*nAtoms*sizeof(float));
00186         }
00187         for (int i=0; i<force_indices.num(); i++) {
00188           int ind = force_indices[i];
00189           ts->force[3*ind  ] += force_vectors[3*i  ];
00190           ts->force[3*ind+1] += force_vectors[3*i+1];
00191           ts->force[3*ind+2] += force_vectors[3*i+2];
00192         }
00193       }
00194       // XXX If we send multiple forces for the same atom, NAMD will keep only
00195       // the last force.  We therefore have to sum multiple contributions to the
00196       // same atom before sending.  Annoying.
00197       ResizeArray<float> summed_forces;
00198       int i;
00199       for (i=0; i<force_indices.num(); i++) {
00200         int ind = force_indices[i];
00201         summed_forces.append(ts->force[3*ind  ]);
00202         summed_forces.append(ts->force[3*ind+1]);
00203         summed_forces.append(ts->force[3*ind+2]);
00204       }
00205       app->imd_sendforces(force_indices.num(), &(force_indices[0]),
00206         &(summed_forces[0]));
00207 
00208       // save the force indices before clearing them
00209       for (i=0; i<force_indices.num(); i++) {
00210         last_force_indices.append(force_indices[i]);
00211       }
00212 
00213       // now clear the force indices
00214       force_indices.clear();
00215       force_vectors.clear();
00216     }
00217   }
00218 
00219   // Inform the top level class that background processing
00220   // is going on to prevent the CPU throttling code from activating
00221   if (newframes > 0)
00222     app->background_processing_set();
00223 
00224   return newframes;  
00225 }
00226 
00227 int Molecule::next_frame() {
00228   CoorData::CoorDataState state = CoorData::DONE;
00229 
00230   while (coorIOFiles.num() > 0) {
00231     // R/W'ing file, do frames until DONE is returned (then close)
00232     state = coorIOFiles[0]->next(this);
00233 
00234     if (state == CoorData::DONE) {
00235       close_coor_file(coorIOFiles[0]);
00236       coorIOFiles.remove(0);
00237     } else {
00238       break; // we got a frame, return to caller;
00239     }
00240   }
00241 
00242   return (state == CoorData::NOTDONE);
00243 }
00244 
00245 // prepare for drawing ... can do one or more of the following:
00246 //  - open a new file and start reading
00247 //  - continue reading an already open file
00248 //  - finish reading a file and close it
00249 //  - always add a new frame if there are frames available
00250 // when done, this then 'prepares' the parent class
00251 void Molecule::prepare() {
00252   get_new_frames(); // add a new frame if there are frames available
00253   DrawMolecule::prepare(); // do prepare for parent class
00254 }
00255 
00256 void Molecule::addForce(int theatom, const float *f) {
00257   force_indices.append(theatom);
00258   for (int i=0; i<3; i++) force_vectors.append(f[i]);
00259 }
00260 
00261 void Molecule::addPersistentForce(int theatom, const float *f) {
00262   // reset the force on this atom if any are stored
00263   // remove it completely if <f> is (0,0,0)
00264   
00265   float mag2 = f[0]*f[0] + f[1]*f[1] + f[2]*f[2];
00266   int ind = persistent_force_indices.find(theatom);
00267   if (ind < 0) {
00268     if (mag2 > 0) {
00269       // only set if non-zero
00270       reset_disp_list();
00271       persistent_force_indices.append(theatom);
00272       for (int i=0; i<3; i++) persistent_force_vectors.append(f[i]);
00273     }
00274   } else {
00275     if (mag2 > 0) {
00276       reset_disp_list();
00277       for (int i=0; i<3; i++) persistent_force_vectors[3*ind+i] = f[i];
00278     } else {
00279       // remove the persistent force (a zero will be sent automatically!)
00280       persistent_force_indices.remove(ind);
00281       persistent_force_vectors.remove(3*ind  );
00282       persistent_force_vectors.remove(3*ind+1);
00283       persistent_force_vectors.remove(3*ind+2);
00284     }
00285   }
00286 }
00287  

Generated on Sat May 26 01:48:10 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002