Changeset 4882d5 for src/Dynamics


Ignore:
Timestamp:
Dec 14, 2012, 5:39:30 PM (12 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
5251af
Parents:
8b886f
git-author:
Frederik Heber <heber@…> (10/05/12 07:59:22)
git-committer:
Frederik Heber <heber@…> (12/14/12 17:39:30)
Message:

Rewrote VerletIntegrationAction to diminish dependence on ForceMatrix.

  • atom::VelocityVerletUpdate() now works on the forces stored in AtomicForces.
  • ThermoStatContainer::getActive() getter for the currently active thermostat.
  • VerletForceIntegration::operator() split up into several smaller functions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Dynamics/VerletForceIntegration.hpp

    r8b886f r4882d5  
    2323#include "Fragmentation/ForceMatrix.hpp"
    2424#include "Helpers/helpers.hpp"
     25#include "Helpers/defs.hpp"
    2526#include "LinearAlgebra/Vector.hpp"
    2627#include "Thermostats/ThermoStatContainer.hpp"
    27 #include "Thermostats/Berendsen.hpp"
     28#include "Thermostats/Thermostat.hpp"
    2829#include "World.hpp"
    2930
     
    3233{
    3334public:
    34   VerletForceIntegration(AtomSetMixin<T> &_atoms, double _Deltat, int _startstep, bool _IsAngstroem) :
     35  /** Constructor of class VerletForceIntegration.
     36   *
     37   * \param _atoms set of atoms to integrate
     38   * \param _Deltat time step width in atomic units
     39   * \param _IsAngstroem whether length units are in angstroem or bohr radii
     40   */
     41  VerletForceIntegration(AtomSetMixin<T> &_atoms, double _Deltat, bool _IsAngstroem) :
    3542    Deltat(_Deltat),
    3643    IsAngstroem(_IsAngstroem),
    37     atoms(_atoms),
    38     MDSteps(_startstep)
     44    atoms(_atoms)
    3945  {}
     46  /** Destructor of class VerletForceIntegration.
     47   *
     48   */
    4049  ~VerletForceIntegration()
    4150  {}
    4251
    43   /** Parses nuclear forces from file and performs Verlet integration.
    44    * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we
    45    * have to transform them).
    46    * This adds a new MD step to the config file.
     52  /** Parses nuclear forces from file.
     53   * Forces are stored in the time step \a TimeStep in the atomicForces in \a atoms.
    4754   * \param *file filename
    48    * \param offset offset in matrix file to the first force component
    49    * \param DoConstrainedMD whether a constrained MD shall be done
    50    * \param FixedCenterOfMass whether forces and velocities are correct to have fixed center of mass
    51    * \return true - file found and parsed, false - file not found or imparsable
    52    * \todo This is not yet checked if it is correctly working with DoConstrainedMD set >0.
    53    */
    54   bool operator()(char *file, const size_t offset, int DoConstrainedMD, bool FixedCenterOfMass)
     55   * \param TimeStep time step to parse forces file into
     56   * \return true - file parsed, false - file not found or imparsable
     57   */
     58  bool parseForcesFile(const char *file, const int TimeStep)
    5559  {
    5660    Info FunctionInfo(__func__);
    57     string token;
    58     stringstream item;
    59     double IonMass, ActualTemp;
    6061    ForceMatrix Force;
    6162
    62     const int AtomCount = atoms.size();
    63     ASSERT(AtomCount != 0, "VerletForceIntegration::operator() - no atoms to integrate.");
    6463    // parse file into ForceMatrix
    6564    std::ifstream input(file);
    6665    if ((input.good()) && (!Force.ParseMatrix(input, 0,0,0))) {
    6766      ELOG(0, "Could not parse Force Matrix file " << file << ".");
    68       performCriticalExit();
    6967      return false;
    7068    }
    7169    input.close();
    72     if (Force.RowCounter[0] != AtomCount) {
     70    if (Force.RowCounter[0] != (int)atoms.size()) {
    7371      ELOG(0, "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << atoms.size() << ".");
    74       performCriticalExit();
    7572      return false;
    7673    }
    7774
    78     if (FixedCenterOfMass) {
    79       Vector ForceVector;
    80       // correct Forces
    81       //std::cout << "Force before correction, " << Force << std::endl;
    82       ForceVector.Zero();
    83       for(int i=0;i<AtomCount;i++)
    84         for(int d=0;d<NDIM;d++) {
    85           ForceVector[d] += Force.Matrix[0][i][d+offset];
    86         }
    87       ForceVector.Scale(1./static_cast<double>(AtomCount));
    88       //std::cout << "Force before second correction, " << Force << std::endl;
    89       for(int i=0;i<AtomCount;i++)
    90         for(int d=0;d<NDIM;d++) {
    91           Force.Matrix[0][i][d+offset] -= ForceVector[d];
    92         }
    93       LOG(3, "INFO: forces correct by " << ForceVector << "each.");
    94     }
     75    addForceMatrixToAtomicForce(Force, TimeStep, 1);
     76    return true;
     77  }
     78
     79  /** Performs Verlet integration.
     80   * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we
     81   * have to transform them).
     82   * This adds a new MD step \f$ t + \Delta t \f$ to the config file.
     83   * \param NextStep current time step (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
     84   * \param offset offset in matrix file to the first force component
     85   * \param DoConstrainedMD whether a constrained MD shall be done
     86   * \param FixedCenterOfMass whether forces and velocities are correct to have fixed center of mass
     87   * \return true - file found and parsed, false - no atoms, file not found or imparsable
     88   * \todo This is not yet checked if it is correctly working with DoConstrainedMD set >0.
     89   */
     90  bool operator()(const int NextStep, const size_t offset, const int DoConstrainedMD, const bool FixedCenterOfMass)
     91  {
     92    Info FunctionInfo(__func__);
     93
     94    // check that atoms are present at all
     95    if (atoms.size() == 0) {
     96      ELOG(2, "VerletForceIntegration::operator() - no atoms to integrate.");
     97      return false;
     98    }
     99
     100    // make sum of forces equal zero
     101    if (FixedCenterOfMass)
     102      correctForceMatrixForFixedCenterOfMass(offset,NextStep);
    95103
    96104    // solve a constrained potential if we are meant to
    97105    if (DoConstrainedMD) {
    98       // calculate forces and potential
    99       std::map<atom *, atom*> PermutationMap;
    100       MinimiseConstrainedPotential Minimiser(atoms, PermutationMap);
    101       //double ConstrainedPotentialEnergy =
    102       Minimiser(DoConstrainedMD, 0, IsAngstroem);
    103       Minimiser.EvaluateConstrainedForces(&Force);
     106      performConstraintMinimization(DoConstrainedMD,NextStep);
    104107    }
    105108
     
    109112    for(typename AtomSetMixin<T>::iterator iter = atoms.begin(); iter != atoms.end(); ++iter) {
    110113      //std::cout << "Id of atom is " << (*iter)->getId() << std::endl;
    111       (*iter)->VelocityVerletUpdate((*iter)->getId(), MDSteps+1, Deltat, IsAngstroem, &Force, (const size_t) 1);
    112     }
    113 
    114     if (FixedCenterOfMass) {
    115       Vector Velocity;
    116       // correct velocities (rather momenta) so that center of mass remains motionless
    117       Velocity = atoms.totalMomentumAtStep(MDSteps+1);
    118       IonMass = atoms.totalMass();
    119 
    120       // correct velocities (rather momenta) so that center of mass remains motionless
    121       Velocity *= 1./IonMass;
    122       atoms.addVelocityAtStep(-1.*Velocity,MDSteps+1);
    123 
    124       LOG(3, "INFO: Velocities corrected by " << Velocity << " each.");
    125     }
     114      (*iter)->VelocityVerletUpdate((*iter)->getId(), NextStep, Deltat, IsAngstroem);
     115    }
     116
     117    // make sum of velocities equal zero
     118    if (FixedCenterOfMass)
     119      correctVelocitiesForFixedCenterOfMass(NextStep);
    126120
    127121    // thermostat
    128     ActualTemp = atoms.totalTemperatureAtStep(MDSteps+1);
    129     LOG(3, "INFO: Current temperature is " << ActualTemp);
    130     Berendsen berendsen = Berendsen();
    131     berendsen.addToContainer(World::getInstance().getThermostats());
    132     double ekin = berendsen.scaleAtoms(MDSteps,ActualTemp,atoms);
    133     ActualTemp = atoms.totalTemperatureAtStep(MDSteps+1);
    134     LOG(3, "INFO: New temperature after thermostat is " << ActualTemp);
    135     LOG(1, "Kinetic energy is " << ekin << ".");
    136 
    137     // next step
    138     MDSteps++;
     122    performThermostatControl(NextStep);
    139123
    140124    // exit
    141125    return true;
    142126  };
     127
     128private:
     129  void addForceMatrixToAtomicForce(const ForceMatrix &Force, const int &TimeStep, const int offset)
     130  {
     131    // place forces from matrix into atoms
     132    Vector tempVector;
     133    size_t i=0;
     134    for(typename AtomSetMixin<T>::iterator iter = atoms.begin(); iter != atoms.end(); ++iter,++i) {
     135      for(size_t d=0;d<NDIM;d++) {
     136        tempVector[d] = Force.Matrix[0][i][d+offset]*(IsAngstroem ? AtomicLengthToAngstroem : 1.);
     137      }
     138      tempVector += (*iter)->getAtomicForceAtStep(TimeStep);
     139      (*iter)->setAtomicForceAtStep(TimeStep, tempVector);
     140    }
     141  }
     142
     143  void correctForceMatrixForFixedCenterOfMass(const size_t offset, const int &TimeStep) {
     144    Vector ForceVector;
     145    // correct Forces
     146    //std::cout << "Force before correction, " << Force << std::endl;
     147    ForceVector.Zero();
     148    for(typename AtomSetMixin<T>::iterator iter = atoms.begin(); iter != atoms.end(); ++iter) {
     149      ForceVector += (*iter)->getAtomicForceAtStep(TimeStep);
     150    }
     151    ForceVector.Scale(1./(double)atoms.size());
     152    //std::cout << "Force before second correction, " << Force << std::endl;
     153    for(typename AtomSetMixin<T>::iterator iter = atoms.begin(); iter != atoms.end(); ++iter) {
     154      const Vector tempVector = (*iter)->getAtomicForceAtStep(TimeStep) - ForceVector;
     155      (*iter)->setAtomicForceAtStep(TimeStep, tempVector);
     156    }
     157    LOG(3, "INFO: forces correct by " << ForceVector << "each.");
     158  }
     159
     160  void correctVelocitiesForFixedCenterOfMass(const int &TimeStep) {
     161    Vector Velocity;
     162    double IonMass;
     163    // correct velocities (rather momenta) so that center of mass remains motionless
     164    Velocity = atoms.totalMomentumAtStep(TimeStep);
     165    IonMass = atoms.totalMass();
     166
     167    // correct velocities (rather momenta) so that center of mass remains motionless
     168    Velocity *= 1./IonMass;
     169    atoms.addVelocityAtStep(-1.*Velocity,TimeStep);
     170
     171    LOG(3, "INFO: Velocities corrected by " << Velocity << " each.");
     172  }
     173
     174  void performConstraintMinimization(const int &DoConstrainedMD, const int &TimeStep) {
     175    // calculate forces and potential
     176    ForceMatrix Force;
     177    std::map<atom *, atom*> PermutationMap;
     178    MinimiseConstrainedPotential Minimiser(atoms, PermutationMap);
     179    //double ConstrainedPotentialEnergy =
     180    Minimiser(DoConstrainedMD, 0, IsAngstroem);
     181    Minimiser.EvaluateConstrainedForces(&Force);
     182    addForceMatrixToAtomicForce(Force, TimeStep, 1);
     183  }
     184
     185  void performThermostatControl(const int &TimeStep) {
     186    double ActualTemp;
     187
     188    // calculate current temperature
     189    ActualTemp = atoms.totalTemperatureAtStep(TimeStep);
     190    LOG(3, "INFO: Current temperature is " << ActualTemp);
     191
     192    // rescale to desired value
     193    double ekin = World::getInstance().getThermostats()->getActive()->scaleAtoms(TimeStep,ActualTemp,atoms);
     194    ActualTemp = atoms.totalTemperatureAtStep(TimeStep);
     195    LOG(3, "INFO: New temperature after thermostat is " << ActualTemp);
     196    LOG(1, "Kinetic energy is " << ekin << ".");
     197  }
    143198
    144199private:
     
    146201  bool IsAngstroem;
    147202  AtomSetMixin<T> atoms;
    148   int MDSteps;
    149203};
    150204
Note: See TracChangeset for help on using the changeset viewer.