| 1 | < | #include <cstdlib> | 
| 2 | < | #include <cstring> | 
| 3 | < | #include <cmath> | 
| 1 | > | #include <stdlib.h> | 
| 2 | > | #include <string.h> | 
| 3 | > | #include <math.h> | 
| 4 |  |  | 
| 5 |  | #include <iostream> | 
| 6 |  | using namespace std; | 
| 26 |  | SimInfo::SimInfo(){ | 
| 27 |  | excludes = NULL; | 
| 28 |  | n_constraints = 0; | 
| 29 | + | nZconstraints = 0; | 
| 30 |  | n_oriented = 0; | 
| 31 |  | n_dipoles = 0; | 
| 32 |  | ndf = 0; | 
| 48 |  | haveOrigEcr = 0; | 
| 49 |  | boxIsInit = 0; | 
| 50 |  |  | 
| 51 | + | resetTime = 1e99; | 
| 52 |  |  | 
| 53 |  |  | 
| 54 |  | usePBC = 0; | 
| 61 |  |  | 
| 62 |  | myConfiguration = new SimState(); | 
| 63 |  |  | 
| 64 | + | properties = new GenericData(); | 
| 65 | + |  | 
| 66 |  | wrapMeSimInfo( this ); | 
| 67 |  | } | 
| 68 |  |  | 
| 70 |  | SimInfo::~SimInfo(){ | 
| 71 |  |  | 
| 72 |  | delete myConfiguration; | 
| 73 | < |  | 
| 70 | < | map<string, GenericData*>::iterator i; | 
| 71 | < |  | 
| 72 | < | for(i = properties.begin(); i != properties.end(); i++) | 
| 73 | < | delete (*i).second; | 
| 74 | < |  | 
| 73 | > | delete properties; | 
| 74 |  | } | 
| 75 |  |  | 
| 76 |  | void SimInfo::setBox(double newBox[3]) { | 
| 91 |  |  | 
| 92 |  | void SimInfo::setBoxM( double theBox[3][3] ){ | 
| 93 |  |  | 
| 94 | < | int i, j, status; | 
| 96 | < | double smallestBoxL, maxCutoff; | 
| 94 | > | int i, j; | 
| 95 |  | double FortranHmat[9]; // to preserve compatibility with Fortran the | 
| 96 |  | // ordering in the array is as follows: | 
| 97 |  | // [ 0 3 6 ] | 
| 278 |  | << "[ " << A[6] << ", " << A[7] << ", " << A[8] << " ]\n"; | 
| 279 |  | } | 
| 280 |  |  | 
| 281 | + |  | 
| 282 | + | void SimInfo::crossProduct3(double a[3],double b[3], double out[3]){ | 
| 283 | + |  | 
| 284 | + | out[0] = a[1] * b[2] - a[2] * b[1]; | 
| 285 | + | out[1] = a[2] * b[0] - a[0] * b[2] ; | 
| 286 | + | out[2] = a[0] * b[1] - a[1] * b[0]; | 
| 287 | + |  | 
| 288 | + | } | 
| 289 | + |  | 
| 290 | + | double SimInfo::dotProduct3(double a[3], double b[3]){ | 
| 291 | + | return a[0]*b[0] + a[1]*b[1]+ a[2]*b[2]; | 
| 292 | + | } | 
| 293 | + |  | 
| 294 | + | double SimInfo::length3(double a[3]){ | 
| 295 | + | return sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); | 
| 296 | + | } | 
| 297 | + |  | 
| 298 |  | void SimInfo::calcBoxL( void ){ | 
| 299 |  |  | 
| 300 |  | double dx, dy, dz, dsq; | 
| 286 | – | int i; | 
| 301 |  |  | 
| 302 |  | // boxVol = Determinant of Hmat | 
| 303 |  |  | 
| 308 |  | dx = Hmat[0][0]; dy = Hmat[1][0]; dz = Hmat[2][0]; | 
| 309 |  | dsq = dx*dx + dy*dy + dz*dz; | 
| 310 |  | boxL[0] = sqrt( dsq ); | 
| 311 | < | maxCutoff = 0.5 * boxL[0]; | 
| 311 | > | //maxCutoff = 0.5 * boxL[0]; | 
| 312 |  |  | 
| 313 |  | // boxLy | 
| 314 |  |  | 
| 315 |  | dx = Hmat[0][1]; dy = Hmat[1][1]; dz = Hmat[2][1]; | 
| 316 |  | dsq = dx*dx + dy*dy + dz*dz; | 
| 317 |  | boxL[1] = sqrt( dsq ); | 
| 318 | < | if( (0.5 * boxL[1]) < maxCutoff ) maxCutoff = 0.5 * boxL[1]; | 
| 318 | > | //if( (0.5 * boxL[1]) < maxCutoff ) maxCutoff = 0.5 * boxL[1]; | 
| 319 |  |  | 
| 320 | + |  | 
| 321 |  | // boxLz | 
| 322 |  |  | 
| 323 |  | dx = Hmat[0][2]; dy = Hmat[1][2]; dz = Hmat[2][2]; | 
| 324 |  | dsq = dx*dx + dy*dy + dz*dz; | 
| 325 |  | boxL[2] = sqrt( dsq ); | 
| 326 | < | if( (0.5 * boxL[2]) < maxCutoff ) maxCutoff = 0.5 * boxL[2]; | 
| 326 | > | //if( (0.5 * boxL[2]) < maxCutoff ) maxCutoff = 0.5 * boxL[2]; | 
| 327 | > |  | 
| 328 | > | //calculate the max cutoff | 
| 329 | > | maxCutoff =  calcMaxCutOff(); | 
| 330 |  |  | 
| 331 |  | checkCutOffs(); | 
| 332 |  |  | 
| 333 |  | } | 
| 334 |  |  | 
| 335 |  |  | 
| 336 | + | double SimInfo::calcMaxCutOff(){ | 
| 337 | + |  | 
| 338 | + | double ri[3], rj[3], rk[3]; | 
| 339 | + | double rij[3], rjk[3], rki[3]; | 
| 340 | + | double minDist; | 
| 341 | + |  | 
| 342 | + | ri[0] = Hmat[0][0]; | 
| 343 | + | ri[1] = Hmat[1][0]; | 
| 344 | + | ri[2] = Hmat[2][0]; | 
| 345 | + |  | 
| 346 | + | rj[0] = Hmat[0][1]; | 
| 347 | + | rj[1] = Hmat[1][1]; | 
| 348 | + | rj[2] = Hmat[2][1]; | 
| 349 | + |  | 
| 350 | + | rk[0] = Hmat[0][2]; | 
| 351 | + | rk[1] = Hmat[1][2]; | 
| 352 | + | rk[2] = Hmat[2][2]; | 
| 353 | + |  | 
| 354 | + | crossProduct3(ri,rj, rij); | 
| 355 | + | distXY = dotProduct3(rk,rij) / length3(rij); | 
| 356 | + |  | 
| 357 | + | crossProduct3(rj,rk, rjk); | 
| 358 | + | distYZ = dotProduct3(ri,rjk) / length3(rjk); | 
| 359 | + |  | 
| 360 | + | crossProduct3(rk,ri, rki); | 
| 361 | + | distZX = dotProduct3(rj,rki) / length3(rki); | 
| 362 | + |  | 
| 363 | + | minDist = min(min(distXY, distYZ), distZX); | 
| 364 | + | return minDist/2; | 
| 365 | + |  | 
| 366 | + | } | 
| 367 | + |  | 
| 368 |  | void SimInfo::wrapVector( double thePos[3] ){ | 
| 369 |  |  | 
| 370 | < | int i, j, k; | 
| 370 | > | int i; | 
| 371 |  | double scaled[3]; | 
| 372 |  |  | 
| 373 |  | if( !orthoRhombic ){ | 
| 405 |  |  | 
| 406 |  |  | 
| 407 |  | int SimInfo::getNDF(){ | 
| 408 | < | int ndf_local, ndf; | 
| 408 | > | int ndf_local; | 
| 409 |  |  | 
| 410 |  | ndf_local = 3 * n_atoms + 3 * n_oriented - n_constraints; | 
| 411 |  |  | 
| 421 |  | } | 
| 422 |  |  | 
| 423 |  | int SimInfo::getNDFraw() { | 
| 424 | < | int ndfRaw_local, ndfRaw; | 
| 424 | > | int ndfRaw_local; | 
| 425 |  |  | 
| 426 |  | // Raw degrees of freedom that we have to set | 
| 427 |  | ndfRaw_local = 3 * n_atoms + 3 * n_oriented; | 
| 434 |  |  | 
| 435 |  | return ndfRaw; | 
| 436 |  | } | 
| 437 | < |  | 
| 437 | > |  | 
| 438 | > | int SimInfo::getNDFtranslational() { | 
| 439 | > | int ndfTrans_local; | 
| 440 | > |  | 
| 441 | > | ndfTrans_local = 3 * n_atoms - n_constraints; | 
| 442 | > |  | 
| 443 | > | #ifdef IS_MPI | 
| 444 | > | MPI_Allreduce(&ndfTrans_local,&ndfTrans,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD); | 
| 445 | > | #else | 
| 446 | > | ndfTrans = ndfTrans_local; | 
| 447 | > | #endif | 
| 448 | > |  | 
| 449 | > | ndfTrans = ndfTrans - 3 - nZconstraints; | 
| 450 | > |  | 
| 451 | > | return ndfTrans; | 
| 452 | > | } | 
| 453 | > |  | 
| 454 |  | void SimInfo::refreshSim(){ | 
| 455 |  |  | 
| 456 |  | simtype fInfo; | 
| 506 |  |  | 
| 507 |  | this->ndf = this->getNDF(); | 
| 508 |  | this->ndfRaw = this->getNDFraw(); | 
| 509 | < |  | 
| 509 | > | this->ndfTrans = this->getNDFtranslational(); | 
| 510 |  | } | 
| 511 |  |  | 
| 512 |  |  | 
| 513 |  | void SimInfo::setRcut( double theRcut ){ | 
| 514 |  |  | 
| 449 | – | if( !haveOrigRcut ){ | 
| 450 | – | haveOrigRcut = 1; | 
| 451 | – | origRcut = theRcut; | 
| 452 | – | } | 
| 453 | – |  | 
| 515 |  | rCut = theRcut; | 
| 516 |  | checkCutOffs(); | 
| 517 |  | } | 
| 518 |  |  | 
| 519 | < | void SimInfo::setEcr( double theEcr ){ | 
| 519 | > | void SimInfo::setDefaultRcut( double theRcut ){ | 
| 520 |  |  | 
| 521 | < | if( !haveOrigEcr ){ | 
| 522 | < | haveOrigEcr = 1; | 
| 523 | < | origEcr = theEcr; | 
| 463 | < | } | 
| 521 | > | haveOrigRcut = 1; | 
| 522 | > | origRcut = theRcut; | 
| 523 | > | rCut = theRcut; | 
| 524 |  |  | 
| 525 | + | ( rCut > ecr )? rList = rCut + 1.0: rList = ecr + 1.0; | 
| 526 | + |  | 
| 527 | + | notifyFortranCutOffs( &rCut, &rList, &ecr, &est ); | 
| 528 | + | } | 
| 529 | + |  | 
| 530 | + | void SimInfo::setEcr( double theEcr ){ | 
| 531 | + |  | 
| 532 |  | ecr = theEcr; | 
| 533 |  | checkCutOffs(); | 
| 534 |  | } | 
| 535 |  |  | 
| 536 | + | void SimInfo::setDefaultEcr( double theEcr ){ | 
| 537 | + |  | 
| 538 | + | haveOrigEcr = 1; | 
| 539 | + | origEcr = theEcr; | 
| 540 | + |  | 
| 541 | + | ( rCut > ecr )? rList = rCut + 1.0: rList = ecr + 1.0; | 
| 542 | + |  | 
| 543 | + | ecr = theEcr; | 
| 544 | + |  | 
| 545 | + | notifyFortranCutOffs( &rCut, &rList, &ecr, &est ); | 
| 546 | + | } | 
| 547 | + |  | 
| 548 |  | void SimInfo::setEcr( double theEcr, double theEst ){ | 
| 549 |  |  | 
| 550 |  | est = theEst; | 
| 551 |  | setEcr( theEcr ); | 
| 552 |  | } | 
| 553 |  |  | 
| 554 | + | void SimInfo::setDefaultEcr( double theEcr, double theEst ){ | 
| 555 |  |  | 
| 556 | < | void SimInfo::checkCutOffs( void ){ | 
| 556 | > | est = theEst; | 
| 557 | > | setDefaultEcr( theEcr ); | 
| 558 | > | } | 
| 559 |  |  | 
| 478 | – | int cutChanged = 0; | 
| 560 |  |  | 
| 561 | + | void SimInfo::checkCutOffs( void ){ | 
| 562 |  |  | 
| 563 | < |  | 
| 563 | > | int cutChanged = 0; | 
| 564 | > |  | 
| 565 |  | if( boxIsInit ){ | 
| 566 |  |  | 
| 567 |  | //we need to check cutOffs against the box | 
| 568 | < |  | 
| 568 | > |  | 
| 569 | > | //detect the change of rCut | 
| 570 |  | if(( maxCutoff > rCut )&&(usePBC)){ | 
| 571 |  | if( rCut < origRcut ){ | 
| 572 | < | rCut = origRcut; | 
| 573 | < | if (rCut > maxCutoff) rCut = maxCutoff; | 
| 574 | < |  | 
| 575 | < | sprintf( painCave.errMsg, | 
| 576 | < | "New Box size is setting the long range cutoff radius " | 
| 577 | < | "to %lf\n", | 
| 578 | < | rCut ); | 
| 579 | < | painCave.isFatal = 0; | 
| 580 | < | simError(); | 
| 572 | > | rCut = origRcut; | 
| 573 | > |  | 
| 574 | > | if (rCut > maxCutoff) | 
| 575 | > | rCut = maxCutoff; | 
| 576 | > |  | 
| 577 | > | sprintf( painCave.errMsg, | 
| 578 | > | "New Box size is setting the long range cutoff radius " | 
| 579 | > | "to %lf at time %lf\n", | 
| 580 | > | rCut, currentTime ); | 
| 581 | > | painCave.isFatal = 0; | 
| 582 | > | simError(); | 
| 583 |  | } | 
| 584 |  | } | 
| 585 | < |  | 
| 500 | < | if( maxCutoff > ecr ){ | 
| 501 | < | if( ecr < origEcr ){ | 
| 502 | < | rCut = origEcr; | 
| 503 | < | if (ecr > maxCutoff) ecr = maxCutoff; | 
| 504 | < |  | 
| 505 | < | sprintf( painCave.errMsg, | 
| 506 | < | "New Box size is setting the electrostaticCutoffRadius " | 
| 507 | < | "to %lf\n", | 
| 508 | < | ecr ); | 
| 509 | < | painCave.isFatal = 0; | 
| 510 | < | simError(); | 
| 511 | < | } | 
| 512 | < | } | 
| 513 | < |  | 
| 514 | < |  | 
| 515 | < | if ((rCut > maxCutoff)&&(usePBC)) { | 
| 585 | > | else if ((rCut > maxCutoff)&&(usePBC)) { | 
| 586 |  | sprintf( painCave.errMsg, | 
| 587 |  | "New Box size is setting the long range cutoff radius " | 
| 588 | < | "to %lf\n", | 
| 589 | < | maxCutoff ); | 
| 588 | > | "to %lf at time %lf\n", | 
| 589 | > | maxCutoff, currentTime ); | 
| 590 |  | painCave.isFatal = 0; | 
| 591 |  | simError(); | 
| 592 |  | rCut = maxCutoff; | 
| 593 |  | } | 
| 594 |  |  | 
| 595 | < | if( ecr > maxCutoff){ | 
| 595 | > |  | 
| 596 | > | //detect the change of ecr | 
| 597 | > | if( maxCutoff > ecr ){ | 
| 598 | > | if( ecr < origEcr ){ | 
| 599 | > | ecr = origEcr; | 
| 600 | > | if (ecr > maxCutoff) ecr = maxCutoff; | 
| 601 | > |  | 
| 602 | > | sprintf( painCave.errMsg, | 
| 603 | > | "New Box size is setting the electrostaticCutoffRadius " | 
| 604 | > | "to %lf at time %lf\n", | 
| 605 | > | ecr, currentTime ); | 
| 606 | > | painCave.isFatal = 0; | 
| 607 | > | simError(); | 
| 608 | > | } | 
| 609 | > | } | 
| 610 | > | else if( ecr > maxCutoff){ | 
| 611 |  | sprintf( painCave.errMsg, | 
| 612 |  | "New Box size is setting the electrostaticCutoffRadius " | 
| 613 | < | "to %lf\n", | 
| 614 | < | maxCutoff  ); | 
| 613 | > | "to %lf at time %lf\n", | 
| 614 | > | maxCutoff, currentTime  ); | 
| 615 |  | painCave.isFatal = 0; | 
| 616 |  | simError(); | 
| 617 |  | ecr = maxCutoff; | 
| 618 |  | } | 
| 619 |  |  | 
| 620 | + | if( (oldEcr != ecr) || ( oldRcut != rCut ) ) cutChanged = 1; | 
| 621 |  |  | 
| 622 | < | } | 
| 537 | < |  | 
| 538 | < |  | 
| 539 | < | if( (oldEcr != ecr) || ( oldRcut != rCut ) ) cutChanged = 1; | 
| 540 | < |  | 
| 541 | < | // rlist is the 1.0 plus max( rcut, ecr ) | 
| 542 | < |  | 
| 543 | < | ( rCut > ecr )? rList = rCut + 1.0: rList = ecr + 1.0; | 
| 544 | < |  | 
| 545 | < | if( cutChanged ){ | 
| 622 | > | // rlist is the 1.0 plus max( rcut, ecr ) | 
| 623 |  |  | 
| 624 | < | notifyFortranCutOffs( &rCut, &rList, &ecr, &est ); | 
| 548 | < | } | 
| 549 | < |  | 
| 550 | < | oldEcr = ecr; | 
| 551 | < | oldRcut = rCut; | 
| 552 | < | } | 
| 553 | < |  | 
| 554 | < | void SimInfo::addProperty(GenericData* prop){ | 
| 555 | < |  | 
| 556 | < | map<string, GenericData*>::iterator result; | 
| 557 | < | result = properties.find(prop->getID()); | 
| 558 | < |  | 
| 559 | < | //we can't simply use  properties[prop->getID()] = prop, | 
| 560 | < | //it will cause memory leak if we already contain a propery which has the same name of prop | 
| 561 | < |  | 
| 562 | < | if(result != properties.end()){ | 
| 624 | > | ( rCut > ecr )? rList = rCut + 1.0: rList = ecr + 1.0; | 
| 625 |  |  | 
| 626 | < | delete (*result).second; | 
| 627 | < | (*result).second = prop; | 
| 628 | < |  | 
| 567 | < | } | 
| 568 | < | else{ | 
| 569 | < |  | 
| 570 | < | properties[prop->getID()] = prop; | 
| 571 | < |  | 
| 572 | < | } | 
| 626 | > | if( cutChanged ){ | 
| 627 | > | notifyFortranCutOffs( &rCut, &rList, &ecr, &est ); | 
| 628 | > | } | 
| 629 |  |  | 
| 630 | < | } | 
| 631 | < |  | 
| 632 | < | GenericData* SimInfo::getProperty(const string& propName){ | 
| 633 | < |  | 
| 634 | < | map<string, GenericData*>::iterator result; | 
| 630 | > | oldEcr = ecr; | 
| 631 | > | oldRcut = rCut; | 
| 632 | > |  | 
| 633 | > | } else { | 
| 634 | > | // initialize this stuff before using it, OK? | 
| 635 | > | sprintf( painCave.errMsg, | 
| 636 | > | "Trying to check cutoffs without a box. Be smarter.\n" ); | 
| 637 | > | painCave.isFatal = 1; | 
| 638 | > | simError(); | 
| 639 | > | } | 
| 640 |  |  | 
| 580 | – | //string lowerCaseName = (); | 
| 581 | – |  | 
| 582 | – | result = properties.find(propName); | 
| 583 | – |  | 
| 584 | – | if(result != properties.end()) | 
| 585 | – | return (*result).second; | 
| 586 | – | else | 
| 587 | – | return NULL; | 
| 641 |  | } | 
| 642 |  |  | 
| 643 | < | vector<GenericData*> SimInfo::getProperties(){ | 
| 643 | > | GenericData* SimInfo::getProperty(char* propName){ | 
| 644 |  |  | 
| 645 | < | vector<GenericData*> result; | 
| 593 | < | map<string, GenericData*>::iterator i; | 
| 594 | < |  | 
| 595 | < | for(i = properties.begin(); i != properties.end(); i++) | 
| 596 | < | result.push_back((*i).second); | 
| 597 | < |  | 
| 598 | < | return result; | 
| 645 | > | return properties->find( propName ); | 
| 646 |  | } | 
| 647 |  |  | 
| 648 | + | double SimInfo::matTrace3(double m[3][3]){ | 
| 649 | + | double trace; | 
| 650 | + | trace = m[0][0] + m[1][1] + m[2][2]; | 
| 651 |  |  | 
| 652 | + | return trace; | 
| 653 | + | } |