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 void ComputeCylindricalBC::doForce(CompAtom* p, CompAtomExt* pExt, Results* r)
00094 {
00095 Vector diff;
00096 Vector f;
00097 int i, j;
00098 BigReal dist, dist_2;
00099
00100 BigReal rval;
00101
00102 BigReal eval;
00103 BigReal fval;
00104
00105
00106 CompAtom *x = p;
00107 Force *forces = r->f[Results::normal];
00108 BigReal energy = 0;
00109
00110
00111 for (i=0; i<numAtoms; i++)
00112 {
00113
00114
00115 diff.x = ( axis == 'x' ? 0.0 : x[i].position.x - center.x );
00116 diff.y = ( axis == 'y' ? 0.0 : x[i].position.y - center.y );
00117 diff.z = ( axis == 'z' ? 0.0 : x[i].position.z - center.z );
00118
00119
00120 dist_2 = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z;
00121
00122
00123 if ( (dist_2 > r1_2) || (twoForces && (dist_2 > r2_2)) )
00124 {
00125
00126 dist = sqrt(dist_2);
00127
00128
00129 diff /= dist;
00130
00131
00132 if (dist > r1)
00133 {
00134
00135
00136 f.x = diff.x;
00137 f.y = diff.y;
00138 f.z = diff.z;
00139
00140
00141
00142 eval = k1;
00143 rval = fabs(dist - r1);
00144
00145 for (j=0; j<exp1; j++)
00146 {
00147 eval *= rval;
00148 }
00149
00150 energy += eval;
00151
00152
00153
00154 fval = -exp1*k1;
00155
00156 for (j=0; j<exp1-1; j++)
00157 {
00158 fval *= rval;
00159 }
00160
00161
00162
00163
00164 f *= fval;
00165
00166
00167 forces[i].x += f.x;
00168 forces[i].y += f.y;
00169 forces[i].z += f.z;
00170 }
00171
00172
00173
00174 if (twoForces && (dist > r2) )
00175 {
00176
00177
00178 f.x = diff.x;
00179 f.y = diff.y;
00180 f.z = diff.z;
00181
00182
00183
00184 eval = k2;
00185 rval = fabs(dist - r2);
00186
00187 for (j=0; j<exp2; j++)
00188 {
00189 eval *= rval;
00190 }
00191
00192 energy += eval;
00193
00194
00195
00196 fval = -exp2*k2;
00197
00198 for (j=0; j<exp2-1; j++)
00199 {
00200 fval *= rval;
00201 }
00202
00203
00204
00205
00206 f *= fval;
00207
00208
00209 forces[i].x += f.x;
00210 forces[i].y += f.y;
00211 forces[i].z += f.z;
00212 }
00213 }
00214 }
00215
00216 for (i=0; i<numAtoms; i++)
00217 {
00218
00219
00220 diff.x = ( axis != 'x' ? 0.0 : x[i].position.x - center.x );
00221 diff.y = ( axis != 'y' ? 0.0 : x[i].position.y - center.y );
00222 diff.z = ( axis != 'z' ? 0.0 : x[i].position.z - center.z );
00223
00224
00225 dist_2 = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z;
00226
00227
00228 if ( (dist_2 > l1_2) || (twoForces && (dist_2 > l2_2)) )
00229 {
00230
00231 dist = sqrt(dist_2);
00232
00233
00234 diff /= dist;
00235
00236
00237 if (dist > l1)
00238 {
00239
00240
00241
00242 f.x = diff.x;
00243 f.y = diff.y;
00244 f.z = diff.z;
00245
00246
00247
00248 eval = k1;
00249 rval = fabs(dist - l1);
00250
00251 for (j=0; j<exp1; j++)
00252 {
00253 eval *= rval;
00254 }
00255
00256 energy += eval;
00257
00258
00259
00260 fval = -exp1*k1;
00261
00262 for (j=0; j<exp1-1; j++)
00263 {
00264 fval *= rval;
00265 }
00266
00267
00268
00269
00270 f *= fval;
00271
00272
00273 forces[i].x += f.x;
00274 forces[i].y += f.y;
00275 forces[i].z += f.z;
00276 }
00277
00278
00279
00280 if (twoForces && (dist > l2) )
00281 {
00282
00283
00284
00285 f.x = diff.x;
00286 f.y = diff.y;
00287 f.z = diff.z;
00288
00289
00290
00291 eval = k2;
00292 rval = fabs(dist - l2);
00293
00294 for (j=0; j<exp2; j++)
00295 {
00296 eval *= rval;
00297 }
00298
00299 energy += eval;
00300
00301
00302
00303 fval = -exp2*k2;
00304
00305 for (j=0; j<exp2-1; j++)
00306 {
00307 fval *= rval;
00308 }
00309
00310
00311
00312
00313 f *= fval;
00314
00315
00316 forces[i].x += f.x;
00317 forces[i].y += f.y;
00318 forces[i].z += f.z;
00319 }
00320 }
00321 }
00322
00323 reduction->item(REDUCTION_BC_ENERGY) += energy;
00324 reduction->submit();
00325
00326 }
00327
00328