Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

ComputeSphericalBC.C

Go to the documentation of this file.
00001 
00007 #include "ComputeSphericalBC.h"
00008 #include "Node.h"
00009 #include "SimParameters.h"
00010 #include "Patch.h"
00011 
00012 /************************************************************************/
00013 /*                                                                      */
00014 /*                      FUNCTION ComputeSphericalBC                     */
00015 /*                                                                      */
00016 /*      This is the constructor for the ComputeSphericalBC force object.*/
00017 /*   It is responsible for getting all the parameters from the          */
00018 /*   SimParameters object and then determining if this object needs     */
00019 /*   to perform any computation.  It only needs to do so if there is    */
00020 /*   some portion of the patch that lays outside of the spherical       */
00021 /*   boundaries.                                                        */
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         //  Get parameters from the SimParameters object
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         //  Check to see if this is one set of parameters or two
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 /*                      END OF FUNCTION ComputeSphericalBC              */
00056 
00057 /************************************************************************/
00058 /*                                                                      */
00059 /*                      FUNCTION ~ComputeSphericalBC                    */
00060 /*                                                                      */
00061 /*      This is the destructor for the ComputeSphericalBC force object. */
00062 /*   It currently does ABSOLUTELY NOTHING!!                             */
00063 /*                                                                      */
00064 /************************************************************************/
00065 
00066 ComputeSphericalBC::~ComputeSphericalBC()
00067 
00068 {
00069         delete reduction;
00070 }
00071 /*                      END OF FUNCTION ~ComputeSphericalBC             */
00072 
00073 /************************************************************************/
00074 /*                                                                      */
00075 /*                              FUNCTION force                          */
00076 /*                                                                      */
00077 /*   INPUTS:                                                            */
00078 /*      numAtoms - Number of coordinates being passed                   */
00079 /*      x - Array of atom coordinates                                   */
00080 /*      forces - Array of force vectors                                 */
00081 /*                                                                      */
00082 /*      This function calculates the force and energy for the shereical */
00083 /*   boundary conditions for this patch.                                */
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;            //  Distance from atom to center of sphere
00093         Vector f;               //  Calculated force vector
00094         int i, j;               //  Loop counters
00095         BigReal dist, dist_2;   //  Distance from atom to center, and this
00096                                 //  distance squared
00097         BigReal rval;           //  Difference between distance from atom
00098                                 //  to center and radius of sphere
00099         BigReal eval;           //  Energy value for this atom
00100         BigReal fval;           //  Force magnitude for this atom
00101 
00102         // aliases to work with old code
00103         CompAtom *x = p;
00104         Force *forces = r->f[Results::normal];
00105         BigReal energy = 0;
00106 
00107         //  Loop through and check each atom
00108         for (i=0; i<numAtoms; i++)
00109         {
00110                 //  Calculate the vector from the atom to the center of the
00111                 //  sphere
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                 //  Calculate the distance squared
00117                 dist_2 = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z;
00118 
00119                 //  Look to see if we are outside either radius
00120                 if ( (dist_2 > r1_2) || (twoForces && (dist_2 > r2_2)) )
00121                 {
00122                         //  Calculate the distance to the center
00123                         dist = sqrt(dist_2);
00124 
00125                         //  Normalize the direction vector
00126                         diff /= dist;
00127 
00128                         //  Check to see if we are outside radius 1
00129                         if (dist > r1)
00130                         {
00131                                 //  Assign the force vector to the
00132                                 //  unit direction vector
00133                                 f.x = diff.x;
00134                                 f.y = diff.y;
00135                                 f.z = diff.z;
00136 
00137                                 //  Calculate the energy which is
00138                                 //  e = k1*(r_i-r_center)^exp1
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                                 //  Now calculate the force which is
00150                                 //  e = -k1*exp1*(r_i-r_center1)^(exp1-1)
00151                                 fval = -exp1*k1;
00152 
00153                                 for (j=0; j<exp1-1; j++)
00154                                 {
00155                                         fval *= rval;
00156                                 }
00157 
00158                                 //  Multiply the force magnitude to the
00159                                 //  unit direction vector to get the
00160                                 //  resulting force
00161                                 f *= fval;
00162 
00163                                 //  Add the force to the force vectors
00164                                 forces[i].x += f.x;
00165                                 forces[i].y += f.y;
00166                                 forces[i].z += f.z;
00167                         }
00168 
00169                         //  Check to see if there is a second radius
00170                         //  and if we are outside of it
00171                         if (twoForces && (dist > r2) )
00172                         {
00173                                 //  Assign the force vector to the
00174                                 //  unit direction vector
00175                                 f.x = diff.x;
00176                                 f.y = diff.y;
00177                                 f.z = diff.z;
00178 
00179                                 //  Calculate the energy which is
00180                                 //  e = k2*(r_i-r_center2)^exp2
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                                 //  Now calculate the force which is
00192                                 //  e = -k2*exp2*(r_i-r_center2)^(exp2-1)
00193                                 fval = -exp2*k2;
00194 
00195                                 for (j=0; j<exp2-1; j++)
00196                                 {
00197                                         fval *= rval;
00198                                 }
00199 
00200                                 //  Multiply the force magnitude to the
00201                                 //  unit direction vector to get the
00202                                 //  resulting force
00203                                 f *= fval;
00204 
00205                                 //  Add the force to the force vectors
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 /*                      END OF FUNCTION force                           */

Generated on Mon Sep 8 04:07:41 2008 for NAMD by  doxygen 1.3.9.1