00001
00007 #include "ComputeRestraints.h"
00008 #include "Node.h"
00009 #include "Molecule.h"
00010 #include "SimParameters.h"
00011 #include "Patch.h"
00012 #include "NamdOneTools.h"
00013
00014
00015
00016
00017
00018
00019
00020 ComputeRestraints::ComputeRestraints(ComputeID c, PatchID pid)
00021 : ComputeHomePatch(c,pid)
00022 {
00023 reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00024
00025 SimParameters *simParams = Node::Object()->simParameters;
00026
00027
00028 consExp = simParams->constraintExp;
00029
00030
00031 consSelectOn = simParams->selectConstraintsOn;
00032 if (consSelectOn) {
00033 consSelectX = simParams->constrXOn;
00034 consSelectY = simParams->constrYOn;
00035 consSelectZ = simParams->constrZOn;
00036 }
00037
00038
00039
00040 consMoveOn = simParams->movingConstraintsOn;
00041 if (consMoveOn) {
00042 moveVel = simParams->movingConsVel;
00043 }
00044
00045
00046 consRotOn = simParams->rotConstraintsOn;
00047 if (consRotOn) {
00048 rotVel = simParams->rotConsVel;
00049 rotAxis = simParams->rotConsAxis;
00050 rotPivot = simParams->rotConsPivot;
00051 }
00052
00053
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 ComputeRestraints::~ComputeRestraints()
00066
00067 {
00068 delete reduction;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077 void ComputeRestraints::doForce(FullAtom* p, Results* res)
00078 {
00079 Molecule *molecule = Node::Object()->molecule;
00080 Real k;
00081 BigReal scaling = Node::Object()->simParameters->constraintScaling;
00082 Vector refPos;
00083 BigReal r, r2;
00084
00085 Vector Rij;
00086 BigReal value;
00087
00088
00089 Force *f = res->f[Results::normal];
00090 BigReal energy = 0;
00091 BigReal m[9];
00092 Tensor virial;
00093 Vector netForce = 0;
00094
00095
00096
00097
00098
00099
00100 int currentTime = patch->flags.step;
00101 if (consRotOn) {
00102 vec_rotation_matrix(rotVel * currentTime, rotAxis, m);
00103 }
00104
00105
00106
00107
00108 if (scaling != 0.) for (int localID=0; localID<numAtoms; ++localID)
00109 {
00110 if (molecule->is_atom_constrained(p[localID].id))
00111 {
00112 molecule->get_cons_params(k, refPos, p[localID].id);
00113
00114 k *= scaling;
00115
00116
00117
00118 if (consMoveOn) {
00119 refPos += currentTime * moveVel;
00120 }
00121 else if(consRotOn) {
00122 refPos = mat_multiply_vec(refPos - rotPivot, m) + rotPivot;
00123 }
00124
00125
00126
00127 Rij = patch->lattice.delta(refPos,p[localID].position);
00128 Vector vpos = refPos - Rij;
00129
00130
00131 if (consSelectOn) {
00132 if (!consSelectX) {Rij.x=0.0;}
00133 if (!consSelectY) {Rij.y=0.0;}
00134 if (!consSelectZ) {Rij.z=0.0;}
00135 }
00136
00137
00138
00139
00140
00141 r2 = Rij.length2();
00142 r = sqrt(r2);
00143
00144
00145
00146
00147 if (r>0.0)
00148 {
00149 value=k;
00150
00151
00152
00153
00154 for (int k=0; k<consExp; ++k)
00155 {
00156 value *= r;
00157 }
00158
00159
00160 energy += value;
00161
00162
00163
00164
00165 value *= consExp;
00166 value /= r2;
00167
00168 Rij *= value;
00169
00170
00171 f[localID] += Rij;
00172 netForce += Rij;
00173 virial += outer(Rij,vpos);
00174 }
00175 }
00176 }
00177
00178 reduction->item(REDUCTION_BC_ENERGY) += energy;
00179 ADD_TENSOR_OBJECT(reduction,REDUCTION_VIRIAL_NORMAL,virial);
00180 ADD_VECTOR_OBJECT(reduction,REDUCTION_EXT_FORCE_NORMAL,netForce);
00181 reduction->submit();
00182
00183 }
00184
00185