/** Thermostat : a class for atom-continuum control of energy/temperature */ #ifndef THERMOSTAT_H #define THERMOSTAT_H // ATC_Transfer headers #include "AtomicRegulator.h" // other headers #include #include namespace ATC { /** * @class Thermtostat * @brief Manager class for atom-continuum control of thermal energy */ //-------------------------------------------------------- //-------------------------------------------------------- // Class Thermostat //-------------------------------------------------------- //-------------------------------------------------------- class Thermostat : public AtomicRegulator { public: /** thermostat types */ enum ThermostatType { NONE=0, RESCALE, HOOVER, FLUX }; // constructor Thermostat(ATC_Transfer * atcTransfer); // destructor ~Thermostat(){}; /** parser/modifier */ virtual bool modify(int narg, char **arg); /** pre time integration */ virtual void initialize(); // data access, intended for method objects /** reset the nodal power to a prescribed value */ void reset_lambda_power(DENS_MAT & target); /** return the nodal power induced by lambda */ DENS_VEC & get_nodal_atomic_lambda_power(){return nodalAtomicLambdaPower_;}; /** return value filtered lambda */ DENS_VEC & get_filtered_lambda_power(){return lambdaPowerFiltered_;}; /** access to thermostat type */ ThermostatType get_thermostat_type() const {return thermostatType_;}; protected: /** thermostat type flag */ ThermostatType thermostatType_; // thermostat data /** lambda power applied to atoms */ DENS_VEC nodalAtomicLambdaPower_; /** filtered lambda power */ DENS_VEC lambdaPowerFiltered_; private: // DO NOT define this Thermostat(); }; /** * @class ThermostatShapeFunction * @brief Base class for implementation of thermostat algorithms using the shape function matrices */ //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatShapeFunction // base class for all thermostats of general form // of N^T w N lambda = rhs //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatShapeFunction : public RegulatorShapeFunction { public: ThermostatShapeFunction(Thermostat * thermostat); ~ThermostatShapeFunction(){}; /** reset number of local atoms, as well as atomic data */ virtual void reset_nlocal(); protected: // methods /** set weighting factor for in matrix Nhat^T * weights * Nhat */ virtual void set_weights(DIAG_MAT & weights); // member data /** pointer to thermostat object for data */ Thermostat * thermostat_; /** pointer to lammps atomic velocities */ double ** v_; /** MD mass matrix */ MATRIX & mdMassMatrix_; /** mass of ATC internal atoms on this processor */ DENS_VEC atomicMass_; private: // DO NOT define this ThermostatShapeFunction(); }; /** * @class ThermostatRescale * @brief Enforces constraint on atomic kinetic energy based on FE temperature */ //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatRescale //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatRescale : public ThermostatShapeFunction { public: ThermostatRescale(Thermostat * thermostat); ~ThermostatRescale(){}; /** applies thermostat to atoms in the post-corrector phase */ virtual void apply_post_corrector(double dt); /** get data for output */ virtual void output(double dt, OUTPUT_LIST & outputData); protected: /** apply solution to atomic quantities */ void apply_to_atoms(double ** atomicVelocity, double dt); /** FE temperature field */ DENS_MAT & nodalTemperature_; private: // DO NOT define this ThermostatRescale(); }; /** * @class ThermostatGlc * @brief Base class for implementation of thermostat algorithms based on Gaussian least constraints (GLC) */ //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatGlc // base clas for all thermostats of general form of a // Gaussian least constraint (GLC) //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatGlc : public ThermostatShapeFunction { public: ThermostatGlc(Thermostat * thermostat); ~ThermostatGlc(){}; protected: // methods /** compute force induced by lambda */ virtual void compute_lambda_force(double * const * atomicQuantity, DENS_MAT & lambdaForce); /** apply forces to atoms */ virtual void apply_to_atoms(double ** atomicVelocity, const DENS_MAT & lambdaForce, double dt); // member data /** pointer to a time filtering object */ TimeFilter * timeFilter_; /** power induced by lambda */ DENS_VEC & nodalAtomicLambdaPower_; /** filtered lambda power */ DENS_VEC & lambdaPowerFiltered_; /** atomic force induced by lambda */ DENS_MAT & lambdaForce_; /** bool to determine if node is fixed or not */ Array2D & isFixedNode_; private: // DO NOT define this ThermostatGlc(); }; /** * @class ThermostatPower * @brief Enforces GLC on atomic forces based on FE power * when using fractional step time integration */ //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatPower //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatPower : public ThermostatGlc { public: ThermostatPower(Thermostat * thermostat); ~ThermostatPower(); /** reset number of local atoms, as well as atomic data */ virtual void reset_nlocal(); /** applies thermostat to atoms in the predictor phase */ virtual void apply_pre_predictor(double dt); /** applies thermostat to atoms in the pre-corrector phase */ virtual void apply_pre_corrector(double dt); /** applies thermostat to atoms in the post-corrector phase */ virtual void apply_post_corrector(double dt); protected: // methods /** destroys allocated memory */ void destroy(); /** update the nodal quantities after predictor step */ virtual void update_nodal_quantities_predictor(double dt); /** compute the change in nodal atomic temperature */ virtual void compute_delta_nodal_atomic_temperature(double dt); /** update the nodal quantities after pre-corrector step */ virtual void update_nodal_quantities_pre_corrector(double dt); /** undoes the update the nodal quantities after pre-corrector step */ virtual void undo_update_nodal_quantities_pre_corrector(double dt); /** update the nodal quantities after post-corrector step */ virtual void update_nodal_quantities_post_corrector(double dt); /** sets up appropriate rhs for thermostat equations */ virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes, double dt); /** apply forces to atoms */ virtual void apply_to_atoms(double ** atomicVelocity, const DENS_MAT & lambdaForce, double dt); /** solves the non-linear equation for lambda iteratively */ void iterate_lambda(const MATRIX & rhs, double * const * atomicVelocity, double dt); /** set weighting factor for in matrix Nhat^T * weights * Nhat */ virtual void set_weights(DIAG_MAT & weights); // data /** reference to AtC FE temperature */ DENS_MAT & nodalTemperature_; /** reference to AtC restricted atomic temperature */ DENS_MAT & nodalAtomicTemperature_; /** reference to ATC sources coming from prescribed data, AtC coupling, and extrinsic coupling */ DENS_MAT & heatSource_; /** reference to weights for Nhat */ DIAG_MAT & nodalWeights_; /** change in FE temperature over a timestep */ DENS_MAT deltaTemperature_; /** change in restricted atomic FE temperature over a timestep */ DENS_MAT deltaNodalAtomicTemperature_; /** FE temperature rate of change */ DENS_MAT nodalTemperatureRoc_; /** local version of velocity used as predicted final veloctiy */ double ** myAtomicVelocity_; /** pointer to lammps atomic forces */ double ** f_; /** number of total atoms on this processor */ int nLocalTotal_; /** maximum number of iterations used in iterative solve for lambda */ int lambdaMaxIterations_; /** tolerance used in iterative solve for lambda */ double lambdaTolerance_; /** coefficient to account for effect of time filtering on rhs terms */ double filterCoefficient_; /** reference to ATC unity shape function on ghost atoms */ SPAR_MAT & Nstar_; /** maps ghost atom and LAMMPS atom ids */ Array & ghostToAtom_; private: // DO NOT define this ThermostatPower(); }; //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatHoover //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatHoover : public ThermostatPower { public: ThermostatHoover(Thermostat * thermostat); ~ThermostatHoover(); /** reset number of local atoms, as well as atomic data */ virtual void reset_nlocal(); /** applies thermostat to atoms in the predictor phase */ virtual void apply_pre_predictor(double dt); /** applies thermostat to atoms in the pre-corrector phase */ virtual void apply_pre_corrector(double dt); /** applies thermostat to atoms in the post-corrector phase */ virtual void apply_post_corrector(double dt); protected: // methods /** compute boundary flux, requires thermostat input since it is part of the coupling scheme */ virtual void compute_boundary_flux(FIELDS & fields) {boundaryFlux_[TEMPERATURE] = 0.;}; /** adds Hoover power terms to nodal variables after the predictor phase */ void add_to_lambda_power_predictor(double dt); /** adds Hoover power terms to nodal variables after the pre-corrector phase */ void add_to_lambda_power_pre_corrector(double dt); /** adds Hoover power terms to nodal variables after the post-corrector phase */ void add_to_lambda_power_post_corrector(double dt); /** sets up appropriate rhs for thermostat equations */ virtual void set_hoover_rhs(DENS_MAT & rhs_nodes, double dt); /** add Hoover contributions to lambda power */ void add_to_lambda_power(DENS_MAT & myLambdaForce); // data /** force coming from Hoover contribution */ DENS_MAT lambdaForceHoover_; /** reference to ATC map from global nodes to overlap nodes */ Array & nodeToOverlapMap_; private: // DO NOT define this ThermostatHoover(); }; //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatPowerFiltered //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatPowerFiltered : public ThermostatPower { public: ThermostatPowerFiltered(Thermostat * thermostat); ~ThermostatPowerFiltered(){}; protected: /** update the nodal quantities after predictor step */ virtual void update_nodal_quantities_predictor(double dt); /** compute the change in nodal atomic temperature */ virtual void compute_delta_nodal_atomic_temperature(double dt); /** update the nodal quantities after pre-corrector step */ virtual void update_nodal_quantities_pre_corrector(double dt); /** update the nodal quantities after post-corrector step */ virtual void update_nodal_quantities_post_corrector(double dt); /** sets up appropriate rhs for thermostat equations */ virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes, double dt); private: // DO NOT define this ThermostatPowerFiltered(); }; //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatPowerVerlet //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatPowerVerlet : public ThermostatGlc { public: ThermostatPowerVerlet(Thermostat * thermostat); ~ThermostatPowerVerlet(){}; /** applies thermostat to atoms in the predictor phase */ virtual void apply_pre_predictor(double dt); /** applies thermostat to atoms in the pre-corrector phase */ virtual void apply_pre_corrector(double dt); /** get data for output */ virtual void output(double dt, OUTPUT_LIST & outputData); protected: /** nodal temperature rate of change */ DENS_MAT & nodalTemperatureRoc_; /** reference to ATC sources coming from prescribed data, AtC coupling, and extrinsic coupling */ DENS_MAT & heatSource_; /** pointer to lammps atomic forces */ double ** f_; /** sets up and solves thermostat equations */ virtual void compute_thermostat(double dt); /** sets up appropriate rhs for thermostat equations */ virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes); /** computes the nodal FE power applied by the thermostat */ virtual void compute_nodal_lambda_power(double dt); /** add contributions (if any) to the finite element right-hand side */ virtual void add_to_rhs(FIELDS & rhs); private: // DO NOT define this ThermostatPowerVerlet(); }; //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatHooverVerlet //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatHooverVerlet : public ThermostatPowerVerlet { public: ThermostatHooverVerlet(Thermostat * thermostat); ~ThermostatHooverVerlet(){}; protected: /** reference to ATC map from global nodes to overlap nodes */ Array & nodeToOverlapMap_; /** sets up and solves thermostat equations */ virtual void compute_thermostat(double dt); /** compute boundary flux, requires thermostat input since it is part of the coupling scheme */ virtual void compute_boundary_flux(FIELDS & fields) {boundaryFlux_[TEMPERATURE] = 0.;}; /** sets up Hoover component of the thermostat */ void set_hoover_rhs(DENS_MAT & rhs_nodes); /** add Hoover contributions to lambda power */ void add_to_lambda_power(DENS_MAT & myLambdaForce, double dt); private: // DO NOT implement this ThermostatHooverVerlet(); }; //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatPowerVerletFiltered //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatPowerVerletFiltered : public ThermostatPowerVerlet { public: ThermostatPowerVerletFiltered(Thermostat * thermostat); ~ThermostatPowerVerletFiltered(){}; /** compute boundary flux, requires thermostat input since it is part of the coupling scheme */ virtual void compute_boundary_flux(FIELDS & fields); /** get data for output */ virtual void output(double dt, OUTPUT_LIST & outputData); protected: /** sets up appropriate rhs for thermostat equations */ virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes); /** add contributions (if any) to the finite element right-hand side */ virtual void add_to_rhs(FIELDS & rhs); /** nodal temperature 2nd rate of change (i.e. second time derivative) */ DENS_MAT & nodalTemperature2Roc_; /** reference to ATC rate of change sources coming from prescribed data, AtC coupling, and extrinsic coupling */ DENS_MAT heatSourceRoc_; /** references to ATC field rates of changing for inverting the filtered heat sources */ FIELDS & fieldsRoc_; /** flux rate of changes for inverting filtered fluxes */ FIELDS fluxRoc_; /** time scale for the time filter */ double filterScale_; private: // DO NOT define this ThermostatPowerVerletFiltered(); }; //-------------------------------------------------------- //-------------------------------------------------------- // Class ThermostatHooverVerletFiltered //-------------------------------------------------------- //-------------------------------------------------------- class ThermostatHooverVerletFiltered : public ThermostatPowerVerletFiltered { public: ThermostatHooverVerletFiltered(Thermostat * thermostat); ~ThermostatHooverVerletFiltered(){}; protected: /** reference to ATC map from global nodes to overlap nodes */ Array & nodeToOverlapMap_; /** sets up and solves thermostat equations */ virtual void compute_thermostat(double dt); /** compute boundary flux, requires thermostat input since it is part of the coupling scheme */ virtual void compute_boundary_flux(FIELDS & fields) {boundaryFlux_[TEMPERATURE] = 0.;}; /** sets up Hoover component of the thermostat */ void set_hoover_rhs(DENS_MAT & rhs_nodes); /** add Hoover contributions to lambda power */ void add_to_lambda_power(DENS_MAT & myLambdaForce, double dt); private: // DO NOT implement this ThermostatHooverVerletFiltered(); }; }; #endif