Page MenuHomec4science

bridging_atomic_continuum.cc
No OneTemporary

File Metadata

Created
Mon, Jun 24, 11:38

bridging_atomic_continuum.cc

/**
* @file bridging_atomic_continuum.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Oct 28 19:23:14 2013
*
* @brief Bridging object between atomistic and finite elements
*
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
//#define TIMER
/* -------------------------------------------------------------------------- */
#include "bridging_atomic_continuum.hh"
#include "compute_extract.hh"
#include "lib_bridging.hh"
#include "lm_common.hh"
#include "reference_manager.hh"
#include "trace_atom.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
BridgingAtomicContinuum::BridgingAtomicContinuum(const std::string &name)
: LMObject(name), Bridging(name), comm_group_continuum(this->comm_group_B),
comm_group_atomic(this->comm_group_A) {}
/* -------------------------------------------------------------------------- */
BridgingAtomicContinuum::~BridgingAtomicContinuum() {}
/* -------------------------------------------------------------------------- */
void BridgingAtomicContinuum::updateForMigration() {
Bridging::updateForMigration();
if (this->check_coherency) {
checkPositionCoherency();
}
}
/* -------------------------------------------------------------------------- */
INSTANCIATE_DISPATCH(BridgingAtomicContinuum::init)
template <typename DomainA, typename DomainC>
void BridgingAtomicContinuum::init(DomainA &domA, DomainC &domC) {
Bridging::init(domA.getContainer(), domC.getContainer());
auto &pointList = this->pointList.get<typename DomainA::ContainerSubset>();
domA.getContainer().addSubSet(pointList);
DUMP(this->getID() << " : attach duo vector", DBG_MESSAGE);
if (this->in_group_A) {
pointList.attachObject(this->getDuoVector());
DUMP(this->getID() << " : attaching Parent::duo_vector", DBG_INFO);
}
MPI_Barrier(MPI_COMM_WORLD);
}
/* -------------------------------------------------------------------------- */
// void BridgingAtomicContinuum::averageDOFsOnElements(
// ContainerArray<Real> &data_mesh, FieldType field) {
// LM_FATAL("to adapt");
// if (comm_group_atomic == comm_group_continuum) {
// ComputeExtract extracted_field("ComputeExtract:" + this->getID());
// extracted_field.setParam("FIELD", field);
// extracted_field.buildManual(*this->pointList);
// this->averageOnElements<dispatch>(extracted_field.getArray(), data_mesh,
// meshList);
// return;
// }
// ComputeExtract extracted_field("ComputeExtract:" + this->getID());
// extracted_field.setParam("FIELD", field);
// if (this->is_in_atomic)
// extracted_field.buildManual(*this->pointList);
// LM_TOIMPLEMENT;
// // extracted_field.resize(Parent::local_points * Dim);
// /* do communication */
// this->communicateBufferAtom2Continuum(extracted_field.getArray());
// if (this->is_in_continuum)
// this->averageOnElements<dispatch>(extracted_field.getArray(), data_mesh,
// meshList);
// }
/* -------------------------------------------------------------------------- */
void BridgingAtomicContinuum::leastSquareAtomicData(
ContainerArray<Real> &data_mesh, ContainerArray<Real> &data_atom) {
if (comm_group_atomic == comm_group_continuum) {
this->solveLeastSquare<dispatch>(data_mesh, data_atom,
this->evalOutput("meshList"));
return;
}
/* do communication */
this->commPoint2Continuum(data_atom);
if (this->is_in_continuum) {
this->solveLeastSquare<dispatch>(data_mesh, data_atom,
this->getOutput("meshList"));
}
}
/* -------------------------------------------------------------------------- */
void BridgingAtomicContinuum::leastSquareAtomicDOFs(
ContainerArray<Real> &data_mesh, FieldType field) {
LM_FATAL("to adapt");
if (comm_group_atomic == comm_group_continuum) {
ComputeExtract extracted_field("ComputeExtract:" + this->getID());
extracted_field.setParam("FIELD", field);
extracted_field.compute(this->pointList);
this->solveLeastSquare<dispatch>(
data_mesh, extracted_field.evalArrayOutput(), this->meshList);
return;
}
ComputeExtract extracted_field("ComputeExtract:" + this->getID());
extracted_field.setParam("FIELD", field);
if (this->is_in_atomic)
extracted_field.compute(this->pointList);
LM_TOIMPLEMENT;
// extracted_field.resize(Parent::local_points * Dim);
this->leastSquareAtomicData(data_mesh, extracted_field.evalArrayOutput());
}
/* -------------------------------------------------------------------------- */
void BridgingAtomicContinuum::buildAtomicDOFsNoiseVector(std::vector<Real> &,
FieldType field) {
ComputeExtract extracted_field("ComputeExtract:" + this->getID());
extracted_field.setParam("FIELD", field);
if (this->is_in_atomic)
extracted_field.compute(this->pointList);
if (this->is_in_continuum) {
LM_TOIMPLEMENT;
// auto &field = extracted_field.evalArrayOutput();
// this->interpolatePointData(field, ??);
for (UInt i = 0; i < this->local_points * spatial_dimension; ++i)
LM_TOIMPLEMENT;
// extracted_field[i] *= -1;
}
/* do communication */
this->synchSumBuffer(extracted_field.evalArrayOutput());
}
/* -------------------------------------------------------------------------- */
template <typename DomainA, typename DomainC>
void BridgingAtomicContinuum::checkPositionCoherency(DomainA &domA,
DomainC &domC) {
LM_TOIMPLEMENT;
// constexpr UInt Dim = DomainC::ContainerPoints::Dim;
// if (this->in_group_B) {
// // interpolate atomic sites to check everything is ok from this
// auto &&field = domC.getField(_position0);
// UInt *assoc_tmp = &this->pointToElement[0];
// for (UInt i = 0; i < this->local_points; ++i) {
// Vector<Dim> X;
// Vector<Dim> pos = this->positions(i);
// X = this->interpolate(i, field, assoc_tmp[i]);
// for (UInt k = 0; k < Dim; ++k) {
// if (X[k] != pos[k])
// if (fabs(pos[k] - X[k]) > 1e-5) {
// searchAtomInLocalPool(
// static_cast<typename DomainA::ContainerSubset &>(
// this->pointList),
// pos);
// DUMP("mismatch in positions (X), atom "
// << i << " dist is " << pos[k] - X[k]
// << " : probably a redistribution trouble check "
// "migrations\n"
// << "computed position is " << X[0] << " " << X[1] << " "
// << X[2] << " position was " << pos[0] << " " << pos[1]
// << " " << pos[2],
// DBG_MESSAGE);
// }
// }
// }
// }
// this->distributeVectorB2A("temp_positions", this->positions);
// if (this->in_group_A) {
// UInt i = 0;
// UInt global_flag = 0;
// for (auto &&at : this->pointList) {
// UInt local_flag = 0;
// Vector<Dim> pos = VectorView<Dim>(&this->positions[Dim * i]);
// Vector<Dim> at_pos = at.position0();
// for (UInt k = 0; k < Dim; ++k) {
// if (pos[k] != at_pos[k])
// if (!local_flag && fabs(pos[k] - at_pos[k]) > 1e-5) {
// searchAtomInLocalPool(this->pointList, pos);
// DUMP("mismatch in positions (X), atom "
// << i << " dist is "
// << this->positions[Dim * i] - at.position0()[0]
// << " : probably a redistribution trouble check
// migrations"
// << std::endl
// << "ref is " << at << "\nand send position is " <<
// pos[0]
// << " " << pos[1] << " " << pos[2],
// DBG_MESSAGE);
// local_flag = 1;
// global_flag = 1;
// }
// }
// ++i;
// }
// if (global_flag) {
// this->getDuoVector().print("buggy-redistrib");
// LM_FATAL("abort due to migration problem");
// }
// }
// DUMP("position coherency OK", DBG_INFO);
}
/* -------------------------------------------------------------------------- */
template <typename Cont, typename Vec>
void BridgingAtomicContinuum::searchAtomInLocalPool(Cont &container, Vec &x) {
LM_TOIMPLEMENT;
// UInt i = 0;
// for (auto &&at : container) {
// #ifdef TRACE_ATOM
// auto pos = at.position0();
// #endif
// IF_COORD_EQUALS(pos, x) {
// DUMP("actually searched atom is at ref " << at << " bridge index " <<
// i,
// DBG_MESSAGE);
// break;
// }
// ++i;
// }
// if (i == container.size())
// DUMP("atom " << x[0] << " " << x[1] << " " << x[2] << " "
// << " not found locally : probably has migrated"
// << " or is simply lost !"
// << " NOT GOOD",
// DBG_MESSAGE);
// i = 0;
// for (auto &&at : domA.getContainer()) {
// #ifdef TRACE_ATOM
// auto pos = at.position0();
// #endif
// IF_COORD_EQUALS(pos, x) {
// DUMP("actually searched atom is at ref " << at << " bridge index " <<
// i,
// DBG_MESSAGE);
// break;
// }
// ++i;
// }
// if (i == domA.getContainer().size())
// DUMP("atom not found locally : probably has migrated"
// << "or is simply lost !"
// << " NOT GOOD",
// DBG_MESSAGE);
}
/* -------------------------------------------------------------------------- */
void BridgingAtomicContinuum::projectAtomicFieldOnMesh(FieldType field_type) {
const UInt Dim = spatial_dimension;
if (is_in_continuum && !this->total_points)
DUMP("Warning : atomic container is empty: "
<< "cannot proceed atomic projection (check geometries ?!) "
<< this->getID(),
DBG_WARNING);
if (!this->local_points)
return;
this->buffer_for_points.resize(this->local_points, Dim);
if (is_in_continuum) {
ComputeExtract extracted_field("ComputeExtract:" + this->getID());
extracted_field.setParam("FIELD", field_type);
extracted_field.compute(this->meshList);
this->mesh2Point(extracted_field.evalArrayOutput(),
this->buffer_for_points);
this->buffer_for_points.setCommGroup(comm_group_continuum);
}
this->distributeVectorB2A("correction_fictifs", this->buffer_for_points);
if (is_in_atomic)
this->setPointField(field_type, this->buffer_for_points);
}
/* -------------------------------------------------------------------------- */
void BridgingAtomicContinuum::projectAtomicFieldOnMesh(
FieldType field [[gnu::unused]], ContainerArray<Real> &buffer) {
if (is_in_continuum && !this->total_points)
DUMP("Warning : atomic container is empty: "
<< "cannot proceed atomic projection (check geometries ?!)",
DBG_WARNING);
if (is_in_continuum) {
LM_TOIMPLEMENT;
// this->interpolateAtomicDOFs(field, buffer);
}
this->distributeVectorB2A("correction_fictifs", buffer);
}
/* -------------------------------------------------------------------------- */
void BridgingAtomicContinuum::checkPositionCoherency() { LM_TOIMPLEMENT; }
__END_LIBMULTISCALE__

Event Timeline