13 #include "ComputeFmmSerialMgr.decl.h"    18 #include "ComputeMgr.decl.h"    20 #define MIN_DEBUG_LEVEL 3    41 extern "C" void fmmlap_uni_(
    88   CProxy_ComputeFmmSerialMgr fmmProxy;
   103   double *chargebuffer;
   105   double (*posbuffer)[3];
   106   double (*forcebuffer)[3];
   110   fmmProxy(thisgroup), fmmCompute(0), numSources(0), numArrived(0),
   111   coordMsgs(0), coord(0), force(0), oldmsg(0), numAtoms(0),
   112   fmmsolver(0), nlevels(0), scaling(0), center(0),
   113   chargebuffer(0), epotbuffer(0), posbuffer(0), forcebuffer(0)
   115   CkpvAccess(BOCclass_group).computeFmmSerialMgr = thisgroup;
   120   for (
int i=0;  i < numSources;  i++)  
delete coordMsgs[i];
   125   if (chargebuffer) 
delete[] chargebuffer;
   126   if (epotbuffer)   
delete[] epotbuffer;
   127   if (posbuffer)    
delete[] posbuffer;
   128   if (forcebuffer)  
delete[] forcebuffer;
   134   CProxy_ComputeFmmSerialMgr::ckLocalBranch(
   135         CkpvAccess(BOCclass_group).computeFmmSerialMgr)->setCompute(
this);
   148   if ( ! 
patchList[0].p->flags.doFullElectrostatics )
   150     for (ap = ap.
begin(); ap != ap.
end(); ap++) {
   151       CompAtom *x = (*ap).positionBox->open();
   152       Results *r = (*ap).forceBox->open();
   153       (*ap).positionBox->close(&x);
   154       (*ap).forceBox->close(&r);
   161   int numLocalAtoms = 0;
   162   for (ap = ap.
begin(); ap != ap.
end(); ap++) {
   163     numLocalAtoms += (*ap).p->getNumAtoms();
   173   for (ap = ap.
begin();  ap != ap.
end();  ap++) {
   174     CompAtom *x = (*ap).positionBox->open();
   177       (*ap).positionBox->close(&x);
   178       x = (*ap).avgPositionBox->open();
   180     int numAtoms = (*ap).p->getNumAtoms();
   182     for(
int i=0;  i < numAtoms;  i++)
   186       data_ptr->
id = xExt[i].
id;
   190     if ( 
patchList[0].p->flags.doMolly ) { (*ap).avgPositionBox->close(&x); }
   191     else { (*ap).positionBox->close(&x); }
   194   CProxy_ComputeFmmSerialMgr fmmProxy(
   195       CkpvAccess(BOCclass_group).computeFmmSerialMgr);
   196   fmmProxy[0].recvCoord(msg);
   202   if ( ! numSources ) {
   205     for ( i=0; i<numSources; ++i ) { coordMsgs[i] = 0; }
   212   for ( i=0; i < msg->
numAtoms; ++i ) {
   216   coordMsgs[numArrived] = msg;
   219   if ( numArrived < numSources ) 
return;
   227   double virial[3][3] = { 0 };  
   237     if (lattice.
a_p() || lattice.
b_p() || lattice.
c_p()) {
   238       NAMD_die(
"FMM solver requires non-periodic boundaries");
   248       nlevels = (int) floor(log((
double)numAtoms) / log(8.) + 0.5);
   253       NAMD_die(
"setting up FMM with no atoms");
   257     for (i = 1;  i < numAtoms;  i++) {
   259       if      (r.
x < min.
x)  min.
x = r.
x;
   260       else if (r.
x > max.
x)  max.
x = r.
x;
   261       if      (r.
y < min.
y)  min.
y = r.
y;
   262       else if (r.
y > max.
y)  max.
y = r.
y;
   263       if      (r.
z < min.
z)  min.
z = r.
z;
   264       else if (r.
z > max.
z)  max.
z = r.
z;
   267     if (padding <= 0) padding = 0.01;  
   270     double len = max.
x - min.
x;
   271     if (len < max.
y - min.
y)  len = max.
y - min.
y;
   272     if (len < max.
z - min.
z)  len = max.
z - min.
z;
   274     center = 0.5*(min + max);  
   275     iout << 
iINFO << 
"FMM scaling length set to " << len << 
" A\n" << 
endi;
   276     iout << 
iINFO << 
"FMM center set to " << center << 
"\n" << 
endi;
   279     chargebuffer = 
new double[numAtoms];     
   280     epotbuffer   = 
new double[numAtoms];     
   281     posbuffer    = 
new double[numAtoms][3];  
   282     forcebuffer  = 
new double[numAtoms][3];  
   283     if (chargebuffer == 0 || epotbuffer == 0 ||
   284         posbuffer == 0 || forcebuffer == 0) {
   285       NAMD_die(
"can't allocate buffer space for FMM data");
   290     for (i = 0;  i < numAtoms;  i++) {
   291       chargebuffer[i] = celec * coord[i].
charge;
   297   for (i = 0;  i < numAtoms;  i++) {
   298     posbuffer[i][0] = scaling*(coord[i].
position.
x - center.
x);
   299     posbuffer[i][1] = scaling*(coord[i].
position.
y - center.
y);
   300     posbuffer[i][2] = scaling*(coord[i].
position.
z - center.
z);
   306   fmmlap_uni_(&numAtoms, posbuffer, chargebuffer, epotbuffer, forcebuffer,
   309   NAMD_die(
"Must link to FMM library to use FMM\n");
   313   for (i = 0;  i < numAtoms;  i++) {
   314     double qs = chargebuffer[i] * scaling;
   315     force[i].
x = qs * scaling * forcebuffer[i][0];
   316     force[i].
y = qs * scaling * forcebuffer[i][1];
   317     force[i].
z = qs * scaling * forcebuffer[i][2];
   318     energy += qs * epotbuffer[i];
   323   for (
int j=0;  j < numSources;  j++) {
   328     for (
int i=0;  i < cmsg->
numAtoms;  i++) {
   334       for (
int k=0;  k < 3;  k++) {
   335         for (
int l=0;  l < 3;  l++) {
   336           fmsg->
virial[k][l] = virial[k][l];
   342       for (
int k=0;  k < 3;  k++) {
   343         for (
int l=0;  l < 3;  l++) {
   367   for (ap = ap.
begin(); ap != ap.
end(); ap++) {
   368     Results *r = (*ap).forceBox->open();
   370     int numAtoms = (*ap).p->getNumAtoms();
   372     for(
int i=0; i<numAtoms; ++i) {
   373       f[i].
x += results_ptr->
x;
   374       f[i].
y += results_ptr->
y;
   375       f[i].
z += results_ptr->
z;
   379     (*ap).forceBox->close(&r);
   383   reduction->
item(REDUCTION_VIRIAL_SLOW_XX) += msg->
virial[0][0];
   384   reduction->
item(REDUCTION_VIRIAL_SLOW_XY) += msg->
virial[0][1];
   385   reduction->
item(REDUCTION_VIRIAL_SLOW_XZ) += msg->
virial[0][2];
   386   reduction->
item(REDUCTION_VIRIAL_SLOW_YX) += msg->
virial[1][0];
   387   reduction->
item(REDUCTION_VIRIAL_SLOW_YY) += msg->
virial[1][1];
   388   reduction->
item(REDUCTION_VIRIAL_SLOW_YZ) += msg->
virial[1][2];
   389   reduction->
item(REDUCTION_VIRIAL_SLOW_ZX) += msg->
virial[2][0];
   390   reduction->
item(REDUCTION_VIRIAL_SLOW_ZY) += msg->
virial[2][1];
   391   reduction->
item(REDUCTION_VIRIAL_SLOW_ZZ) += msg->
virial[2][2];
   395 #include "ComputeFmmSerialMgr.def.h" 
std::ostream & iINFO(std::ostream &s)
 
virtual ~ComputeFmmSerial()
 
NAMD_HOST_DEVICE int c_p() const
 
static PatchMap * Object()
 
virtual void submit(void)=0
 
SimParameters * simParameters
 
ComputeHomePatchList patchList
 
std::ostream & endi(std::ostream &s)
 
void recvCoord(FmmSerialCoordMsg *)
 
SubmitReduction * willSubmit(int setID, int size=-1)
 
ResizeArrayIter< T > begin(void) const
 
static ReductionMgr * Object(void)
 
NAMD_HOST_DEVICE int b_p() const
 
void setCompute(ComputeFmmSerial *c)
 
ComputeFmmSerialAtom * coord
 
ComputeFmmSerial(ComputeID c)
 
NAMD_HOST_DEVICE int a_p() const
 
void NAMD_die(const char *err_msg)
 
void saveResults(FmmSerialForceMsg *)
 
void recvForce(FmmSerialForceMsg *)
 
ResizeArrayIter< T > end(void) const