00001
00007 #include "ComputeNonbondedSelf.h"
00008 #include "ReductionMgr.h"
00009 #include "Patch.h"
00010 #include "LdbCoordinator.h"
00011
00012 #define MIN_DEBUG_LEVEL 4
00013
00014 #include "Debug.h"
00015
00016 ComputeNonbondedSelf::ComputeNonbondedSelf(ComputeID c, PatchID pid,
00017 ComputeNonbondedWorkArrays* _workArrays,
00018 int minPartition, int maxPartition, int numPartitions)
00019 : ComputePatch(c,pid), workArrays(_workArrays),
00020 minPart(minPartition), maxPart(maxPartition), numParts(numPartitions)
00021 {
00022 reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00023 if (pressureProfileOn) {
00024 int n = pressureProfileAtomTypes;
00025 pressureProfileData = new BigReal[3*n*n*pressureProfileSlabs];
00026 pressureProfileReduction = ReductionMgr::Object()->willSubmit(
00027 REDUCTIONS_PPROF_NONBONDED, 3*pressureProfileSlabs*((n*(n+1))/2));
00028 } else {
00029 pressureProfileReduction = NULL;
00030 pressureProfileData = NULL;
00031 }
00032 pairlistsValid = 0;
00033 pairlistTolerance = 0.;
00034 }
00035
00036 void ComputeNonbondedSelf::initialize() {
00037 ComputePatch::initialize();
00038 avgPositionBox = patch->registerAvgPositionPickup(cid);
00039 }
00040
00041 ComputeNonbondedSelf::~ComputeNonbondedSelf()
00042 {
00043 delete reduction;
00044 delete pressureProfileReduction;
00045 delete [] pressureProfileData;
00046 if (avgPositionBox != NULL) {
00047 patch->unregisterAvgPositionPickup(cid,&avgPositionBox);
00048 }
00049 }
00050
00051 #ifdef MEM_OPT_VERSION
00052 void ComputeNonbondedSelf::doForce(CompAtom* p, CompAtomExt* pExt, Results* r)
00053 #else
00054 void ComputeNonbondedSelf::doForce(CompAtom* p, Results* r)
00055 #endif
00056 {
00057
00058
00059 LdbCoordinator::Object()->startWork(cid,0);
00060
00061 #ifdef TRACE_COMPUTE_OBJECTS
00062 double traceObjStartTime = CmiWallTimer();
00063 #endif
00064
00065 DebugM(2,"doForce() called.\n");
00066 DebugM(1,numAtoms << " patch 1 atoms\n");
00067 DebugM(3, "NUMATOMSxNUMATOMS = " << numAtoms*numAtoms << "\n");
00068
00069 BigReal reductionData[reductionDataSize];
00070 for ( int i = 0; i < reductionDataSize; ++i ) reductionData[i] = 0;
00071 if (pressureProfileOn) {
00072 int n = pressureProfileAtomTypes;
00073 memset(pressureProfileData, 0, 3*n*n*pressureProfileSlabs*sizeof(BigReal));
00074
00075 const Lattice &lattice = patch->lattice;
00076 pressureProfileThickness = lattice.c().z / pressureProfileSlabs;
00077 pressureProfileMin = lattice.origin().z - 0.5*lattice.c().z;
00078 }
00079 if ( patch->flags.doNonbonded )
00080 {
00081 plint maxa = (plint)(-1);
00082 if ( numAtoms > maxa ) {
00083 char estr[1024];
00084 sprintf(estr,"patch has %d atoms, maximum allowed is %d",numAtoms,maxa);
00085 NAMD_die(estr);
00086 }
00087
00088 int doEnergy = patch->flags.doEnergy;
00089 nonbonded params;
00090 params.offset = 0.;
00091 params.p[0] = p;
00092 params.p[1] = p;
00093 #ifdef MEM_OPT_VERSION
00094 params.pExt[0] = pExt;
00095 params.pExt[1] = pExt;
00096 #endif
00097 params.ff[0] = r->f[Results::nbond];
00098 params.ff[1] = r->f[Results::nbond];
00099 params.numAtoms[0] = numAtoms;
00100 params.numAtoms[1] = numAtoms;
00101
00102
00103 #if NAMD_SeparateWaters != 0
00104 params.numWaterAtoms[0] = numWaterAtoms;
00105 params.numWaterAtoms[1] = numWaterAtoms;
00106 #endif
00107
00108 params.reduction = reductionData;
00109 params.pressureProfileReduction = pressureProfileData;
00110
00111 params.minPart = minPart;
00112 params.maxPart = maxPart;
00113 params.numParts = numParts;
00114
00115 params.workArrays = workArrays;
00116
00117 params.pairlists = &pairlists;
00118 params.savePairlists = 0;
00119 params.usePairlists = 0;
00120 if ( patch->flags.savePairlists ) {
00121 params.savePairlists = 1;
00122 params.usePairlists = 1;
00123 } else if ( patch->flags.usePairlists ) {
00124 if ( ! pairlistsValid ||
00125 ( 2. * patch->flags.maxAtomMovement > pairlistTolerance ) ) {
00126 reductionData[pairlistWarningIndex] += 1;
00127 } else {
00128 params.usePairlists = 1;
00129 }
00130 }
00131 if ( ! params.usePairlists ) {
00132 pairlistsValid = 0;
00133 }
00134 params.plcutoff = cutoff;
00135 params.groupplcutoff = cutoff + 2. * patch->flags.maxGroupRadius;
00136 if ( params.savePairlists ) {
00137 pairlistsValid = 1;
00138 pairlistTolerance = 2. * patch->flags.pairlistTolerance;
00139 params.plcutoff += pairlistTolerance;
00140 params.groupplcutoff += pairlistTolerance;
00141 }
00142
00143 if ( patch->flags.doFullElectrostatics )
00144 {
00145 params.fullf[0] = r->f[Results::slow];
00146 params.fullf[1] = r->f[Results::slow];
00147 if ( patch->flags.doMolly ) {
00148 if ( doEnergy ) calcSelfEnergy(¶ms);
00149 else calcSelf(¶ms);
00150 CompAtom *p_avg = avgPositionBox->open();
00151 params.p[0] = p_avg;
00152 params.p[1] = p_avg;
00153 if ( doEnergy ) calcSlowSelfEnergy(¶ms);
00154 else calcSlowSelf(¶ms);
00155 avgPositionBox->close(&p_avg);
00156 } else if ( patch->flags.maxForceMerged == Results::slow ) {
00157 if ( doEnergy ) calcMergeSelfEnergy(¶ms);
00158 else calcMergeSelf(¶ms);
00159 } else {
00160 if ( doEnergy ) calcFullSelfEnergy(¶ms);
00161 else calcFullSelf(¶ms);
00162 }
00163 }
00164 else
00165 if ( doEnergy ) calcSelfEnergy(¶ms);
00166 else calcSelf(¶ms);
00167 }
00168
00169 submitReductionData(reductionData,reduction);
00170 if (pressureProfileOn)
00171 submitPressureProfileData(pressureProfileData, pressureProfileReduction);
00172
00173 #ifdef TRACE_COMPUTE_OBJECTS
00174 traceUserBracketEvent(TRACE_COMPOBJ_IDOFFSET+cid, traceObjStartTime, CmiWallTimer());
00175 #endif
00176
00177
00178 LdbCoordinator::Object()->endWork(cid,0);
00179
00180 reduction->submit();
00181 if (pressureProfileOn)
00182 pressureProfileReduction->submit();
00183 }
00184