HomePatch.h

Go to the documentation of this file.
00001 
00007 /*
00008    HomePatch is the key distributed source/sink of Atom data
00009    including positions, velocities and forces applied
00010 */
00011 
00012 #ifndef HOMEPATCH_H
00013 #define HOMEPATCH_H
00014 
00015 #include "charm++.h"
00016 
00017 #include "NamdTypes.h"
00018 #include "Patch.h"
00019 #include "PatchMap.h"
00020 
00021 #include "MigrateAtomsMsg.h"
00022 #include "main.h"
00023 #include "common.h"
00024 #include "Migration.h"
00025 #include "Settle.h"
00026 
00027 #include <string>
00028 #include <map>
00029 
00030 //
00031 // DJH: NAMDLite array buffers are memory aligned for vector instructions.
00032 //
00033 //#include "nl_Array.h"
00034 //
00035 
00036 class RegisterProxyMsg;
00037 class UnregisterProxyMsg;
00038 class ProxyResultVarsizeMsg;
00039 class ProxyResultMsg;
00040 class ProxyCombinedResultRawMsg;
00041 class Sequencer;
00042 class SubmitReduction;
00043 class ProxyGBISP1ResultMsg;
00044 class ProxyGBISP2ResultMsg;
00045 class CheckpointAtomsMsg;
00046 class ExchangeAtomsMsg;
00047 
00048 class ProxyNodeAwareSpanningTreeMsg;
00049 
00050 class ComputeQMMgr;
00051 
00052 //
00053 // DJH: Array buffers defined here for storing data from FullAtomList and
00054 // also forces into SOA (structure of arrays) layout. Also declare methods
00055 // for copying from AOS to SOA and back again.
00056 //
00057 // We will also remove derived constants from FullAtom (e.g. recipMass).
00058 // The idea is reduce the messaging footprint as much as possible.
00059 // Recalculate constants after atom migration.
00060 //
00061 //struct PatchDataSOA {
00062 //
00063 //namdlite::Array<float> gaussrand; // fill with Gaussian random numbers
00064 //
00065 //namdlite::Array<float> mass;
00066 //namdlite::Array<float> recipMass; // derived from mass
00067 //namdlite::Array<float> langevinParam;
00068 //namdlite::Array<float> langScalVelBBK2;  // derived from langevinParam
00069 //namdlite::Array<float> langScalRandBBK2; // from langevinParam and recipMass
00070 //
00071 //namdlite::Array<double> vel_x;  // Jim recommends double precision velocity
00072 //namdlite::Array<double> vel_y;
00073 //namdlite::Array<double> vel_z;
00074 //namdlite::Array<double> pos_x;
00075 //namdlite::Array<double> pos_y;
00076 //namdlite::Array<double> pos_z;
00077 //namdlite::Array<double> f_normal_x;
00078 //namdlite::Array<double> f_normal_y;
00079 //namdlite::Array<double> f_normal_z;
00080 //namdlite::Array<double> f_nbond_x;
00081 //namdlite::Array<double> f_nbond_y;
00082 //namdlite::Array<double> f_nbond_z;
00083 //namdlite::Array<double> f_slow_x;
00084 //namdlite::Array<double> f_slow_y;
00085 //namdlite::Array<double> f_slow_z;
00086 //};
00087 
00088 class HomePatch : public Patch {
00089   friend class PatchMgr;
00090   friend class Sequencer;
00091   friend class ComputeGlobal;
00092 
00093 private: 
00094 
00095   HomePatch(PatchID, int atomCnt);
00096   // for PatchMgr to use only
00097   HomePatch(PatchID, FullAtomList&);
00098 
00099 //  HomePatch(PatchID, int atomCnt);
00100 
00101   void reinitAtoms(FullAtomList&);
00102   ScaledPosition min, max, center;
00103   BigReal aAwayDist, bAwayDist, cAwayDist;
00104 
00105   Bool doAtomUpdate;  // atom changes other than migration
00106 
00107   //Note: If new proxies are added to this HomePatch
00108   // after load balancing, and it is not the immediate step
00109   // after atom migration (where ProxyAllMsg will be sent), 
00110   // then the CompAtomExt list has to be resent with the 
00111   // ProxyDataMsg (the normal proxy msg when atoms don't 
00112   // migrate), otherwise, program will crash without such 
00113   // information when doing force calculations --Chao Mei
00114   Bool isNewProxyAdded;
00115   int numGBISP1Arrived, numGBISP2Arrived, numGBISP3Arrived;
00116   bool phase1BoxClosedCalled;
00117   bool phase2BoxClosedCalled;
00118   bool phase3BoxClosedCalled;
00119 
00120 public:
00121   ~HomePatch();
00122 
00123   // Message from ProxyPatch (via ProxyMgr) which registers its existence
00124   void registerProxy(RegisterProxyMsg *);
00125   // opposite of above
00126   void unregisterProxy(UnregisterProxyMsg *);
00127 
00128   // ProxyPatch sends Forces back to here (via ProxyMgr)  
00129   void receiveResults(ProxyResultVarsizeMsg *msg);
00130   void receiveResults(ProxyResultMsg *msg);     
00131   //gbis receiving results from intermediate phases
00132   void receiveResult(ProxyGBISP1ResultMsg *msg);//after P1
00133   void receiveResult(ProxyGBISP2ResultMsg *msg);//after P2
00134   
00135   //direct function calls, not as entry methods
00136   void receiveResults(ProxyCombinedResultRawMsg *msg);
00137 
00138   // AtomMigration messages passes from neighbor HomePatches to here.
00139   void depositMigration(MigrateAtomsMsg *);
00140 
00141   // Bind a Sequencer to this HomePatch
00142   void useSequencer(Sequencer *sequencerPtr);
00143   // start simulation over this Patch of atoms
00144   void runSequencer(void);
00145   
00146   //--------------------------------------------------------------------
00147   // methods for Sequencer to use
00148   //
00149 
00150   // Signal HomePatch that positions stored are to be now to be used
00151   void positionsReady(int doMigration=0);
00152   int marginViolations;
00153 
00154   // methods to implement integration
00155   void saveForce(const int ftag = Results::normal);
00156   void addForceToMomentum(
00157       FullAtom       * __restrict atom_arr,
00158       const Force    * __restrict force_arr,
00159       const BigReal    dt,
00160       int              num_atoms
00161       )
00162 #if !defined(WIN32) && !defined(WIN64)
00163     __attribute__((__noinline__))
00164 #endif
00165     ;
00166   void addForceToMomentum3(
00167       FullAtom       * __restrict atom_arr,
00168       const Force    * __restrict force_arr1,
00169       const Force    * __restrict force_arr2,
00170       const Force    * __restrict force_arr3,
00171       const BigReal    dt1,
00172       const BigReal    dt2,
00173       const BigReal    dt3,
00174       int              num_atoms
00175       ) 
00176 #if !defined(WIN32) && !defined(WIN64)
00177     __attribute__((__noinline__))
00178 #endif
00179     ;
00180   void addVelocityToPosition(
00181       FullAtom       * __restrict atom_arr,
00182       const BigReal    dt,
00183       int              num_atoms
00184       ) 
00185 #if !defined(WIN32) && !defined(WIN64)
00186     __attribute__((__noinline__))
00187 #endif
00188     ;
00189 
00190   // impose hard wall constraint on Drude bond length
00191   int hardWallDrude(const BigReal, Tensor *virial, SubmitReduction *);
00192 
00193   // methods for rigidBonds
00194   struct RattleList {
00195     int ig;
00196     int icnt;
00197   };
00198 
00199   std::vector<int> settleList;
00200   std::vector<RattleList> rattleList;
00201   std::vector<RattleParam> rattleParam;
00202   std::vector<int> noconstList;
00203 
00204   bool rattleListValid;
00205 
00206   // Array to store new positions and velocities. Allocated in "buildRattleList" to size numAtoms
00207   std::vector<Vector> velNew;
00208   std::vector<Vector> posNew;
00209 
00210   void addRattleForce(const BigReal invdt, Tensor& wc);
00211 
00212   void buildRattleList();
00213   int rattle1old(const BigReal, Tensor *virial, SubmitReduction *);
00214   int rattle1(const BigReal, Tensor *virial, SubmitReduction *);
00215   void rattle2(const BigReal, Tensor *virial);
00216   void minimize_rattle2(const BigReal, Tensor *virial, bool forces=false);
00217 
00218   // methods for mollified impluse (MOLLY)
00219   void mollyAverage();
00220   void mollyMollify(Tensor *virial);
00221 //  Bool average(Vector qtilde[],const Vector q[],BigReal lambda[],const int n,const int m, const BigReal imass[], const BigReal length2[], const int ial[], const int ilb[], const Vector qji[], const BigReal tolf, const int ntrial);
00222 //  void mollify(Vector qtilde[],const Vector q0[],const BigReal lambda[], Vector force[],const int n, const int m, const BigReal imass[],const int ial[],const int ibl[],const Vector refab[]); 
00223   
00224   // BEGIN LA
00225   void loweAndersenVelocities();
00226   void loweAndersenFinish();
00227   // END LA
00228 
00229   void setGBISIntrinsicRadii();
00230   void gbisComputeAfterP1();//calculate bornRad
00231   void gbisComputeAfterP2();//calculate dHdrPrefix or self energies
00232   void gbisP2Ready();
00233   void gbisP3Ready();
00234 
00235   //LCPO
00236   void setLcpoType();
00237 
00238   // methods for CONTRA, etc
00239   void checkpoint(void);
00240   void revert(void);
00241 
00242   void exchangeCheckpoint(int scriptTask, int &bpc);
00243   void recvCheckpointReq(int task, const char *key, int replica, int pe);
00244   void recvCheckpointLoad(CheckpointAtomsMsg *msg);
00245   void recvCheckpointStore(CheckpointAtomsMsg *msg);
00246   void recvCheckpointAck();
00247   int checkpoint_task;
00248   struct checkpoint_t {
00249     Lattice lattice;
00250     int berendsenPressure_count;
00251     int numAtoms;
00252     ResizeArray<FullAtom> atoms;
00253   };
00254   std::map<std::string,checkpoint_t*> checkpoints;
00255 
00256   // replica exchange
00257   void exchangeAtoms(int scriptTask);
00258   void recvExchangeReq(int req);
00259   void recvExchangeMsg(ExchangeAtomsMsg *msg);
00260   int exchange_dst;
00261   int exchange_src;
00262   int exchange_req;
00263   ExchangeAtomsMsg *exchange_msg;
00264 
00265   // methods for QM (ExtForces replacement)
00266   void replaceForces(ExtForce *f);
00267 
00268   void qmSwapAtoms();
00269   
00270   // load-balancing trigger
00271   void submitLoadStats(int timestep);
00272 
00273   // for ComputeHomePatches
00274   FullAtomList &getAtomList() { return (atom); }
00275 
00276 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00277   // build spanning tree for proxy nodes
00278   void buildNodeAwareSpanningTree(void);
00279   void setupChildrenFromProxySpanningTree();
00280 #else
00281     // build spanning tree for proxy nodes
00282   void buildSpanningTree(void);
00283 #endif
00284 
00285   void sendNodeAwareSpanningTree();
00286   void recvNodeAwareSpanningTree(ProxyNodeAwareSpanningTreeMsg *msg);
00287 
00288   void sendSpanningTree();
00289   void recvSpanningTree(int *t, int n);
00290 
00291 
00292   void sendProxies();
00293 
00294 #if USE_TOPOMAP 
00295   int findSubroots(int dim, int* subroots, int psize, int* pidscopy);
00296 #endif
00297 
00298   LDObjHandle ldObjHandle;
00299 protected:
00300   virtual void boxClosed(int);
00301 
00302   // Internal Atom Migration methods and data
00303   void doPairlistCheck();
00304   void doGroupSizeCheck();
00305   void doMarginCheck();
00306   void doAtomMigration();
00307   int inMigration;
00308   int numMlBuf;
00309   MigrateAtomsMsg *msgbuf[PatchMap::MaxOneAway];
00310   
00311 private:
00312   // Store of Atom-wise variables
00313   FullAtomList  atom;
00314   ForceList f_saved[Results::maxNumForces];
00315   ExtForce *replacementForces;
00316 
00317   CudaAtomList cudaAtomList;
00318 
00319   //
00320   // DJH: SOA data structure declared here.
00321   //
00322   //PatchDataSOA patchDataSOA;
00323   //
00324   // Copy fields from FullAtom into SOA form.
00325   //void copy_atoms_to_SOA();
00326   //
00327   // Copy forces into SOA form.
00328   //void copy_forces_to_SOA();
00329   //
00330   // Calculate derived constants after atom migration.
00331   //void calculate_derived_SOA();
00332   //
00333   // Copy the updated quantities, e.g., positions and velocities, from SOA
00334   // back to AOS form.
00335   //void copy_updates_to_AOS();
00336   //
00337 
00338   // DMK - Atom Separation (water vs. non-water)
00339   #if NAMD_SeparateWaters != 0
00340     FullAtomList tempAtom;  // A temporary array used to sort waters
00341                             //   from non-waters in the atom array
00342     void separateAtoms();   // Function to separate the atoms currently in atoms.
00343     void mergeAtomList(FullAtomList &al);  // Function to combine and separate
00344                                            //   the atoms in al with atoms.
00345   #endif
00346 
00347 
00348   // checkpointed state
00349   FullAtomList  checkpoint_atom;
00350   Lattice  checkpoint_lattice;
00351 
00352   // DMK - Atom Separation (water vs. non-water)
00353   #if NAMD_SeparateWaters != 0
00354     int checkpoint_numWaterAtoms;
00355   #endif
00356 
00357 
00358   // checkPairlist data
00359   CompAtomList doPairlistCheck_positions;
00360   Lattice doPairlistCheck_lattice;
00361   BigReal doPairlistCheck_newTolerance;
00362 
00363   // MOLLY data
00364   ResizeArray<BigReal> molly_lambda;
00365   
00366   // List of Proxies
00367   NodeIDList proxy;
00368   
00369   Sequencer  *sequencer;
00370 
00371   // Needed for initialization
00372   int patchMapRead;
00373   void readPatchMap();
00374 
00375   // Atom Migration internals
00376   int allMigrationIn;
00377   int migrationSuspended;
00378   int patchMigrationCounter;
00379   int numNeighbors;
00380   MigrationInfo realInfo[PatchMap::MaxOneAway];
00381   MigrationInfo *mInfo[3][3][3];
00382 
00383 #ifdef NODEAWARE_PROXY_SPANNINGTREE
00384   //the whole spanning tree for all the proxies this home patch has
00385   proxyTreeNodeList ptnTree;
00386   //the immediate children (recording pe ids) containing two parts: 
00387   //one part of them all belong to the physical node this home patch
00388   // resides on; the other part of pes belong to all external nodes.
00389   /* Moved to Patch.h */ 
00390   //int *children;
00391   //int numChild;
00392 #else
00393   NodeIDList tree;              // the whole tree
00394   int *child;   // spanning tree of proxies - immediate children
00395   int nChild;
00396 #endif
00397 
00398   // Cached settle1 parameters
00399   int settle_initialized;
00400   BigReal settle_mOrmT; BigReal settle_mHrmT; BigReal settle_ra;
00401   BigReal settle_rb; BigReal settle_rc; BigReal settle_rra;
00402 
00403   // Drude lone pairs
00404   void redistrib_lonepair_forces(const int, Tensor *);
00405 
00406   // PLF -- for TIP4P
00407   //void redistrib_tip4p_force(Vector&, Vector&, Vector&, Vector&, int, Tensor*);
00408   void redistrib_tip4p_forces(const int, Tensor*);
00409   void tip4_omrepos(Vector*, Vector*, Vector*, BigReal);
00410   void init_tip4();
00411 
00412   // Drude SWM4
00413   void redistrib_swm4_forces(const int, Tensor*);
00414   void swm4_omrepos(Vector*, Vector*, Vector*, BigReal);
00415   void init_swm4();
00416 
00417   // reposition a lone pair using its host atoms and additional parameters
00418   void reposition_lonepair(
00419       Vector& ri, const Vector& rj, const Vector& rk, const Vector& rl,
00420       Real distance, Real angle, Real dihedral);
00421 
00422   void reposition_all_lonepairs(void);
00423 
00424   // general redistribution of lone pair forces to host atoms
00425   void redistrib_lp_force(
00426       Vector& fi, Vector& fj, Vector& fk, Vector& fl,
00427       const Vector& ri, const Vector& rj, const Vector& rk, const Vector& rl,
00428       Tensor *virial, int midpt);
00429 
00430   // use for both TIP4P and SWM4 water
00431   void redistrib_lp_water_force(
00432       Vector& f_ox, Vector& f_h1, Vector& f_h2, Vector& f_lp,
00433       const Vector& p_ox, const Vector& p_h1, const Vector& p_h2,
00434       const Vector& p_lp, Tensor *virial);
00435 
00436   BigReal r_om, r_ohc;
00437   void write_tip4_props(void);
00438 
00439   int isProxyChanged;
00440 
00441 #if CMK_PERSISTENT_COMM
00442   PersistentHandle *localphs;
00443   int nphs;
00444 #endif
00445 };
00446 
00447 #endif
00448 

Generated on Tue Nov 21 01:17:13 2017 for NAMD by  doxygen 1.4.7