ATC version 2.0, date: Nov20

git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@12757 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
jatempl
2014-11-20 18:59:03 +00:00
parent 2fecb0f4b8
commit ac5973073f
69 changed files with 5895 additions and 2159 deletions

View File

@ -16,6 +16,10 @@ using std::string;
using std::map;
using std::pair;
using std::set;
using std::ifstream;
using std::stringstream;
using ATC_Utility::is_numeric;
using ATC_Utility::to_string;
namespace ATC {
//--------------------------------------------------
@ -138,11 +142,11 @@ namespace ATC {
/*! \page man_fix_nodes fix_modify AtC fix
\section syntax
fix_modify AtC fix <field> <nodeset> <constant | function>
fix_modify AtC fix <field> <nodeset> <constant | function | >
- <field> = field name valid for type of physics
- <nodeset> = name of set of nodes to apply boundary condition
- <constant | function> = value or name of function followed by its
parameters
- <constant | function | > = value or name of function followed by its
parameters or nothing to fix the field at its current state
\section examples
<TT> fix_modify AtC fix temperature groupNAME 10. </TT> \n
<TT> fix_modify AtC fix temperature groupNAME 0 0 0 10.0 0 0 1.0 </TT> \n
@ -174,10 +178,30 @@ namespace ATC {
prescribedDataMgr_->fix_field(one,thisField,thisIndex,f);
}
}
// parse constant
// parse constant or file
else if (narg == argIdx+1) {
f = XT_Function_Mgr::instance()->constant_function(atof(arg[argIdx]));
prescribedDataMgr_->fix_field(nsetName,thisField,thisIndex,f);
string a(arg[argIdx]);
if (is_numeric(a)) { // constant
f = XT_Function_Mgr::instance()->constant_function(atof(arg[argIdx]));
prescribedDataMgr_->fix_field(nsetName,thisField,thisIndex,f);
}
else {
ATC::LammpsInterface::instance()->print_msg("reading "+field_to_string(thisField)+" on nodeset "+nsetName+" from file "+a);
string s = ATC::LammpsInterface::instance()->read_file(a);
stringstream ss; ss << s;
double v;
set<int> nodeSet = (feEngine_->fe_mesh())->nodeset(nsetName);
set<int>::const_iterator iset;
for (iset = nodeSet.begin(); iset != nodeSet.end(); iset++) {
int inode = *iset;
int i;
ss >> i >> v;
if (i != inode) ATC::LammpsInterface::instance()->print_msg_once("WARNING: node mismatch in file read");
f = XT_Function_Mgr::instance()->constant_function(v);
set<int> one; one.insert(inode);
prescribedDataMgr_->fix_field(one,thisField,thisIndex,f);
}
}
}
// parse function
else {
@ -237,13 +261,38 @@ namespace ATC {
XT_Function * f = NULL;
// parse constant
if (narg == argIdx+1) {
f = XT_Function_Mgr::instance()->constant_function(atof(arg[argIdx]));
string a(arg[argIdx]);
if (is_numeric(a)) { // constant
f = XT_Function_Mgr::instance()->constant_function(atof(arg[argIdx]));
prescribedDataMgr_->fix_source(esetName,thisField,thisIndex,f);
}
else {
ATC::LammpsInterface::instance()->print_msg("reading "+field_to_string(thisField)+" source on node set "+esetName+" from file "+a);
string s = ATC::LammpsInterface::instance()->read_file(arg[argIdx]);
stringstream ss; ss << s;
double v;
set<int> nset = (feEngine_->fe_mesh())->nodeset(esetName);
set< pair < int, double > > src;
set<int>::const_iterator iset;
double sum = 0.;
for (iset = nset.begin(); iset != nset.end(); iset++) {
int inode = *iset;
int i;
ss >> i >> v;
if (i != inode) ATC::LammpsInterface::instance()->print_msg_once("WARNING: node mismatch in file read");
src.insert(pair<int,double> (inode,v));
sum += v;
}
if (ss.gcount()) ATC::LammpsInterface::instance()->print_msg_once("WARNING: not all of file read");
ATC::LammpsInterface::instance()->print_msg_once("total source: "+to_string(sum));
prescribedDataMgr_->fix_source(thisField,thisIndex,src);
}
}
// parse function
else {
f = XT_Function_Mgr::instance()->function(&(arg[argIdx]),narg-argIdx);
prescribedDataMgr_->fix_source(esetName,thisField,thisIndex,f);
}
prescribedDataMgr_->fix_source(esetName,thisField,thisIndex,f);
fieldMask_(thisField,PRESCRIBED_SOURCE) = true;
match = true;
}
@ -271,6 +320,30 @@ namespace ATC {
fieldMask_(thisField,PRESCRIBED_SOURCE) = false;
match = true;
}
else if (strcmp(arg[argIdx],"write_source")==0) {
argIdx++;
FieldName thisField;
int thisIndex;
parse_field(arg,argIdx,thisField,thisIndex);
string nsetName(arg[argIdx++]);
string filename(arg[argIdx++]);
set_sources();
FIELDS * s = & sources_; // PRESCRIBED_SOURCES
if (argIdx < narg && strcmp(arg[argIdx],"extrinsic")==0) s = & extrinsicSources_;
//s = & extrinsicSources_;
stringstream f;
set<int> nodeSet = (feEngine_->fe_mesh())->nodeset(nsetName);
set<int>::const_iterator iset;
const DENS_MAT & source =(s->find(thisField)->second).quantity();
for (iset = nodeSet.begin(); iset != nodeSet.end(); iset++) {
int inode = *iset;
double v = source(inode,thisIndex);
f << inode << " " << std::setprecision(17) << v << "\n";
}
LammpsInterface::instance()->write_file(filename,f.str());
match = true;
}
/*! \page man_fix_flux fix_modify AtC fix_flux
\section syntax
@ -478,6 +551,24 @@ namespace ATC {
match = true;
}
else if (strcmp(arg[argIdx],"fix_open")==0) {
argIdx++;
parse_field(arg,argIdx,thisField);
string fsetName(arg[argIdx++]);
prescribedDataMgr_->fix_open(fsetName,thisField);
fieldMask_(thisField,OPEN_SOURCE) = true;
match = true;
}
else if (strcmp(arg[argIdx],"unfix_open")==0) {
argIdx++;
parse_field(arg,argIdx,thisField);
string fsetName(arg[argIdx++]);
prescribedDataMgr_->unfix_open(fsetName,thisField);
fieldMask_(thisField,OPEN_SOURCE) = false;
match = true;
}
/*! \page man_atomic_charge fix_modify AtC atomic_charge
\section syntax
fix_modify AtC <include | omit> atomic_charge
@ -525,6 +616,9 @@ namespace ATC {
if (strcmp(arg[argIdx],"fe")==0) {
sourceIntegration_ = FULL_DOMAIN;
}
else {
sourceIntegration_ = FULL_DOMAIN_ATOMIC_QUADRATURE_SOURCE;
}
match = true;
}
@ -816,9 +910,8 @@ namespace ATC {
//--------------------------------------------------------
void ATC_Coupling::set_sources()
{
// set fields
prescribedDataMgr_->set_sources(time(),sources_);
prescribedDataMgr_->set_sources(time(),sources_); // PRESCRIBED_SOURCE
extrinsicModelManager_.set_sources(fields_,extrinsicSources_); // EXTRINSIC_SOURCE
}
//-----------------------------------------------------------------
// this is w_a source_a
@ -902,10 +995,45 @@ namespace ATC {
const PhysicsModel * physicsModel)
{
if (integrationType == FULL_DOMAIN_ATOMIC_QUADRATURE_SOURCE) {
RHS_MASK rhsMaskFE = rhsMask;
RHS_MASK rhsMaskMD = rhsMask; rhsMaskMD = false;
for (FIELDS::const_iterator field = fields.begin();
field != fields.end(); field++) {
FieldName thisFieldName = field->first;
if ( rhsMaskFE(thisFieldName,SOURCE) ) {
rhsMaskFE(thisFieldName,SOURCE) = false;
rhsMaskMD(thisFieldName,SOURCE) = true;
}
}
feEngine_->compute_tangent_matrix(rhsMaskFE, row_col,
fields , physicsModel, elementToMaterialMap_, stiffness);
masked_atom_domain_rhs_tangent(row_col,
rhsMaskMD,
fields,
stiffnessAtomDomain_,
physicsModel);
stiffness += stiffnessAtomDomain_;
}
else {
feEngine_->compute_tangent_matrix(rhsMask, row_col,
fields , physicsModel, elementToMaterialMap_, stiffness);
}
ROBIN_SURFACE_SOURCE & robinFcn = *(prescribedDataMgr_->robin_functions());
feEngine_->add_robin_tangent(rhsMask, fields, time(), robinFcn, stiffness);
OPEN_SURFACE & openFaces = *(prescribedDataMgr_->open_faces());
feEngine_->add_open_tangent(rhsMask, fields, openFaces, stiffness);
}
//-----------------------------------------------------------------
void ATC_Coupling::tangent_matrix(
const pair<FieldName,FieldName> row_col,
const RHS_MASK & rhsMask,
const PhysicsModel * physicsModel,
SPAR_MAT & stiffness)
{
feEngine_->compute_tangent_matrix(rhsMask, row_col,
fields_ , physicsModel, elementToMaterialMap_, stiffness);
}
//-----------------------------------------------------------------
void ATC_Coupling::compute_rhs_vector(const RHS_MASK & rhsMask,
@ -916,7 +1044,6 @@ namespace ATC {
{
if (!physicsModel) physicsModel = physicsModel_;
// compute FE contributions
evaluate_rhs_integral(rhsMask,fields,rhs,domain,physicsModel);
@ -943,8 +1070,10 @@ namespace ATC {
}
}
ROBIN_SURFACE_SOURCE & robinFcn = *(prescribedDataMgr_->robin_functions());
ROBIN_SURFACE_SOURCE & robinFcn = *(prescribedDataMgr_->robin_functions());
feEngine_->add_robin_fluxes(rhsMask, fields, time(), robinFcn, rhs);
OPEN_SURFACE & openFaces = *(prescribedDataMgr_->open_faces());
feEngine_->add_open_fluxes(rhsMask, fields, openFaces, rhs);
}
//-----------------------------------------------------------------
void ATC_Coupling::masked_atom_domain_rhs_integral(
@ -988,7 +1117,7 @@ namespace ATC {
fields,
physicsModel,
elementToMaterialMap_,
rhs,
rhs, false,
&(elementMask_->quantity()));
masked_atom_domain_rhs_integral(rhsMask,
fields,
@ -1007,6 +1136,42 @@ namespace ATC {
rhs,
physicsModel);
}
else if (integrationType == FULL_DOMAIN_ATOMIC_QUADRATURE_SOURCE) {
RHS_MASK rhsMaskFE = rhsMask;
RHS_MASK rhsMaskMD = rhsMask; rhsMaskMD = false;
for (FIELDS::const_iterator field = fields.begin();
field != fields.end(); field++) {
FieldName thisFieldName = field->first;
if ( rhsMaskFE(thisFieldName,SOURCE) ) {
rhsMaskFE(thisFieldName,SOURCE) = false;
rhsMaskMD(thisFieldName,SOURCE) = true;
}
}
feEngine_->compute_rhs_vector(rhsMaskFE,
fields,
physicsModel,
elementToMaterialMap_,
rhs);
masked_atom_domain_rhs_integral(rhsMaskMD,
fields,
rhsAtomDomain_,
physicsModel);
for (FIELDS::const_iterator field = fields.begin();
field != fields.end(); field++) {
FieldName thisFieldName = field->first;
if ( ((rhs[thisFieldName].quantity()).size() > 0)
&& ((rhsAtomDomain_[thisFieldName].quantity()).size() > 0) )
rhs[thisFieldName] += rhsAtomDomain_[thisFieldName].quantity();
}
}
else if (integrationType == FULL_DOMAIN_FREE_ONLY) {
feEngine_->compute_rhs_vector(rhsMask,
fields,
physicsModel,
elementToMaterialMap_,
rhs, true);
}
else { // domain == FULL_DOMAIN
feEngine_->compute_rhs_vector(rhsMask,
fields,
@ -1336,7 +1501,7 @@ namespace ATC {
if (internalElementSet_.size()) {
// when geometry is based on elements, there are no mixed elements
elementMask_ = new MatrixDependencyManager<DenseMatrix, bool>;
(elementMask_->set_quantity()).reset(feEngine_->num_elements(),1,false);
(elementMask_->set_quantity()).reset(feEngine_->num_elements(),1);
}
else {
elementMask_ = new ElementMask(this);
@ -1375,7 +1540,7 @@ namespace ATC {
}
//--------------------------------------------------------
// construct_interpolant
// constructs: interpolatn, accumulant, weights, and spatial derivatives
// constructs: interpolant, accumulant, weights, and spatial derivatives
//--------------------------------------------------------
void ATC_Coupling::construct_interpolant()
{
@ -1593,6 +1758,23 @@ namespace ATC {
// brute force computation of inverse
consistentMassMatsInv_[thisField] = inv((consistentMassMats_[thisField].quantity()).dense_copy());
}
else if (! is_intrinsic(thisField)) {
Array<FieldName> massMask(1);
massMask(0) = thisField;
feEngine_->compute_lumped_mass_matrix(massMask,fields_,physicsModel,
elementToMaterialMap_,massMats_,
&(elementMask_->quantity()));
const DIAG_MAT & myMassMat(massMats_[thisField].quantity());
DIAG_MAT & myMassMatInv(massMatsInv_[thisField].set_quantity());
for (int iNode = 0; iNode < nNodes_; iNode++) {
if (fabs(myMassMat(iNode,iNode))>0)
myMassMatInv(iNode,iNode) = 1./myMassMat(iNode,iNode);
else
myMassMatInv(iNode,iNode) = 0.;
}
}
else { // lumped mass matrix
// compute FE mass matrix in full domain
Array<FieldName> massMask(1);
@ -1631,6 +1813,7 @@ namespace ATC {
// fully remove contributions from internal nodes
DIAG_MAT & myMassMatFE(massMatsFE_[thisField].set_quantity());
//myMassMatFE.print("MMFE");
if (!atomQuadForInternal_) {
const INT_ARRAY & nodeType(nodalGeometryType_->quantity());
for (int iNode = 0; iNode < nNodes_; iNode++)
@ -1939,7 +2122,7 @@ namespace ATC {
// Set sources
prescribedDataMgr_->set_sources(time()+0.5*dt,sources_);
extrinsicModelManager_.pre_final_integrate();
bool needsSources = false;
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
if ((_tiIt_->second)->has_final_predictor()) {
@ -1953,7 +2136,7 @@ namespace ATC {
compute_atomic_sources(intrinsicMask_,fields_,atomicSources_);
}
atomicRegulator_->apply_pre_corrector(dt,lammpsInterface_->ntimestep());
// Compute atom-integrated rhs
// parallel communication happens within FE_Engine
compute_rhs_vector(intrinsicMask_,fields_,rhs_,FE_DOMAIN);
@ -1966,7 +2149,7 @@ namespace ATC {
for (_tiIt_ = timeIntegrators_.begin(); _tiIt_ != timeIntegrators_.end(); ++_tiIt_) {
(_tiIt_->second)->post_final_integrate1(dt);
}
// fix nodes, non-group bcs applied through FE
set_fixed_nodes();
@ -1993,6 +2176,7 @@ namespace ATC {
}
// apply corrector phase of thermostat
set_fixed_nodes();
atomicRegulator_->apply_post_corrector(dt,lammpsInterface_->ntimestep());
// final phase of time integration
@ -2037,7 +2221,7 @@ namespace ATC {
const DIAG_MAN * atomicWeights,
const MatrixDependencyManager<DenseMatrix, bool> * elementMask,
const RegulatedNodes * nodeSet)
const SetDependencyManager<int> * nodeSet)
{
if (bndyIntType_ == FE_QUADRATURE) {
feEngine_->compute_boundary_flux(rhsMask,
@ -2094,7 +2278,8 @@ if (thisFieldName >= rhsMask.nRows()) break;
void ATC_Coupling::compute_flux(const Array2D<bool> & rhsMask,
const FIELDS & fields,
GRAD_FIELD_MATS & flux,
const PhysicsModel * physicsModel)
const PhysicsModel * physicsModel,
bool project)
{
if (! physicsModel) { physicsModel = physicsModel_; }
feEngine_->compute_flux(rhsMask,
@ -2102,9 +2287,22 @@ if (thisFieldName >= rhsMask.nRows()) break;
physicsModel,
elementToMaterialMap_,
flux);
if (project) {
for (FIELDS::const_iterator field = fields.begin();
field != fields.end(); field++) {
FieldName name = field->first;
if ( rhsMask(name,FLUX) ) {
for(int i=0; i < nsd_ ; ++i) {
DENS_MAT & f = flux[name][i];
if (i==0) f.print("pre flux_"+field_to_string(name)+"_"+ATC_Utility::to_string(i));
apply_inverse_mass_matrix(f);
if (i==0) f.print("flux_"+field_to_string(name)+"_"+ATC_Utility::to_string(i));
}
}
}
}
}
//--------------------------------------------------------
void ATC_Coupling::nodal_projection(const FieldName & fieldName,