00001
00007 #include "ComputeSphericalBC.h"
00008 #include "Node.h"
00009 #include "SimParameters.h"
00010 #include "Patch.h"
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 ComputeSphericalBC::ComputeSphericalBC(ComputeID c, PatchID pid)
00026 : ComputePatch(c,pid)
00027 {
00028 reduction = ReductionMgr::Object()->willSubmit(REDUCTIONS_BASIC);
00029
00030 SimParameters *simParams = Node::Object()->simParameters;
00031
00032
00033 r1 = simParams->sphericalBCr1;
00034 r2 = simParams->sphericalBCr2;
00035 r1_2 = r1*r1;
00036 r2_2 = r2*r2;
00037 k1 = simParams->sphericalBCk1;
00038 k2 = simParams->sphericalBCk2;
00039 exp1 = simParams->sphericalBCexp1;
00040 exp2 = simParams->sphericalBCexp2;
00041
00042
00043 if (r2 > -1.0)
00044 {
00045 twoForces = TRUE;
00046 }
00047 else
00048 {
00049 twoForces = FALSE;
00050 }
00051
00052 center = simParams->sphericalCenter;
00053
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 ComputeSphericalBC::~ComputeSphericalBC()
00067
00068 {
00069 delete reduction;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #ifdef MEM_OPT_VERSION
00087 void ComputeSphericalBC::doForce(CompAtom* p, CompAtomExt* pExt, Results* r)
00088 #else
00089 void ComputeSphericalBC::doForce(CompAtom* p, Results* r)
00090 #endif
00091 {
00092 Vector diff;
00093 Vector f;
00094 int i, j;
00095 BigReal dist, dist_2;
00096
00097 BigReal rval;
00098
00099 BigReal eval;
00100 BigReal fval;
00101
00102
00103 CompAtom *x = p;
00104 Force *forces = r->f[Results::normal];
00105 BigReal energy = 0;
00106
00107
00108 for (i=0; i<numAtoms; i++)
00109 {
00110
00111
00112 diff.x = x[i].position.x - center.x;
00113 diff.y = x[i].position.y - center.y;
00114 diff.z = x[i].position.z - center.z;
00115
00116
00117 dist_2 = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z;
00118
00119
00120 if ( (dist_2 > r1_2) || (twoForces && (dist_2 > r2_2)) )
00121 {
00122
00123 dist = sqrt(dist_2);
00124
00125
00126 diff /= dist;
00127
00128
00129 if (dist > r1)
00130 {
00131
00132
00133 f.x = diff.x;
00134 f.y = diff.y;
00135 f.z = diff.z;
00136
00137
00138
00139 eval = k1;
00140 rval = fabs(dist - r1);
00141
00142 for (j=0; j<exp1; j++)
00143 {
00144 eval *= rval;
00145 }
00146
00147 energy += eval;
00148
00149
00150
00151 fval = -exp1*k1;
00152
00153 for (j=0; j<exp1-1; j++)
00154 {
00155 fval *= rval;
00156 }
00157
00158
00159
00160
00161 f *= fval;
00162
00163
00164 forces[i].x += f.x;
00165 forces[i].y += f.y;
00166 forces[i].z += f.z;
00167 }
00168
00169
00170
00171 if (twoForces && (dist > r2) )
00172 {
00173
00174
00175 f.x = diff.x;
00176 f.y = diff.y;
00177 f.z = diff.z;
00178
00179
00180
00181 eval = k2;
00182 rval = fabs(dist - r2);
00183
00184 for (j=0; j<exp2; j++)
00185 {
00186 eval *= rval;
00187 }
00188
00189 energy += eval;
00190
00191
00192
00193 fval = -exp2*k2;
00194
00195 for (j=0; j<exp2-1; j++)
00196 {
00197 fval *= rval;
00198 }
00199
00200
00201
00202
00203 f *= fval;
00204
00205
00206 forces[i].x += f.x;
00207 forces[i].y += f.y;
00208 forces[i].z += f.z;
00209 }
00210 }
00211 }
00212
00213 reduction->item(REDUCTION_BC_ENERGY) += energy;
00214 reduction->submit();
00215
00216 }
00217