00001
00007 #include "ComputeCylindricalBC.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 ComputeCylindricalBC::ComputeCylindricalBC(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 axis = simParams->cylindricalBCAxis;
00034 r1 = simParams->cylindricalBCr1;
00035 r2 = simParams->cylindricalBCr2;
00036 r1_2 = r1*r1;
00037 r2_2 = r2*r2;
00038 k1 = simParams->cylindricalBCk1;
00039 k2 = simParams->cylindricalBCk2;
00040 exp1 = simParams->cylindricalBCexp1;
00041 exp2 = simParams->cylindricalBCexp2;
00042
00043 l1 = simParams->cylindricalBCl1;
00044 l2 = simParams->cylindricalBCl2;
00045 l1_2 = l1*l1;
00046 l2_2 = l2*l2;
00047
00048
00049 if (r2 > -1.0)
00050 {
00051 twoForces = TRUE;
00052 }
00053 else
00054 {
00055 twoForces = FALSE;
00056 }
00057
00058 center = simParams->cylindricalCenter;
00059
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 ComputeCylindricalBC::~ComputeCylindricalBC()
00073
00074 {
00075 delete reduction;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #ifdef MEM_OPT_VERSION
00094 void ComputeCylindricalBC::doForce(CompAtom* p, CompAtomExt* pExt, Results* r)
00095 #else
00096 void ComputeCylindricalBC::doForce(CompAtom* p, Results* r)
00097 #endif
00098 {
00099 Vector diff;
00100 Vector f;
00101 int i, j;
00102 BigReal dist, dist_2;
00103
00104 BigReal rval;
00105
00106 BigReal eval;
00107 BigReal fval;
00108
00109
00110 CompAtom *x = p;
00111 Force *forces = r->f[Results::normal];
00112 BigReal energy = 0;
00113
00114
00115 for (i=0; i<numAtoms; i++)
00116 {
00117
00118
00119 diff.x = ( axis == 'x' ? 0.0 : x[i].position.x - center.x );
00120 diff.y = ( axis == 'y' ? 0.0 : x[i].position.y - center.y );
00121 diff.z = ( axis == 'z' ? 0.0 : x[i].position.z - center.z );
00122
00123
00124 dist_2 = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z;
00125
00126
00127 if ( (dist_2 > r1_2) || (twoForces && (dist_2 > r2_2)) )
00128 {
00129
00130 dist = sqrt(dist_2);
00131
00132
00133 diff /= dist;
00134
00135
00136 if (dist > r1)
00137 {
00138
00139
00140 f.x = diff.x;
00141 f.y = diff.y;
00142 f.z = diff.z;
00143
00144
00145
00146 eval = k1;
00147 rval = fabs(dist - r1);
00148
00149 for (j=0; j<exp1; j++)
00150 {
00151 eval *= rval;
00152 }
00153
00154 energy += eval;
00155
00156
00157
00158 fval = -exp1*k1;
00159
00160 for (j=0; j<exp1-1; j++)
00161 {
00162 fval *= rval;
00163 }
00164
00165
00166
00167
00168 f *= fval;
00169
00170
00171 forces[i].x += f.x;
00172 forces[i].y += f.y;
00173 forces[i].z += f.z;
00174 }
00175
00176
00177
00178 if (twoForces && (dist > r2) )
00179 {
00180
00181
00182 f.x = diff.x;
00183 f.y = diff.y;
00184 f.z = diff.z;
00185
00186
00187
00188 eval = k2;
00189 rval = fabs(dist - r2);
00190
00191 for (j=0; j<exp2; j++)
00192 {
00193 eval *= rval;
00194 }
00195
00196 energy += eval;
00197
00198
00199
00200 fval = -exp2*k2;
00201
00202 for (j=0; j<exp2-1; j++)
00203 {
00204 fval *= rval;
00205 }
00206
00207
00208
00209
00210 f *= fval;
00211
00212
00213 forces[i].x += f.x;
00214 forces[i].y += f.y;
00215 forces[i].z += f.z;
00216 }
00217 }
00218 }
00219
00220 for (i=0; i<numAtoms; i++)
00221 {
00222
00223
00224 diff.x = ( axis != 'x' ? 0.0 : x[i].position.x - center.x );
00225 diff.y = ( axis != 'y' ? 0.0 : x[i].position.y - center.y );
00226 diff.z = ( axis != 'z' ? 0.0 : x[i].position.z - center.z );
00227
00228
00229 dist_2 = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z;
00230
00231
00232 if ( (dist_2 > l1_2) || (twoForces && (dist_2 > l2_2)) )
00233 {
00234
00235 dist = sqrt(dist_2);
00236
00237
00238 diff /= dist;
00239
00240
00241 if (dist > l1)
00242 {
00243
00244
00245
00246 f.x = diff.x;
00247 f.y = diff.y;
00248 f.z = diff.z;
00249
00250
00251
00252 eval = k1;
00253 rval = fabs(dist - l1);
00254
00255 for (j=0; j<exp1; j++)
00256 {
00257 eval *= rval;
00258 }
00259
00260 energy += eval;
00261
00262
00263
00264 fval = -exp1*k1;
00265
00266 for (j=0; j<exp1-1; j++)
00267 {
00268 fval *= rval;
00269 }
00270
00271
00272
00273
00274 f *= fval;
00275
00276
00277 forces[i].x += f.x;
00278 forces[i].y += f.y;
00279 forces[i].z += f.z;
00280 }
00281
00282
00283
00284 if (twoForces && (dist > l2) )
00285 {
00286
00287
00288
00289 f.x = diff.x;
00290 f.y = diff.y;
00291 f.z = diff.z;
00292
00293
00294
00295 eval = k2;
00296 rval = fabs(dist - l2);
00297
00298 for (j=0; j<exp2; j++)
00299 {
00300 eval *= rval;
00301 }
00302
00303 energy += eval;
00304
00305
00306
00307 fval = -exp2*k2;
00308
00309 for (j=0; j<exp2-1; j++)
00310 {
00311 fval *= rval;
00312 }
00313
00314
00315
00316
00317 f *= fval;
00318
00319
00320 forces[i].x += f.x;
00321 forces[i].y += f.y;
00322 forces[i].z += f.z;
00323 }
00324 }
00325 }
00326
00327 reduction->item(REDUCTION_BC_ENERGY) += energy;
00328 reduction->submit();
00329
00330 }
00331
00332