Page MenuHomec4science

quasi_continuum.cc
No OneTemporary

File Metadata

Created
Mon, May 27, 09:38

quasi_continuum.cc

/**
* @file quasi_continuum.cc
*
* @author Till Junge <till.junge@epfl.ch>
*
* @date Mon Jul 07 17:09:15 2014
*
* @brief Quasicontinuum point to point coupling
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but
* WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "quasi_continuum.hh"
#include "communicator.hh"
#include "lib_bridging.hh"
#include "lm_common.hh"
#include "lm_log.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
QuasiContinuum::QuasiContinuum(const std::string &name)
: LMObject(name), CouplingAtomicContinuum(name),
interface_association("InterfaceAssociation:" + name), interface_path(""),
pad_association("PADAssociation:" + name), pad_path(""), weight_path("") {
}
/* -------------------------------------------------------------------------- */
QuasiContinuum::~QuasiContinuum() {}
/* -------------------------------------------------------------------------- */
template <typename DomainA, typename DomainC>
void QuasiContinuum::init(DomainA &domA, DomainC &domC) {
const UInt Dim = spatial_dimension;
std::vector<bool> pbc_flags(spatial_dimension);
for (UInt i = 0; i < Dim; ++i) {
if (this->is_in_atomic)
pbc_flags[i] = domA.isPeriodic(i);
if (this->is_in_continuum)
pbc_flags[i] = domC.isPeriodic(i);
}
this->interface_association.setParam("PBC", pbc_flags);
this->pad_association.setParam("PBC", pbc_flags);
if (!this->arlequin_flag && this->reset_position_freq != 1) {
LM_FATAL("Without arlequin, reset_position_freq must be 1 (which is the "
"default)");
}
STARTTIMER("Interface Association");
this->interface_association.setParam("PATH", this->interface_path);
this->interface_association.init(domA, domC);
this->setBoundary();
STOPTIMER("Interface Association");
STARTTIMER("Pad Association");
this->pad_association.setParam("WEIGHT_PATH", this->weight_path);
this->pad_association.setParam("PATH", this->pad_path);
this->pad_association.init(domA, domC);
this->clearPadForces();
this->clearInterfaceForces();
STOPTIMER("Pad Association");
}
/* -------------------------------------------------------------------------- */
void QuasiContinuum::setBoundary() {
if (this->is_in_continuum) {
LM_TOIMPLEMENT;
// typedef FilterCompatibility<ContMesh> PointsBFilter;
// auto *ptr =
// static_cast<PointsBFilter *>(FilterManager::getManager().getObject(
// "pointsBlist:InterfaceAssociation:" + this->name));
// UInt index = 0;
// for (auto &&point : *ptr) {
// for (UInt dir = 0; dir < Dim; ++dir) {
// point.boundary(dir) = true;
// }
// ++index;
// }
// DUMP("SetBoundary fully blocked " << index << " nodes.", DBG_DETAIL);
}
}
/* -------------------------------------------------------------------------- */
void QuasiContinuum::updateForMigration() {
LM_TOIMPLEMENT;
// Communicator &comm = Communicator::getCommunicator();
// comm.synchronize(Communicator::group_all);
STARTTIMER("updatesForMigrations");
this->interface_association.updateForMigration();
STOPTIMER("updatesForMigrations");
LM_TOIMPLEMENT;
// comm.synchronize(group_all);
STARTTIMER("updatesForMigrations");
this->pad_association.updateForMigration();
STOPTIMER("updatesForMigrations");
LM_TOIMPLEMENT;
// comm.synchronize(group_all);
}
/* -------------------------------------------------------------------------- */
template <typename DomainA, typename DomainC>
void QuasiContinuum::coupling(CouplingStage stage, DomainA &domA,
DomainC &domC) {
if (stage == COUPLING_STEP1) {
updateForMigration();
if (current_step % reset_position_freq == 0) {
this->enforceInterface<_displacement>();
this->enforcePad<_position>();
}
} else if (stage == COUPLING_STEP2) {
this->clearPadForces();
}
// } else if (stage == COUPLING_STEP2) {
// STARTTIMER("clearPadForces");
// this->clearPadForces();
// //this->pad_association.template mixField<_force>();
// STOPTIMER("clearPadForces");
// STARTTIMER("clearInterfaceForces");
// this->clearInterfaceForces();
// //this->interface_association.template mixField<_force>();
// STOPTIMER("clearInterfaceForces");
// }
else if (arlequin_flag && stage == COUPLING_STEP3) {
this->pad_association.template mixField<_velocity>(domA.getContainer(),
domC.getContainer());
this->enforceInterface<_velocity>();
}
}
/* -------------------------------------------------------------------------- */
template <FieldType ftype> void QuasiContinuum::enforceInterface() {
this->interface_association.template enforceField<ftype>();
}
/* -------------------------------------------------------------------------- */
template <FieldType sync_type> void QuasiContinuum::enforcePad() {
this->pad_association.template enforceField<sync_type>();
}
/* -------------------------------------------------------------------------- */
void QuasiContinuum::clearPadForces() {
this->pad_association.zeroFields<_force>();
this->pad_association.zeroFields<_velocity>();
}
/* -------------------------------------------------------------------------- */
void QuasiContinuum::clearInterfaceForces() {
this->interface_association.zeroFields<_force>();
this->interface_association.zeroFields<_velocity>();
}
/* -------------------------------------------------------------------------- */
void QuasiContinuum::clearAll() {
this->interface_association.clearAll();
this->pad_association.clearAll();
}
/* -------------------------------------------------------------------------- */
/* LMDESC QUASICONTINUUM
This coupler implements a CADD/QC style sharp interface coupling between
atomic and continuum domains. The interface and pad atom-nodes are
synchronised using PointAssociation couplers. Based on these, the coupler
creates dumpable containers for:
1) the interface nodes
(pointsBlist:InterfaceAssociation:<name\_of\_coupler>)
2) the interface atoms
(pointsAlist:InterfaceAssociation:<name\_of\_coupler>)
3) the pad nodes (pointsAlist:PadAssociation:<name\_of\_coupler>)
4) the pad atoms (pointsBlist:PadAssociation:<name\_of\_coupler>)
*/
/* LMEXAMPLE
COUPLING_CODE ID md fe QUASICONTINUUM PAD_PATH ./pad_atoms.txt INTERFACE_PATH
./interface_atoms.txt GEOMETRY pad GRID_DIVISION 8 8 4 */
/* LMHERITANCE point_association */
void QuasiContinuum::declareParams() {
// so they can parse their respective tolerances
this->addSubParsableObject(pad_association);
this->addSubParsableObject(interface_association);
/* LMKEYWORD PAD_PATH
String
file path of the file containing pad atoms
*/
this->parseKeyword("PAD_PATH", pad_path);
/* LMKEYWORD INTERFACE_PATH
String
file path of the file containing pad atoms
*/
this->parseKeyword("INTERFACE_PATH", interface_path);
/* LMKEYWORD WEIGHT_SCRIPT
String
file path of the script to use to generate the weights
*/
this->parseKeyword("WEIGHT_SCRIPT", weight_path, "");
/* LMKEYWORD POS_FREQ
The frequency at which the positions should be reset
*/
this->parseKeyword("POS_FREQ", reset_position_freq, 1u);
/* LMKEYWORD ARLEQUIN
Set the arlequin style flavor
*/
this->parseTag("ARLEQUIN", arlequin_flag, false);
}
/* -------------------------------------------------------------------------- */
DECLARE_COUPLER_INIT_MAKE_CALL(QuasiContinuum, domMD, domCONTINUUM)
DECLARE_COUPLING_MAKE_CALL(QuasiContinuum, domMD, domCONTINUUM)
/* ------------------------------------------------------------------------ */
__END_LIBMULTISCALE__

Event Timeline