| 9 |  | #include "parse_me.h" | 
| 10 |  | #include "Integrator.hpp" | 
| 11 |  | #include "simError.h" | 
| 12 | + | #include "RigidBody.hpp" | 
| 13 |  | //#include "ConjugateMinimizer.hpp" | 
| 14 |  | #include "OOPSEMinimizer.hpp" | 
| 15 |  |  | 
| 147 |  | // make the output filenames | 
| 148 |  |  | 
| 149 |  | makeOutNames(); | 
| 149 | – |  | 
| 150 | – | if (globals->haveMinimizer()) | 
| 151 | – | // make minimizer | 
| 152 | – | makeMinimizer(); | 
| 153 | – | else | 
| 154 | – | // make the integrator | 
| 155 | – | makeIntegrator(); | 
| 150 |  |  | 
| 151 |  | #ifdef IS_MPI | 
| 152 |  | mpiSim->mpiRefresh(); | 
| 155 |  | // initialize the Fortran | 
| 156 |  |  | 
| 157 |  | initFortran(); | 
| 158 | + |  | 
| 159 | + | if (globals->haveMinimizer()) | 
| 160 | + | // make minimizer | 
| 161 | + | makeMinimizer(); | 
| 162 | + | else | 
| 163 | + | // make the integrator | 
| 164 | + | makeIntegrator(); | 
| 165 | + |  | 
| 166 |  | } | 
| 167 |  |  | 
| 168 |  |  | 
| 169 |  | void SimSetup::makeMolecules(void){ | 
| 170 | < | int k; | 
| 171 | < | int i, j, exI, exJ, tempEx, stampID, atomOffset, excludeOffset; | 
| 170 | > | int i, j, k; | 
| 171 | > | int exI, exJ, exK, exL, slI, slJ; | 
| 172 | > | int tempI, tempJ, tempK, tempL; | 
| 173 | > | int molI; | 
| 174 | > | int stampID, atomOffset, rbOffset; | 
| 175 |  | molInit molInfo; | 
| 176 |  | DirectionalAtom* dAtom; | 
| 177 | + | RigidBody* myRB; | 
| 178 | + | StuntDouble* mySD; | 
| 179 |  | LinkedAssign* extras; | 
| 180 |  | LinkedAssign* current_extra; | 
| 181 |  | AtomStamp* currentAtom; | 
| 182 |  | BondStamp* currentBond; | 
| 183 |  | BendStamp* currentBend; | 
| 184 |  | TorsionStamp* currentTorsion; | 
| 185 | + | RigidBodyStamp* currentRigidBody; | 
| 186 | + | CutoffGroupStamp* currentCutoffGroup; | 
| 187 | + | CutoffGroup* myCutoffGroup; | 
| 188 | + | int nCutoffGroups;// number of cutoff group of a molecule defined in mdl file | 
| 189 | + | set<int> cutoffAtomSet; //atoms belong to  cutoffgroup defined at mdl file | 
| 190 |  |  | 
| 191 |  | bond_pair* theBonds; | 
| 192 |  | bend_set* theBends; | 
| 193 |  | torsion_set* theTorsions; | 
| 194 |  |  | 
| 195 | + | set<int> skipList; | 
| 196 | + |  | 
| 197 | + | double phi, theta, psi; | 
| 198 | + | char* molName; | 
| 199 | + | char rbName[100]; | 
| 200 | + |  | 
| 201 |  | //init the forceField paramters | 
| 202 |  |  | 
| 203 |  | the_ff->readParams(); | 
| 204 |  |  | 
| 187 | – |  | 
| 205 |  | // init the atoms | 
| 206 |  |  | 
| 207 | < | double phi, theta, psi; | 
| 191 | < | double sux, suy, suz; | 
| 192 | < | double Axx, Axy, Axz, Ayx, Ayy, Ayz, Azx, Azy, Azz; | 
| 193 | < | double ux, uy, uz, u, uSqr; | 
| 207 | > | int nMembers, nNew, rb1, rb2; | 
| 208 |  |  | 
| 209 |  | for (k = 0; k < nInfo; k++){ | 
| 210 |  | the_ff->setSimInfo(&(info[k])); | 
| 211 |  |  | 
| 212 |  | atomOffset = 0; | 
| 213 | < | excludeOffset = 0; | 
| 213 | > |  | 
| 214 |  | for (i = 0; i < info[k].n_mol; i++){ | 
| 215 |  | stampID = info[k].molecules[i].getStampID(); | 
| 216 | + | molName = comp_stamps[stampID]->getID(); | 
| 217 |  |  | 
| 218 |  | molInfo.nAtoms = comp_stamps[stampID]->getNAtoms(); | 
| 219 |  | molInfo.nBonds = comp_stamps[stampID]->getNBonds(); | 
| 220 |  | molInfo.nBends = comp_stamps[stampID]->getNBends(); | 
| 221 |  | molInfo.nTorsions = comp_stamps[stampID]->getNTorsions(); | 
| 222 | < | molInfo.nExcludes = molInfo.nBonds + molInfo.nBends + molInfo.nTorsions; | 
| 222 | > | molInfo.nRigidBodies = comp_stamps[stampID]->getNRigidBodies(); | 
| 223 |  |  | 
| 224 | + | nCutoffGroups = comp_stamps[stampID]->getNCutoffGroups(); | 
| 225 | + |  | 
| 226 |  | molInfo.myAtoms = &(info[k].atoms[atomOffset]); | 
| 210 | – | molInfo.myExcludes = &(info[k].excludes[excludeOffset]); | 
| 211 | – | molInfo.myBonds = new Bond * [molInfo.nBonds]; | 
| 212 | – | molInfo.myBends = new Bend * [molInfo.nBends]; | 
| 213 | – | molInfo.myTorsions = new Torsion * [molInfo.nTorsions]; | 
| 227 |  |  | 
| 228 | + | if (molInfo.nBonds > 0) | 
| 229 | + | molInfo.myBonds = new Bond*[molInfo.nBonds]; | 
| 230 | + | else | 
| 231 | + | molInfo.myBonds = NULL; | 
| 232 | + |  | 
| 233 | + | if (molInfo.nBends > 0) | 
| 234 | + | molInfo.myBends = new Bend*[molInfo.nBends]; | 
| 235 | + | else | 
| 236 | + | molInfo.myBends = NULL; | 
| 237 | + |  | 
| 238 | + | if (molInfo.nTorsions > 0) | 
| 239 | + | molInfo.myTorsions = new Torsion *[molInfo.nTorsions]; | 
| 240 | + | else | 
| 241 | + | molInfo.myTorsions = NULL; | 
| 242 | + |  | 
| 243 |  | theBonds = new bond_pair[molInfo.nBonds]; | 
| 244 |  | theBends = new bend_set[molInfo.nBends]; | 
| 245 |  | theTorsions = new torsion_set[molInfo.nTorsions]; | 
| 246 | < |  | 
| 246 | > |  | 
| 247 |  | // make the Atoms | 
| 248 |  |  | 
| 249 |  | for (j = 0; j < molInfo.nAtoms; j++){ | 
| 250 |  | currentAtom = comp_stamps[stampID]->getAtom(j); | 
| 251 | + |  | 
| 252 |  | if (currentAtom->haveOrientation()){ | 
| 253 |  | dAtom = new DirectionalAtom((j + atomOffset), | 
| 254 |  | info[k].getConfiguration()); | 
| 262 |  | phi = currentAtom->getEulerPhi() * M_PI / 180.0; | 
| 263 |  | theta = currentAtom->getEulerTheta() * M_PI / 180.0; | 
| 264 |  | psi = currentAtom->getEulerPsi()* M_PI / 180.0; | 
| 265 | + |  | 
| 266 | + | dAtom->setUnitFrameFromEuler(phi, theta, psi); | 
| 267 |  |  | 
| 268 | < | Axx = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi)); | 
| 269 | < | Axy = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi)); | 
| 239 | < | Axz = sin(theta) * sin(psi); | 
| 240 | < |  | 
| 241 | < | Ayx = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi)); | 
| 242 | < | Ayy = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi)); | 
| 243 | < | Ayz = sin(theta) * cos(psi); | 
| 244 | < |  | 
| 245 | < | Azx = sin(phi) * sin(theta); | 
| 246 | < | Azy = -cos(phi) * sin(theta); | 
| 247 | < | Azz = cos(theta); | 
| 268 | > | } | 
| 269 | > | else{ | 
| 270 |  |  | 
| 271 | < | sux = 0.0; | 
| 250 | < | suy = 0.0; | 
| 251 | < | suz = 1.0; | 
| 271 | > | molInfo.myAtoms[j] = new Atom((j + atomOffset), info[k].getConfiguration()); | 
| 272 |  |  | 
| 253 | – | ux = (Axx * sux) + (Ayx * suy) + (Azx * suz); | 
| 254 | – | uy = (Axy * sux) + (Ayy * suy) + (Azy * suz); | 
| 255 | – | uz = (Axz * sux) + (Ayz * suy) + (Azz * suz); | 
| 256 | – |  | 
| 257 | – | uSqr = (ux * ux) + (uy * uy) + (uz * uz); | 
| 258 | – |  | 
| 259 | – | u = sqrt(uSqr); | 
| 260 | – | ux = ux / u; | 
| 261 | – | uy = uy / u; | 
| 262 | – | uz = uz / u; | 
| 263 | – |  | 
| 264 | – | dAtom->setSUx(ux); | 
| 265 | – | dAtom->setSUy(uy); | 
| 266 | – | dAtom->setSUz(uz); | 
| 273 |  | } | 
| 268 | – | else{ | 
| 269 | – | molInfo.myAtoms[j] = new GeneralAtom((j + atomOffset), | 
| 270 | – | info[k].getConfiguration()); | 
| 271 | – | } | 
| 272 | – | molInfo.myAtoms[j]->setType(currentAtom->getType()); | 
| 274 |  |  | 
| 275 | + | molInfo.myAtoms[j]->setType(currentAtom->getType()); | 
| 276 |  | #ifdef IS_MPI | 
| 277 |  |  | 
| 278 | < | molInfo.myAtoms[j]->setGlobalIndex(globalIndex[j + atomOffset]); | 
| 278 | > | molInfo.myAtoms[j]->setGlobalIndex(globalAtomIndex[j + atomOffset]); | 
| 279 |  |  | 
| 280 |  | #endif // is_mpi | 
| 281 |  | } | 
| 286 |  | theBonds[j].a = currentBond->getA() + atomOffset; | 
| 287 |  | theBonds[j].b = currentBond->getB() + atomOffset; | 
| 288 |  |  | 
| 289 | < | exI = theBonds[j].a; | 
| 290 | < | exJ = theBonds[j].b; | 
| 289 | > | tempI = theBonds[j].a; | 
| 290 | > | tempJ = theBonds[j].b; | 
| 291 |  |  | 
| 290 | – | // exclude_I must always be the smaller of the pair | 
| 291 | – | if (exI > exJ){ | 
| 292 | – | tempEx = exI; | 
| 293 | – | exI = exJ; | 
| 294 | – | exJ = tempEx; | 
| 295 | – | } | 
| 292 |  | #ifdef IS_MPI | 
| 293 | < | tempEx = exI; | 
| 294 | < | exI = info[k].atoms[tempEx]->getGlobalIndex() + 1; | 
| 295 | < | tempEx = exJ; | 
| 296 | < | exJ = info[k].atoms[tempEx]->getGlobalIndex() + 1; | 
| 293 | > | exI = info[k].atoms[tempI]->getGlobalIndex() + 1; | 
| 294 | > | exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1; | 
| 295 | > | #else | 
| 296 | > | exI = tempI + 1; | 
| 297 | > | exJ = tempJ + 1; | 
| 298 | > | #endif | 
| 299 |  |  | 
| 300 | < | info[k].excludes[j + excludeOffset]->setPair(exI, exJ); | 
| 303 | < | #else  // isn't MPI | 
| 304 | < |  | 
| 305 | < | info[k].excludes[j + excludeOffset]->setPair((exI + 1), (exJ + 1)); | 
| 306 | < | #endif  //is_mpi | 
| 300 | > | info[k].excludes->addPair(exI, exJ); | 
| 301 |  | } | 
| 308 | – | excludeOffset += molInfo.nBonds; | 
| 302 |  |  | 
| 303 |  | //make the bends | 
| 304 |  | for (j = 0; j < molInfo.nBends; j++){ | 
| 348 |  | } | 
| 349 |  | } | 
| 350 |  |  | 
| 351 | < | if (!theBends[j].isGhost){ | 
| 352 | < | exI = theBends[j].a; | 
| 353 | < | exJ = theBends[j].c; | 
| 354 | < | } | 
| 355 | < | else{ | 
| 363 | < | exI = theBends[j].a; | 
| 364 | < | exJ = theBends[j].b; | 
| 365 | < | } | 
| 366 | < |  | 
| 367 | < | // exclude_I must always be the smaller of the pair | 
| 368 | < | if (exI > exJ){ | 
| 369 | < | tempEx = exI; | 
| 370 | < | exI = exJ; | 
| 371 | < | exJ = tempEx; | 
| 372 | < | } | 
| 351 | > | if (theBends[j].isGhost) { | 
| 352 | > |  | 
| 353 | > | tempI = theBends[j].a; | 
| 354 | > | tempJ = theBends[j].b; | 
| 355 | > |  | 
| 356 |  | #ifdef IS_MPI | 
| 357 | < | tempEx = exI; | 
| 358 | < | exI = info[k].atoms[tempEx]->getGlobalIndex() + 1; | 
| 359 | < | tempEx = exJ; | 
| 360 | < | exJ = info[k].atoms[tempEx]->getGlobalIndex() + 1; | 
| 357 | > | exI = info[k].atoms[tempI]->getGlobalIndex() + 1; | 
| 358 | > | exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1; | 
| 359 | > | #else | 
| 360 | > | exI = tempI + 1; | 
| 361 | > | exJ = tempJ + 1; | 
| 362 | > | #endif | 
| 363 | > | info[k].excludes->addPair(exI, exJ); | 
| 364 |  |  | 
| 365 | < | info[k].excludes[j + excludeOffset]->setPair(exI, exJ); | 
| 366 | < | #else  // isn't MPI | 
| 367 | < | info[k].excludes[j + excludeOffset]->setPair((exI + 1), (exJ + 1)); | 
| 368 | < | #endif  //is_mpi | 
| 365 | > | } else { | 
| 366 | > |  | 
| 367 | > | tempI = theBends[j].a; | 
| 368 | > | tempJ = theBends[j].b; | 
| 369 | > | tempK = theBends[j].c; | 
| 370 | > |  | 
| 371 | > | #ifdef IS_MPI | 
| 372 | > | exI = info[k].atoms[tempI]->getGlobalIndex() + 1; | 
| 373 | > | exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1; | 
| 374 | > | exK = info[k].atoms[tempK]->getGlobalIndex() + 1; | 
| 375 | > | #else | 
| 376 | > | exI = tempI + 1; | 
| 377 | > | exJ = tempJ + 1; | 
| 378 | > | exK = tempK + 1; | 
| 379 | > | #endif | 
| 380 | > |  | 
| 381 | > | info[k].excludes->addPair(exI, exK); | 
| 382 | > | info[k].excludes->addPair(exI, exJ); | 
| 383 | > | info[k].excludes->addPair(exJ, exK); | 
| 384 | > | } | 
| 385 |  | } | 
| 384 | – | excludeOffset += molInfo.nBends; | 
| 386 |  |  | 
| 387 |  | for (j = 0; j < molInfo.nTorsions; j++){ | 
| 388 |  | currentTorsion = comp_stamps[stampID]->getTorsion(j); | 
| 391 |  | theTorsions[j].c = currentTorsion->getC() + atomOffset; | 
| 392 |  | theTorsions[j].d = currentTorsion->getD() + atomOffset; | 
| 393 |  |  | 
| 394 | < | exI = theTorsions[j].a; | 
| 395 | < | exJ = theTorsions[j].d; | 
| 394 | > | tempI = theTorsions[j].a; | 
| 395 | > | tempJ = theTorsions[j].b; | 
| 396 | > | tempK = theTorsions[j].c; | 
| 397 | > | tempL = theTorsions[j].d; | 
| 398 |  |  | 
| 396 | – | // exclude_I must always be the smaller of the pair | 
| 397 | – | if (exI > exJ){ | 
| 398 | – | tempEx = exI; | 
| 399 | – | exI = exJ; | 
| 400 | – | exJ = tempEx; | 
| 401 | – | } | 
| 399 |  | #ifdef IS_MPI | 
| 400 | < | tempEx = exI; | 
| 401 | < | exI = info[k].atoms[tempEx]->getGlobalIndex() + 1; | 
| 402 | < | tempEx = exJ; | 
| 403 | < | exJ = info[k].atoms[tempEx]->getGlobalIndex() + 1; | 
| 400 | > | exI = info[k].atoms[tempI]->getGlobalIndex() + 1; | 
| 401 | > | exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1; | 
| 402 | > | exK = info[k].atoms[tempK]->getGlobalIndex() + 1; | 
| 403 | > | exL = info[k].atoms[tempL]->getGlobalIndex() + 1; | 
| 404 | > | #else | 
| 405 | > | exI = tempI + 1; | 
| 406 | > | exJ = tempJ + 1; | 
| 407 | > | exK = tempK + 1; | 
| 408 | > | exL = tempL + 1; | 
| 409 | > | #endif | 
| 410 |  |  | 
| 411 | < | info[k].excludes[j + excludeOffset]->setPair(exI, exJ); | 
| 412 | < | #else  // isn't MPI | 
| 413 | < | info[k].excludes[j + excludeOffset]->setPair((exI + 1), (exJ + 1)); | 
| 414 | < | #endif  //is_mpi | 
| 411 | > | info[k].excludes->addPair(exI, exJ); | 
| 412 | > | info[k].excludes->addPair(exI, exK); | 
| 413 | > | info[k].excludes->addPair(exI, exL); | 
| 414 | > | info[k].excludes->addPair(exJ, exK); | 
| 415 | > | info[k].excludes->addPair(exJ, exL); | 
| 416 | > | info[k].excludes->addPair(exK, exL); | 
| 417 |  | } | 
| 413 | – | excludeOffset += molInfo.nTorsions; | 
| 418 |  |  | 
| 419 | + |  | 
| 420 | + | molInfo.myRigidBodies.clear(); | 
| 421 | + |  | 
| 422 | + | for (j = 0; j < molInfo.nRigidBodies; j++){ | 
| 423 |  |  | 
| 424 | < | // send the arrays off to the forceField for init. | 
| 424 | > | currentRigidBody = comp_stamps[stampID]->getRigidBody(j); | 
| 425 | > | nMembers = currentRigidBody->getNMembers(); | 
| 426 |  |  | 
| 427 | + | // Create the Rigid Body: | 
| 428 | + |  | 
| 429 | + | myRB = new RigidBody(); | 
| 430 | + |  | 
| 431 | + | sprintf(rbName,"%s_RB_%d", molName, j); | 
| 432 | + | myRB->setType(rbName); | 
| 433 | + |  | 
| 434 | + | for (rb1 = 0; rb1 < nMembers; rb1++) { | 
| 435 | + |  | 
| 436 | + | // molI is atom numbering inside this molecule | 
| 437 | + | molI = currentRigidBody->getMember(rb1); | 
| 438 | + |  | 
| 439 | + | // tempI is atom numbering on local processor | 
| 440 | + | tempI = molI + atomOffset; | 
| 441 | + |  | 
| 442 | + | // currentAtom is the AtomStamp (which we need for | 
| 443 | + | // rigid body reference positions) | 
| 444 | + | currentAtom = comp_stamps[stampID]->getAtom(molI); | 
| 445 | + |  | 
| 446 | + | // When we add to the rigid body, add the atom itself and | 
| 447 | + | // the stamp info: | 
| 448 | + |  | 
| 449 | + | myRB->addAtom(info[k].atoms[tempI], currentAtom); | 
| 450 | + |  | 
| 451 | + | // Add this atom to the Skip List for the integrators | 
| 452 | + | #ifdef IS_MPI | 
| 453 | + | slI = info[k].atoms[tempI]->getGlobalIndex(); | 
| 454 | + | #else | 
| 455 | + | slI = tempI; | 
| 456 | + | #endif | 
| 457 | + | skipList.insert(slI); | 
| 458 | + |  | 
| 459 | + | } | 
| 460 | + |  | 
| 461 | + | for(rb1 = 0; rb1 < nMembers - 1; rb1++) { | 
| 462 | + | for(rb2 = rb1+1; rb2 < nMembers; rb2++) { | 
| 463 | + |  | 
| 464 | + | tempI = currentRigidBody->getMember(rb1); | 
| 465 | + | tempJ = currentRigidBody->getMember(rb2); | 
| 466 | + |  | 
| 467 | + | // Some explanation is required here. | 
| 468 | + | // Fortran indexing starts at 1, while c indexing starts at 0 | 
| 469 | + | // Also, in parallel computations, the GlobalIndex is | 
| 470 | + | // used for the exclude list: | 
| 471 | + |  | 
| 472 | + | #ifdef IS_MPI | 
| 473 | + | exI = molInfo.myAtoms[tempI]->getGlobalIndex() + 1; | 
| 474 | + | exJ = molInfo.myAtoms[tempJ]->getGlobalIndex() + 1; | 
| 475 | + | #else | 
| 476 | + | exI = molInfo.myAtoms[tempI]->getIndex() + 1; | 
| 477 | + | exJ = molInfo.myAtoms[tempJ]->getIndex() + 1; | 
| 478 | + | #endif | 
| 479 | + |  | 
| 480 | + | info[k].excludes->addPair(exI, exJ); | 
| 481 | + |  | 
| 482 | + | } | 
| 483 | + | } | 
| 484 | + |  | 
| 485 | + | molInfo.myRigidBodies.push_back(myRB); | 
| 486 | + | info[k].rigidBodies.push_back(myRB); | 
| 487 | + | } | 
| 488 | + |  | 
| 489 | + |  | 
| 490 | + | //create cutoff group for molecule | 
| 491 | + |  | 
| 492 | + | cutoffAtomSet.clear(); | 
| 493 | + | molInfo.myCutoffGroups.clear(); | 
| 494 | + |  | 
| 495 | + | for (j = 0; j < nCutoffGroups; j++){ | 
| 496 | + |  | 
| 497 | + | currentCutoffGroup = comp_stamps[stampID]->getCutoffGroup(j); | 
| 498 | + | nMembers = currentCutoffGroup->getNMembers(); | 
| 499 | + |  | 
| 500 | + | myCutoffGroup = new CutoffGroup(); | 
| 501 | + |  | 
| 502 | + | for (int cg = 0; cg < nMembers; cg++) { | 
| 503 | + |  | 
| 504 | + | // molI is atom numbering inside this molecule | 
| 505 | + | molI = currentCutoffGroup->getMember(cg); | 
| 506 | + |  | 
| 507 | + | // tempI is atom numbering on local processor | 
| 508 | + | tempI = molI + atomOffset; | 
| 509 | + |  | 
| 510 | + | myCutoffGroup->addAtom(info[k].atoms[tempI]); | 
| 511 | + |  | 
| 512 | + | cutoffAtomSet.insert(tempI); | 
| 513 | + | } | 
| 514 | + |  | 
| 515 | + | molInfo.myCutoffGroups.push_back(myCutoffGroup); | 
| 516 | + | }//end for (j = 0; j < molInfo.nCutoffGroups; j++) | 
| 517 | + |  | 
| 518 | + | //creat a cutoff group for every atom  in current molecule which does not belong to cutoffgroup defined at mdl file | 
| 519 | + |  | 
| 520 | + | for(j = 0; j < molInfo.nAtoms; j++){ | 
| 521 | + |  | 
| 522 | + | if(cutoffAtomSet.find(molInfo.myAtoms[j]->getIndex()) == cutoffAtomSet.end()){ | 
| 523 | + | myCutoffGroup = new CutoffGroup(); | 
| 524 | + | myCutoffGroup->addAtom(molInfo.myAtoms[j]); | 
| 525 | + | molInfo.myCutoffGroups.push_back(myCutoffGroup); | 
| 526 | + | } | 
| 527 | + |  | 
| 528 | + | } | 
| 529 | + |  | 
| 530 | + |  | 
| 531 | + |  | 
| 532 | + |  | 
| 533 | + | // After this is all set up, scan through the atoms to | 
| 534 | + | // see if they can be added to the integrableObjects: | 
| 535 | + |  | 
| 536 | + | molInfo.myIntegrableObjects.clear(); | 
| 537 | + |  | 
| 538 | + |  | 
| 539 | + | for (j = 0; j < molInfo.nAtoms; j++){ | 
| 540 | + |  | 
| 541 | + | #ifdef IS_MPI | 
| 542 | + | slJ = molInfo.myAtoms[j]->getGlobalIndex(); | 
| 543 | + | #else | 
| 544 | + | slJ = j+atomOffset; | 
| 545 | + | #endif | 
| 546 | + |  | 
| 547 | + | // if they aren't on the skip list, then they can be integrated | 
| 548 | + |  | 
| 549 | + | if (skipList.find(slJ) == skipList.end()) { | 
| 550 | + | mySD = (StuntDouble *) molInfo.myAtoms[j]; | 
| 551 | + | info[k].integrableObjects.push_back(mySD); | 
| 552 | + | molInfo.myIntegrableObjects.push_back(mySD); | 
| 553 | + | } | 
| 554 | + | } | 
| 555 | + |  | 
| 556 | + | // all rigid bodies are integrated: | 
| 557 | + |  | 
| 558 | + | for (j = 0; j < molInfo.nRigidBodies; j++) { | 
| 559 | + | mySD = (StuntDouble *) molInfo.myRigidBodies[j]; | 
| 560 | + | info[k].integrableObjects.push_back(mySD); | 
| 561 | + | molInfo.myIntegrableObjects.push_back(mySD); | 
| 562 | + | } | 
| 563 | + |  | 
| 564 | + |  | 
| 565 | + | // send the arrays off to the forceField for init. | 
| 566 | + |  | 
| 567 |  | the_ff->initializeAtoms(molInfo.nAtoms, molInfo.myAtoms); | 
| 568 |  | the_ff->initializeBonds(molInfo.nBonds, molInfo.myBonds, theBonds); | 
| 569 |  | the_ff->initializeBends(molInfo.nBends, molInfo.myBends, theBends); | 
| 570 |  | the_ff->initializeTorsions(molInfo.nTorsions, molInfo.myTorsions, | 
| 571 |  | theTorsions); | 
| 572 |  |  | 
| 424 | – |  | 
| 573 |  | info[k].molecules[i].initialize(molInfo); | 
| 574 |  |  | 
| 575 |  |  | 
| 577 |  | delete[] theBonds; | 
| 578 |  | delete[] theBends; | 
| 579 |  | delete[] theTorsions; | 
| 580 | < | } | 
| 580 | > | } | 
| 581 |  | } | 
| 582 |  |  | 
| 583 |  | #ifdef IS_MPI | 
| 584 |  | sprintf(checkPointMsg, "all molecules initialized succesfully"); | 
| 585 |  | MPIcheckPoint(); | 
| 586 |  | #endif // is_mpi | 
| 439 | – |  | 
| 440 | – | // clean up the forcefield | 
| 587 |  |  | 
| 442 | – | the_ff->calcRcut(); | 
| 443 | – | the_ff->cleanMe(); | 
| 588 |  | } | 
| 589 |  |  | 
| 590 |  | void SimSetup::initFromBass(void){ | 
| 871 |  | } | 
| 872 |  |  | 
| 873 |  | //check whether sample time, status time, thermal time and reset time are divisble by dt | 
| 874 | < | if (!isDivisible(globals->getSampleTime(), globals->getDt())){ | 
| 874 | > | if (globals->haveSampleTime() && !isDivisible(globals->getSampleTime(), globals->getDt())){ | 
| 875 |  | sprintf(painCave.errMsg, | 
| 876 |  | "Sample time is not divisible by dt.\n" | 
| 877 |  | "\tThis will result in samples that are not uniformly\n" | 
| 881 |  | simError(); | 
| 882 |  | } | 
| 883 |  |  | 
| 884 | < | if (globals->haveStatusTime() && !isDivisible(globals->getSampleTime(), globals->getDt())){ | 
| 884 | > | if (globals->haveStatusTime() && !isDivisible(globals->getStatusTime(), globals->getDt())){ | 
| 885 |  | sprintf(painCave.errMsg, | 
| 886 |  | "Status time is not divisible by dt.\n" | 
| 887 |  | "\tThis will result in status reports that are not uniformly\n" | 
| 917 |  | if (globals->haveSampleTime()){ | 
| 918 |  | info[i].sampleTime = globals->getSampleTime(); | 
| 919 |  | info[i].statusTime = info[i].sampleTime; | 
| 776 | – | info[i].thermalTime = info[i].sampleTime; | 
| 920 |  | } | 
| 921 |  | else{ | 
| 922 |  | info[i].sampleTime = globals->getRunTime(); | 
| 923 |  | info[i].statusTime = info[i].sampleTime; | 
| 781 | – | info[i].thermalTime = info[i].sampleTime; | 
| 924 |  | } | 
| 925 |  |  | 
| 926 |  | if (globals->haveStatusTime()){ | 
| 929 |  |  | 
| 930 |  | if (globals->haveThermalTime()){ | 
| 931 |  | info[i].thermalTime = globals->getThermalTime(); | 
| 932 | + | } else { | 
| 933 | + | info[i].thermalTime = globals->getRunTime(); | 
| 934 |  | } | 
| 935 |  |  | 
| 936 |  | info[i].resetIntegrator = 0; | 
| 1001 |  | void SimSetup::finalInfoCheck(void){ | 
| 1002 |  | int index; | 
| 1003 |  | int usesDipoles; | 
| 1004 | + | int usesCharges; | 
| 1005 |  | int i; | 
| 1006 |  |  | 
| 1007 |  | for (i = 0; i < nInfo; i++){ | 
| 1013 |  | usesDipoles = (info[i].atoms[index])->hasDipole(); | 
| 1014 |  | index++; | 
| 1015 |  | } | 
| 1016 | < |  | 
| 1016 | > | index = 0; | 
| 1017 | > | usesCharges = 0; | 
| 1018 | > | while ((index < info[i].n_atoms) && !usesCharges){ | 
| 1019 | > | usesCharges= (info[i].atoms[index])->hasCharge(); | 
| 1020 | > | index++; | 
| 1021 | > | } | 
| 1022 |  | #ifdef IS_MPI | 
| 1023 |  | int myUse = usesDipoles; | 
| 1024 |  | MPI_Allreduce(&myUse, &usesDipoles, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD); | 
| 1025 |  | #endif //is_mpi | 
| 1026 |  |  | 
| 1027 | < | double theEcr, theEst; | 
| 1027 | > | double theRcut, theRsw; | 
| 1028 |  |  | 
| 1029 | + | if (globals->haveRcut()) { | 
| 1030 | + | theRcut = globals->getRcut(); | 
| 1031 | + |  | 
| 1032 | + | if (globals->haveRsw()) | 
| 1033 | + | theRsw = globals->getRsw(); | 
| 1034 | + | else | 
| 1035 | + | theRsw = theRcut; | 
| 1036 | + |  | 
| 1037 | + | info[i].setDefaultRcut(theRcut, theRsw); | 
| 1038 | + |  | 
| 1039 | + | } else { | 
| 1040 | + |  | 
| 1041 | + | the_ff->calcRcut(); | 
| 1042 | + | theRcut = info[i].getRcut(); | 
| 1043 | + |  | 
| 1044 | + | if (globals->haveRsw()) | 
| 1045 | + | theRsw = globals->getRsw(); | 
| 1046 | + | else | 
| 1047 | + | theRsw = theRcut; | 
| 1048 | + |  | 
| 1049 | + | info[i].setDefaultRcut(theRcut, theRsw); | 
| 1050 | + | } | 
| 1051 | + |  | 
| 1052 |  | if (globals->getUseRF()){ | 
| 1053 |  | info[i].useReactionField = 1; | 
| 1054 | < |  | 
| 1055 | < | if (!globals->haveECR()){ | 
| 1054 | > |  | 
| 1055 | > | if (!globals->haveRcut()){ | 
| 1056 |  | sprintf(painCave.errMsg, | 
| 1057 | < | "SimSetup Warning: No value was set for electrostaticCutoffRadius.\n" | 
| 1057 | > | "SimSetup Warning: No value was set for the cutoffRadius.\n" | 
| 1058 |  | "\tOOPSE will use a default value of 15.0 angstroms" | 
| 1059 | < | "\tfor the electrostaticCutoffRadius.\n"); | 
| 1059 | > | "\tfor the cutoffRadius.\n"); | 
| 1060 |  | painCave.isFatal = 0; | 
| 1061 |  | simError(); | 
| 1062 | < | theEcr = 15.0; | 
| 1062 | > | theRcut = 15.0; | 
| 1063 |  | } | 
| 1064 |  | else{ | 
| 1065 | < | theEcr = globals->getECR(); | 
| 1065 | > | theRcut = globals->getRcut(); | 
| 1066 |  | } | 
| 1067 |  |  | 
| 1068 | < | if (!globals->haveEST()){ | 
| 1068 | > | if (!globals->haveRsw()){ | 
| 1069 |  | sprintf(painCave.errMsg, | 
| 1070 | < | "SimSetup Warning: No value was set for electrostaticSkinThickness.\n" | 
| 1070 | > | "SimSetup Warning: No value was set for switchingRadius.\n" | 
| 1071 |  | "\tOOPSE will use a default value of\n" | 
| 1072 | < | "\t0.05 * electrostaticCutoffRadius\n" | 
| 900 | < | "\tfor the electrostaticSkinThickness\n"); | 
| 1072 | > | "\t0.95 * cutoffRadius for the switchingRadius\n"); | 
| 1073 |  | painCave.isFatal = 0; | 
| 1074 |  | simError(); | 
| 1075 | < | theEst = 0.05 * theEcr; | 
| 1075 | > | theRsw = 0.95 * theRcut; | 
| 1076 |  | } | 
| 1077 |  | else{ | 
| 1078 | < | theEst = globals->getEST(); | 
| 1078 | > | theRsw = globals->getRsw(); | 
| 1079 |  | } | 
| 1080 |  |  | 
| 1081 | < | info[i].setDefaultEcr(theEcr, theEst); | 
| 1081 | > | info[i].setDefaultRcut(theRcut, theRsw); | 
| 1082 |  |  | 
| 1083 |  | if (!globals->haveDielectric()){ | 
| 1084 |  | sprintf(painCave.errMsg, | 
| 1091 |  | info[i].dielectric = globals->getDielectric(); | 
| 1092 |  | } | 
| 1093 |  | else{ | 
| 1094 | < | if (usesDipoles){ | 
| 1095 | < | if (!globals->haveECR()){ | 
| 1094 | > | if (usesDipoles || usesCharges){ | 
| 1095 | > |  | 
| 1096 | > | if (!globals->haveRcut()){ | 
| 1097 |  | sprintf(painCave.errMsg, | 
| 1098 | < | "SimSetup Warning: No value was set for electrostaticCutoffRadius.\n" | 
| 1098 | > | "SimSetup Warning: No value was set for the cutoffRadius.\n" | 
| 1099 |  | "\tOOPSE will use a default value of 15.0 angstroms" | 
| 1100 | < | "\tfor the electrostaticCutoffRadius.\n"); | 
| 1101 | < | painCave.isFatal = 0; | 
| 1102 | < | simError(); | 
| 1103 | < | theEcr = 15.0; | 
| 1104 | < | } | 
| 1100 | > | "\tfor the cutoffRadius.\n"); | 
| 1101 | > | painCave.isFatal = 0; | 
| 1102 | > | simError(); | 
| 1103 | > | theRcut = 15.0; | 
| 1104 | > | } | 
| 1105 |  | else{ | 
| 1106 | < | theEcr = globals->getECR(); | 
| 1106 | > | theRcut = globals->getRcut(); | 
| 1107 |  | } | 
| 1108 | < |  | 
| 1109 | < | if (!globals->haveEST()){ | 
| 1108 | > |  | 
| 1109 | > | if (!globals->haveRsw()){ | 
| 1110 |  | sprintf(painCave.errMsg, | 
| 1111 | < | "SimSetup Warning: No value was set for electrostaticSkinThickness.\n" | 
| 1111 | > | "SimSetup Warning: No value was set for switchingRadius.\n" | 
| 1112 |  | "\tOOPSE will use a default value of\n" | 
| 1113 | < | "\t0.05 * electrostaticCutoffRadius\n" | 
| 941 | < | "\tfor the electrostaticSkinThickness\n"); | 
| 1113 | > | "\t0.95 * cutoffRadius for the switchingRadius\n"); | 
| 1114 |  | painCave.isFatal = 0; | 
| 1115 |  | simError(); | 
| 1116 | < | theEst = 0.05 * theEcr; | 
| 1116 | > | theRsw = 0.95 * theRcut; | 
| 1117 |  | } | 
| 1118 |  | else{ | 
| 1119 | < | theEst = globals->getEST(); | 
| 1119 | > | theRsw = globals->getRsw(); | 
| 1120 |  | } | 
| 1121 | + |  | 
| 1122 | + | info[i].setDefaultRcut(theRcut, theRsw); | 
| 1123 |  |  | 
| 950 | – | info[i].setDefaultEcr(theEcr, theEst); | 
| 1124 |  | } | 
| 1125 |  | } | 
| 1126 |  | } | 
| 1128 |  | strcpy(checkPointMsg, "post processing checks out"); | 
| 1129 |  | MPIcheckPoint(); | 
| 1130 |  | #endif // is_mpi | 
| 1131 | + |  | 
| 1132 | + | // clean up the forcefield | 
| 1133 | + | the_ff->cleanMe(); | 
| 1134 |  | } | 
| 1135 |  |  | 
| 1136 |  | void SimSetup::initSystemCoords(void){ | 
| 1345 |  | LinkedMolStamp* headStamp = new LinkedMolStamp(); | 
| 1346 |  | LinkedMolStamp* currentStamp = NULL; | 
| 1347 |  | comp_stamps = new MoleculeStamp * [n_components]; | 
| 1348 | + | bool haveCutoffGroups; | 
| 1349 |  |  | 
| 1350 | + | haveCutoffGroups = false; | 
| 1351 | + |  | 
| 1352 |  | // make an array of molecule stamps that match the components used. | 
| 1353 |  | // also extract the used stamps out into a separate linked list | 
| 1354 |  |  | 
| 1383 |  | headStamp->add(currentStamp); | 
| 1384 |  | comp_stamps[i] = headStamp->match(id); | 
| 1385 |  | } | 
| 1386 | + |  | 
| 1387 | + | if(comp_stamps[i]->getNCutoffGroups() > 0) | 
| 1388 | + | haveCutoffGroups = true; | 
| 1389 |  | } | 
| 1390 | + |  | 
| 1391 | + | for (i = 0; i < nInfo; i++) | 
| 1392 | + | info[i].haveCutoffGroups = haveCutoffGroups; | 
| 1393 |  |  | 
| 1394 |  | #ifdef IS_MPI | 
| 1395 |  | strcpy(checkPointMsg, "Component stamps successfully extracted\n"); | 
| 1406 |  | tot_bonds = 0; | 
| 1407 |  | tot_bends = 0; | 
| 1408 |  | tot_torsions = 0; | 
| 1409 | + | tot_rigid = 0; | 
| 1410 |  | for (i = 0; i < n_components; i++){ | 
| 1411 |  | tot_atoms += components_nmol[i] * comp_stamps[i]->getNAtoms(); | 
| 1412 |  | tot_bonds += components_nmol[i] * comp_stamps[i]->getNBonds(); | 
| 1413 |  | tot_bends += components_nmol[i] * comp_stamps[i]->getNBends(); | 
| 1414 |  | tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions(); | 
| 1415 | + | tot_rigid += components_nmol[i] * comp_stamps[i]->getNRigidBodies(); | 
| 1416 |  | } | 
| 1417 | < |  | 
| 1417 | > |  | 
| 1418 |  | tot_SRI = tot_bonds + tot_bends + tot_torsions; | 
| 1419 |  | molMembershipArray = new int[tot_atoms]; | 
| 1420 |  |  | 
| 1436 |  | int i, j, k; | 
| 1437 |  | int localMol, allMol; | 
| 1438 |  | int local_atoms, local_bonds, local_bends, local_torsions, local_SRI; | 
| 1439 | + | int local_rigid; | 
| 1440 | + | vector<int> globalMolIndex; | 
| 1441 |  |  | 
| 1442 |  | mpiSim = new mpiSimulation(info); | 
| 1443 |  |  | 
| 1444 | < | globalIndex = mpiSim->divideLabor(); | 
| 1444 | > | mpiSim->divideLabor(); | 
| 1445 | > | globalAtomIndex = mpiSim->getGlobalAtomIndex(); | 
| 1446 | > | //globalMolIndex = mpiSim->getGlobalMolIndex(); | 
| 1447 |  |  | 
| 1448 |  | // set up the local variables | 
| 1449 |  |  | 
| 1456 |  | local_bonds = 0; | 
| 1457 |  | local_bends = 0; | 
| 1458 |  | local_torsions = 0; | 
| 1459 | < | globalAtomIndex = 0; | 
| 1459 | > | local_rigid = 0; | 
| 1460 | > | globalAtomCounter = 0; | 
| 1461 |  |  | 
| 1270 | – |  | 
| 1462 |  | for (i = 0; i < n_components; i++){ | 
| 1463 |  | for (j = 0; j < components_nmol[i]; j++){ | 
| 1464 |  | if (mol2proc[allMol] == worldRank){ | 
| 1466 |  | local_bonds += comp_stamps[i]->getNBonds(); | 
| 1467 |  | local_bends += comp_stamps[i]->getNBends(); | 
| 1468 |  | local_torsions += comp_stamps[i]->getNTorsions(); | 
| 1469 | + | local_rigid += comp_stamps[i]->getNRigidBodies(); | 
| 1470 |  | localMol++; | 
| 1471 |  | } | 
| 1472 |  | for (k = 0; k < comp_stamps[i]->getNAtoms(); k++){ | 
| 1473 | < | info[0].molMembershipArray[globalAtomIndex] = allMol; | 
| 1474 | < | globalAtomIndex++; | 
| 1473 | > | info[0].molMembershipArray[globalAtomCounter] = allMol; | 
| 1474 | > | globalAtomCounter++; | 
| 1475 |  | } | 
| 1476 |  |  | 
| 1477 |  | allMol++; | 
| 1480 |  | local_SRI = local_bonds + local_bends + local_torsions; | 
| 1481 |  |  | 
| 1482 |  | info[0].n_atoms = mpiSim->getMyNlocal(); | 
| 1483 | + |  | 
| 1484 |  |  | 
| 1485 |  | if (local_atoms != info[0].n_atoms){ | 
| 1486 |  | sprintf(painCave.errMsg, | 
| 1513 |  |  | 
| 1514 |  | Atom** the_atoms; | 
| 1515 |  | Molecule* the_molecules; | 
| 1323 | – | Exclude** the_excludes; | 
| 1516 |  |  | 
| 1325 | – |  | 
| 1517 |  | for (l = 0; l < nInfo; l++){ | 
| 1518 |  | // create the atom and short range interaction arrays | 
| 1519 |  |  | 
| 1539 |  | #else // is_mpi | 
| 1540 |  |  | 
| 1541 |  | molIndex = 0; | 
| 1542 | < | globalAtomIndex = 0; | 
| 1542 | > | globalAtomCounter = 0; | 
| 1543 |  | for (i = 0; i < n_components; i++){ | 
| 1544 |  | for (j = 0; j < components_nmol[i]; j++){ | 
| 1545 |  | the_molecules[molIndex].setStampID(i); | 
| 1546 |  | the_molecules[molIndex].setMyIndex(molIndex); | 
| 1547 |  | the_molecules[molIndex].setGlobalIndex(molIndex); | 
| 1548 |  | for (k = 0; k < comp_stamps[i]->getNAtoms(); k++){ | 
| 1549 | < | info[l].molMembershipArray[globalAtomIndex] = molIndex; | 
| 1550 | < | globalAtomIndex++; | 
| 1549 | > | info[l].molMembershipArray[globalAtomCounter] = molIndex; | 
| 1550 | > | globalAtomCounter++; | 
| 1551 |  | } | 
| 1552 |  | molIndex++; | 
| 1553 |  | } | 
| 1556 |  |  | 
| 1557 |  | #endif // is_mpi | 
| 1558 |  |  | 
| 1559 | < |  | 
| 1560 | < | if (info[l].n_SRI){ | 
| 1561 | < | Exclude::createArray(info[l].n_SRI); | 
| 1371 | < | the_excludes = new Exclude * [info[l].n_SRI]; | 
| 1372 | < | for (int ex = 0; ex < info[l].n_SRI; ex++){ | 
| 1373 | < | the_excludes[ex] = new Exclude(ex); | 
| 1374 | < | } | 
| 1375 | < | info[l].globalExcludes = new int; | 
| 1376 | < | info[l].n_exclude = info[l].n_SRI; | 
| 1377 | < | } | 
| 1378 | < | else{ | 
| 1379 | < | Exclude::createArray(1); | 
| 1380 | < | the_excludes = new Exclude * ; | 
| 1381 | < | the_excludes[0] = new Exclude(0); | 
| 1382 | < | the_excludes[0]->setPair(0, 0); | 
| 1383 | < | info[l].globalExcludes = new int; | 
| 1384 | < | info[l].globalExcludes[0] = 0; | 
| 1385 | < | info[l].n_exclude = 0; | 
| 1386 | < | } | 
| 1387 | < |  | 
| 1559 | > | info[l].globalExcludes = new int; | 
| 1560 | > | info[l].globalExcludes[0] = 0; | 
| 1561 | > |  | 
| 1562 |  | // set the arrays into the SimInfo object | 
| 1563 |  |  | 
| 1564 |  | info[l].atoms = the_atoms; | 
| 1565 |  | info[l].molecules = the_molecules; | 
| 1566 |  | info[l].nGlobalExcludes = 0; | 
| 1567 | < | info[l].excludes = the_excludes; | 
| 1394 | < |  | 
| 1567 | > |  | 
| 1568 |  | the_ff->setSimInfo(info); | 
| 1569 |  | } | 
| 1570 |  | } |