00001
00007 #include "ComputeGridForce.h"
00008 #include "GridForceGrid.h"
00009 #include "Node.h"
00010
00011 #define MIN_DEBUG_LEVEL 2
00012
00013 #include "Debug.h"
00014
00015 #include "GridForceGrid.inl"
00016 #include "MGridforceParams.h"
00017
00018
00019
00020 #define GF_OVERLAPCHECK_FREQ 100
00021
00022
00023 ComputeGridForce::ComputeGridForce(ComputeID c, PatchID pid)
00024 : ComputeHomePatch(c,pid)
00025 {
00026
00027 reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00028
00029 }
00030
00031
00032
00033 ComputeGridForce::~ComputeGridForce()
00034 {
00035 delete reduction;
00036 }
00037
00038
00039 template <class T> void ComputeGridForce::do_calc(T *grid, int gridnum, FullAtom *p, int numAtoms, Molecule *mol, Force *forces, BigReal &energy, Force &extForce, Tensor &extVirial)
00040 {
00041 Real scale;
00042 Charge charge;
00043 Vector dV;
00044 float V;
00045
00046 Vector gfScale = grid->get_scale();
00047
00048
00049 for (int i = 0; i < numAtoms; i++) {
00050 if (mol->is_atom_gridforced(p[i].id, gridnum))
00051 {
00052 DebugM(1, "Atom " << p[i].id << " is gridforced\n" << endi);
00053
00054 mol->get_gridfrc_params(scale, charge, p[i].id, gridnum);
00055
00056
00057 Position pos = grid->wrap_position(p[i].position, homePatch->lattice);
00058 DebugM(1, "pos = " << pos << "\n" << endi);
00059
00060
00061 int err = grid->compute_VdV(pos, V, dV);
00062
00063 if (err) {
00064 DebugM(2, "V = 0\n" << endi);
00065 DebugM(2, "dV = 0 0 0\n" << endi);
00066 continue;
00067 }
00068
00069
00070 Force force = -charge * scale * Vector(gfScale.x * dV.x, gfScale.y * dV.y, gfScale.z * dV.z);
00071
00072 #ifdef DEBUGM
00073 DebugM(2, "scale = " << scale << " gfScale = " << gfScale << " charge = " << charge << "\n" << endi);
00074
00075 DebugM(2, "V = " << V << "\n" << endi);
00076 DebugM(2, "dV = " << dV << "\n" << endi);
00077 DebugM(2, "grid = " << gridnum << " force = " << force << " pos = " << pos << " V = " << V << " dV = " << dV << " step = " << homePatch->flags.step << " index = " << p[i].id << "\n" << endi);
00078
00079 DebugM(1, "transform = " << (int)p[i].transform.i << " "
00080 << (int)p[i].transform.j << " " << (int)p[i].transform.k << "\n" << endi);
00081
00082 if (V != V) {
00083 iout << iWARN << "V is NaN!\natomid = " << p[i].id << " loc = " << p[i].position << " V = " << V << "\n" << endi;
00084 }
00085 #endif
00086
00087 forces[i] += force;
00088 extForce += force;
00089 Position vpos = homePatch->lattice.reverse_transform(p[i].position, p[i].transform);
00090
00091
00092 if (gfScale.x == gfScale.y && gfScale.x == gfScale.z)
00093 {
00094
00095 energy += scale * gfScale.x * (charge * V);
00096
00097
00098 }
00099 extVirial += outer(force,vpos);
00100 }
00101 }
00102 }
00103
00104 void ComputeGridForce::doForce(FullAtom* p, Results* r)
00105 {
00106 SimParameters *simParams = Node::Object()->simParameters;
00107 Molecule *mol = Node::Object()->molecule;
00108
00109 Force *forces = r->f[Results::normal];
00110 BigReal energy = 0;
00111 Force extForce = 0.;
00112 Tensor extVirial;
00113
00114 int numAtoms = homePatch->getNumAtoms();
00115
00116 for (int gridnum = 0; gridnum < mol->numGridforceGrids; gridnum++) {
00117 GridforceGrid *grid = mol->get_gridfrc_grid(gridnum);
00118
00119 if (homePatch->flags.step % GF_OVERLAPCHECK_FREQ == 0) {
00120
00121 if (simParams->langevinPistonOn || simParams->berendsenPressureOn) {
00122
00123
00124 if (!grid->fits_lattice(homePatch->lattice)) {
00125 char errmsg[512];
00126 sprintf(errmsg, "Periodic cell basis too small for Gridforce grid %d\n", gridnum);
00127 NAMD_die(errmsg);
00128 }
00129 }
00130 }
00131
00132 Position center = grid->get_center();
00133
00134 if (homePatch->flags.step % 100 == 1) {
00135 DebugM(3, "center = " << center << "\n" << endi);
00136 DebugM(3, "e = " << grid->get_e() << "\n" << endi);
00137 }
00138
00139 if (grid->get_grid_type() == GridforceGrid::GridforceGridTypeFull) {
00140 GridforceFullMainGrid *g = (GridforceFullMainGrid *)grid;
00141 do_calc(g, gridnum, p, numAtoms, mol, forces, energy, extForce, extVirial);
00142 } else if (grid->get_grid_type() == GridforceGrid::GridforceGridTypeLite) {
00143 GridforceLiteGrid *g = (GridforceLiteGrid *)grid;
00144 do_calc(g, gridnum, p, numAtoms, mol, forces, energy, extForce, extVirial);
00145 }
00146 }
00147 reduction->item(REDUCTION_MISC_ENERGY) += energy;
00148 ADD_VECTOR_OBJECT(reduction,REDUCTION_EXT_FORCE_NORMAL,extForce);
00149 ADD_TENSOR_OBJECT(reduction,REDUCTION_VIRIAL_NORMAL,extVirial);
00150 reduction->submit();
00151 }
00152