00001
00007 #include "InfoStream.h"
00008 #include "ComputeThole.h"
00009 #include "Molecule.h"
00010 #include "Parameters.h"
00011 #include "Node.h"
00012 #include "ReductionMgr.h"
00013 #include "Lattice.h"
00014 #include "PressureProfile.h"
00015 #include "Debug.h"
00016
00017 #define CALCULATE_THOLE_CORRECTION
00018
00019
00020 int TholeElem::pressureProfileSlabs = 0;
00021 int TholeElem::pressureProfileAtomTypes = 1;
00022 BigReal TholeElem::pressureProfileThickness = 0;
00023 BigReal TholeElem::pressureProfileMin = 0;
00024
00025 void TholeElem::getMoleculePointers
00026 (Molecule* mol, int* count, int32*** byatom, Thole** structarray)
00027 {
00028 #ifdef MEM_OPT_VERSION
00029 NAMD_die("Should not be called in TholeElem::getMoleculePointers in memory optimized version!");
00030 #else
00031 *count = mol->numTholes;
00032 *byatom = mol->tholesByAtom;
00033 *structarray = mol->tholes;
00034 #endif
00035 }
00036
00037 void TholeElem::getParameterPointers(Parameters *p, const TholeValue **v) {
00038 *v = NULL;
00039 }
00040
00041 void TholeElem::computeForce(BigReal *reduction,
00042 BigReal *pressureProfileData)
00043 {
00044 DebugM(3, "::computeForce() localIndex = " << localIndex[0] << " "
00045 << localIndex[1] << " " << localIndex[2] << " "
00046 << localIndex[3] << std::endl);
00047
00048 #ifdef CALCULATE_THOLE_CORRECTION
00049 const BigReal aa = value->aa;
00050 const BigReal qq = value->qq;
00051
00052
00053 const Position & rai = p[0]->x[localIndex[0]].position;
00054 const Position & rdi = p[1]->x[localIndex[1]].position;
00055 const Position & raj = p[2]->x[localIndex[2]].position;
00056 const Position & rdj = p[3]->x[localIndex[3]].position;
00057
00058
00059 const Lattice & lattice = p[0]->p->lattice;
00060 Vector raa = lattice.delta(rai,raj);
00061 Vector rad = lattice.delta(rai,rdj);
00062 Vector rda = lattice.delta(rdi,raj);
00063 Vector rdd = lattice.delta(rdi,rdj);
00064
00065
00066 BigReal raa_invlen = raa.rlength();
00067 BigReal rad_invlen = rad.rlength();
00068 BigReal rda_invlen = rda.rlength();
00069 BigReal rdd_invlen = rdd.rlength();
00070
00071
00072 BigReal auaa = aa / raa_invlen;
00073 BigReal auad = aa / rad_invlen;
00074 BigReal auda = aa / rda_invlen;
00075 BigReal audd = aa / rdd_invlen;
00076
00077
00078 BigReal expauaa = exp(-auaa);
00079 BigReal expauad = exp(-auad);
00080 BigReal expauda = exp(-auda);
00081 BigReal expaudd = exp(-audd);
00082
00083
00084 BigReal polyauaa = 1 + 0.5*auaa;
00085 BigReal polyauad = 1 + 0.5*auad;
00086 BigReal polyauda = 1 + 0.5*auda;
00087 BigReal polyaudd = 1 + 0.5*audd;
00088
00089
00090 BigReal ethole = 0;
00091 ethole += qq * raa_invlen * (1 - polyauaa * expauaa);
00092 ethole += -qq * rad_invlen * (1 - polyauad * expauad);
00093 ethole += -qq * rda_invlen * (1 - polyauda * expauda);
00094 ethole += qq * rdd_invlen * (1 - polyaudd * expaudd);
00095
00096 polyauaa = 1 + auaa*polyauaa;
00097 polyauad = 1 + auad*polyauad;
00098 polyauda = 1 + auda*polyauda;
00099 polyaudd = 1 + audd*polyaudd;
00100
00101 BigReal raa_invlen3 = raa_invlen * raa_invlen * raa_invlen;
00102 BigReal rad_invlen3 = rad_invlen * rad_invlen * rad_invlen;
00103 BigReal rda_invlen3 = rda_invlen * rda_invlen * rda_invlen;
00104 BigReal rdd_invlen3 = rdd_invlen * rdd_invlen * rdd_invlen;
00105
00106
00107 BigReal dfaa = qq * raa_invlen3 * (polyauaa*expauaa - 1);
00108 BigReal dfad = -qq * rad_invlen3 * (polyauad*expauad - 1);
00109 BigReal dfda = -qq * rda_invlen3 * (polyauda*expauda - 1);
00110 BigReal dfdd = qq * rdd_invlen3 * (polyaudd*expaudd - 1);
00111
00112 Vector faa = -dfaa * raa;
00113 Vector fad = -dfad * rad;
00114 Vector fda = -dfda * rda;
00115 Vector fdd = -dfdd * rdd;
00116
00117 p[0]->f[localIndex[0]] += faa + fad;
00118 p[1]->f[localIndex[1]] += fda + fdd;
00119 p[2]->f[localIndex[2]] -= faa + fda;
00120 p[3]->f[localIndex[3]] -= fad + fdd;
00121
00122 DebugM(3, "::computeForce() -- ending with delta energy " << ethole
00123 << std::endl);
00124 reduction[tholeEnergyIndex] += ethole;
00125
00126 reduction[virialIndex_XX] += faa.x * raa.x + fad.x * rad.x
00127 + fda.x * rda.x + fdd.x * rdd.x;
00128 reduction[virialIndex_XY] += faa.x * raa.y + fad.x * rad.y
00129 + fda.x * rda.y + fdd.x * rdd.y;
00130 reduction[virialIndex_XZ] += faa.x * raa.z + fad.x * rad.z
00131 + fda.x * rda.z + fdd.x * rdd.z;
00132 reduction[virialIndex_YX] += faa.y * raa.x + fad.y * rad.x
00133 + fda.y * rda.x + fdd.y * rdd.x;
00134 reduction[virialIndex_YY] += faa.y * raa.y + fad.y * rad.y
00135 + fda.y * rda.y + fdd.y * rdd.y;
00136 reduction[virialIndex_YZ] += faa.y * raa.z + fad.y * rad.z
00137 + fda.y * rda.z + fdd.y * rdd.z;
00138 reduction[virialIndex_ZX] += faa.z * raa.x + fad.z * rad.x
00139 + fda.z * rda.x + fdd.z * rdd.x;
00140 reduction[virialIndex_ZY] += faa.z * raa.y + fad.z * rad.y
00141 + fda.z * rda.y + fdd.z * rdd.y;
00142 reduction[virialIndex_ZZ] += faa.z * raa.z + fad.z * rad.z
00143 + fda.z * rda.z + fdd.z * rdd.z;
00144
00145 if (pressureProfileData) {
00146 BigReal zai = p[0]->x[localIndex[0]].position.z;
00147 BigReal zdi = p[1]->x[localIndex[1]].position.z;
00148 BigReal zaj = p[2]->x[localIndex[2]].position.z;
00149 BigReal zdj = p[3]->x[localIndex[3]].position.z;
00150 int nai = (int)floor((zai-pressureProfileMin)/pressureProfileThickness);
00151 int ndi = (int)floor((zdi-pressureProfileMin)/pressureProfileThickness);
00152 int naj = (int)floor((zaj-pressureProfileMin)/pressureProfileThickness);
00153 int ndj = (int)floor((zdj-pressureProfileMin)/pressureProfileThickness);
00154 pp_clamp(nai, pressureProfileSlabs);
00155 pp_clamp(ndi, pressureProfileSlabs);
00156 pp_clamp(naj, pressureProfileSlabs);
00157 pp_clamp(ndj, pressureProfileSlabs);
00158 int pai = p[0]->x[localIndex[0]].partition;
00159 int pdi = p[1]->x[localIndex[1]].partition;
00160 int paj = p[2]->x[localIndex[2]].partition;
00161 int pdj = p[3]->x[localIndex[3]].partition;
00162 int pn = pressureProfileAtomTypes;
00163 pp_reduction(pressureProfileSlabs, nai, naj,
00164 pai, paj, pn, faa.x * raa.x, faa.y * raa.y, faa.z * raa.z,
00165 pressureProfileData);
00166 pp_reduction(pressureProfileSlabs, nai, ndj,
00167 pai, pdj, pn, fad.x * rad.x, fad.y * rad.y, fad.z * rad.z,
00168 pressureProfileData);
00169 pp_reduction(pressureProfileSlabs, ndi, naj,
00170 pdi, paj, pn, fda.x * rda.x, fda.y * rda.y, fda.z * rda.z,
00171 pressureProfileData);
00172 pp_reduction(pressureProfileSlabs, ndi, ndj,
00173 pdi, pdj, pn, fdd.x * rdd.x, fdd.y * rdd.y, fdd.z * rdd.z,
00174 pressureProfileData);
00175 }
00176 #endif
00177 }
00178
00179
00180
00181
00182 void TholeElem::submitReductionData(BigReal *data, SubmitReduction *reduction)
00183 {
00184 reduction->item(REDUCTION_ELECT_ENERGY) += data[tholeEnergyIndex];
00185 ADD_TENSOR(reduction,REDUCTION_VIRIAL_NORMAL,data,virialIndex);
00186 }
00187