lammps/lib/atc/ATC_Coupling.h

501 lines
20 KiB
C
Raw Normal View History

#ifndef ATC_COUPLING_H
#define ATC_COUPLING_H
#include <set>
#include <map>
#include <string>
#include <utility>
// ATC headers
#include "ATC_Method.h"
#include "ExtrinsicModel.h"
namespace ATC {
// Forward declarations
class PrescribedDataManager;
class AtomicRegulator;
class TimeIntegrator;
class ReferencePositions;
/**
* @class ATC_Coupling
* @brief Base class for atom-continuum coupling
*/
class ATC_Coupling : public ATC_Method {
public: /** methods */
friend class ExtrinsicModel; // friend is not inherited
friend class ExtrinsicModelTwoTemperature;
friend class ExtrinsicModelDriftDiffusion;
friend class ExtrinsicModelDriftDiffusionConvection;
friend class ExtrinsicModelElectrostatic;
friend class ExtrinsicModelElectrostaticMomentum;
friend class SchrodingerPoissonSolver;
friend class SliceSchrodingerPoissonSolver;
friend class GlobalSliceSchrodingerPoissonSolver;
/** constructor */
ATC_Coupling(std::string groupName, double **& perAtomArray, LAMMPS_NS::Fix * thisFix);
/** destructor */
virtual ~ATC_Coupling();
/** parser/modifier */
virtual bool modify(int narg, char **arg);
/** pre neighbor */
virtual void pre_neighbor();
/** pre exchange */
virtual void pre_exchange();
virtual void reset_atoms(){};
/** pre force */
virtual void pre_force();
/** post force */
virtual void post_force();
/** pre integration run */
virtual void initialize();
/** flags whether a methods reset is required */
virtual bool reset_methods() const;
/** post integration run : called at end of run or simulation */
virtual void finish();
/** first time, before atomic integration */
virtual void pre_init_integrate();
/** Predictor phase, Verlet first step for velocity and position */
virtual void init_integrate();
/** Predictor phase, executed after Verlet */
virtual void post_init_integrate();
/** Corrector phase, executed after Verlet*/
virtual void post_final_integrate();
/** pre/post atomic force calculation in minimize */
virtual void min_pre_force(){};
virtual void min_post_force(){};
// data access
/** get map general atomic shape function matrix to overlap region */
SPAR_MAT &get_atom_to_overlap_mat() {return atomToOverlapMat_.set_quantity();};
/** get map general atomic shape function matrix to overlap region */
SPAR_MAN &atom_to_overlap_mat() {return atomToOverlapMat_;};
/** check if atomic quadrature is being used for MD_ONLY nodes */
bool atom_quadrature_on(){return atomQuadForInternal_;};
const std::set<std::string> & boundary_face_names() {return boundaryFaceNames_;};
/** access to boundary integration method */
int boundary_integration_type() {return bndyIntType_;};
void set_boundary_integration_type(int boundaryIntegrationType)
{bndyIntType_ = boundaryIntegrationType;};
void set_boundary_face_set(const std::set< std::pair<int,int> > * boundaryFaceSet)
{bndyFaceSet_ = boundaryFaceSet;};
BoundaryIntegrationType parse_boundary_integration
(int narg, char **arg, const std::set< std::pair<int,int> > * boundaryFaceSet);
TemperatureDefType temperature_def() const {return temperatureDef_;};
void set_temperature_def(TemperatureDefType tdef) {temperatureDef_ = tdef;};
//--------------------------------------------------------
/** access to all boundary fluxes */
FIELDS &boundary_fluxes() {return boundaryFlux_;};
/** wrapper for FE_Engine's compute_boundary_flux functions */
void compute_boundary_flux(const Array2D<bool> & rhs_mask,
const FIELDS &fields,
FIELDS &rhs,
const Array< std::set <int> > atomMaterialGroups,
const VectorDependencyManager<SPAR_MAT * > * shpFcnDerivs,
const SPAR_MAN * shpFcn = NULL,
const DIAG_MAN * atomicWeights = NULL,
const MatrixDependencyManager<DenseMatrix, bool> * elementMask = NULL,
const SetDependencyManager<int> * nodeSet = NULL);
/** access to full right hand side / forcing vector */
FIELDS &rhs() {return rhs_;};
Array2D <bool> rhs_mask() const {
Array2D <bool> mask(NUM_FIELDS,NUM_FLUX);
mask = false;
return mask;
}
DENS_MAN &field_rhs(FieldName thisField) { return rhs_[thisField]; };
/** allow FE_Engine to construct ATC structures after mesh is constructed */
virtual void initialize_mesh_data(void);
// public for FieldIntegrator
bool source_atomic_quadrature(FieldName field)
{ return (sourceIntegration_ == FULL_DOMAIN_ATOMIC_QUADRATURE_SOURCE); }
ATC::IntegrationDomainType source_integration()
{ return sourceIntegration_; }
/** wrapper for FE_Engine's compute_sources */
void compute_sources_at_atoms(const RHS_MASK & rhsMask,
const FIELDS & fields,
const PhysicsModel * physicsModel,
FIELD_MATS & atomicSources);
/** computes tangent matrix using atomic quadrature near FE region */
void masked_atom_domain_rhs_tangent(const std::pair<FieldName,FieldName> row_col,
const RHS_MASK & rhsMask,
const FIELDS & fields,
SPAR_MAT & stiffness,
const PhysicsModel * physicsModel);
/** wrapper for FE_Engine's compute_rhs_vector functions */
void compute_rhs_vector(const RHS_MASK & rhs_mask,
const FIELDS &fields,
FIELDS &rhs,
const IntegrationDomainType domain, // = FULL_DOMAIN
const PhysicsModel * physicsModel=NULL);
/** wrapper for FE_Engine's compute_tangent_matrix */
void compute_rhs_tangent(const std::pair<FieldName,FieldName> row_col,
const RHS_MASK & rhsMask,
const FIELDS & fields,
SPAR_MAT & stiffness,
const IntegrationDomainType integrationType,
const PhysicsModel * physicsModel=NULL);
void tangent_matrix(const std::pair<FieldName,FieldName> row_col,
const RHS_MASK & rhsMask,
const PhysicsModel * physicsModel,
SPAR_MAT & stiffness);
/** PDE type */
WeakEquation::PDE_Type pde_type(const FieldName fieldName) const;
/** is dynamic PDE */
bool is_dynamic(const FieldName fieldName) const;
// public for ImplicitSolveOperator
/** return pointer to PrescribedDataManager */
PrescribedDataManager * prescribed_data_manager()
{ return prescribedDataMgr_; }
// public for Kinetostat
// TODO rename to "mass_matrix"
DIAG_MAT &get_mass_mat(FieldName thisField)
{ return massMats_[thisField].set_quantity();};
/** access to underlying mass matrices */
MATRIX * mass_matrix(FieldName thisField)
{
if (!useConsistentMassMatrix_(thisField)) {
return & massMats_[thisField].set_quantity();
}
else {
return & consistentMassMats_[thisField].set_quantity();
}
}
/** const access to underlying mass matrices */
const MATRIX * mass_matrix(FieldName thisField) const
{
if (!useConsistentMassMatrix_(thisField)) {
MASS_MATS::const_iterator it = massMats_.find(thisField);
if (it != massMats_.end()) {
return & (it->second).quantity();
}
else {
return NULL;
}
}
else {
CON_MASS_MATS::const_iterator it = consistentMassMats_.find(thisField);
if (it != consistentMassMats_.end()) {
return & (it->second).quantity();
}
else {
return NULL;
}
}
}
/** */
DENS_MAN &atomic_source(FieldName thisField){return atomicSources_[thisField];};
//---------------------------------------------------------------
/** \name materials */
//---------------------------------------------------------------
/*@{*/
/** access to element to material map */
Array<int> &element_to_material_map(void){return elementToMaterialMap_;}
/*@}*/
/** check if method is tracking charge */
bool track_charge() {return trackCharge_;};
void set_mass_mat_time_filter(FieldName thisField,TimeFilterManager::FilterIntegrationType filterIntegrationType);
/** return referece to ExtrinsicModelManager */
ExtrinsicModelManager & extrinsic_model_manager()
{ return extrinsicModelManager_; }
/** access to time integrator */
const TimeIntegrator * time_integrator(const FieldName & field) const {
_ctiIt_ = timeIntegrators_.find(field);
if (_ctiIt_ == timeIntegrators_.end()) return NULL;
return _ctiIt_->second;
};
//---------------------------------------------------------------
/** \name managers */
//---------------------------------------------------------------
/*@{*/
/** allow FE_Engine to construct data manager after mesh is constructed */
void construct_prescribed_data_manager (void);
/** method to create physics model */
void create_physics_model(const PhysicsType & physicsType,
std::string matFileName);
/** access to physics model */
PhysicsModel * physics_model() {return physicsModel_; };
/*@}*/
//---------------------------------------------------------------
/** \name creation */
//---------------------------------------------------------------
/*@{*/
/** set up atom to material identification */
virtual void reset_atom_materials();
/** */
void reset_node_mask();
/** */
void reset_overlap_map();
/*@}*/
//---------------------------------------------------------------
/** \name output/restart */
//---------------------------------------------------------------
/*@{*/
void pack_fields(RESTART_LIST & data);
virtual void read_restart_data(std::string fileName_, RESTART_LIST & data);
virtual void write_restart_data(std::string fileName_, RESTART_LIST & data);
void output() { ATC_Method::output(); }
/*@}*/
//---------------------------------------------------------------
/** \name initial & boundary conditions */
//---------------------------------------------------------------
/*@{*/
/** mask for computation of fluxes */
void set_fixed_nodes();
/** set initial conditions by changing fields */
void set_initial_conditions();
/*@}*/
//---------------------------------------------------------------
/** \name sources */
//---------------------------------------------------------------
/** calculate and set matrix of sources_ */
void set_sources();
/** assemble various contributions to the heat flux in the atomic region */
void compute_atomic_sources(const Array2D<bool> & rhs_mask,
const FIELDS &fields,
FIELDS &atomicSources);
DENS_MAT &get_source(FieldName thisField){return sources_[thisField].set_quantity();};
DENS_MAN &source(FieldName thisField){return sources_[thisField];};
FIELDS & sources(){return sources_;};
/** access to name atomic source terms */
DENS_MAT &get_atomic_source(FieldName thisField){return atomicSources_[thisField].set_quantity();};
/** access to name extrinsic source terms */
DENS_MAT &get_extrinsic_source(FieldName thisField){return extrinsicSources_[thisField].set_quantity();};
DENS_MAN &extrinsic_source(FieldName thisField){return extrinsicSources_[thisField];};
/** nodal projection of a field through the physics model */
void nodal_projection(const FieldName & fieldName,
const PhysicsModel * physicsModel,
FIELD & field);
/*@}*/
//---------------------------------------------------------------
/** \name fluxes */
//---------------------------------------------------------------
/*@{*/
/** access for field mask */
Array2D<bool> &field_mask() {return fieldMask_;};
/** create field mask */
void reset_flux_mask();
/** field mask for intrinsic integration */
Array2D<bool> intrinsicMask_;
/** wrapper for FE_Engine's compute_flux functions */
void compute_flux(const Array2D<bool> & rhs_mask,
const FIELDS &fields,
GRAD_FIELD_MATS &flux,
const PhysicsModel * physicsModel=NULL,
const bool normalize = false);
/** evaluate rhs on the atomic domain which is near the FE region */
void masked_atom_domain_rhs_integral(const Array2D<bool> & rhs_mask,
const FIELDS &fields,
FIELDS &rhs,
const PhysicsModel * physicsModel);
/** evaluate rhs on a specified domain defined by mask and physics model */
void evaluate_rhs_integral(const Array2D<bool> & rhs_mask,
const FIELDS &fields,
FIELDS &rhs,
const IntegrationDomainType domain,
const PhysicsModel * physicsModel=NULL);
/** access to boundary fluxes */
DENS_MAT &get_boundary_flux(FieldName thisField){return boundaryFlux_[thisField].set_quantity();};
DENS_MAN &boundary_flux(FieldName thisField){return boundaryFlux_[thisField];};
/** access to finite element right-hand side data */
DENS_MAT &get_field_rhs(FieldName thisField)
{ return rhs_[thisField].set_quantity(); };
/*@}*/
//---------------------------------------------------------------
/** \name mass matrices */
//---------------------------------------------------------------
/*@{*/
// atomic field time derivative filtering
virtual void init_filter(void);
// mass matrix filtering
void delete_mass_mat_time_filter(FieldName thisField);
/** compute mass matrix for requested field */
void compute_mass_matrix(FieldName thisField, PhysicsModel * physicsModel = NULL);
/** updates filtering of MD contributions */
void update_mass_matrix(FieldName thisField);
/** compute the mass matrix components coming from MD integration */
virtual void compute_md_mass_matrix(FieldName thisField,
DIAG_MAT & massMats);
private: /** methods */
ATC_Coupling(); // do not define
protected: /** data */
//---------------------------------------------------------------
/** initialization routines */
//---------------------------------------------------------------
/** sets up all data necessary to define the computational geometry */
virtual void set_computational_geometry();
/** constructs all data which is updated with time integration, i.e. fields */
virtual void construct_time_integration_data();
/** create methods, e.g. time integrators, filters */
virtual void construct_methods();
/** set up data which is dependency managed */
virtual void construct_transfers();
/** sets up mol transfers */
virtual void construct_molecule_transfers();
/** sets up accumulant & interpolant */
virtual void construct_interpolant();
/** reset number of local atoms */
virtual void reset_nlocal();
//---------------------------------------------------------------
/** status */
//---------------------------------------------------------------
/*@{*/
/** flag on if FE nodes in MD region should be initialized to projected MD values */
bool consistentInitialization_;
bool equilibriumStart_;
bool useFeMdMassMatrix_;
/** flag to determine if charge is tracked */
bool trackCharge_;
/** temperature definition model */
TemperatureDefType temperatureDef_;
/*@}*/
//---------------------------------------------------------------
/** \name managers */
//---------------------------------------------------------------
/*@{*/
/** prescribed data handler */
PrescribedDataManager * prescribedDataMgr_;
/** pointer to physics model */
PhysicsModel * physicsModel_;
/** manager for extrinsic models */
ExtrinsicModelManager extrinsicModelManager_;
/** manager for regulator */
AtomicRegulator * atomicRegulator_;
/** managers for time integrators per field */
std::map<FieldName,TimeIntegrator * > timeIntegrators_;
/** time integrator iterator */
mutable std::map<FieldName,TimeIntegrator * >::iterator _tiIt_;
/** time integrator const iterator */
mutable std::map<FieldName,TimeIntegrator * >::const_iterator _ctiIt_;
/*@}*/
//---------------------------------------------------------------
/** materials */
//---------------------------------------------------------------
/*@{*/
Array<int> elementToMaterialMap_; // ATOMIC_TAG * elementToMaterialMap_;
/** atomic ATC material tag */
Array< std::set <int> > atomMaterialGroups_; // ATOMIC_TAG*atomMaterialGroups_;
Array< std::set <int> > atomMaterialGroupsMask_; // ATOMIC_TAG*atomMaterialGroupsMask_;
/*@}*/
//---------------------------------------------------------------
/** computational geometry */
//---------------------------------------------------------------
/*@{*/
bool atomQuadForInternal_;
MatrixDependencyManager<DenseMatrix, bool> * elementMask_;
MatrixDependencyManager<DenseMatrix, bool> * elementMaskMass_;
MatrixDependencyManager<DenseMatrix, bool> * elementMaskMassMd_;
/** operator to compute the mass matrix for the momentum equation from MD integration */
AtfShapeFunctionRestriction * nodalAtomicMass_;
/** operator to compute the dimensionless mass matrix from MD integration */
AtfShapeFunctionRestriction * nodalAtomicCount_;
/** operator to compute mass matrix from MD */
AtfShapeFunctionRestriction * nodalAtomicHeatCapacity_;
MatrixDependencyManager<DenseMatrix, bool> * create_full_element_mask();
MatrixDependencyManager<DenseMatrix, int> * create_element_set_mask(const std::string & elementSetName);
LargeToSmallAtomMap * internalToMask_;
MatrixDependencyManager<DenseMatrix, int> * internalElement_;
MatrixDependencyManager<DenseMatrix, int> * ghostElement_;
DenseMatrixTransfer<int> * nodalGeometryType_;
/*@}*/
/** \name boundary integration */
/*@{*/
/** boundary flux quadrature */
int bndyIntType_;
const std::set< std::pair<int,int> > * bndyFaceSet_;
std::set<std::string> boundaryFaceNames_;
/*@}*/
//----------------------------------------------------------------
/** \name shape function matrices */
//----------------------------------------------------------------
/*@{*/
DIAG_MAN * atomicWeightsMask_;
SPAR_MAN * shpFcnMask_;
VectorDependencyManager<SPAR_MAT * > * shpFcnDerivsMask_;
Array<bool> atomMask_;
SPAR_MAN atomToOverlapMat_;
DIAG_MAN nodalMaskMat_;
/*@}*/
//---------------------------------------------------------------
/** \name PDE data */
//---------------------------------------------------------------
/*@{*/
/** mask for computation of fluxes */
Array2D<bool> fieldMask_;
DIAG_MAT fluxMask_;
DIAG_MAT fluxMaskComplement_;
/** sources */
FIELDS sources_;
FIELDS atomicSources_;
FIELDS extrinsicSources_;
ATC::IntegrationDomainType sourceIntegration_;
SPAR_MAT stiffnessAtomDomain_;
/** rhs/forcing terms */
FIELDS rhs_; // for pde
FIELDS rhsAtomDomain_; // for thermostat
FIELDS boundaryFlux_; // for thermostat & rhs pde
// DATA structures for tracking individual species and molecules
FIELD_POINTERS atomicFields_;
/*@}*/
// workspace variables
mutable DENS_MAT _deltaQuantity_;
};
};
#endif