Page MenuHomec4science

point_association_inline_impl.hh
No OneTemporary

File Metadata

Created
Sun, Feb 2, 13:00

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, UInt Dim>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
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");
this->field_buffer.resize(Dim * this->pointsAlist.nbElem(),0);
// make the average in the field_buffer thing
{
typename PointsAFilter::iterator point_it = this->pointsAlist.getIterator();
RefA point;
UInt index = 0;
UInt index_weight = 0;
for (point = point_it.getFirst(); !point_it.end();
point = point_it.getNext(), ++index_weight) {
for (UInt dir = 0 ; dir < Dim ; ++dir,++index) {
this->field_buffer[index] =
weightsA[index_weight] * point.template field<ftype>(dir);
}
}
}
{
typename PointsBFilter::iterator point_it = this->pointsBlist.getIterator();
RefB point;
UInt index = 0;
UInt index_weight = 0;
for (point = point_it.getFirst(); !point_it.end();
point = point_it.getNext(),++index_weight) {
for (UInt dir = 0 ; dir < Dim ; ++dir,++index) {
this->field_buffer[index] +=
weightsB[index_weight] * point.template field<ftype>(dir);
}
}
}
// apply the result to the fields
{
typename PointsAFilter::iterator point_it = this->pointsAlist.getIterator();
RefA point;
UInt index = 0;
for (point = point_it.getFirst(); !point_it.end();
point = point_it.getNext()) {
for (UInt dir = 0 ; dir < Dim ; ++dir,++index) {
point.template field<ftype>(dir) = this->field_buffer[index];
}
}
}
{
typename PointsBFilter::iterator point_it = this->pointsBlist.getIterator();
RefB point;
UInt index = 0;
for (point = point_it.getFirst(); !point_it.end();
point = point_it.getNext()) {
for (UInt dir = 0 ; dir < Dim ; ++dir,++index) {
point.template field<ftype>(dir) = this->field_buffer[index];
}
}
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB, UInt Dim>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
prepareSynchronisation() {
if (ftype == _displacement){
this->prepareSynchronisationDisplacement();
return;
}
if (this->in_group_A) {
this->field_buffer.resize(Dim * this->pointsAlist.nbElem(),0);
typename PointsAFilter::iterator point_it = this->pointsAlist.getIterator();
RefA point;
UInt index = 0;
for (point = point_it.getFirst(); !point_it.end();
point = point_it.getNext()) {
for (UInt dir = 0 ; dir < Dim ; ++dir,++index) {
this->field_buffer[index] = point.template field<ftype>(dir);
}
}
} else if (this->in_group_B) {
this->field_buffer.resize(Dim * this->pointsAlist.nbElem(),0);
}
}
/* -------------------------------------------------------------------------- */
// specialize this for ComputeTrueDisplacement
template <typename ContainerA, typename ContainerB, UInt Dim>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
prepareSynchronisationDisplacement() {
if (this->in_group_A) {
this->field_buffer.resize(Dim * this->pointsAlist.nbElem(),0);
DUMP(this->getID() << ": bounding box of " <<
this->pointsAlist.getID() << " is "
<< this->pointsAlist.getBoundingBox(),DBG_INFO);
this->true_disp.manualBuild(this->pointsAlist);
typename ComputeTrueDisplacement<typename ContainerA::ContainerSubset>::iterator
disp_it = this->true_disp.getIterator();
Real disp = disp_it.getFirst();
for (UInt index = 0; !disp_it.end() ; disp = disp_it.getNext(), ++index) {
this->field_buffer[index] = disp;
DUMP(this->getID() << ": prepareSyncDisp.template field<" << _displacement << ">(" << index%Dim << ") = "
<< disp,DBG_DETAIL);
}
} else if (this->in_group_B) {
this->field_buffer.resize(Dim * this->pointsAlist.nbElem(),0);
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB, UInt Dim>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
synchronise() {
std::stringstream sstr;
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, UInt Dim>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
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;
}
for (UInt point_idx = 0 ; point_idx < this->pointsBlist.size() ; ++point_idx) {
RefB 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];
for (UInt dir = 0 ; dir < Dim ; ++dir) {
point.template field<ftype>(dir) = field_vals[dir];
DUMP(this->getID() << ": point.template field<" << ftype << ">(" << dir << ") = "
<< field_vals[dir],DBG_DETAIL);
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt Dim, bool pbc_x, bool pbc_y, bool pbc_z>
inline void fix_pbc(Real * pos, const Quantity<Length,3> & xmin, const Real * 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, UInt Dim>
template<bool pbc_x, bool pbc_y, bool pbc_z>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
applyBufferPosition() {
DUMP(this->getID() << ": bounding box of " <<
this->pointsBlist.getID() << " is "
<< this->pointsBlist.getBoundingBox(),DBG_INFO);
Cube & bbox = this->pointsBlist.getBoundingBox();
const Real * d_size = bbox.getSize();
const Quantity<Length,3> & xmin = bbox.getXmin();
for (UInt point_idx = 0 ; point_idx < this->pointsBlist.size() ; ++point_idx) {
RefB point = this->pointsBlist.get(point_idx);
Real * field_vals = &this->field_buffer[Dim*point_idx];
DUMP(this->getID() << ": apply buffer position for point " << point,DBG_DETAIL);
fix_pbc<Dim, pbc_x, pbc_y, pbc_z>(field_vals, xmin, d_size);
for (UInt dir = 0 ; dir < Dim ; ++dir) {
point.template field<_position>(dir) = field_vals[dir];
DUMP(this->getID() << ": point.template field<" << _position << ">(" << dir << ") = "
<< field_vals[dir],DBG_DETAIL);
}
}
}
/* -------------------------------------------------------------------------- */
template <typename ContainerA, typename ContainerB, UInt Dim>
template <FieldType ftype>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
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, UInt Dim>
template <FieldType ftype1, FieldType ftype2>
inline void PointAssociation<ContainerA, ContainerB, Dim>::
zeroFields() {
for (UInt point_idx = 0 ; point_idx < this->pointsBlist.size() ; ++point_idx) {
RefB point = this->pointsBlist.get(point_idx);
for (UInt dir = 0 ; dir < Dim ; ++dir) {
point.template field<ftype1>(dir) = 0.;
point.template field<ftype2>(dir) = 0.;
}
}
}
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__

Event Timeline