forked from lijiext/lammps
545 lines
19 KiB
C++
545 lines
19 KiB
C++
|
// ATC_Transfer headers
|
||
|
#include "ATC_CouplingMass.h"
|
||
|
#include "ATC_Error.h"
|
||
|
#include "FE_Engine.h"
|
||
|
#include "SpeciesTimeIntegrator.h"
|
||
|
#include "PrescribedDataManager.h"
|
||
|
#include "ExtrinsicModelElectrostatic.h"
|
||
|
#include "PoissonSolver.h"
|
||
|
#include "ChargeRegulator.h"
|
||
|
#include "ConcentrationRegulator.h"
|
||
|
#include "PerAtomQuantityLibrary.h"
|
||
|
#include "TransferOperator.h"
|
||
|
#include "AtomToMoleculeTransfer.h"
|
||
|
#include "MoleculeSet.h"
|
||
|
#include "FieldManager.h"
|
||
|
|
||
|
// Other Headers
|
||
|
#include <vector>
|
||
|
#include <map>
|
||
|
#include <set>
|
||
|
#include <utility>
|
||
|
|
||
|
namespace ATC {
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
//--------------------------------------------------------
|
||
|
// Class ATC_CouplingMass
|
||
|
//--------------------------------------------------------
|
||
|
//--------------------------------------------------------
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// Constructor
|
||
|
//--------------------------------------------------------
|
||
|
ATC_CouplingMass::ATC_CouplingMass(string groupName,
|
||
|
double **& perAtomArray,
|
||
|
LAMMPS_NS::Fix * thisFix,
|
||
|
string matParamFile,
|
||
|
ExtrinsicModelType extrinsicModel)
|
||
|
: ATC_Coupling(groupName,perAtomArray,thisFix),
|
||
|
resetNlocal_(false)
|
||
|
{
|
||
|
// Allocate PhysicsModel
|
||
|
create_physics_model(SPECIES, matParamFile);
|
||
|
|
||
|
// create extrinsic physics model
|
||
|
if (extrinsicModel != NO_MODEL) {
|
||
|
extrinsicModelManager_.create_model(extrinsicModel,matParamFile);
|
||
|
}
|
||
|
|
||
|
// Defaults
|
||
|
set_time();
|
||
|
bndyIntType_ = NO_QUADRATURE;
|
||
|
|
||
|
|
||
|
// set up field data based on physicsModel
|
||
|
physicsModel_->num_fields(fieldSizes_,fieldMask_);
|
||
|
|
||
|
// regulator
|
||
|
atomicRegulator_ = new ConcentrationRegulator(this);
|
||
|
|
||
|
// set up physics specific time integrator
|
||
|
//WIP_JAT should be species concentration
|
||
|
timeIntegrators_[MASS_DENSITY] = new SpeciesTimeIntegrator(this,TimeIntegrator::FRACTIONAL_STEP);
|
||
|
|
||
|
// output variable vector info:
|
||
|
// output[1] = system mass density
|
||
|
vectorFlag_ = 1;
|
||
|
sizeVector_ = 0;
|
||
|
scalarVectorFreq_ = 1;
|
||
|
extVector_ = 1;
|
||
|
if (extrinsicModel != NO_MODEL)
|
||
|
sizeVector_ += extrinsicModelManager_.size_vector(sizeVector_);
|
||
|
sizeVector_ += atomicRegulator_->size_vector(sizeVector_);
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// Destructor
|
||
|
//--------------------------------------------------------
|
||
|
ATC_CouplingMass::~ATC_CouplingMass()
|
||
|
{
|
||
|
interscaleManager_.clear();
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// modify
|
||
|
// parses inputs and modifies state
|
||
|
//--------------------------------------------------------
|
||
|
bool ATC_CouplingMass::modify(int narg, char **arg)
|
||
|
{
|
||
|
bool match = false;
|
||
|
// check to see if it is a transfer class command
|
||
|
|
||
|
// check derived class before base class
|
||
|
int argIndex = 0;
|
||
|
// pass-through to concentration regulator
|
||
|
if (strcmp(arg[argIndex],"control")==0) {
|
||
|
argIndex++;
|
||
|
if (strcmp(arg[argIndex],"concentration")==0) {
|
||
|
argIndex++;
|
||
|
match = atomicRegulator_->modify(narg-argIndex,&arg[argIndex]);
|
||
|
}
|
||
|
}
|
||
|
// no match, call base class parser
|
||
|
if (!match) {
|
||
|
match = ATC_Coupling::modify(narg, arg);
|
||
|
}
|
||
|
return match;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// initialize
|
||
|
// sets up all the necessary data
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::initialize()
|
||
|
{
|
||
|
|
||
|
fieldSizes_[SPECIES_CONCENTRATION] = speciesIds_.size();
|
||
|
|
||
|
// Base class initalizations
|
||
|
ATC_Coupling::initialize();
|
||
|
|
||
|
// check that only all atoms
|
||
|
|
||
|
if (bndyIntType_ != NO_QUADRATURE) throw ATC_Error("ATC_CouplingMass: only all atoms simulations are supported");
|
||
|
|
||
|
// set consistent initial conditions, if requested
|
||
|
if (!timeFilterManager_.filter_dynamics()) {
|
||
|
if (consistentInitialization_) {
|
||
|
|
||
|
DENS_MAT & massDensity(fields_[MASS_DENSITY].set_quantity());
|
||
|
const DENS_MAT & atomicMassDensity(nodalAtomicFields_[MASS_DENSITY].quantity());
|
||
|
|
||
|
DENS_MAT & speciesConcentration(fields_[SPECIES_CONCENTRATION].set_quantity());
|
||
|
//const DENS_MAT & atomicSpeciesConcentration(nodalAtomicFields_[SPECIES_CONCENTRATION].quantity());
|
||
|
const DENS_MAT & atomicSpeciesConcentration(atomicFields_[SPECIES_CONCENTRATION]->quantity());
|
||
|
|
||
|
const INT_ARRAY & nodeType(nodalGeometryType_->quantity());
|
||
|
for (int i = 0; i<nNodes_; ++i) {
|
||
|
|
||
|
if (nodeType(i,0)==MD_ONLY) {
|
||
|
massDensity(i,0) = atomicMassDensity(i,0);
|
||
|
for (int j = 0; j < atomicSpeciesConcentration.nCols(); ++j) {
|
||
|
speciesConcentration(i,j) = atomicSpeciesConcentration(i,j);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// other initializatifields_[SPECIES_CONCENTRATION].quantity()ons
|
||
|
if (reset_methods()) {
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->initialize();
|
||
|
}
|
||
|
}
|
||
|
extrinsicModelManager_.initialize(); // always needed to construct new Poisson solver
|
||
|
if (timeFilterManager_.need_reset()) { init_filter(); }
|
||
|
timeFilterManager_.initialize(); // clears need for reset
|
||
|
atomicRegulator_->initialize();
|
||
|
|
||
|
if (!initialized_) {
|
||
|
// initialize sources based on initial FE temperature
|
||
|
double dt = lammpsInterface_->dt();
|
||
|
// set sources
|
||
|
|
||
|
prescribedDataMgr_->set_sources(time()+0.5*dt,sources_);
|
||
|
extrinsicModelManager_.set_sources(fields_,extrinsicSources_);
|
||
|
compute_atomic_sources(fieldMask_,fields_,atomicSources_);
|
||
|
|
||
|
// read in field data if necessary
|
||
|
if (useRestart_) {
|
||
|
RESTART_LIST data;
|
||
|
read_restart_data(restartFileName_,data);
|
||
|
useRestart_ = false;
|
||
|
}
|
||
|
|
||
|
initialized_ = true;
|
||
|
}
|
||
|
|
||
|
// reset integration field mask
|
||
|
speciesMask_.reset(NUM_FIELDS,NUM_FLUX);
|
||
|
speciesMask_ = false;
|
||
|
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// construct_methods
|
||
|
// have managers instantiate requested algorithms
|
||
|
// and methods
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::construct_methods()
|
||
|
{
|
||
|
ATC_Coupling::construct_methods();
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->construct_methods();
|
||
|
}
|
||
|
atomicRegulator_->construct_methods();
|
||
|
}
|
||
|
|
||
|
void ATC_CouplingMass::construct_transfers()
|
||
|
{
|
||
|
ATC_Coupling::construct_transfers();
|
||
|
FieldManager fmgr(this);
|
||
|
atomicFields_[MASS_DENSITY] = fmgr.nodal_atomic_field(MASS_DENSITY, field_to_intrinsic_name(MASS_DENSITY));
|
||
|
|
||
|
if (has_tracked_species()) {
|
||
|
atomicFields_[SPECIES_CONCENTRATION] = fmgr.nodal_atomic_field(SPECIES_CONCENTRATION, field_to_intrinsic_name(SPECIES_CONCENTRATION));
|
||
|
|
||
|
//if (atomicRegulator_->needs_temperature()) {
|
||
|
|
||
|
atomicFields_[TEMPERATURE] = fmgr.nodal_atomic_field(KINETIC_TEMPERATURE, field_to_intrinsic_name(TEMPERATURE));
|
||
|
//atomicFields_[TEMPERATURE] = fmgr.nodal_atomic_field(TEMPERATURE, field_to_intrinsic_name(TEMPERATURE));
|
||
|
field(TEMPERATURE) = atomicFields_[TEMPERATURE]->quantity();
|
||
|
//}
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
throw ATC_Error("ATC_CouplingMass: no tracked species");
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
// add molecule mass density transfer operators
|
||
|
//==========================================================================
|
||
|
map<string,pair<MolSize,int> >::const_iterator molecule;
|
||
|
FundamentalAtomQuantity * mass = interscaleManager_.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
||
|
PROC_GHOST);
|
||
|
|
||
|
for (molecule = moleculeIds_.begin(); molecule != moleculeIds_.end(); molecule++) {
|
||
|
const string moleculeName = molecule->first;
|
||
|
SmallMoleculeSet * smallMoleculeSet = interscaleManager_.small_molecule_set(moleculeName);
|
||
|
SPAR_MAN * shpFcnMol = interscaleManager_.sparse_matrix("ShapeFunction"+moleculeName);
|
||
|
AtomToSmallMoleculeTransfer<double> * moleculeMass =
|
||
|
new AtomToSmallMoleculeTransfer<double>(this,mass,smallMoleculeSet);
|
||
|
interscaleManager_.add_dense_matrix(moleculeMass,"MoleculeMass"+moleculeName);
|
||
|
MotfShapeFunctionRestriction * nodalAtomicMoleculeMass =
|
||
|
new MotfShapeFunctionRestriction(moleculeMass,shpFcnMol);
|
||
|
interscaleManager_.add_dense_matrix(nodalAtomicMoleculeMass,"NodalMoleculeMass"+moleculeName);
|
||
|
|
||
|
|
||
|
AtfShapeFunctionMdProjection * nodalAtomicMoleculeMassDensity =
|
||
|
new AtfShapeFunctionMdProjection(this,nodalAtomicMoleculeMass,MASS_DENSITY);
|
||
|
interscaleManager_.add_dense_matrix(nodalAtomicMoleculeMassDensity,"NodalMoleculeMassDensity"+moleculeName);
|
||
|
}
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->construct_transfers();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ATC_CouplingMass::init_filter()
|
||
|
{
|
||
|
|
||
|
ATC_Coupling::init_filter();
|
||
|
}
|
||
|
|
||
|
void ATC_CouplingMass::compute_md_mass_matrix(FieldName thisField,
|
||
|
DIAG_MAT & massMat)
|
||
|
{
|
||
|
|
||
|
if (thisField == MASS_DENSITY ||
|
||
|
thisField == SPECIES_CONCENTRATION) {
|
||
|
massMat.reset(nodalAtomicVolume_->quantity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// pack_fields
|
||
|
// bundle all allocated field matrices into a list
|
||
|
// for output needs
|
||
|
//--------------------------------------------------
|
||
|
|
||
|
void ATC_CouplingMass::pack_species_fields(RESTART_LIST & data)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// write_restart_file
|
||
|
// bundle matrices that need to be saved and call
|
||
|
// fe_engine to write the file
|
||
|
//--------------------------------------------------
|
||
|
void ATC_CouplingMass::write_restart_data(string fileName, RESTART_LIST & data)
|
||
|
{
|
||
|
pack_species_fields(data);
|
||
|
ATC_Method::write_restart_data(fileName,data);
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// write_restart_file
|
||
|
// bundle matrices that need to be saved and call
|
||
|
// fe_engine to write the file
|
||
|
//--------------------------------------------------
|
||
|
void ATC_CouplingMass::read_restart_data(string fileName, RESTART_LIST & data)
|
||
|
{
|
||
|
|
||
|
pack_species_fields(data);
|
||
|
ATC_Method::read_restart_data(fileName,data);
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// pre_force
|
||
|
// prior to calculation of forces
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::pre_force()
|
||
|
{
|
||
|
ATC_Coupling::pre_force();
|
||
|
atomicRegulator_->pre_force();
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// pre_exchange
|
||
|
// prior to exchange of atoms
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::pre_exchange()
|
||
|
{
|
||
|
ATC_Coupling::pre_exchange();
|
||
|
|
||
|
//if (atomicRegulator_->needs_temperature()) {
|
||
|
field(TEMPERATURE) = atomicFields_[TEMPERATURE]->quantity();
|
||
|
///}
|
||
|
atomicRegulator_->pre_exchange();
|
||
|
if (resetNlocal_) {
|
||
|
this->reset_nlocal();
|
||
|
resetNlocal_ = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// pre_init_integrate
|
||
|
// time integration before the lammps atomic
|
||
|
// integration of the Verlet step 1
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::pre_init_integrate()
|
||
|
{
|
||
|
ATC_Coupling::pre_init_integrate();
|
||
|
double dt = lammpsInterface_->dt();
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->pre_initial_integrate1(dt);
|
||
|
}
|
||
|
|
||
|
// Apply thermostat force to atom velocities
|
||
|
atomicRegulator_->apply_pre_predictor(dt,lammpsInterface_->ntimestep());
|
||
|
|
||
|
// Predict nodal temperatures and time derivatives based on FE data
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->pre_initial_integrate2(dt);
|
||
|
}
|
||
|
extrinsicModelManager_.pre_init_integrate();
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// mid_init_integrate
|
||
|
// time integration between the velocity update and
|
||
|
// the position lammps update of Verlet step 1
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::mid_init_integrate()
|
||
|
{
|
||
|
ATC_Coupling::mid_init_integrate();
|
||
|
double dt = lammpsInterface_->dt();
|
||
|
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->mid_initial_integrate1(dt);
|
||
|
}
|
||
|
|
||
|
atomicRegulator_->apply_mid_predictor(dt,lammpsInterface_->ntimestep());
|
||
|
|
||
|
extrinsicModelManager_.mid_init_integrate();
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// post_init_integrate
|
||
|
// time integration after the lammps atomic updates of
|
||
|
// Verlet step 1
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::post_init_integrate()
|
||
|
{
|
||
|
double dt = lammpsInterface_->dt();
|
||
|
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->post_initial_integrate1(dt);
|
||
|
}
|
||
|
|
||
|
atomicRegulator_->apply_post_predictor(dt,lammpsInterface_->ntimestep());
|
||
|
|
||
|
extrinsicModelManager_.post_init_integrate();
|
||
|
|
||
|
set_fixed_nodes();
|
||
|
update_time(0.5); // half step
|
||
|
ATC_Coupling::post_init_integrate();
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// post_final_integrate
|
||
|
// integration after the second stage lammps atomic
|
||
|
// update of Verlet step 2
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::post_final_integrate()
|
||
|
{
|
||
|
double dt = lammpsInterface_->dt();
|
||
|
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->pre_final_integrate1(dt);
|
||
|
}
|
||
|
|
||
|
prescribedDataMgr_->set_sources(time()+0.5*dt,sources_);
|
||
|
extrinsicModelManager_.pre_final_integrate();
|
||
|
|
||
|
|
||
|
if (timeIntegrators_[MASS_DENSITY]->has_final_predictor()) {
|
||
|
// set state-based sources
|
||
|
extrinsicModelManager_.set_sources(fields_,extrinsicSources_);
|
||
|
|
||
|
compute_atomic_sources(speciesMask_,fields_,atomicSources_);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// set state-based RHS
|
||
|
// Determine FE contributions to dv/dt-----------------------
|
||
|
// Compute atom-integrated rhs
|
||
|
// parallel communication happens within FE_Engine
|
||
|
compute_rhs_vector(speciesMask_,fields_,rhs_,FE_DOMAIN);
|
||
|
// Compute and add atomic contributions to FE equations
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->add_to_rhs();
|
||
|
}
|
||
|
atomicRegulator_->add_to_rhs(rhs_);
|
||
|
|
||
|
// final phase predictor step
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->post_final_integrate1(dt);
|
||
|
}
|
||
|
|
||
|
set_fixed_nodes();
|
||
|
|
||
|
// corrector step extrinsic model
|
||
|
extrinsicModelManager_.post_final_integrate();
|
||
|
|
||
|
if (timeIntegrators_[MASS_DENSITY]->has_final_corrector()) {
|
||
|
// set state-based sources
|
||
|
extrinsicModelManager_.set_sources(fields_,extrinsicSources_);
|
||
|
|
||
|
compute_atomic_sources(speciesMask_,fields_,atomicSources_);
|
||
|
}
|
||
|
|
||
|
// finish FE temperature update
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->post_final_integrate2(dt);
|
||
|
}
|
||
|
|
||
|
// apply corrector phase of thermostat
|
||
|
atomicRegulator_->apply_post_corrector(dt,lammpsInterface_->ntimestep());
|
||
|
|
||
|
// finalize time integration
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->post_final_integrate3(dt);
|
||
|
}
|
||
|
|
||
|
// Fix nodes, non-group bcs applied through FE
|
||
|
set_fixed_nodes();
|
||
|
|
||
|
update_time(0.5);
|
||
|
output();
|
||
|
ATC_Coupling::post_final_integrate(); // addstep for computes
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------
|
||
|
// output
|
||
|
// does post-processing steps and outputs data
|
||
|
//--------------------------------------------------------
|
||
|
void ATC_CouplingMass::output()
|
||
|
{
|
||
|
if (output_now()) {
|
||
|
feEngine_->departition_mesh();
|
||
|
OUTPUT_LIST outputData;
|
||
|
|
||
|
// base class output
|
||
|
ATC_Coupling::output();
|
||
|
|
||
|
// push atc fields time integrator modifies into output arrays
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->post_process();
|
||
|
}
|
||
|
|
||
|
// auxilliary data
|
||
|
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
|
||
|
(_tiIt_->second)->output(outputData);
|
||
|
}
|
||
|
extrinsicModelManager_.output(outputData);
|
||
|
atomicRegulator_->output(outputData);
|
||
|
|
||
|
FIELD_POINTERS::iterator itr;
|
||
|
for (itr=atomicFields_.begin(); itr!=atomicFields_.end();itr++) {
|
||
|
FieldName name = itr->first;
|
||
|
const DENS_MAT & data = (itr->second)->quantity();
|
||
|
outputData[field_to_intrinsic_name(name)] = & data;
|
||
|
}
|
||
|
// compute partial forces
|
||
|
int * type =lammpsInterface_->atom_type();
|
||
|
double ** f =lammpsInterface_->fatom();
|
||
|
for (unsigned int j = 0; j < typeList_.size(); j++) {
|
||
|
string speciesName = typeNames_[j];
|
||
|
int sType = typeList_[j];
|
||
|
double localF[3] = {0,0,0}, F[3] = {0,0,0};
|
||
|
for (int i = 0; i < nLocal_; i++) {
|
||
|
int a = internalToAtom_(i);
|
||
|
if (sType == type[a]) {
|
||
|
double * fa = f[a];
|
||
|
localF[0] += fa[0];
|
||
|
localF[1] += fa[1];
|
||
|
localF[2] += fa[2];
|
||
|
}
|
||
|
}
|
||
|
lammpsInterface_->allsum(localF,F,3);
|
||
|
if (lammpsInterface_->rank_zero()) {
|
||
|
for (int i = 0; i < 3; ++i) {
|
||
|
feEngine_->add_global(speciesName+"_F"+to_string(i+1), F[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (lammpsInterface_->rank_zero()) {
|
||
|
// tagged data
|
||
|
|
||
|
map<string,DENS_MAN>::iterator densMan;
|
||
|
for (densMan = taggedDensMan_.begin(); densMan != taggedDensMan_.end(); densMan++) {
|
||
|
outputData[densMan->first] = & (densMan->second).set_quantity();
|
||
|
}
|
||
|
|
||
|
feEngine_->write_data(output_index(), fields_, & outputData);
|
||
|
}
|
||
|
// force reset of tagged data to keep in sync
|
||
|
map<string,DENS_MAN>::iterator densMan;
|
||
|
for (densMan = taggedDensMan_.begin(); densMan != taggedDensMan_.end(); densMan++)
|
||
|
(densMan->second).force_reset();
|
||
|
feEngine_->partition_mesh();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------
|
||
|
// compute_vector
|
||
|
//--------------------------------------------------------------------
|
||
|
// this is for direct output to lammps thermo
|
||
|
double ATC_CouplingMass::compute_vector(int n)
|
||
|
{
|
||
|
return atomicRegulator_->compute_vector(n);
|
||
|
}
|
||
|
};
|