00001
00007 #include "InfoStream.h"
00008 #include "ComputeAniso.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_ANISO
00018
00019
00020 int AnisoElem::pressureProfileSlabs = 0;
00021 int AnisoElem::pressureProfileAtomTypes = 1;
00022 BigReal AnisoElem::pressureProfileThickness = 0;
00023 BigReal AnisoElem::pressureProfileMin = 0;
00024
00025 void AnisoElem::getMoleculePointers
00026 (Molecule* mol, int* count, int32*** byatom, Aniso** structarray)
00027 {
00028 #ifdef MEM_OPT_VERSION
00029 NAMD_die("Should not be called in AnisoElem::getMoleculePointers in memory optimized version!");
00030 #else
00031 *count = mol->numAnisos;
00032 *byatom = mol->anisosByAtom;
00033 *structarray = mol->anisos;
00034 #endif
00035 }
00036
00037 void AnisoElem::getParameterPointers(Parameters *p, const AnisoValue **v) {
00038 *v = NULL;
00039 }
00040
00041 void AnisoElem::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_ANISO
00049
00050
00051 const BigReal kpar0 = 2*value->k11;
00052 const BigReal kperp0 = 2*value->k22;
00053 const BigReal kiso0 = 2*value->k33;
00054
00055 const Position & ri = p[0]->x[localIndex[0]].position;
00056 const Position & rj = p[0]->x[localIndex[0]+1].position;
00057 const Position & rl = p[1]->x[localIndex[1]].position;
00058 const Position & rm = p[2]->x[localIndex[2]].position;
00059 const Position & rn = p[3]->x[localIndex[3]].position;
00060
00061
00062 const Lattice & lattice = p[0]->p->lattice;
00063 Vector r_il = lattice.delta(ri,rl);
00064 Vector r_mn = lattice.delta(rm,rn);
00065
00066 BigReal r_il_invlen = r_il.rlength();
00067 BigReal r_mn_invlen = r_mn.rlength();
00068
00069 Vector u1 = r_il * r_il_invlen;
00070 Vector u2 = r_mn * r_mn_invlen;
00071
00072 Vector dr = rj - ri;
00073
00074 BigReal dpar = dr * u1;
00075 BigReal dperp = dr * u2;
00076
00077
00078
00079
00080
00081 BigReal eaniso;
00082 eaniso = 0.5*kpar0*dpar*dpar + 0.5*kperp0*dperp*dperp + 0.5*kiso0*(dr*dr);
00083
00084
00085
00086
00087
00088 Vector fj = -kiso0 * dr;
00089 fj -= kpar0 * dpar * u1;
00090 fj -= kperp0 * dperp * u2;
00091
00092
00093 Vector fl = kpar0 * dpar * r_il_invlen * dr;
00094 fl -= kpar0 * dpar * dpar * r_il_invlen * u1;
00095
00096
00097 Vector fm = kperp0 * dperp * dperp * r_mn_invlen * u2;
00098 fm -= kperp0 * dperp * r_mn_invlen * dr;
00099
00100
00101 p[0]->f[localIndex[0]] -= (fj + fl);
00102 p[0]->f[localIndex[0]+1] += fj;
00103 p[1]->f[localIndex[1]] += fl;
00104 p[2]->f[localIndex[2]] += fm;
00105 p[3]->f[localIndex[3]] -= fm;
00106
00107
00108 reduction[anisoEnergyIndex] += eaniso;
00109
00110
00111 reduction[virialIndex_XX] += fj.x * dr.x - fl.x * r_il.x + fm.x * r_mn.x;
00112 reduction[virialIndex_XY] += fj.x * dr.y - fl.x * r_il.y + fm.x * r_mn.y;
00113 reduction[virialIndex_XZ] += fj.x * dr.z - fl.x * r_il.z + fm.x * r_mn.z;
00114 reduction[virialIndex_YX] += fj.y * dr.x - fl.y * r_il.x + fm.y * r_mn.x;
00115 reduction[virialIndex_YY] += fj.y * dr.y - fl.y * r_il.y + fm.y * r_mn.y;
00116 reduction[virialIndex_YZ] += fj.y * dr.z - fl.y * r_il.z + fm.y * r_mn.z;
00117 reduction[virialIndex_ZX] += fj.z * dr.x - fl.z * r_il.x + fm.z * r_mn.x;
00118 reduction[virialIndex_ZY] += fj.z * dr.y - fl.z * r_il.y + fm.z * r_mn.y;
00119 reduction[virialIndex_ZZ] += fj.z * dr.z - fl.z * r_il.z + fm.z * r_mn.z;
00120
00121
00122 if (pressureProfileData) {
00123 BigReal zi = p[0]->x[localIndex[0]].position.z;
00124 BigReal zj = p[0]->x[localIndex[0]+1].position.z;
00125 BigReal zl = p[1]->x[localIndex[1]].position.z;
00126 BigReal zm = p[2]->x[localIndex[2]].position.z;
00127 BigReal zn = p[3]->x[localIndex[3]].position.z;
00128 int ni = (int)floor((zi-pressureProfileMin)/pressureProfileThickness);
00129 int nj = (int)floor((zj-pressureProfileMin)/pressureProfileThickness);
00130 int nl = (int)floor((zl-pressureProfileMin)/pressureProfileThickness);
00131 int nm = (int)floor((zm-pressureProfileMin)/pressureProfileThickness);
00132 int nn = (int)floor((zn-pressureProfileMin)/pressureProfileThickness);
00133 pp_clamp(ni, pressureProfileSlabs);
00134 pp_clamp(nj, pressureProfileSlabs);
00135 pp_clamp(nl, pressureProfileSlabs);
00136 pp_clamp(nm, pressureProfileSlabs);
00137 pp_clamp(nn, pressureProfileSlabs);
00138 int pi = p[0]->x[localIndex[0]].partition;
00139 int pj = p[0]->x[localIndex[0]+1].partition;
00140 int pl = p[1]->x[localIndex[1]].partition;
00141 int pm = p[2]->x[localIndex[2]].partition;
00142 int pn = p[3]->x[localIndex[3]].partition;
00143 int pt = pressureProfileAtomTypes;
00144 pp_reduction(pressureProfileSlabs, nj, ni,
00145 pj, pi, pt, fj.x * dr.x, fj.y * dr.y, fj.z * dr.z,
00146 pressureProfileData);
00147 pp_reduction(pressureProfileSlabs, ni, nl,
00148 pi, pl, pt, -fl.x * r_il.x, -fl.y * r_il.y, -fl.z * r_il.z,
00149 pressureProfileData);
00150 pp_reduction(pressureProfileSlabs, nm, nn,
00151 pm, pn, pt, fm.x * r_mn.x, fm.y * r_mn.y, fm.z * r_mn.z,
00152 pressureProfileData);
00153 }
00154 #endif
00155 }
00156
00157
00158 void AnisoElem::submitReductionData(BigReal *data, SubmitReduction *reduction)
00159 {
00160 reduction->item(REDUCTION_BOND_ENERGY) += data[anisoEnergyIndex];
00161 ADD_TENSOR(reduction,REDUCTION_VIRIAL_NORMAL,data,virialIndex);
00162 }
00163