// ATC transfer headers #include "PerAtomQuantityLibrary.h" #include "ATC_Transfer.h" #include "FE_Engine.h" #include "LammpsInterface.h" #include #include #include 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 * atomPositions, AtomType atomType) : ProtectedAtomQuantity(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::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 * 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 & 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 & atomGroupVolume, AtomType atomType) : ProtectedAtomDiagonalMatrix(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::reset(); const int *mask = lammpsInterface_->atom_mask(); quantity_ = 0.; map::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 & 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(atc,atomType), lammpsInterface_(atc->lammps_interface()) { // do nothing } //-------------------------------------------------------- // reset //-------------------------------------------------------- void AtomVolumeLattice::reset() const { if (need_reset()) { PerAtomDiagonalMatrix::reset(); quantity_ = lammpsInterface_->volume_per_atom(); } } //-------------------------------------------------------- //-------------------------------------------------------- // Class AtomVolumeElement //-------------------------------------------------------- //-------------------------------------------------------- //-------------------------------------------------------- // Constructor //-------------------------------------------------------- AtomVolumeElement::AtomVolumeElement(ATC_Method * atc, PerAtomQuantity * atomElement, AtomType atomType) : ProtectedAtomDiagonalMatrix(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::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)maxx) maxx = _nodalCoordinates_(0,j); if (_nodalCoordinates_(1,j)maxy) maxy = _nodalCoordinates_(1,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(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::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(atc,atomType), atomVolumeFile_(atomVolumeFile), lammpsInterface_(atc->lammps_interface()) { // do nothing } //-------------------------------------------------------- // reset //-------------------------------------------------------- void AtomVolumeFile::reset() const { if (need_reset()) { PerAtomDiagonalMatrix::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 tag2id; map ::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(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 typeList, AtomType atomType) : ProtectedAtomQuantity(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 typeList, vector groupList, AtomType atomType) : ProtectedAtomQuantity(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::reset(); int nlocal = atc_->nlocal(); quantity_.reset(nlocal,typeList_.size()+groupList_.size()); const Array & quantityToLammps = (PerAtomQuantity::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(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 * atomPositions, PerAtomQuantity * atomMasses, PerAtomQuantity * atomReferencePositions, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomVelocities, PerAtomQuantity * atomMasses, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomVelocities, PerAtomQuantity * 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::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 * atomVelocities, PerAtomQuantity * atomMeanVelocities, AtomType atomType) : ProtectedAtomQuantity(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(field_to_prolongation_name(VELOCITY)); } 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::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 * atomVelocities, FundamentalAtomQuantity * atomCharge, AtomType atomType) : ProtectedAtomQuantity(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::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 * fluctuatingVelocities, PerAtomQuantity * atomTypeVector, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomVelocities, PerAtomQuantity * atomMasses, PerAtomQuantity * 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(field_to_prolongation_name(VELOCITY)); } 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::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 * atomVelocities, PerAtomQuantity * atomMasses, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomVelocities, PerAtomQuantity * atomMasses, PerAtomQuantity * atomMeanVelocities, AtomType atomType) : ProtectedAtomQuantity(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(field_to_prolongation_name(VELOCITY)); } 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::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 * twiceKineticEnergy, PerAtomQuantity * 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::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 * twiceKineticEnergy, PerAtomQuantity * potentialEnergy, AtomType atomType) : ProtectedAtomQuantity(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::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 * potentialEnergy, PerAtomQuantity * 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::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 * atomForces, PerAtomQuantity * atomVelocities, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomVelocities, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomMasses, PerAtomQuantity * atomVelocitiesSquared, PerAtomQuantity * atomLambdas, AtomType atomType) : ProtectedAtomQuantity(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::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::reset(); quantity_ = -1.; size_ = 0; const int * type = lammpsInterface_->atom_type(); const Array & 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::reset(); quantity_ = -1.; size_ = 0; const int * mask = lammpsInterface_->atom_mask(); const Array & 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 * subsetNodes, PerAtomQuantity * 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::reset(); const INT_ARRAY & atomElement(atomElement_->quantity()); const set & 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 * elementMask, PerAtomQuantity * 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::reset(); const INT_ARRAY & atomElement(atomElement_->quantity()); const DenseMatrix & 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 * source, LargeToSmallAtomMap * map, AtomType atomType) : ProtectedMappedAtomQuantity(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::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 * atomMap, PerAtomQuantity * atomVelocities, AtomType atomType) : ProtectedMappedAtomQuantity(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::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 * atomMap, PerAtomQuantity * atomMasses, PerAtomQuantity * atomVelocitiesSquared, PerAtomQuantity * atomLambdas, AtomType atomType) : ProtectedMappedAtomQuantity(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::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(atc,1,1,atomType) { constant_ = (atc->nsd())*(lammpsInterface_->kBoltzmann()); } //-------------------------------------------------------- //-------------------------------------------------------- // Class AtomicVelocityRescaleFactor //-------------------------------------------------------- //-------------------------------------------------------- //-------------------------------------------------------- // constructor //-------------------------------------------------------- AtomicVelocityRescaleFactor::AtomicVelocityRescaleFactor(ATC_Method * atc, PerAtomQuantity * atomLambdas, AtomType atomType) : ProtectedAtomQuantity(atc,1,atomType), atomLambdas_(atomLambdas) { InterscaleManager & interscaleManager(atc->interscale_manager()); if (!atomLambdas) { atomLambdas_ = interscaleManager.per_atom_quantity("AtomLambdaEnergy"); } atomLambdas_->register_dependence(this); } //-------------------------------------------------------- // destructor //-------------------------------------------------------- AtomicVelocityRescaleFactor::~AtomicVelocityRescaleFactor() { atomLambdas_->remove_dependence(this); } //-------------------------------------------------------- // reset //-------------------------------------------------------- void AtomicVelocityRescaleFactor::reset() const { if (need_reset()) { PerAtomQuantity::reset(); const DENS_MAT & lambda(atomLambdas_->quantity()); for (int i = 0; i < quantity_.nRows(); i++) { quantity_(i,0) = sqrt(lambda(i,0)); } } } //-------------------------------------------------------- //-------------------------------------------------------- // Class AtomicFluctuatingVelocityRescaled //-------------------------------------------------------- //-------------------------------------------------------- //-------------------------------------------------------- // constructor //-------------------------------------------------------- AtomicFluctuatingVelocityRescaled::AtomicFluctuatingVelocityRescaled(ATC_Method * atc, PerAtomQuantity * atomRescaleFactor, PerAtomQuantity * atomFluctuatingVelocity, AtomType atomType) : ProtectedAtomQuantity(atc,atc->nsd(),atomType), atomRescaleFactor_(atomRescaleFactor), atomFluctuatingVelocity_(atomFluctuatingVelocity) { InterscaleManager & interscaleManager(atc->interscale_manager()); if (!atomRescaleFactor_) { atomRescaleFactor_ = interscaleManager.per_atom_quantity("AtomVelocityRescaling"); } if (!atomFluctuatingVelocity_) { atomFluctuatingVelocity_ = interscaleManager.per_atom_quantity("AtomicFluctuatingVelocity"); } atomRescaleFactor_->register_dependence(this); atomFluctuatingVelocity_->register_dependence(this); } //-------------------------------------------------------- // destructor //-------------------------------------------------------- AtomicFluctuatingVelocityRescaled::~AtomicFluctuatingVelocityRescaled() { atomRescaleFactor_->remove_dependence(this); atomFluctuatingVelocity_->remove_dependence(this); } //-------------------------------------------------------- // reset //-------------------------------------------------------- void AtomicFluctuatingVelocityRescaled::reset() const { if (need_reset()) { PerAtomQuantity::reset(); const DENS_MAT & factor(atomRescaleFactor_->quantity()); const DENS_MAT & v(atomFluctuatingVelocity_->quantity()); for (int i = 0; i < quantity_.nRows(); i++) { for (int j = 0; j < quantity_.nCols(); j++) { quantity_(i,j) = factor(i,0)*v(i,j); } } } } //-------------------------------------------------------- //-------------------------------------------------------- // Class AtomicCombinedRescaleThermostatError //-------------------------------------------------------- //-------------------------------------------------------- //-------------------------------------------------------- // constructor //-------------------------------------------------------- AtomicCombinedRescaleThermostatError::AtomicCombinedRescaleThermostatError(ATC_Method * atc, PerAtomQuantity * atomFluctuatingMomentumRescaled, PerAtomQuantity * atomMeanVelocity, PerAtomQuantity * atomStreamingVelocity, PerAtomQuantity * atomMass, AtomType atomType) : ProtectedAtomQuantity(atc,1,atomType), atomFluctuatingMomentumRescaled_(atomFluctuatingMomentumRescaled), atomMeanVelocity_(atomMeanVelocity), atomStreamingVelocity_(atomStreamingVelocity), atomMass_(atomMass) { InterscaleManager & interscaleManager(atc->interscale_manager()); if (!atomFluctuatingMomentumRescaled_) { atomFluctuatingMomentumRescaled_ = interscaleManager.per_atom_quantity("AtomFluctuatingMomentumRescaled"); } if (!atomMeanVelocity_) { atomMeanVelocity_ = interscaleManager.per_atom_quantity(field_to_prolongation_name(VELOCITY)); } if (!atomStreamingVelocity_) { atomStreamingVelocity_ = interscaleManager.per_atom_quantity("AtomLambdaMomentum"); } if (!atomMass_) { atomMass_ = interscaleManager.fundamental_atom_quantity(LammpsInterface::ATOM_MASS, atomType); } atomFluctuatingMomentumRescaled_->register_dependence(this); atomMeanVelocity_->register_dependence(this); atomStreamingVelocity_->register_dependence(this); atomMass_->register_dependence(this); } //-------------------------------------------------------- // destructor //-------------------------------------------------------- AtomicCombinedRescaleThermostatError::~AtomicCombinedRescaleThermostatError() { atomFluctuatingMomentumRescaled_->remove_dependence(this); atomMeanVelocity_->remove_dependence(this); atomStreamingVelocity_->remove_dependence(this); atomMass_->remove_dependence(this); } //-------------------------------------------------------- // reset //-------------------------------------------------------- void AtomicCombinedRescaleThermostatError::reset() const { if (need_reset()) { PerAtomQuantity::reset(); const DENS_MAT & m(atomMass_->quantity()); const DENS_MAT & p(atomFluctuatingMomentumRescaled_->quantity()); const DENS_MAT & v(atomMeanVelocity_->quantity()); const DENS_MAT & s(atomStreamingVelocity_->quantity()); double diff; for (int i = 0; i < quantity_.nRows(); i++) { diff = s(i,0)-v(i,0); quantity_(i,0) = 2.*p(i,0)*diff + m(i,0)*diff*diff; for (int j = 1; j < p.nCols(); j++) { diff = s(i,j)-v(i,j); quantity_(i,0) += 2.*p(i,j)*diff + m(i,0)*diff*diff; } } } } //-------------------------------------------------------- //-------------------------------------------------------- // Class AtomicThermostatForce //-------------------------------------------------------- //-------------------------------------------------------- //-------------------------------------------------------- // constructor //-------------------------------------------------------- AtomicThermostatForce::AtomicThermostatForce(ATC_Method * atc, PerAtomQuantity * atomLambdas, PerAtomQuantity * atomVelocities, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomLambda, PerAtomQuantity * atomMass, AtomType atomType) : ProtectedAtomQuantity(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::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 * atomLambda, AtomType atomType) : ProtectedAtomQuantity(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::reset(); const DENS_MAT & lambda(atomLambda_->quantity()); // force = -lambda quantity_ = lambda; quantity_ *= -1.; } } //-------------------------------------------------------- //-------------------------------------------------------- // Class PerAtomKernelFunction //-------------------------------------------------------- //-------------------------------------------------------- //-------------------------------------------------------- // constructor //-------------------------------------------------------- PerAtomKernelFunction::PerAtomKernelFunction(ATC_Method * atc, PerAtomQuantity * atomPositions, AtomType atomType) : ProtectedAtomSparseMatrix(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::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 * atomPositions, PerAtomQuantity * atomElements, AtomType atomType) : ProtectedAtomSparseMatrix(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::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 * nodeToOverlapMap, SPAR_MAN * shapeFunction) : ProtectedMappedAtomSparseMatrix(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::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 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 * lambdaAtomMap, MatrixDependencyManager * 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::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 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 * subsetNodes, MatrixDependencyManager * nodeToOverlapMap) : LambdaCouplingMatrix(atc,nodeToOverlapMap,shapeFunction), subsetNodes_(subsetNodes) { subsetNodes_->register_dependence(this); } //-------------------------------------------------------- // reset_quantity //-------------------------------------------------------- void GhostCouplingMatrix::reset() const { if (need_reset()) { PerAtomSparseMatrix::reset(); const SPAR_MAT & shapeFunction(shapeFunction_->quantity()); const set & 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 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_; } } };