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

Generated on Thu Jun 21 01:17:15 2018 for NAMD by  doxygen 1.4.7