Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F84823943
bridging_atomic_continuum.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Sep 25, 02:19
Size
14 KB
Mime Type
text/x-c++
Expires
Fri, Sep 27, 02:19 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
21091981
Attached To
rLIBMULTISCALE LibMultiScale
bridging_atomic_continuum.cc
View Options
/**
* @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
(
Communicator
::
getGroup
(
"all"
)),
comm_group_atomic
(
Communicator
::
getGroup
(
"all"
))
{}
/* -------------------------------------------------------------------------- */
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
[[
gnu
::
unused
]],
DomainC
&
domC
[[
gnu
::
unused
]])
{
LM_TOIMPLEMENT
;
// comm_group_continuum = domC.getCommGroup();
// comm_group_atomic = domA.getCommGroup();
// auto &pointList = this->pointList->cast<typename
// DomainA::ContainerSubset>(); if (domA.getContainer().hasRefManager()) {
// auto ref_manager = domA.getContainer().getRefManager();
// ref_manager->addSubSet(pointList);
// }
// Bridging::init(domA, domC);
// DUMP(this->getID() << " : attach duo vector", DBG_MESSAGE);
// if (this->in_group_A) {
// try {
// domA.getContainer().getRefManager()->attachObject(this->getDuoVector(),
// pointList);
// DUMP(this->getID() << " : attaching Parent::duo_vector", DBG_INFO);
// } catch (LibMultiScaleException &e) {
// }
// }
// 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);
// }
/* -------------------------------------------------------------------------- */
// template <typename DomainA, typename DomainC,UInt Dim>
// template <FieldType field>
// void BridgingAtomicContinuum<DomainA,DomainC,Dim>::
// buildAtomicDOFsVector(std::vector<Real> & v_out){
// IteratorAtomsSubset it = this->pointList->begin();
// UInt nmax = this->pointList->size();
// UInt i =0;
// Real * v_out_ptr = &v_out[0];
// for (RefAtom at = it.getFirst(); !it.end() ;
// at = it.getNext() , ++i, v_out_ptr+= Dim) {
// LM_ASSERT(i < nmax,"overflow detected");
// at.template getField<field>(v_out_ptr);
// }
// }
// /* --------------------------------------------------------------------------
// */
// template <typename DomainA, typename DomainC,UInt Dim>
// void BridgingAtomicContinuum<DomainA,DomainC,Dim>::
// buildAtomicDOFsVector(std::vector<Real> & v_out,
// FieldType field){
// switch(field){
// case _position0: buildAtomicDOFsVector<_position0 >(v_out); break;
// case _position: buildAtomicDOFsVector<_position >(v_out); break;
// case _displacement: buildAtomicDOFsVector<_displacement>(v_out); break;
// case _velocity: buildAtomicDOFsVector<_velocity >(v_out); break;
// case _force: buildAtomicDOFsVector<_force >(v_out);
// break;
// default: LM_FATAL("not handled field");
// }
// }
/* -------------------------------------------------------------------------- */
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
,
meshList
);
return
;
}
/* do communication */
this
->
communicateBufferAtom2Continuum
(
data_atom
);
if
(
this
->
is_in_continuum
)
{
this
->
solveLeastSquare
<
dispatch
>
(
data_mesh
,
data_atom
,
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
.
buildManual
(
this
->
pointList
);
this
->
solveLeastSquare
<
dispatch
>
(
data_mesh
,
extracted_field
.
getArray
(),
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);
this
->
leastSquareAtomicData
(
data_mesh
,
extracted_field
.
getArray
());
}
/* -------------------------------------------------------------------------- */
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
.
buildManual
(
*
this
->
pointList
);
if
(
this
->
is_in_continuum
)
{
this
->
interpolateAtomicDOFs
(
field
,
extracted_field
.
getArray
());
for
(
UInt
i
=
0
;
i
<
this
->
local_points
*
spatial_dimension
;
++
i
)
LM_TOIMPLEMENT
;
// extracted_field[i] *= -1;
}
/* do communication */
this
->
synchSumBuffer
(
extracted_field
.
getArray
());
}
/* -------------------------------------------------------------------------- */
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
)
{
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
.
resize
(
this
->
local_points
,
Dim
);
if
(
is_in_continuum
)
this
->
interpolateAtomicDOFs
(
field
);
this
->
distributeVectorB2A
(
"correction_fictifs"
,
this
->
buffer
);
if
(
is_in_atomic
)
setAtomicDOFs
(
field
);
}
/* -------------------------------------------------------------------------- */
void
BridgingAtomicContinuum
::
projectAtomicFieldOnMesh
(
FieldType
field
,
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
)
this
->
interpolateAtomicDOFs
(
field
,
buffer
);
this
->
distributeVectorB2A
(
"correction_fictifs"
,
buffer
);
}
/* -------------------------------------------------------------------------- */
void
BridgingAtomicContinuum
::
interpolateAtomicDOFs
(
FieldType
field_code
[[
gnu
::
unused
]],
ContainerArray
<
Real
>
&
buffer
[[
gnu
::
unused
]])
{
LM_TOIMPLEMENT
;
}
/* -------------------------------------------------------------------------- */
void
BridgingAtomicContinuum
::
interpolateAtomicDOFs
(
FieldType
field_code
[[
gnu
::
unused
]])
{
LM_TOIMPLEMENT
;
}
/* -------------------------------------------------------------------------- */
void
BridgingAtomicContinuum
::
checkPositionCoherency
()
{
LM_TOIMPLEMENT
;
}
// DECLARE_ATOMIC_CONTINUUM_TEMPLATE(BridgingAtomicContinuum)
__END_LIBMULTISCALE__
Event Timeline
Log In to Comment