lammps/lib/atc/KinetoThermostat.cpp

437 lines
17 KiB
C++

#include "KinetoThermostat.h"
#include "ATC_Coupling.h"
#include "ATC_Error.h"
#include "PrescribedDataManager.h"
#include "ElasticTimeIntegrator.h"
#include "ThermalTimeIntegrator.h"
#include "TransferOperator.h"
using namespace std;
namespace ATC {
//--------------------------------------------------------
//--------------------------------------------------------
// Class KinetoThermostat
//--------------------------------------------------------
//--------------------------------------------------------
//--------------------------------------------------------
// Constructor
//--------------------------------------------------------
KinetoThermostat::KinetoThermostat(ATC_Coupling * atc,
const string & regulatorPrefix) :
AtomicRegulator(atc,regulatorPrefix),
kinetostat_(atc,"Momentum"),
thermostat_(atc,"Energy")
{
// nothing to do
}
//--------------------------------------------------------
// modify:
// parses and adjusts thermostat state based on
// user input, in the style of LAMMPS user input
//--------------------------------------------------------
bool KinetoThermostat::modify(int narg, char **arg)
{
bool foundMatch = false;
return foundMatch;
}
//--------------------------------------------------------
// reset_lambda_contribution:
// resets the thermostat generated power to a
// prescribed value
//--------------------------------------------------------
void KinetoThermostat::reset_lambda_contribution(const DENS_MAT & target,
const FieldName field)
{
//TEMP_JAT
if (field==VELOCITY) {
kinetostat_.reset_lambda_contribution(target);
}
else if (field == TEMPERATURE) {
thermostat_.reset_lambda_contribution(target);
}
else {
throw ATC_Error("KinetoThermostat::reset_lambda_contribution - invalid field given");
}
}
//--------------------------------------------------------
// construct_methods:
// instantiations desired regulator method(s)
// dependence, but in general there is also a
// time integrator dependence. In general the
// precedence order is:
// time filter -> time integrator -> thermostat
// In the future this may need to be added if
// different types of time integrators can be
// specified.
//--------------------------------------------------------
void KinetoThermostat::construct_methods()
{
// #ifdef WIP_JAT
// // get data associated with stages 1 & 2 of ATC_Method::initialize
// AtomicRegulator::construct_methods();
// if (atc_->reset_methods()) {
// // eliminate existing methods
// delete_method();
// // update time filter
// TimeIntegrator::TimeIntegrationType myIntegrationType = (atc_->time_integrator(TEMPERATURE))->time_integration_type();
// TimeFilterManager * timeFilterManager = atc_->time_filter_manager();
// if (timeFilterManager->need_reset() ) {
// if (myIntegrationType == TimeIntegrator::GEAR)
// timeFilter_ = timeFilterManager->construct(TimeFilterManager::EXPLICIT);
// else if (myIntegrationType == TimeIntegrator::FRACTIONAL_STEP)
// timeFilter_ = timeFilterManager->construct(TimeFilterManager::EXPLICIT_IMPLICIT);
// }
// if (timeFilterManager->filter_dynamics()) {
// switch (regulatorTarget_) {
// case NONE: {
// regulatorMethod_ = new RegulatorMethod(this);
// break;
// }
// case FIELD: { // error check, rescale and filtering not supported together
// throw ATC_Error("Cannot use rescaling thermostat with time filtering");
// break;
// }
// case DYNAMICS: {
// switch (couplingMode_) {
// case FIXED: {
// if (use_lumped_lambda_solve()) {
// throw ATC_Error("Thermostat:construct_methods - lumped lambda solve cannot be used with Hoover thermostats");
// }
// if (myIntegrationType == TimeIntegrator::FRACTIONAL_STEP) {
// if (md_flux_nodes(TEMPERATURE)) {
// if (!md_fixed_nodes(TEMPERATURE) && (boundaryIntegrationType_ == NO_QUADRATURE)) {
// // there are fluxes but no fixed or coupled nodes
// regulatorMethod_ = new ThermostatFluxFiltered(this);
// }
// else {
// // there are both fixed and flux nodes
// regulatorMethod_ = new ThermostatFluxFixedFiltered(this);
// }
// }
// else {
// // there are only fixed nodes
// regulatorMethod_ = new ThermostatFixedFiltered(this);
// }
// }
// else {
// regulatorMethod_ = new ThermostatHooverVerletFiltered(this);
// }
// break;
// }
// case FLUX: {
// if (myIntegrationType == TimeIntegrator::FRACTIONAL_STEP) {
// if (use_lumped_lambda_solve()) {
// throw ATC_Error("Thermostat:construct_methods - lumped lambda solve has been depricated for fractional step thermostats");
// }
// if (md_fixed_nodes(TEMPERATURE)) {
// if (!md_flux_nodes(TEMPERATURE) && (boundaryIntegrationType_ == NO_QUADRATURE)) {
// // there are fixed nodes but no fluxes
// regulatorMethod_ = new ThermostatFixedFiltered(this);
// }
// else {
// // there are both fixed and flux nodes
// regulatorMethod_ = new ThermostatFluxFixedFiltered(this);
// }
// }
// else {
// // there are only flux nodes
// regulatorMethod_ = new ThermostatFluxFiltered(this);
// }
// }
// else {
// if (use_localized_lambda()) {
// if (!((atc_->prescribed_data_manager())->no_fluxes(TEMPERATURE)) &&
// atc_->boundary_integration_type() != NO_QUADRATURE) {
// throw ATC_Error("Cannot use flux coupling with localized lambda");
// }
// }
// regulatorMethod_ = new ThermostatPowerVerletFiltered(this);
// }
// break;
// }
// default:
// throw ATC_Error("Unknown coupling mode in Thermostat::initialize");
// }
// break;
// }
// default:
// throw ATC_Error("Unknown thermostat type in Thermostat::initialize");
// }
// }
// else {
// switch (regulatorTarget_) {
// case NONE: {
// regulatorMethod_ = new RegulatorMethod(this);
// break;
// }
// case FIELD: {
// if (atc_->temperature_def()==KINETIC)
// regulatorMethod_ = new ThermostatRescale(this);
// else if (atc_->temperature_def()==TOTAL)
// regulatorMethod_ = new ThermostatRescaleMixedKePe(this);
// else
// throw ATC_Error("Unknown temperature definition");
// break;
// }
// case DYNAMICS: {
// switch (couplingMode_) {
// case FIXED: {
// if (use_lumped_lambda_solve()) {
// throw ATC_Error("Thermostat:construct_methods - lumped lambda solve cannot be used with Hoover thermostats");
// }
// if (myIntegrationType == TimeIntegrator::FRACTIONAL_STEP) {
// if (md_flux_nodes(TEMPERATURE)) {
// if (!md_fixed_nodes(TEMPERATURE) && (boundaryIntegrationType_ == NO_QUADRATURE)) {
// // there are fluxes but no fixed or coupled nodes
// regulatorMethod_ = new ThermostatFlux(this);
// }
// else {
// // there are both fixed and flux nodes
// regulatorMethod_ = new ThermostatFluxFixed(this);
// }
// }
// else {
// // there are only fixed nodes
// regulatorMethod_ = new ThermostatFixed(this);
// }
// }
// else {
// regulatorMethod_ = new ThermostatHooverVerlet(this);
// }
// break;
// }
// case FLUX: {
// if (myIntegrationType == TimeIntegrator::FRACTIONAL_STEP) {
// if (use_lumped_lambda_solve()) {
// throw ATC_Error("Thermostat:construct_methods - lumped lambda solve has been depricated for fractional step thermostats");
// }
// if (md_fixed_nodes(TEMPERATURE)) {
// if (!md_flux_nodes(TEMPERATURE) && (boundaryIntegrationType_ == NO_QUADRATURE)) {
// // there are fixed nodes but no fluxes
// regulatorMethod_ = new ThermostatFixed(this);
// }
// else {
// // there are both fixed and flux nodes
// regulatorMethod_ = new ThermostatFluxFixed(this);
// }
// }
// else {
// // there are only flux nodes
// regulatorMethod_ = new ThermostatFlux(this);
// }
// }
// else {
// if (use_localized_lambda()) {
// if (!((atc_->prescribed_data_manager())->no_fluxes(TEMPERATURE)) &&
// atc_->boundary_integration_type() != NO_QUADRATURE) {
// throw ATC_Error("Cannot use flux coupling with localized lambda");
// }
// }
// regulatorMethod_ = new ThermostatPowerVerlet(this);
// }
// break;
// }
// default:
// throw ATC_Error("Unknown coupling mode in Thermostat::initialize");
// }
// break;
// }
// default:
// throw ATC_Error("Unknown thermostat target in Thermostat::initialize");
// }
// }
// AtomicRegulator::reset_method();
// }
// else {
// set_all_data_to_used();
// }
// #endif
//TEMP_JAT
kinetostat_.construct_methods();
thermostat_.construct_methods();
}
//TEMP_JAT all functions which have explicit thermo and kinetostats need to be removed
//--------------------------------------------------------
// reset_nlocal:
// resizes lambda force if necessary
//--------------------------------------------------------
void KinetoThermostat::reset_nlocal()
{
kinetostat_.reset_nlocal();
thermostat_.reset_nlocal();
}
//--------------------------------------------------------
// reset_atom_materials:
// resets the localized atom to material map
//--------------------------------------------------------
void KinetoThermostat::reset_atom_materials(const Array<int> & elementToMaterialMap,
const MatrixDependencyManager<DenseMatrix, int> * atomElement)
{
kinetostat_.reset_atom_materials(elementToMaterialMap,
atomElement);
thermostat_.reset_atom_materials(elementToMaterialMap,
atomElement);
}
//--------------------------------------------------------
// construct_transfers:
// pass through to appropriate transfer constuctors
//--------------------------------------------------------
void KinetoThermostat::construct_transfers()
{
kinetostat_.construct_transfers();
thermostat_.construct_transfers();
}
//--------------------------------------------------------
// initialize:
// sets up methods before a run
//--------------------------------------------------------
void KinetoThermostat::initialize()
{
kinetostat_.initialize();
thermostat_.initialize();
needReset_ = false;
}
//--------------------------------------------------------
// output:
// pass through to appropriate output methods
//--------------------------------------------------------
void KinetoThermostat::output(OUTPUT_LIST & outputData) const
{
kinetostat_.output(outputData);
thermostat_.output(outputData);
}
//--------------------------------------------------------
// finish:
// pass through to appropriate end-of-run methods
//--------------------------------------------------------
void KinetoThermostat::finish()
{
kinetostat_.finish();
thermostat_.finish();
}
//--------------------------------------------------
// pack_fields
// bundle all allocated field matrices into a list
// for output needs
//--------------------------------------------------
void KinetoThermostat::pack_fields(RESTART_LIST & data)
{
kinetostat_.pack_fields(data);
thermostat_.pack_fields(data);
}
//--------------------------------------------------------
// compute_boundary_flux:
// computes the boundary flux to be consistent with
// the controller
//--------------------------------------------------------
void KinetoThermostat::compute_boundary_flux(FIELDS & fields)
{
kinetostat_.compute_boundary_flux(fields);
thermostat_.compute_boundary_flux(fields);
}
//--------------------------------------------------------
// add_to_rhs:
// adds any controller contributions to the FE rhs
//--------------------------------------------------------
void KinetoThermostat::add_to_rhs(FIELDS & rhs)
{
thermostat_.add_to_rhs(rhs);
kinetostat_.add_to_rhs(rhs);
}
//--------------------------------------------------------
// apply_pre_predictor:
// applies the controller in the pre-predictor
// phase of the time integrator
//--------------------------------------------------------
void KinetoThermostat::apply_pre_predictor(double dt, int timeStep)
{
thermostat_.apply_pre_predictor(dt,timeStep);
kinetostat_.apply_pre_predictor(dt,timeStep);
}
//--------------------------------------------------------
// apply_mid_predictor:
// applies the controller in the mid-predictor
// phase of the time integrator
//--------------------------------------------------------
void KinetoThermostat::apply_mid_predictor(double dt, int timeStep)
{
thermostat_.apply_mid_predictor(dt,timeStep);
kinetostat_.apply_mid_predictor(dt,timeStep);
}
//--------------------------------------------------------
// apply_post_predictor:
// applies the controller in the post-predictor
// phase of the time integrator
//--------------------------------------------------------
void KinetoThermostat::apply_post_predictor(double dt, int timeStep)
{
thermostat_.apply_post_predictor(dt,timeStep);
kinetostat_.apply_post_predictor(dt,timeStep);
}
//--------------------------------------------------------
// apply_pre_corrector:
// applies the controller in the pre-corrector phase
// of the time integrator
//--------------------------------------------------------
void KinetoThermostat::apply_pre_corrector(double dt, int timeStep)
{
thermostat_.apply_pre_corrector(dt,timeStep);
kinetostat_.apply_pre_corrector(dt,timeStep);
}
//--------------------------------------------------------
// apply_post_corrector:
// applies the controller in the post-corrector phase
// of the time integrator
//--------------------------------------------------------
void KinetoThermostat::apply_post_corrector(double dt, int timeStep)
{
thermostat_.apply_post_corrector(dt,timeStep);
kinetostat_.apply_post_corrector(dt,timeStep);
}
//--------------------------------------------------------
// pre_exchange
//--------------------------------------------------------
void KinetoThermostat::pre_exchange()
{
thermostat_.pre_exchange();
kinetostat_.pre_exchange();
}
//--------------------------------------------------------
// pre_force
//--------------------------------------------------------
void KinetoThermostat::pre_force()
{
thermostat_.pre_force();
kinetostat_.pre_force();
}
//--------------------------------------------------------
// coupling_mode
//-------------------------------------------------------
AtomicRegulator::RegulatorCouplingType KinetoThermostat::coupling_mode(const FieldName field) const
{
//TEMP_JAT
if (field==VELOCITY) {
return kinetostat_.coupling_mode();
}
else if (field == TEMPERATURE) {
return thermostat_.coupling_mode();
}
else {
throw ATC_Error("KinetoThermostat::coupling_mode - invalid field given");
}
}
};