forked from lijiext/lammps
2384 lines
87 KiB
C++
2384 lines
87 KiB
C++
// ATC transfer headers
|
|
#include "PerAtomQuantityLibrary.h"
|
|
#include "ATC_Transfer.h"
|
|
#include "FE_Engine.h"
|
|
#include "LammpsInterface.h"
|
|
#include <typeinfo>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
|
|
using std::map;
|
|
using std::ifstream;
|
|
using std::stringstream;
|
|
using std::set;
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
using ATC_Utility::to_string;
|
|
|
|
namespace ATC {
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomToElementMap
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomToElementMap::AtomToElementMap(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomPositions,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<int>(atc,1,atomType),
|
|
atomPositions_(atomPositions)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomPositions_)
|
|
atomPositions_ = interscaleManager.per_atom_quantity("AtomicCoarseGrainingPositions");
|
|
if (!atomPositions_)
|
|
throw ATC_Error("AtomToElementMap::AtomToElementMap - atom position quantity is undefined");
|
|
|
|
atomPositions_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomToElementMap::~AtomToElementMap()
|
|
{
|
|
atomPositions_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomToElementMap::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<int>::reset();
|
|
const DENS_MAT & position(atomPositions_->quantity());
|
|
const FE_Mesh * feMesh = atc_.fe_engine()->fe_mesh();
|
|
int nsd = atc_.nsd();
|
|
DENS_VEC coords(nsd);
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
for (int j = 0; j < nsd; j++) {
|
|
coords(j) = position(i,j);
|
|
}
|
|
quantity_(i,0) = feMesh->map_to_element(coords);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomInElementSet
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomInElementSet::AtomInElementSet(ATC_Method * atc,
|
|
PerAtomQuantity<int> * map,
|
|
ESET eset, int type):
|
|
atc_(atc,INTERNAL),
|
|
map_(map),eset_(eset),type_(type),
|
|
quantityToLammps_(atc_.atc_to_lammps_map())
|
|
{
|
|
map_->register_dependence(this);
|
|
needReset_ = true;
|
|
|
|
}
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomInElementSet::~AtomInElementSet()
|
|
{
|
|
map_->remove_dependence(this);
|
|
}
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomInElementSet::reset()
|
|
{
|
|
if (map_->need_reset() || needReset_) {
|
|
list_.clear();
|
|
INT_ARRAY map = map_->quantity();
|
|
int * type = ATC::LammpsInterface::instance()->atom_type();
|
|
ESET::const_iterator itr;
|
|
const Array<int> & quantityToLammps = atc_.atc_to_lammps_map();
|
|
for (int i = 0; i < map.size(); i++) {
|
|
for (itr=eset_.begin(); itr != eset_.end(); itr++) {
|
|
if (map(i,0) == *itr) {
|
|
int a = quantityToLammps(i);
|
|
if (type[a] == type_) {
|
|
list_.push_back(ID_PAIR(i,a));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
needReset_ = false;
|
|
}
|
|
}
|
|
//--------------------------------------------------------
|
|
// qauntity
|
|
//--------------------------------------------------------
|
|
const ID_LIST & AtomInElementSet::quantity()
|
|
{
|
|
reset();
|
|
return list_;
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomVolumeUser
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeUser::AtomVolumeUser(ATC_Method * atc,
|
|
map<int,double> & atomGroupVolume,
|
|
AtomType atomType) :
|
|
ProtectedAtomDiagonalMatrix<double>(atc,atomType),
|
|
atomGroupVolume_(atomGroupVolume),
|
|
lammpsInterface_(atc->lammps_interface()),
|
|
atcToLammps_(atc->internal_to_atom_map())
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomVolumeUser::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomDiagonalMatrix<double>::reset();
|
|
const int *mask = lammpsInterface_->atom_mask();
|
|
quantity_ = 0.;
|
|
|
|
map<int, double>::const_iterator igroup;
|
|
for (igroup = atomGroupVolume_.begin(); igroup != atomGroupVolume_.end(); igroup++) {
|
|
int gid = igroup->first;
|
|
double weight = igroup->second;
|
|
for (int i = 0; i < quantity_.nRows(); ++i) {
|
|
if (mask[atcToLammps_(i)] & gid) {
|
|
quantity_(i,i) = weight;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomVolumeGroup
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeGroup::AtomVolumeGroup(ATC_Method * atc,
|
|
map<int,double> & atomGroupVolume,
|
|
AtomType atomType) :
|
|
AtomVolumeUser(atc,atomGroupVolume,atomType),
|
|
atomGroupVolume_(atomGroupVolume),
|
|
lammpsInterface_(atc->lammps_interface()),
|
|
atcToLammps_(atc->internal_to_atom_map())
|
|
{
|
|
// Uses group bounding box as total volume
|
|
// ASSUME will *only* work if atoms exactly fill the box
|
|
int ngroup = lammpsInterface_->ngroup();
|
|
const int *mask = lammpsInterface_->atom_mask();
|
|
double * bounds;
|
|
|
|
bounds = new double[6];
|
|
for (int i = 0; i < ngroup; ++i) {
|
|
lammpsInterface_->group_bounds(i, bounds);
|
|
atomGroupVolume_[lammpsInterface_->group_bit(i)] =
|
|
(bounds[1]-bounds[0])*(bounds[3]-bounds[2])*(bounds[5]-bounds[4]);
|
|
}
|
|
delete [] bounds;
|
|
|
|
INT_VECTOR localCount(ngroup);
|
|
INT_VECTOR globalCount(ngroup);
|
|
|
|
// loop over atoms
|
|
localCount = 0;
|
|
for (int i = 0; i < atcToLammps_.size(); ++i) {
|
|
for (int j = 0; j < ngroup; ++j) {
|
|
if (mask[atcToLammps_(i)] & lammpsInterface_->group_bit(j))
|
|
localCount(j)++;
|
|
}
|
|
}
|
|
|
|
// communication to get total atom counts per group
|
|
lammpsInterface_->int_allsum(localCount.ptr(),
|
|
globalCount.ptr(),ngroup);
|
|
|
|
for (int i = 0; i < ngroup; ++i) {
|
|
int iGroupBit = lammpsInterface_->group_bit(i);
|
|
if (globalCount(i) > 0)
|
|
atomGroupVolume_[iGroupBit] /= globalCount(i);
|
|
else
|
|
atomGroupVolume_[iGroupBit] = 0;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomVolumeLattice
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeLattice::AtomVolumeLattice(ATC_Method * atc,
|
|
AtomType atomType) :
|
|
ProtectedAtomDiagonalMatrix<double>(atc,atomType),
|
|
lammpsInterface_(atc->lammps_interface())
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomVolumeLattice::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomDiagonalMatrix<double>::reset();
|
|
quantity_ = lammpsInterface_->volume_per_atom();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomVolumeElement
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeElement::AtomVolumeElement(ATC_Method * atc,
|
|
PerAtomQuantity<int> * atomElement,
|
|
AtomType atomType) :
|
|
ProtectedAtomDiagonalMatrix<double>(atc,atomType),
|
|
atomElement_(atomElement),
|
|
lammpsInterface_(atc->lammps_interface()),
|
|
feMesh_((atc->fe_engine())->fe_mesh())
|
|
{
|
|
if (!atomElement_) {
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
atomElement_ = interscaleManager.per_atom_int_quantity("AtomElement");
|
|
}
|
|
atomElement_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// Destructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeElement::~AtomVolumeElement()
|
|
{
|
|
atomElement_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomVolumeElement::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomDiagonalMatrix<double>::reset();
|
|
int nElts = feMesh_->num_elements();
|
|
int nLocal = quantity_.nRows();
|
|
_elementAtomCountLocal_.reset(nElts);
|
|
_elementAtomCount_.resize(nElts);
|
|
const INT_ARRAY & atomElement(atomElement_->quantity());
|
|
_elementAtomVolume_.resize(nElts);
|
|
|
|
// determine number of atoms in each element, partial sum
|
|
for (int i = 0; i < nLocal; ++i) {
|
|
_elementAtomCountLocal_(atomElement(i,0)) += 1;
|
|
}
|
|
|
|
// mpi to determine total atoms
|
|
lammpsInterface_->int_allsum(_elementAtomCountLocal_.ptr(),_elementAtomCount_.ptr(),nElts);
|
|
|
|
// divide element volume by total atoms to get atomic volume
|
|
if (nLocal>0) {
|
|
for (int i = 0; i < nElts; ++i) {
|
|
|
|
double minx, maxx, miny, maxy, minz, maxz;
|
|
feMesh_->element_coordinates(i,_nodalCoordinates_);
|
|
minx = _nodalCoordinates_(0,0); maxx = _nodalCoordinates_(0,0);
|
|
miny = _nodalCoordinates_(1,0); maxy = _nodalCoordinates_(1,0);
|
|
minz = _nodalCoordinates_(2,0); maxz = _nodalCoordinates_(2,0);
|
|
for (int j = 1; j < _nodalCoordinates_.nCols(); ++j) {
|
|
if (_nodalCoordinates_(0,j)<minx) minx = _nodalCoordinates_(0,j);
|
|
if (_nodalCoordinates_(0,j)>maxx) maxx = _nodalCoordinates_(0,j);
|
|
if (_nodalCoordinates_(1,j)<miny) miny = _nodalCoordinates_(1,j);
|
|
if (_nodalCoordinates_(1,j)>maxy) maxy = _nodalCoordinates_(1,j);
|
|
if (_nodalCoordinates_(2,j)<minz) minz = _nodalCoordinates_(2,j);
|
|
if (_nodalCoordinates_(2,j)>maxz) maxz = _nodalCoordinates_(2,j);
|
|
}
|
|
double eltVol = (maxx-minx)*(maxy-miny)*(maxz-minz);
|
|
if (eltVol<0) eltVol *= -1.;
|
|
_elementAtomVolume_(i) = eltVol/_elementAtomCount_(i);
|
|
}
|
|
|
|
for (int i = 0; i < nLocal; ++i)
|
|
quantity_(i,i) = _elementAtomVolume_(atomElement(i,0));
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomVolumeRegion
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeRegion::AtomVolumeRegion(ATC_Method * atc,
|
|
DENS_MAN * atomCoarseGrainingPositions,
|
|
AtomType atomType) :
|
|
ProtectedAtomDiagonalMatrix<double>(atc,atomType),
|
|
lammpsInterface_(atc->lammps_interface())
|
|
{
|
|
if (!atomCoarseGrainingPositions) {
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
atomCoarseGrainingPositions_ = interscaleManager.per_atom_quantity("AtomicCoarseGrainingPositions");
|
|
}
|
|
atomCoarseGrainingPositions_->register_dependence(this);
|
|
|
|
// compute volumes and atom counts in each region
|
|
int nregion = lammpsInterface_->nregion();
|
|
regionalAtomVolume_.resize(nregion);
|
|
|
|
for (int i = 0; i < nregion; ++i) {
|
|
regionalAtomVolume_(i) =
|
|
(lammpsInterface_->region_xhi(i)-lammpsInterface_->region_xlo(i))
|
|
*(lammpsInterface_->region_yhi(i)-lammpsInterface_->region_ylo(i))
|
|
*(lammpsInterface_->region_zhi(i)-lammpsInterface_->region_zlo(i));
|
|
}
|
|
|
|
INT_VECTOR localCount(nregion);
|
|
INT_VECTOR globalCount(nregion);
|
|
// loop over atoms
|
|
localCount = 0;
|
|
const DENS_MAT atomicCoordinates(atomCoarseGrainingPositions->quantity());
|
|
for (int i = 0; i < quantity_.nRows(); ++i) {
|
|
for (int j = 0; j < nregion; ++j) {
|
|
if (lammpsInterface_->region_match(j,
|
|
atomicCoordinates(i,0),
|
|
atomicCoordinates(i,1),
|
|
atomicCoordinates(i,2))) {
|
|
localCount(j)++;
|
|
}
|
|
}
|
|
}
|
|
// communication to get total atom counts per group
|
|
lammpsInterface_->int_allsum(localCount.ptr(),
|
|
globalCount.ptr(),nregion);
|
|
|
|
for (int i = 0; i < nregion; ++i) {
|
|
if (globalCount(i) > 0)
|
|
regionalAtomVolume_(i) /= globalCount(i);
|
|
else
|
|
regionalAtomVolume_(i) = 0;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// Destructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeRegion::~AtomVolumeRegion()
|
|
{
|
|
atomCoarseGrainingPositions_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomVolumeRegion::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomDiagonalMatrix<double>::reset();
|
|
const DENS_MAT & atomicCoordinates(atomCoarseGrainingPositions_->quantity());
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
for (int iregion = 0; iregion < lammpsInterface_->nregion(); iregion++) {
|
|
if (lammpsInterface_->region_match(iregion,
|
|
atomicCoordinates(i,0),
|
|
atomicCoordinates(i,0),
|
|
atomicCoordinates(i,2)))
|
|
quantity_(i,i) = regionalAtomVolume_(iregion);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomVolumeFile
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomVolumeFile::AtomVolumeFile(ATC_Method * atc,
|
|
const string & atomVolumeFile,
|
|
AtomType atomType) :
|
|
ProtectedAtomDiagonalMatrix<double>(atc,atomType),
|
|
atomVolumeFile_(atomVolumeFile),
|
|
lammpsInterface_(atc->lammps_interface())
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomVolumeFile::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomDiagonalMatrix<double>::reset();
|
|
int nlocal = lammpsInterface_->nlocal();
|
|
ifstream in;
|
|
const int lineSize = 256;
|
|
char line[lineSize];
|
|
const char* fname = &atomVolumeFile_[0];
|
|
|
|
// create tag to local id map for this processor
|
|
map <int,int> tag2id;
|
|
map <int,int>::const_iterator itr;
|
|
const int * atom_tag = lammpsInterface_->atom_tag();
|
|
for (int i = 0; i < nlocal; ++i) {
|
|
tag2id[atom_tag[i]] = i;
|
|
}
|
|
|
|
// get number of atoms
|
|
int natoms = 0;
|
|
if (ATC::LammpsInterface::instance()->rank_zero()) {
|
|
in.open(fname);
|
|
string msg;
|
|
string name = atomVolumeFile_;
|
|
msg = "no "+name+" atomic weights file found";
|
|
if (! in.good()) throw ATC_Error(msg);
|
|
in.getline(line,lineSize); // header
|
|
in.getline(line,lineSize); // blank line
|
|
in.getline(line,lineSize); // number of atoms
|
|
stringstream inss (line,stringstream::in | stringstream::out);
|
|
inss >> natoms; // number of atoms
|
|
stringstream ss;
|
|
ss << " found " << natoms << " atoms in atomic weights file";
|
|
lammpsInterface_->print_msg(ss.str());
|
|
if (natoms != lammpsInterface_->natoms()) {
|
|
throw ATC_Error("Incorrect number of atomic weights read-in!");
|
|
}
|
|
in.getline(line,lineSize); // blank line
|
|
}
|
|
|
|
// read and assign atomic weights
|
|
int nread = 0, tag = -1, count = 0;
|
|
double atomic_weight;
|
|
while (nread < natoms) {
|
|
if (ATC::LammpsInterface::instance()->rank_zero()) {
|
|
in.getline(line,lineSize);
|
|
stringstream ss (line,stringstream::in | stringstream::out);
|
|
ss >> tag >> atomic_weight;
|
|
nread++;
|
|
}
|
|
lammpsInterface_->int_broadcast(&nread);
|
|
lammpsInterface_->int_broadcast(&tag);
|
|
lammpsInterface_->broadcast(&atomic_weight);
|
|
itr = tag2id.find(tag);
|
|
if (itr != tag2id.end()) {
|
|
int iatom = itr->second;
|
|
quantity_(iatom,0) = atomic_weight;
|
|
count++;
|
|
}
|
|
}
|
|
if (lammpsInterface_->rank_zero()) {
|
|
in.close();
|
|
stringstream ss;
|
|
ss << " read " << nread << " atomic weights";
|
|
lammpsInterface_->print_msg(ss.str());
|
|
}
|
|
if (count != nlocal)
|
|
throw ATC_Error("reset "+to_string(count)+" atoms vs "+to_string(nlocal));
|
|
}
|
|
}
|
|
|
|
// need to add capability to take in group bit (JAT, 04/02/11)
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomNumber
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomNumber::AtomNumber(ATC_Method * atc, AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,1,atomType),
|
|
atc_(atc)
|
|
{
|
|
}
|
|
|
|
void AtomNumber::reset() const
|
|
{
|
|
int nlocal = atc_->nlocal();
|
|
quantity_.reset(nlocal,1);
|
|
quantity_ = 1;
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomTypeVector
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomTypeVector::AtomTypeVector(ATC_Method * atc,
|
|
vector<int> typeList, AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,
|
|
typeList.size(),
|
|
atomType),
|
|
atc_(atc), ntypes_(ATC::LammpsInterface::instance()->ntypes()),
|
|
typeList_(typeList)
|
|
{
|
|
if (typeList_.size() == 0) throw ATC_Error("type list is empty");
|
|
index_.resize(ntypes_,-1);
|
|
for (unsigned int i = 0; i < typeList_.size(); i++) {
|
|
index_[typeList_[i]] = i;
|
|
}
|
|
}
|
|
AtomTypeVector::AtomTypeVector(ATC_Method * atc,
|
|
vector<int> typeList, vector<int> groupList, AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,
|
|
typeList.size()+groupList.size(),
|
|
atomType),
|
|
atc_(atc), ntypes_(ATC::LammpsInterface::instance()->ntypes()),
|
|
typeList_(typeList),
|
|
groupList_(groupList)
|
|
{
|
|
if ((typeList_.size() == 0) && (groupList_.size() == 0)) throw ATC_Error("type/group lists are empty");
|
|
// reverse map
|
|
index_.resize(ntypes_,-1);
|
|
for (unsigned int i = 0; i < typeList_.size(); i++) {
|
|
index_[typeList_[i]-1] = i;
|
|
}
|
|
}
|
|
|
|
void AtomTypeVector::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
//PerAtomQuantity<double>::reset();
|
|
int nlocal = atc_->nlocal();
|
|
quantity_.reset(nlocal,typeList_.size()+groupList_.size());
|
|
const Array<int> & quantityToLammps = (PerAtomQuantity<double>::atc_).atc_to_lammps_map();
|
|
if (typeList_.size()) {
|
|
int * type = ATC::LammpsInterface::instance()->atom_type();
|
|
for (int i = 0; i < nlocal; i++) {
|
|
int a = quantityToLammps(i);
|
|
int index = index_[type[a]-1];
|
|
if (index > -1) quantity_(i,index) = 1;
|
|
}
|
|
}
|
|
int index = typeList_.size();
|
|
if (groupList_.size()) {
|
|
const int * mask = ATC::LammpsInterface::instance()->atom_mask();
|
|
for (unsigned int j = 0; j < groupList_.size(); j++) {
|
|
int group = groupList_[j];
|
|
for (int i = 0; i < nlocal; i++) {
|
|
int a = quantityToLammps(i);
|
|
if (mask[a] & group) quantity_(i,index) = 1;
|
|
}
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class XrefWrapper
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
XrefWrapper::XrefWrapper(ATC_Method * atc, AtomType atomType) :
|
|
ProtectedClonedAtomQuantity<double>(atc,atc->nsd(),atomType),
|
|
atc_(atc)
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// lammps_vector
|
|
//--------------------------------------------------------
|
|
double ** XrefWrapper::lammps_vector() const
|
|
{
|
|
return atc_->xref();
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomicMassWeightedDisplacement
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomicMassWeightedDisplacement::AtomicMassWeightedDisplacement(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomPositions,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
PerAtomQuantity<double> * atomReferencePositions,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,atc->nsd(),atomType),
|
|
atomPositions_(atomPositions),
|
|
atomMasses_(atomMasses),
|
|
atomReferencePositions_(atomReferencePositions)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomPositions_)
|
|
atomPositions_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_POSITION,
|
|
atomType);
|
|
if (!atomMasses_)
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
if (!atomReferencePositions_)
|
|
atomReferencePositions_ = interscaleManager.per_atom_quantity("AtomicCoarseGrainingPositions");
|
|
|
|
atomPositions_->register_dependence(this);
|
|
atomMasses_->register_dependence(this);
|
|
atomReferencePositions_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomicMassWeightedDisplacement::~AtomicMassWeightedDisplacement()
|
|
{
|
|
atomPositions_->remove_dependence(this);
|
|
atomMasses_->remove_dependence(this);
|
|
atomReferencePositions_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomicMassWeightedDisplacement::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & position(atomPositions_->quantity());
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & refPosition(atomReferencePositions_->quantity());
|
|
|
|
// q = m * (x - xref)
|
|
quantity_ = position;
|
|
quantity_ -= refPosition;
|
|
quantity_ *= mass;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomicMomentum
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomicMomentum::AtomicMomentum(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,atc->nsd(),atomType),
|
|
atomVelocities_(atomVelocities),
|
|
atomMasses_(atomMasses)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_)
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
if (!atomMasses_)
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
|
|
atomVelocities_->register_dependence(this);
|
|
atomMasses_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomicMomentum::~AtomicMomentum()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
atomMasses_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomicMomentum::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
|
|
// q = m * v
|
|
quantity_ = velocity;
|
|
quantity_ *= mass;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TwiceKineticEnergy
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
TwiceKineticEnergy::TwiceKineticEnergy(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
AtomType atomType) :
|
|
AtomicEnergyForTemperature(atc,atomType),
|
|
atomVelocities_(atomVelocities),
|
|
atomMasses_(atomMasses)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_)
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
if (!atomMasses_)
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
|
|
atomVelocities_->register_dependence(this);
|
|
atomMasses_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
TwiceKineticEnergy::~TwiceKineticEnergy()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
atomMasses_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void TwiceKineticEnergy::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
|
|
// q = m * (v dot v)
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
quantity_(i,0) = velocity(i,0)*velocity(i,0);
|
|
for (int j = 1; j < velocity.nCols(); j++) {
|
|
quantity_(i,0) += velocity(i,j)*velocity(i,j);
|
|
}
|
|
quantity_(i,0) *= mass(i,0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class FluctuatingVelocity
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
FluctuatingVelocity::FluctuatingVelocity(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
PerAtomQuantity<double> * atomMeanVelocities,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,3,atomType),
|
|
atomVelocities_(atomVelocities),
|
|
atomMeanVelocities_(atomMeanVelocities)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_) {
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(
|
|
LammpsInterface::ATOM_VELOCITY, atomType);
|
|
}
|
|
if (!atomMeanVelocities_) {
|
|
atomMeanVelocities_ = interscaleManager.per_atom_quantity("AtomicMeanVelocity");
|
|
}
|
|
|
|
atomVelocities_->register_dependence(this);
|
|
atomMeanVelocities_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
FluctuatingVelocity::~FluctuatingVelocity()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
atomMeanVelocities_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void FluctuatingVelocity::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
const DENS_MAT & meanVelocity(atomMeanVelocities_->quantity());
|
|
|
|
// q = m * (v dot v)
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
for (int j = 0; j < velocity.nCols(); j++) {
|
|
quantity_(i,j) = velocity(i,j) - meanVelocity(i,j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class ChargeVelocity
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
ChargeVelocity::ChargeVelocity(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
FundamentalAtomQuantity * atomCharge,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,3,atomType),
|
|
fluctuatingVelocities_(atomVelocities),
|
|
atomCharge_(atomCharge)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!fluctuatingVelocities_) {
|
|
fluctuatingVelocities_ = interscaleManager.per_atom_quantity("AtomicFluctuatingVelocity");
|
|
}
|
|
if (!atomCharge_) {
|
|
atomCharge_ = interscaleManager.fundamental_atom_quantity(
|
|
LammpsInterface::ATOM_CHARGE, atomType);
|
|
}
|
|
fluctuatingVelocities_->register_dependence(this);
|
|
atomCharge_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
ChargeVelocity::~ChargeVelocity()
|
|
{
|
|
fluctuatingVelocities_->remove_dependence(this);
|
|
atomCharge_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void ChargeVelocity::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & velocity(fluctuatingVelocities_->quantity());
|
|
const DENS_MAT & charge(atomCharge_->quantity());
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
for (int j = 0; j < velocity.nCols(); j++) {
|
|
quantity_(i,j) = charge(i,0)*velocity(i,j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class SpeciesVelocity
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
SpeciesVelocity::SpeciesVelocity(ATC_Method * atc,
|
|
PerAtomQuantity<double> * fluctuatingVelocities,
|
|
PerAtomQuantity<double> * atomTypeVector,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,3*(atomTypeVector->nCols()),atomType),
|
|
fluctuatingVelocities_(fluctuatingVelocities),
|
|
atomTypeVector_(atomTypeVector)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!fluctuatingVelocities_) {
|
|
fluctuatingVelocities_ = interscaleManager.per_atom_quantity("AtomicFluctuatingVelocity");
|
|
}
|
|
if (!atomTypeVector_) {
|
|
atomTypeVector_ = interscaleManager.per_atom_quantity("AtomicTypeVector");
|
|
}
|
|
fluctuatingVelocities_->register_dependence(this);
|
|
atomTypeVector_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
SpeciesVelocity::~SpeciesVelocity()
|
|
{
|
|
fluctuatingVelocities_->remove_dependence(this);
|
|
atomTypeVector_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void SpeciesVelocity::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & velocity(fluctuatingVelocities_->quantity());
|
|
const DENS_MAT & tv(atomTypeVector_->quantity());
|
|
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
int m = 0;
|
|
for (int j = 0; j < velocity.nCols(); j++) {
|
|
for (int k = 0; j < tv.nCols(); j++) {
|
|
quantity_(i,m++) = tv(i,k)*velocity(i,j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TwiceFluctuatingKineticEnergy
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
TwiceFluctuatingKineticEnergy::TwiceFluctuatingKineticEnergy(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
PerAtomQuantity<double> * atomMeanVelocities,
|
|
AtomType atomType) :
|
|
AtomicEnergyForTemperature(atc,atomType),
|
|
atomVelocities_(atomVelocities),
|
|
atomMasses_(atomMasses),
|
|
atomMeanVelocities_(atomMeanVelocities)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_) {
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
}
|
|
if (!atomMasses_) {
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
}
|
|
if (!atomMeanVelocities_) {
|
|
atomMeanVelocities_ = interscaleManager.per_atom_quantity("AtomicMeanVelocity");
|
|
}
|
|
|
|
atomVelocities_->register_dependence(this);
|
|
atomMasses_->register_dependence(this);
|
|
atomMeanVelocities_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
TwiceFluctuatingKineticEnergy::~TwiceFluctuatingKineticEnergy()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
atomMasses_->remove_dependence(this);
|
|
atomMeanVelocities_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void TwiceFluctuatingKineticEnergy::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
const DENS_MAT & meanVelocity(atomMeanVelocities_->quantity());
|
|
|
|
// q = m * (v dot v)
|
|
double vRel;
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
vRel = velocity(i,0) - meanVelocity(i,0);
|
|
quantity_(i,0) = vRel*vRel;
|
|
for (int j = 1; j < velocity.nCols(); j++) {
|
|
vRel = velocity(i,j) - meanVelocity(i,j);
|
|
quantity_(i,0) += vRel*vRel;;
|
|
}
|
|
quantity_(i,0) *= mass(i,0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class KineticTensor
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
KineticTensor::KineticTensor(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,6,atomType),
|
|
atomVelocities_(atomVelocities),
|
|
atomMasses_(atomMasses)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_) {
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
}
|
|
if (!atomMasses_) {
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
}
|
|
|
|
atomVelocities_->register_dependence(this);
|
|
atomMasses_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
KineticTensor::~KineticTensor()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
atomMasses_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void KineticTensor::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
|
|
// K = m * (v \otimes v)
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
double m = mass(i,0);
|
|
double v[3] = {velocity(i,0),velocity(i,1),velocity(i,2)};
|
|
quantity_(i,0) -= m*v[0]*v[0];
|
|
quantity_(i,1) -= m*v[1]*v[1];
|
|
quantity_(i,2) -= m*v[2]*v[2];
|
|
quantity_(i,3) -= m*v[0]*v[1];
|
|
quantity_(i,4) -= m*v[0]*v[2];
|
|
quantity_(i,5) -= m*v[1]*v[2];
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class FluctuatingKineticTensor
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
FluctuatingKineticTensor::FluctuatingKineticTensor(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
PerAtomQuantity<double> * atomMeanVelocities,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,6,atomType),
|
|
atomVelocities_(atomVelocities),
|
|
atomMasses_(atomMasses)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_) {
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
}
|
|
if (!atomMasses_) {
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
}
|
|
if (!atomMeanVelocities_) {
|
|
atomMeanVelocities_ = interscaleManager.per_atom_quantity("AtomicMeanVelocity");
|
|
}
|
|
|
|
atomVelocities_->register_dependence(this);
|
|
atomMasses_->register_dependence(this);
|
|
atomMeanVelocities_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
FluctuatingKineticTensor::~FluctuatingKineticTensor()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
atomMasses_->remove_dependence(this);
|
|
atomMeanVelocities_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void FluctuatingKineticTensor::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
const DENS_MAT & meanVelocity(atomMeanVelocities_->quantity());
|
|
|
|
// K = m * (v \otimes v)
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
double m = mass(i,0);
|
|
double v[3] = {velocity(i,0)-meanVelocity(i,0),
|
|
velocity(i,1)-meanVelocity(i,0),
|
|
velocity(i,2)-meanVelocity(i,0)};
|
|
quantity_(i,0) -= m*v[0]*v[0];
|
|
quantity_(i,1) -= m*v[1]*v[1];
|
|
quantity_(i,2) -= m*v[2]*v[2];
|
|
quantity_(i,3) -= m*v[0]*v[1];
|
|
quantity_(i,4) -= m*v[0]*v[2];
|
|
quantity_(i,5) -= m*v[1]*v[2];
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class MixedKePeEnergy
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
MixedKePeEnergy::MixedKePeEnergy(ATC_Method * atc,
|
|
double keMultiplier,
|
|
double peMultiplier,
|
|
PerAtomQuantity<double> * twiceKineticEnergy,
|
|
PerAtomQuantity<double> * potentialEnergy,
|
|
AtomType atomType) :
|
|
AtomicEnergyForTemperature(atc,atomType),
|
|
keMultiplier_(keMultiplier),
|
|
peMultiplier_(peMultiplier),
|
|
twiceKineticEnergy_(twiceKineticEnergy),
|
|
potentialEnergy_(potentialEnergy)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!twiceKineticEnergy_) {
|
|
twiceKineticEnergy_ = interscaleManager.per_atom_quantity("AtomicTwiceKineticEnergy");
|
|
}
|
|
if (!potentialEnergy_) {
|
|
potentialEnergy_ = interscaleManager.per_atom_quantity("AtomicFluctuatingPotentialEnergy");
|
|
}
|
|
|
|
twiceKineticEnergy_->register_dependence(this);
|
|
potentialEnergy_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
MixedKePeEnergy::~MixedKePeEnergy()
|
|
{
|
|
twiceKineticEnergy_->remove_dependence(this);
|
|
potentialEnergy_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void MixedKePeEnergy::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & twoKe(twiceKineticEnergy_->quantity());
|
|
const DENS_MAT & pe(potentialEnergy_->quantity());
|
|
|
|
// q = peScale * pe + keScale * ke
|
|
quantity_ = pe;
|
|
quantity_ *= peMultiplier_;
|
|
quantity_ += (keMultiplier_/2.)*twoKe;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class TotalEnergy
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
TotalEnergy::TotalEnergy(ATC_Method * atc,
|
|
PerAtomQuantity<double> * twiceKineticEnergy,
|
|
PerAtomQuantity<double> * potentialEnergy,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,atomType),
|
|
twiceKineticEnergy_(twiceKineticEnergy),
|
|
potentialEnergy_(potentialEnergy)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
|
|
if (!twiceKineticEnergy_) {
|
|
twiceKineticEnergy_ = interscaleManager.per_atom_quantity("AtomicTwiceKineticEnergy");
|
|
}
|
|
if (!potentialEnergy_) {
|
|
potentialEnergy_ = interscaleManager.per_atom_quantity("AtomicPotentialEnergy");
|
|
}
|
|
twiceKineticEnergy_->register_dependence(this);
|
|
potentialEnergy_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
TotalEnergy::~TotalEnergy()
|
|
{
|
|
twiceKineticEnergy_->remove_dependence(this);
|
|
potentialEnergy_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void TotalEnergy::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & twoKe(twiceKineticEnergy_->quantity());
|
|
const DENS_MAT & pe(potentialEnergy_->quantity());
|
|
quantity_ = pe;
|
|
quantity_ += (0.5)*twoKe;
|
|
}
|
|
}
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class FluctuatingPotentialEnergy
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
FluctuatingPotentialEnergy::FluctuatingPotentialEnergy(ATC_Method * atc,
|
|
PerAtomQuantity<double> * potentialEnergy,
|
|
PerAtomQuantity<double> * referencePotential,
|
|
AtomType atomType) :
|
|
AtomicEnergyForTemperature(atc,atomType),
|
|
potentialEnergy_(potentialEnergy),
|
|
referencePotential_(referencePotential)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!potentialEnergy_) {
|
|
potentialEnergy_ = interscaleManager.per_atom_quantity("AtomicPotentialEnergy");
|
|
}
|
|
if (!referencePotential_) {
|
|
referencePotential_ = interscaleManager.per_atom_quantity("AtomicReferencePotential");
|
|
}
|
|
|
|
potentialEnergy_->register_dependence(this);
|
|
referencePotential_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
FluctuatingPotentialEnergy::~FluctuatingPotentialEnergy()
|
|
{
|
|
potentialEnergy_->remove_dependence(this);
|
|
referencePotential_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void FluctuatingPotentialEnergy::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & pe(potentialEnergy_->quantity());
|
|
const DENS_MAT & refPe(referencePotential_->quantity());
|
|
|
|
quantity_ = pe;
|
|
quantity_ -= refPe;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class DotTwiceKineticEnergy
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
DotTwiceKineticEnergy::DotTwiceKineticEnergy(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomForces,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,1,atomType),
|
|
atomForces_(atomForces),
|
|
atomVelocities_(atomVelocities)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomForces_)
|
|
atomForces_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_FORCE,
|
|
atomType);
|
|
if (!atomVelocities_)
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
|
|
atomForces_->register_dependence(this);
|
|
atomVelocities_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
DotTwiceKineticEnergy::~DotTwiceKineticEnergy()
|
|
{
|
|
atomForces_->remove_dependence(this);
|
|
atomVelocities_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void DotTwiceKineticEnergy::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
const DENS_MAT & force(atomForces_->quantity());
|
|
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
quantity_(i,0) = velocity(i,0)*force(i,0);
|
|
for (int j = 1; j < velocity.nCols(); j++) {
|
|
quantity_(i,0) += velocity(i,j)*force(i,j);
|
|
}
|
|
quantity_(i,0) *= 2.;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class VelocitySquared
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
VelocitySquared::VelocitySquared(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,1,atomType),
|
|
atomVelocities_(atomVelocities)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_)
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
atomVelocities_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
VelocitySquared::~VelocitySquared()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void VelocitySquared::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
quantity_(i,0) = velocity(i,0)*velocity(i,0);
|
|
for (int j = 1; j < velocity.nCols(); j++) {
|
|
quantity_(i,0) += velocity(i,j)*velocity(i,j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class LambdaSquared
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
LambdaSquared::LambdaSquared(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
PerAtomQuantity<double> * atomVelocitiesSquared,
|
|
PerAtomQuantity<double> * atomLambdas,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,1,atomType),
|
|
atomMasses_(atomMasses),
|
|
atomVelocitiesSquared_(atomVelocitiesSquared),
|
|
atomLambdas_(atomLambdas)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomMasses_) {
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
}
|
|
atomMasses_->register_dependence(this);
|
|
|
|
if (!atomVelocitiesSquared) {
|
|
atomVelocitiesSquared_ = interscaleManager.per_atom_quantity("LambdaSquared");
|
|
}
|
|
atomVelocitiesSquared_->register_dependence(this);
|
|
|
|
if (!atomLambdas_) {
|
|
atomLambdas_ = interscaleManager.per_atom_quantity("AtomLambdaEnergy");
|
|
}
|
|
atomLambdas_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
LambdaSquared::~LambdaSquared()
|
|
{
|
|
atomMasses_->remove_dependence(this);
|
|
atomVelocitiesSquared_->remove_dependence(this);
|
|
atomLambdas_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void LambdaSquared::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & velocitySquared(atomVelocitiesSquared_->quantity());
|
|
const DENS_MAT & lambda(atomLambdas_->quantity());
|
|
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
quantity_(i,0) = lambda(i,0)*lambda(i,0)*velocitySquared(i,0)/mass(i,0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomToType
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomToType::AtomToType(ATC_Method * atc,
|
|
int type,
|
|
AtomType atomType) :
|
|
LargeToSmallAtomMap(atc,atomType),
|
|
type_(type)
|
|
{
|
|
// DO NOTHING
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomToType::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<int>::reset();
|
|
quantity_ = -1.;
|
|
size_ = 0;
|
|
const int * type = lammpsInterface_->atom_type();
|
|
|
|
const Array<int> & quantityToLammps = atc_.atc_to_lammps_map();
|
|
for (int i = 0; i < quantity_.nRows(); ++i) {
|
|
int atomIdx = quantityToLammps(i);
|
|
if (type[atomIdx] == type_) {
|
|
quantity_(i,0) = size_;
|
|
++size_;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomToGroup
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomToGroup::AtomToGroup(ATC_Method * atc,
|
|
int group,
|
|
AtomType atomType) :
|
|
LargeToSmallAtomMap(atc,atomType),
|
|
group_(group)
|
|
{
|
|
// DO NOTHING
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomToGroup::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<int>::reset();
|
|
quantity_ = -1.;
|
|
size_ = 0;
|
|
const int * mask = lammpsInterface_->atom_mask();
|
|
|
|
const Array<int> & quantityToLammps = atc_.atc_to_lammps_map();
|
|
for (int i = 0; i < quantity_.nRows(); ++i) {
|
|
int atomIdx = quantityToLammps(i);
|
|
if (mask[atomIdx] & group_) {
|
|
quantity_(i,0) = size_;
|
|
++size_;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomToNodeset
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomToNodeset::AtomToNodeset(ATC_Method * atc,
|
|
SetDependencyManager<int> * subsetNodes,
|
|
PerAtomQuantity<int> * atomElement,
|
|
AtomType atomType) :
|
|
LargeToSmallAtomMap(atc,atomType),
|
|
subsetNodes_(subsetNodes),
|
|
atomElement_(atomElement),
|
|
feMesh_((atc->fe_engine())->fe_mesh())
|
|
{
|
|
if (!atomElement_) {
|
|
atomElement_ = (atc->interscale_manager()).per_atom_int_quantity("AtomElement");
|
|
}
|
|
if (atomElement_) {
|
|
atomElement_->register_dependence(this);
|
|
}
|
|
else {
|
|
throw ATC_Error("PerAtomQuantityLibrary::AtomToRegulated - No AtomElement provided");
|
|
}
|
|
|
|
subsetNodes_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// quantity
|
|
//--------------------------------------------------------
|
|
void AtomToNodeset::reset() const
|
|
{
|
|
|
|
//so it has been commented out.
|
|
/*
|
|
if (need_reset()) {
|
|
PerAtomQuantity<int>::reset();
|
|
const INT_ARRAY & atomElement(atomElement_->quantity());
|
|
const set<int> & subsetNodes(subsetNodes_->quantity());
|
|
int nLocal = atomElement.nRows();
|
|
quantity_.resize(nLocal,1);
|
|
quantity_ = -1;
|
|
size_ = 0;
|
|
|
|
for (int i = 0; i < nLocal; ++i) {
|
|
feMesh_->element_connectivity_unique(atomElement(i,0),_nodes_);
|
|
for (int j = 0; j < _nodes_.size(); ++j) {
|
|
if (subsetNodes.find(_nodes_(j)) != subsetNodes.end()) {
|
|
quantity_(i,0) = size_;
|
|
size_++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomToElementset
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
AtomToElementset::AtomToElementset(ATC_Method * atc,
|
|
MatrixDependencyManager<DenseMatrix, bool> * elementMask,
|
|
PerAtomQuantity<int> * atomElement,
|
|
AtomType atomType) :
|
|
LargeToSmallAtomMap(atc,atomType),
|
|
elementMask_(elementMask),
|
|
atomElement_(atomElement),
|
|
feMesh_((atc->fe_engine())->fe_mesh())
|
|
{
|
|
if (!atomElement_) {
|
|
atomElement_ = (atc->interscale_manager()).per_atom_int_quantity("AtomElement");
|
|
}
|
|
if (atomElement_) {
|
|
atomElement_->register_dependence(this);
|
|
}
|
|
else {
|
|
throw ATC_Error("PerAtomQuantityLibrary::AtomToRegulated - No AtomElement provided");
|
|
}
|
|
|
|
elementMask_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomToElementset::~AtomToElementset()
|
|
{
|
|
atomElement_->remove_dependence(this);
|
|
elementMask_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// quantity
|
|
//--------------------------------------------------------
|
|
void AtomToElementset::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<int>::reset();
|
|
const INT_ARRAY & atomElement(atomElement_->quantity());
|
|
const DenseMatrix<bool> & elementMask(elementMask_->quantity());
|
|
int nLocal = atomElement.nRows();
|
|
quantity_.resize(nLocal,1);
|
|
quantity_ = -1;
|
|
size_ = 0;
|
|
|
|
for (int i = 0; i < nLocal; ++i) {
|
|
if (elementMask(atomElement(i,0),0)) {
|
|
quantity_(i,0) = size_;
|
|
size_++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class MappedAtomQuantity
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
MappedAtomQuantity::MappedAtomQuantity(ATC_Method * atc,
|
|
PerAtomQuantity<double> * source,
|
|
LargeToSmallAtomMap * map,
|
|
AtomType atomType) :
|
|
ProtectedMappedAtomQuantity<double>(atc,map,source->nCols(),atomType),
|
|
source_(source),
|
|
map_(map)
|
|
{
|
|
source_->register_dependence(this);
|
|
map_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset_quantity
|
|
//--------------------------------------------------------
|
|
void MappedAtomQuantity::reset() const
|
|
{
|
|
if (needReset_) {
|
|
ProtectedMappedAtomQuantity<double>::reset();
|
|
const DENS_MAT & source(source_->quantity());
|
|
const INT_ARRAY & map(map_->quantity());
|
|
quantity_.resize(map_->size(),source.nCols());
|
|
|
|
for (int i = 0; i < source.nRows(); i++) {
|
|
int idx = map(i,0);
|
|
if (idx > -1) {
|
|
for (int j = 0; j < source.nCols(); j++) {
|
|
quantity_(idx,j) = source(i,j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class VelocitySquaredMapped
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
VelocitySquaredMapped::VelocitySquaredMapped(ATC_Method * atc,
|
|
MatrixDependencyManager<DenseMatrix, int> * atomMap,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
AtomType atomType) :
|
|
ProtectedMappedAtomQuantity<double>(atc,atomMap,1,atomType),
|
|
atomVelocities_(atomVelocities)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomVelocities_)
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
atomVelocities_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
VelocitySquaredMapped::~VelocitySquaredMapped()
|
|
{
|
|
atomVelocities_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void VelocitySquaredMapped::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
ProtectedMappedAtomQuantity<double>::reset();
|
|
const DENS_MAT & velocity(atomVelocities_->quantity());
|
|
const INT_ARRAY & atomMap(atomMap_->quantity());
|
|
|
|
for (int i = 0; i < atomMap.nRows(); i++) {
|
|
int idx = atomMap(i,0);
|
|
if (idx > -1) {
|
|
quantity_(idx,0) = velocity(i,0)*velocity(i,0);
|
|
for (int j = 1; j < velocity.nCols(); j++) {
|
|
quantity_(idx,0) += velocity(i,j)*velocity(i,j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class LambdaSquaredMapped
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
LambdaSquaredMapped::LambdaSquaredMapped(ATC_Method * atc,
|
|
MatrixDependencyManager<DenseMatrix, int> * atomMap,
|
|
PerAtomQuantity<double> * atomMasses,
|
|
PerAtomQuantity<double> * atomVelocitiesSquared,
|
|
PerAtomQuantity<double> * atomLambdas,
|
|
AtomType atomType) :
|
|
ProtectedMappedAtomQuantity<double>(atc,atomMap,1,atomType),
|
|
atomMasses_(atomMasses),
|
|
atomVelocitiesSquared_(atomVelocitiesSquared),
|
|
atomLambdas_(atomLambdas)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomMasses_) {
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
}
|
|
atomMasses_->register_dependence(this);
|
|
|
|
if (!atomVelocitiesSquared) {
|
|
atomVelocitiesSquared_ = interscaleManager.per_atom_quantity("LambdaSquared");
|
|
}
|
|
atomVelocitiesSquared_->register_dependence(this);
|
|
|
|
if (!atomLambdas_) {
|
|
atomLambdas_ = interscaleManager.per_atom_quantity("AtomLambdaEnergy");
|
|
}
|
|
atomLambdas_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
LambdaSquaredMapped::~LambdaSquaredMapped()
|
|
{
|
|
atomMasses_->remove_dependence(this);
|
|
atomVelocitiesSquared_->remove_dependence(this);
|
|
atomLambdas_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void LambdaSquaredMapped::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
ProtectedMappedAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & velocitySquared(atomVelocitiesSquared_->quantity());
|
|
const DENS_MAT & lambda(atomLambdas_->quantity());
|
|
const INT_ARRAY & atomMap(atomMap_->quantity());
|
|
|
|
for (int i = 0; i < atomMap.nRows(); i++) {
|
|
int idx = atomMap(i,0);
|
|
if (idx > -1) {
|
|
quantity_(idx,0) = lambda(i,0)*lambda(i,0)*velocitySquared(idx,0)/mass(i,0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class HeatCapacity
|
|
// computes the classical atomic heat capacity
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
HeatCapacity::HeatCapacity(ATC_Method * atc, AtomType atomType) :
|
|
ConstantQuantity<double>(atc,1,1,atomType)
|
|
{
|
|
constant_ = (atc->nsd())*(lammpsInterface_->kBoltzmann());
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomicVelocityRescaleFactor
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomicVelocityRescaleFactor::AtomicVelocityRescaleFactor(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomLambdas,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,1,atomType),
|
|
atomMasses_(NULL),
|
|
atomLambdas_(atomLambdas)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
atomMasses_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
if (!atomLambdas) {
|
|
atomLambdas_ = interscaleManager.per_atom_quantity("AtomLambdaEnergy");
|
|
}
|
|
|
|
atomMasses_->register_dependence(this);
|
|
atomLambdas_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomicVelocityRescaleFactor::~AtomicVelocityRescaleFactor()
|
|
{
|
|
atomMasses_->remove_dependence(this);
|
|
atomLambdas_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomicVelocityRescaleFactor::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & mass(atomMasses_->quantity());
|
|
const DENS_MAT & lambda(atomLambdas_->quantity());
|
|
|
|
for (int i = 0; i < quantity_.nRows(); i++) {
|
|
quantity_(i,0) = sqrt(lambda(i,0)/mass(i,0));
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomicThermostatForce
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomicThermostatForce::AtomicThermostatForce(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomLambdas,
|
|
PerAtomQuantity<double> * atomVelocities,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,atc->nsd(),atomType),
|
|
atomLambdas_(atomLambdas),
|
|
atomVelocities_(atomVelocities)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomLambdas) {
|
|
atomLambdas_ = interscaleManager.per_atom_quantity("AtomLambdaEnergy");
|
|
}
|
|
if (!atomVelocities_) {
|
|
atomVelocities_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_VELOCITY,
|
|
atomType);
|
|
}
|
|
|
|
atomLambdas_->register_dependence(this);
|
|
atomVelocities_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomicThermostatForce::~AtomicThermostatForce()
|
|
{
|
|
atomLambdas_->remove_dependence(this);
|
|
atomVelocities_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomicThermostatForce::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & v(atomVelocities_->quantity());
|
|
const DENS_MAT & lambda(atomLambdas_->quantity());
|
|
|
|
// force = -lambda*v
|
|
quantity_ = v;
|
|
quantity_ *= lambda;
|
|
quantity_ *= -1.;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomicKinetostatForceDisplacement
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomicKinetostatForceDisplacement::AtomicKinetostatForceDisplacement(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomLambda,
|
|
PerAtomQuantity<double> * atomMass,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,atc->nsd(),atomType),
|
|
atomLambda_(atomLambda),
|
|
atomMass_(atomMass)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomLambda) {
|
|
atomLambda_ = interscaleManager.per_atom_quantity("AtomLambdaMomentum");
|
|
}
|
|
if (!atomMass_) {
|
|
atomMass_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS,
|
|
atomType);
|
|
}
|
|
|
|
atomLambda_->register_dependence(this);
|
|
atomMass_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomicKinetostatForceDisplacement::~AtomicKinetostatForceDisplacement()
|
|
{
|
|
atomLambda_->remove_dependence(this);
|
|
atomMass_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomicKinetostatForceDisplacement::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & m(atomMass_->quantity());
|
|
const DENS_MAT & lambda(atomLambda_->quantity());
|
|
double timeFactor = time_step_factor(0.5*atc_.dt());
|
|
|
|
//force = -lambda*m*(timestep factor)
|
|
quantity_ = lambda;
|
|
quantity_ *= m;
|
|
quantity_ *= -1.*timeFactor;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class AtomicKinetostatForceStress
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
AtomicKinetostatForceStress::AtomicKinetostatForceStress(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomLambda,
|
|
AtomType atomType) :
|
|
ProtectedAtomQuantity<double>(atc,atc->nsd(),atomType),
|
|
atomLambda_(atomLambda)
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomLambda_) {
|
|
atomLambda_ = interscaleManager.per_atom_quantity("AtomLambdaMomentum");
|
|
}
|
|
|
|
atomLambda_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
AtomicKinetostatForceStress::~AtomicKinetostatForceStress()
|
|
{
|
|
atomLambda_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void AtomicKinetostatForceStress::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomQuantity<double>::reset();
|
|
const DENS_MAT & lambda(atomLambda_->quantity());
|
|
|
|
// force = -lambda
|
|
quantity_ = lambda;
|
|
quantity_ *= -1.;
|
|
}
|
|
}
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class PerAtomKernelFunction
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
PerAtomKernelFunction::PerAtomKernelFunction(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomPositions,
|
|
AtomType atomType) :
|
|
ProtectedAtomSparseMatrix<double>(atc,(atc->fe_engine())->num_nodes(),atc->accumulant_bandwidth(),atomType),
|
|
atomPositions_(atomPositions),
|
|
feEngine_(atc->fe_engine())
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomPositions_) {
|
|
atomPositions_ = interscaleManager.per_atom_quantity("AtomicCoarseGrainingPositions");
|
|
}
|
|
atomPositions_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
PerAtomKernelFunction::~PerAtomKernelFunction()
|
|
{
|
|
atomPositions_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void PerAtomKernelFunction::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomSparseMatrix<double>::reset();
|
|
const DENS_MAT & positions(atomPositions_->quantity());
|
|
if (positions.nRows() > 0) {
|
|
feEngine_->evaluate_kernel_functions(positions,quantity_);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class PerAtomShapeFunction
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// constructor
|
|
//--------------------------------------------------------
|
|
PerAtomShapeFunction::PerAtomShapeFunction(ATC_Method * atc,
|
|
PerAtomQuantity<double> * atomPositions,
|
|
PerAtomQuantity<int> * atomElements,
|
|
AtomType atomType) :
|
|
ProtectedAtomSparseMatrix<double>(atc,atc->num_nodes(),(atc->fe_engine())->num_nodes_per_element(),atomType),
|
|
atomPositions_(atomPositions),
|
|
atomElements_(atomElements),
|
|
feEngine_(atc->fe_engine())
|
|
{
|
|
InterscaleManager & interscaleManager(atc->interscale_manager());
|
|
if (!atomPositions_) {
|
|
atomPositions_ = interscaleManager.per_atom_quantity("AtomicCoarseGrainingPositions");
|
|
}
|
|
if (!atomElements_) {
|
|
atomElements_ = interscaleManager.per_atom_int_quantity("AtomElement");
|
|
}
|
|
|
|
atomPositions_->register_dependence(this);
|
|
atomElements_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// destructor
|
|
//--------------------------------------------------------
|
|
PerAtomShapeFunction::~PerAtomShapeFunction()
|
|
{
|
|
atomPositions_->remove_dependence(this);
|
|
atomElements_->remove_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset
|
|
//--------------------------------------------------------
|
|
void PerAtomShapeFunction::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomSparseMatrix<double>::reset();
|
|
const DENS_MAT & positions(atomPositions_->quantity());
|
|
const INT_ARRAY & elements(atomElements_->quantity());
|
|
if (positions.nRows() > 0) {
|
|
feEngine_->evaluate_shape_functions(positions,
|
|
elements,
|
|
quantity_);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class LambdaCouplingMatrix
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
LambdaCouplingMatrix::LambdaCouplingMatrix(ATC_Method * atc,
|
|
MatrixDependencyManager<DenseMatrix, int> * nodeToOverlapMap,
|
|
SPAR_MAN * shapeFunction) :
|
|
ProtectedMappedAtomSparseMatrix<double>(atc,nodeToOverlapMap->size(),
|
|
(atc->fe_engine())->num_nodes_per_element(),
|
|
INTERNAL),
|
|
shapeFunction_(shapeFunction),
|
|
nodeToOverlapMap_(nodeToOverlapMap)
|
|
{
|
|
if (!shapeFunction_) {
|
|
shapeFunction_ = (atc->interscale_manager()).per_atom_sparse_matrix("Interpolant");;
|
|
}
|
|
if (!nodeToOverlapMap_) {
|
|
nodeToOverlapMap_ = (atc->interscale_manager()).dense_matrix_int("NodeToOverlapMap");
|
|
}
|
|
|
|
shapeFunction_->register_dependence(this);
|
|
nodeToOverlapMap_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset_quantity
|
|
//--------------------------------------------------------
|
|
void LambdaCouplingMatrix::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomSparseMatrix<double>::reset();
|
|
int nNodeOverlap = nodeToOverlapMap_->size();
|
|
const SPAR_MAT & shapeFunction(shapeFunction_->quantity());
|
|
quantity_.reset(shapeFunction.nRows(),nNodeOverlap); // number of atoms X number of nodes overlapping MD region
|
|
const INT_ARRAY nodeToOverlapMap(nodeToOverlapMap_->quantity());
|
|
|
|
for (int i = 0; i < shapeFunction.size(); ++i) {
|
|
TRIPLET<double> myTriplet = shapeFunction.triplet(i);
|
|
int myCol = nodeToOverlapMap(myTriplet.j,0);
|
|
if (myCol > -1) {
|
|
quantity_.set(myTriplet.i,myCol,myTriplet.v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class LocalLambdaCouplingMatrix
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
LocalLambdaCouplingMatrix::LocalLambdaCouplingMatrix(ATC_Method * atc,
|
|
MatrixDependencyManager<DenseMatrix, int> * lambdaAtomMap,
|
|
MatrixDependencyManager<DenseMatrix, int> * nodeToOverlapMap,
|
|
SPAR_MAN * shapeFunction) :
|
|
LambdaCouplingMatrix(atc,nodeToOverlapMap,shapeFunction),
|
|
lambdaAtomMap_(lambdaAtomMap)
|
|
{
|
|
if (!lambdaAtomMap_) {
|
|
lambdaAtomMap_ = (atc->interscale_manager()).dense_matrix_int("LambdaAtomMap");
|
|
}
|
|
|
|
lambdaAtomMap_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset_quantity
|
|
//--------------------------------------------------------
|
|
void LocalLambdaCouplingMatrix::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomSparseMatrix<double>::reset();
|
|
int nNodeOverlap = nodeToOverlapMap_->size();
|
|
int nLocalLambda = lambdaAtomMap_->size();
|
|
|
|
quantity_.reset(nLocalLambda,nNodeOverlap); // number of regulated atoms X number of nodes containing them
|
|
const SPAR_MAT & shapeFunction(shapeFunction_->quantity());
|
|
const INT_ARRAY nodeToOverlapMap(nodeToOverlapMap_->quantity());
|
|
const INT_ARRAY lambdaAtomMap(lambdaAtomMap_->quantity());
|
|
|
|
for (int i = 0; i < shapeFunction.size(); ++i) {
|
|
TRIPLET<double> myTriplet = shapeFunction.triplet(i);
|
|
int myRow = lambdaAtomMap(myTriplet.i,0);
|
|
int myCol = nodeToOverlapMap(myTriplet.j,0);
|
|
if ((myRow > -1) && (myCol > -1)) {
|
|
quantity_.set(myRow,myCol,myTriplet.v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
// Class GhostCouplingMatrix
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
// Constructor
|
|
//--------------------------------------------------------
|
|
GhostCouplingMatrix::GhostCouplingMatrix(ATC_Method * atc,
|
|
SPAR_MAN * shapeFunction,
|
|
SetDependencyManager<int> * subsetNodes,
|
|
MatrixDependencyManager<DenseMatrix, int> * nodeToOverlapMap) :
|
|
LambdaCouplingMatrix(atc,nodeToOverlapMap,shapeFunction),
|
|
subsetNodes_(subsetNodes)
|
|
{
|
|
subsetNodes_->register_dependence(this);
|
|
}
|
|
|
|
//--------------------------------------------------------
|
|
// reset_quantity
|
|
//--------------------------------------------------------
|
|
void GhostCouplingMatrix::reset() const
|
|
{
|
|
if (need_reset()) {
|
|
PerAtomSparseMatrix<double>::reset();
|
|
const SPAR_MAT & shapeFunction(shapeFunction_->quantity());
|
|
const set<int> & subsetNodes(subsetNodes_->quantity());
|
|
int nNodes = nodeToOverlapMap_->nRows();
|
|
int nLocalGhost = shapeFunction.nRows();
|
|
quantity_.reset(nLocalGhost,nNodes);
|
|
const INT_ARRAY nodeToOverlapMap(nodeToOverlapMap_->quantity());
|
|
for (int i = 0; i < shapeFunction.size(); ++i) {
|
|
TRIPLET<double> myTriplet = shapeFunction.triplet(i);
|
|
int myCol = myTriplet.j;
|
|
if (nodeToOverlapMap(myCol,0) > -1) {
|
|
quantity_.set(myTriplet.i,myCol,myTriplet.v);
|
|
}
|
|
}
|
|
quantity_.compress();
|
|
|
|
//int nNodes = nodeToOverlapMap_->nRows();
|
|
_activeNodes_.reset(nNodes);
|
|
for (int i = 0; i < nNodes; ++i) {
|
|
if (subsetNodes.find(i) != subsetNodes.end()) {
|
|
_activeNodes_(i) = 1.;
|
|
}
|
|
}
|
|
|
|
//const SPAR_MAT & shapeFunction(shapeFunction_->quantity());
|
|
//int nLocalGhost = shapeFunction.nRows();
|
|
_weights_ = shapeFunction*_activeNodes_;
|
|
_weightMatrix_.resize(nLocalGhost,nLocalGhost);
|
|
for (int i = 0; i < nLocalGhost; ++i) {
|
|
_weightMatrix_(i,i) = 1./_weights_(i);
|
|
}
|
|
quantity_ = _weightMatrix_*quantity_;
|
|
}
|
|
}
|
|
};
|