Page MenuHomec4science

point_association_inline_impl.hh
No OneTemporary

File Metadata

Created
Sat, Jun 29, 04:09

point_association_inline_impl.hh

/**
* @file point_association_inline_impl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
*
* @date Mon Jun 16 17:13:26 2014
*
* @brief computes the association between point degrees of freedom of
* different domains
*
* @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 "point_association.hh"
#include <string>
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB>::mixField() {
if (this->in_group_A && !this->in_group_B)
LM_FATAL("not a parallel routine yet");
if (this->pointsAlist->size() != this->pointsBlist->size())
LM_FATAL("inconsistency here");
constexpr UInt Dim = ContainerA::Dim;
this->field_buffer.resize(Dim * this->pointsAlist->size(), 0);
// make the average in the field_buffer thing
UInt index = 0;
UInt index_weight = 0;
for (auto &&point : this->pointsAlist) {
auto &&_field = point.template field<ftype>();
for (UInt dir = 0; dir < Dim; ++dir, ++index) {
this->field_buffer[index] = weightsA[index_weight] * _field[dir];
}
++index_weight;
}
index = 0;
index_weight = 0;
for (auto &&point : this->pointsBlist) {
auto &&_field = point.template field<ftype>();
for (UInt dir = 0; dir < Dim; ++dir, ++index) {
this->field_buffer[index] += weightsB[index_weight] * _field[dir];
}
++index_weight;
}
// apply the result to the fields
index = 0;
for (auto &&point : this->pointsAlist) {
auto &&_field = point.template field<ftype>();
for (UInt dir = 0; dir < Dim; ++dir, ++index) {
_field[dir] = this->field_buffer[index];
}
}
index = 0;
for (auto &&point : this->pointsBlist) {
auto &&_field = point.template field<ftype>();
for (UInt dir = 0; dir < Dim; ++dir, ++index) {
_field[dir] = this->field_buffer[index];
}
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB>::prepareSynchronisation() {
if (ftype == _displacement) {
this->prepareSynchronisationDisplacement();
return;
}
constexpr UInt Dim = ContainerA::Dim;
if (this->in_group_A) {
this->field_buffer.resize(Dim * this->pointsAlist->size(), 0);
UInt index = 0;
for (auto &&point : this->pointsAlist) {
auto &&_field = point.template field<ftype>();
for (UInt dir = 0; dir < Dim; ++dir, ++index) {
this->field_buffer[index] = _field[dir];
}
}
} else if (this->in_group_B) {
this->field_buffer.resize(Dim * this->pointsAlist->size(), 0);
}
}
/* -------------------------------------------------------------------------- */
// specialize this for ComputeTrueDisplacement
template <typename ContainerA, typename ContainerB>
inline void
PointAssociation<ContainerA, ContainerB>::prepareSynchronisationDisplacement() {
constexpr UInt Dim = ContainerA::Dim;
if (this->in_group_A) {
this->field_buffer.resize(Dim * this->pointsAlist->size(), 0);
DUMP(this->getID() << ": bounding box of " << this->pointsAlist.getID()
<< " is " << this->pointsAlist->getBoundingBox(),
DBG_INFO);
this->true_disp.buildManual(this->pointsAlist);
UInt index = 0;
for (auto &&disp : this->true_disp.getArray()) {
this->field_buffer[index] = disp;
DUMP(this->getID() << ": prepareSyncDisp.template field<" << _displacement
<< ">(" << index % Dim << ") = " << disp,
DBG_DETAIL);
++index;
}
} else if (this->in_group_B) {
this->field_buffer.resize(Dim * this->pointsAlist->size(), 0);
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB>::synchronise() {
std::stringstream sstr;
constexpr UInt Dim = ContainerA::Dim;
sstr << "Sync " << ftype << " for object " << this->getID();
this->field_buffer.resize(this->local_points * Dim);
this->distributeVectorA2B(sstr.str(), this->field_buffer, Dim);
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB>::applyBuffer() {
if (ftype == _position) {
if (pbc[0] == 0 && pbc[1] == 0 && pbc[2] == 0)
this->template applyBufferPosition<false, false, false>();
if (pbc[0] == 1 && pbc[1] == 0 && pbc[2] == 0)
this->template applyBufferPosition<true, false, false>();
if (pbc[0] == 1 && pbc[1] == 1 && pbc[2] == 0)
this->template applyBufferPosition<true, true, false>();
if (pbc[0] == 1 && pbc[1] == 1 && pbc[2] == 1)
this->template applyBufferPosition<true, true, true>();
if (pbc[0] == 1 && pbc[1] == 0 && pbc[2] == 1)
this->template applyBufferPosition<true, false, true>();
if (pbc[0] == 0 && pbc[1] == 1 && pbc[2] == 0)
this->template applyBufferPosition<false, true, false>();
if (pbc[0] == 0 && pbc[1] == 1 && pbc[2] == 1)
this->template applyBufferPosition<false, true, true>();
if (pbc[0] == 0 && pbc[1] == 0 && pbc[2] == 1)
this->template applyBufferPosition<false, false, true>();
return;
}
constexpr UInt Dim = ContainerA::Dim;
for (UInt point_idx = 0; point_idx < this->pointsBlist->size(); ++point_idx) {
auto point = this->pointsBlist->get(point_idx);
DUMP(this->getID() << ": apply buffer for point " << point, DBG_DETAIL);
Real *field_vals = &this->field_buffer[Dim * point_idx];
auto &&_field = point.template field<ftype>();
for (UInt dir = 0; dir < Dim; ++dir) {
_field[dir] = field_vals[dir];
DUMP(this->getID() << ": point.template field<" << ftype << ">(" << dir
<< ") = " << field_vals[dir],
DBG_DETAIL);
}
}
}
/* -------------------------------------------------------------------------- */
template <typename Vec1, typename Vec2, typename Vec3, UInt Dim, bool pbc_x,
bool pbc_y, bool pbc_z>
inline void fix_pbc(Vec1 &pos, Vec2 &xmin, Vec3 &d_size) {
for (UInt i = 0; i < Dim; ++i) {
if ((pbc_x && i == 0) || (pbc_y && i == 1) || (pbc_z && i == 2)) {
int offset = floor((pos[i] - xmin[i]) / d_size[i]);
pos[i] -= offset * d_size[i];
}
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB>
template <bool pbc_x, bool pbc_y, bool pbc_z>
inline void PointAssociation<ContainerA, ContainerB>::applyBufferPosition() {
DUMP(this->getID() << ": bounding box of " << this->pointsBlist.getID()
<< " is " << this->pointsBlist->getBoundingBox(),
DBG_INFO);
constexpr UInt Dim = ContainerA::Dim;
Cube &bbox = this->pointsBlist->getBoundingBox();
auto &&d_size = bbox.getSize();
auto &&xmin = bbox.getXmin<Dim>();
for (UInt point_idx = 0; point_idx < this->pointsBlist->size(); ++point_idx) {
auto point = this->pointsBlist->get(point_idx);
Vector<Dim> field_vals = this->field_buffer.row(point_idx);
DUMP(this->getID() << ": apply buffer position for point " << point,
DBG_DETAIL);
fix_pbc<Vector<Dim>, Vector<Dim>, Vector<3, Real>, Dim, pbc_x, pbc_y,
pbc_z>(field_vals, xmin, d_size);
auto &&_field = point.template field<_position>();
for (UInt dir = 0; dir < Dim; ++dir) {
_field[dir] = field_vals[dir];
DUMP(this->getID() << ": point.template field<" << _position << ">("
<< dir << ") = " << field_vals[dir],
DBG_DETAIL);
}
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB>::enforceField() {
if (this->in_group_A) {
STARTTIMER("Point Assoc. Synch.");
this->prepareSynchronisation<ftype>();
STOPTIMER("Point Assoc. Synch.");
}
this->synchronise<ftype>();
if (this->in_group_B) {
STARTTIMER("Apply Assoc. Synch.");
this->applyBuffer<ftype>();
STOPTIMER("Apply Assoc. Synch.");
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB>
template <FieldType ftype1, FieldType ftype2>
inline void PointAssociation<ContainerA, ContainerB>::zeroFields() {
constexpr UInt Dim = ContainerA::Dim;
for (UInt point_idx = 0; point_idx < this->pointsBlist->size(); ++point_idx) {
auto point = this->pointsBlist->get(point_idx);
auto &&f1 = point.template field<ftype1>();
auto &&f2 = point.template field<ftype1>();
for (UInt dir = 0; dir < Dim; ++dir) {
f1[dir] = 0.;
f2[dir] = 0.;
}
}
}
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__

Event Timeline