00001
00007 #ifndef COMPUTESELFTUPLES_H
00008 #define COMPUTESELFTUPLES_H
00009
00010 #include "ComputeHomeTuples.h"
00011 #include "LdbCoordinator.h"
00012
00013 template <class T, class S, class P> class ComputeSelfTuples :
00014 public ComputeHomeTuples<T,S,P> {
00015
00016 private:
00017
00018 virtual void loadTuples(void) {
00019 int numTuples;
00020
00021 #ifdef MEM_OPT_VERSION
00022 typename ElemTraits<T>::signature *allSigs;
00023 #else
00024 int32 **tuplesByAtom;
00025 S *tupleStructs;
00026 #endif
00027
00028 const P *tupleValues;
00029 Node *node = Node::Object();
00030
00031 #ifdef MEM_OPT_VERSION
00032 allSigs = ElemTraits<T>::get_sig_pointer(node->molecule);
00033 #else
00034 T::getMoleculePointers(node->molecule,
00035 &numTuples, &tuplesByAtom, &tupleStructs);
00036 #endif
00037
00038 T::getParameterPointers(node->parameters, &tupleValues);
00039
00040 this->tupleList.resize(0);
00041
00042 LocalID aid[T::size];
00043
00044 const int lesOn = node->simParameters->lesOn;
00045 Real invLesFactor = lesOn ?
00046 1.0/node->simParameters->lesFactor :
00047 1.0;
00048
00049
00050
00051 TuplePatchListIter ai(this->tuplePatchList);
00052
00053 for ( ai = ai.begin(); ai != ai.end(); ai++ )
00054 {
00055
00056
00057 Patch *patch = (*ai).p;
00058 int numAtoms = patch->getNumAtoms();
00059 CompAtomExt *atomExt = (*ai).xExt;
00060
00061
00062 for (int j=0; j < numAtoms; j++)
00063 {
00064 #ifdef MEM_OPT_VERSION
00065 typename ElemTraits<T>::signature *thisAtomSig =
00066 &allSigs[ElemTraits<T>::get_sig_id(atomExt[j])];
00067 TupleSignature *allTuples;
00068 T::getTupleInfo(thisAtomSig, &numTuples, &allTuples);
00069 for(int k=0; k<numTuples; k++) {
00070 T t(atomExt[j].id, &allTuples[k], tupleValues);
00071 #else
00072
00073 int32 *curTuple = tuplesByAtom[atomExt[j].id];
00074
00075 for( ; *curTuple != -1; ++curTuple) {
00076 T t(&tupleStructs[*curTuple],tupleValues);
00077 #endif
00078 register int i;
00079 aid[0] = this->atomMap->localID(t.atomID[0]);
00080 int homepatch = aid[0].pid;
00081 int samepatch = 1;
00082 int has_les = lesOn && node->molecule->get_fep_type(t.atomID[0]);
00083 for (i=1; i < T::size; i++) {
00084 aid[i] = this->atomMap->localID(t.atomID[i]);
00085 samepatch = samepatch && ( homepatch == aid[i].pid );
00086 has_les |= lesOn && node->molecule->get_fep_type(t.atomID[i]);
00087 }
00088 if ( samepatch ) {
00089 t.scale = has_les ? invLesFactor : 1;
00090 TuplePatchElem *p;
00091 p = this->tuplePatchList.find(TuplePatchElem(homepatch));
00092 for(i=0; i < T::size; i++) {
00093 t.p[i] = p;
00094 t.localIndex[i] = aid[i].index;
00095 }
00096 #ifdef MEM_OPT_VERSION
00097
00098 if(node->simParameters->fixedAtomsOn &&
00099 !node->simParameters->fixedAtomsForces) {
00100 int allfixed = 1;
00101 for(i=0; i<T::size; i++){
00102 CompAtomExt *one = &(p->xExt[aid[i].index]);
00103 allfixed = allfixed & one->atomFixed;
00104 }
00105 if(!allfixed) this->tupleList.add(t);
00106 }else{
00107 this->tupleList.add(t);
00108 }
00109 #else
00110 this->tupleList.add(t);
00111 #endif
00112 }
00113 }
00114 }
00115 }
00116 }
00117
00118 PatchID patchID;
00119
00120 public:
00121
00122 ComputeSelfTuples(ComputeID c, PatchID p) : ComputeHomeTuples<T,S,P>(c) {
00123 patchID = p;
00124 }
00125
00126 virtual ~ComputeSelfTuples() {
00127 UniqueSetIter<TuplePatchElem> ap(this->tuplePatchList);
00128 for (ap = ap.begin(); ap != ap.end(); ap++) {
00129 ap->p->unregisterPositionPickup(this,&(ap->positionBox));
00130 ap->p->unregisterAvgPositionPickup(this,&(ap->avgPositionBox));
00131 ap->p->unregisterForceDeposit(this,&(ap->forceBox));
00132 }
00133 }
00134
00135
00136
00137
00138
00139
00140 virtual void initialize(void) {
00141
00142
00143 this->tuplePatchList.clear();
00144
00145 this->tuplePatchList.add(TuplePatchElem(ComputeHomeTuples<T,S,P>::patchMap->patch(patchID), this));
00146
00147 this->setNumPatches(this->tuplePatchList.size());
00148 this->doLoadTuples = true;
00149
00150 int myNode = CkMyPe();
00151 if ( PatchMap::Object()->node(patchID) != myNode )
00152 {
00153 this->basePriority = COMPUTE_PROXY_PRIORITY + PATCH_PRIORITY(patchID);
00154 }
00155 else
00156 {
00157 this->basePriority = COMPUTE_HOME_PRIORITY + PATCH_PRIORITY(patchID);
00158 }
00159 }
00160
00161 void doWork(void) {
00162
00163
00164 #ifdef TRACE_COMPUTE_OBJECTS
00165 double traceObjStartTime = CmiWallTimer();
00166 #endif
00167
00168 ComputeHomeTuples<T,S,P>::doWork();
00169
00170 #ifdef TRACE_COMPUTE_OBJECTS
00171 traceUserBracketEvent(TRACE_COMPOBJ_IDOFFSET+this->cid, traceObjStartTime, CmiWallTimer());
00172 #endif
00173
00174
00175 }
00176
00177 };
00178
00179
00180 #endif
00181