Page MenuHomec4science

No OneTemporary

File Metadata

Created
Thu, May 30, 19:30
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/examples/boundary_conditions/predefined_bc/predefined_bc.cc b/examples/boundary_conditions/predefined_bc/predefined_bc.cc
index c59eeb2ef..8810ff5f6 100644
--- a/examples/boundary_conditions/predefined_bc/predefined_bc.cc
+++ b/examples/boundary_conditions/predefined_bc/predefined_bc.cc
@@ -1,63 +1,63 @@
/**
* @file predefined_bc.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Dec 16 2015
* @date last modification: Mon Jan 18 2016
*
* @brief boundary condition example
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
Mesh mesh(2);
mesh.read("square.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
// model initialization
SolidMechanicsModel model(mesh);
model.initFull();
// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
// output in a paraview file
model.setBaseName("plate");
model.addDumpFieldVector("displacement");
model.addDumpField("blocked_dofs");
- model.addDumpField("force" );
+ model.addDumpField("force");
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
index 32e1e048d..3bdbbee4a 100644
--- a/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
+++ b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
@@ -1,89 +1,89 @@
/**
* @file user_defined_bc.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Wed Dec 16 2015
* @date last modification: Mon Jan 18 2016
*
* @brief user-defined boundary condition example
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
-#include <iostream>
#include <cmath>
+#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
class SineBoundary : public BC::Dirichlet::DirichletFunctor {
public:
- SineBoundary(Real amp, Real phase, BC::Axis ax = _x) : DirichletFunctor(ax),
- amplitude(amp),
- phase(phase) {}
+ SineBoundary(Real amp, Real phase, BC::Axis ax = _x)
+ : DirichletFunctor(ax), amplitude(amp), phase(phase) {}
+
public:
inline void operator()(__attribute__((unused)) UInt node,
- Vector<bool> & flags,
- Vector<Real> & primal,
+ Vector<bool> & flags, Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
primal(axis) = -amplitude * std::sin(phase * coord(1));
}
+
protected:
Real amplitude;
Real phase;
};
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("fine_mesh.msh");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
/// boundary conditions
mesh.createGroupsFromMeshData<std::string>("physical_names");
Vector<Real> traction(2, 0.2);
model.applyBC(SineBoundary(.2, 10., _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Fixed_y");
model.applyBC(BC::Neumann::FromTraction(traction), "Traction");
// output a paraview file with the boundary conditions
model.setBaseName("plate");
model.addDumpFieldVector("displacement");
model.addDumpFieldVector("force");
model.addDumpField("blocked_dofs");
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
index 2c4f4e55d..a5c165c81 100644
--- a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
+++ b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
@@ -1,124 +1,125 @@
/**
* @file cohesive_extrinsic.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Mon Jan 18 2016
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
const UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
- Real time_step = model.getStableTimeStep()*0.05;
+ Real time_step = model.getStableTimeStep() * 0.05;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
CohesiveElementInserter & inserter = model.getElementInserter();
inserter.setLimit(_y, 0.30, 0.20);
model.updateAutomaticInsertion();
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
model.setBaseName("extrinsic");
model.addDumpFieldVector("displacement");
- model.addDumpField("velocity" );
+ model.addDumpField("velocity");
model.addDumpField("acceleration");
- model.addDumpField("residual" );
+ model.addDumpField("residual");
model.addDumpField("stress");
model.addDumpField("grad_u");
model.dump();
/// initial conditions
Real loading_rate = 0.5;
Real disp_update = loading_rate * time_step;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
}
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
/// update displacement on extreme nodes
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
displacement(n, 1) += disp_update * position(n, 1);
}
model.checkCohesiveStress();
model.solveStep();
- if(s % 10 == 0) {
+ if (s % 10 == 0) {
model.dump();
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
}
Real Ed = model.getEnergy("dissipated");
- Real Edt = 200*std::sqrt(2);
+ Real Edt = 200 * std::sqrt(2);
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc b/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
index 89f3b66b1..bacfd4dfd 100644
--- a/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
+++ b/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
@@ -1,153 +1,153 @@
/**
* @file cohesive_intrinsic.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Mon Jan 18 2016
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
static void updateDisplacement(SolidMechanicsModelCohesive &, Array<UInt> &,
ElementType, Real);
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
const UInt max_steps = 350;
const ElementType type = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
CohesiveElementInserter inserter(mesh);
inserter.setLimit(_x, -0.26, -0.24);
inserter.insertIntrinsicElements();
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep() * 0.8;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
Array<bool> & boundary = model.getBlockedDOFs();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
for (UInt n = 0; n < nb_nodes; ++n) {
boundary(n, dim) = true;
}
}
model.setBaseName("intrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity");
model.addDumpField("acceleration");
model.addDumpField("stress");
model.addDumpField("grad_u");
model.addDumpField("external_force");
model.addDumpField("internal_force");
model.dump();
/// update displacement
Array<UInt> elements;
Vector<Real> barycenter(spatial_dimension);
for_each_element(mesh, [&](auto && el) {
- mesh.getBarycenter(el, barycenter);
- if(barycenter(_x) > -0.25)
- elements.push_back(el.element);
- });
+ mesh.getBarycenter(el, barycenter);
+ if (barycenter(_x) > -0.25)
+ elements.push_back(el.element);
+ });
Real increment = 0.01;
updateDisplacement(model, elements, type, increment);
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
updateDisplacement(model, elements, type, increment);
if (s % 1 == 0) {
model.dump();
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
}
Real Ed = model.getEnergy("dissipated");
Real Edt = 2 * sqrt(2);
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
static void updateDisplacement(SolidMechanicsModelCohesive & model,
Array<UInt> & elements, ElementType type,
Real increment) {
Mesh & mesh = model.getMesh();
UInt nb_element = elements.size();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
update.clear();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(elements(el), n);
if (!update(node)) {
displacement(node, 0) -= increment;
// displacement(node, 1) += increment;
update(node) = true;
}
}
}
}
diff --git a/examples/explicit/explicit_dynamic.cc b/examples/explicit/explicit_dynamic.cc
index f8449d4f2..e640a7344 100644
--- a/examples/explicit/explicit_dynamic.cc
+++ b/examples/explicit/explicit_dynamic.cc
@@ -1,107 +1,106 @@
/**
* @file explicit_dynamic.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
*
* @date creation: Sun Jul 12 2015
* @date last modification: Mon Jan 18 2016
*
* @brief This code refers to the explicit dynamic example from the user manual
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
-
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 3;
const Real pulse_width = 2.;
const Real A = 0.01;
Real time_step;
Real time_factor = 0.8;
UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.read("bar.msh");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(_analysis_method = _explicit_lumped_mass);
time_step = model.getStableTimeStep();
std::cout << "Time Step = " << time_step * time_factor << "s (" << time_step
<< "s)" << std::endl;
model.setTimeStep(time_step * time_factor);
/// boundary and initial conditions
Array<Real> & displacement = model.getDisplacement();
const Array<Real> & nodes = mesh.getNodes();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
Real x = nodes(n);
// Sinus * Gaussian
Real L = pulse_width;
Real k = 0.1 * 2 * M_PI * 3 / L;
displacement(n) = A * sin(k * x) * exp(-(k * x) * (k * x) / (L * L));
}
std::ofstream energy;
energy.open("energy.csv");
energy << "id,rtime,epot,ekin,tot" << std::endl;
model.setBaseName("explicit_dynamic");
model.addDumpField("displacement");
model.addDumpField("velocity");
model.addDumpField("acceleration");
model.addDumpField("stress");
model.dump();
for (UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
Real epot = model.getEnergy("potential");
Real ekin = model.getEnergy("kinetic");
energy << s << "," << s * time_step << "," << epot << "," << ekin << ","
<< epot + ekin << "," << std::endl;
if (s % 10 == 0)
std::cout << "passing step " << s << "/" << max_steps << std::endl;
model.dump();
}
energy.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/io/dumper/dumper_low_level.cc b/examples/io/dumper/dumper_low_level.cc
index 8cc06087d..83d5c577d 100644
--- a/examples/io/dumper/dumper_low_level.cc
+++ b/examples/io/dumper/dumper_low_level.cc
@@ -1,194 +1,194 @@
/**
* @file dumper_low_level.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Aug 17 2015
*
* @brief Example of dumper::DumperIOHelper low-level methods.
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh.hh"
-#include "group_manager.hh"
#include "element_group.hh"
+#include "group_manager.hh"
+#include "mesh.hh"
#include "dumper_elemental_field.hh"
#include "dumper_nodal_field.hh"
#include "dumper_iohelper_paraview.hh"
#include "locomotive_tools.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
/* This example aims at illustrating how to manipulate low-level methods of
DumperIOHelper.
The aims is to visualize a colorized moving train with Paraview */
initialize(argc, argv);
// To start let us load the swiss train mesh and its mesh data information.
// We aknowledge here a weel-known swiss industry for mesh donation.
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("swiss_train.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
Array<Real> & nodes = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
/* swiss_train.msh has the following physical groups that can be viewed with
GMSH:
"$MeshFormat
2.2 0 8
$EndMeshFormat
$PhysicalNames
6
2 1 "red"
2 2 "white"
2 3 "lwheel_1"
2 4 "lwheel_2"
2 5 "rwheel_2"
2 6 "rwheel_1"
$EndPhysicalNames
..."
*/
// Grouping nodes and elements belonging to train wheels (=four mesh data)
ElementGroup & wheels_elements =
mesh.createElementGroup("wheels", spatial_dimension);
wheels_elements.append(mesh.getElementGroup("lwheel_1"));
wheels_elements.append(mesh.getElementGroup("lwheel_2"));
wheels_elements.append(mesh.getElementGroup("rwheel_1"));
wheels_elements.append(mesh.getElementGroup("rwheel_2"));
const Array<UInt> & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes();
const Array<UInt> & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes();
const Array<UInt> & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes();
const Array<UInt> & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes();
/* Note this Array is constructed with three components in order to warp train
deformation on Paraview. A more appropriate way to do this is to set a
padding in the NodalField (See example_dumpable_interface.cc.) */
Array<Real> displacement(nb_nodes, 3);
// ElementalField are constructed with an ElementTypeMapArray.
ElementTypeMapArray<UInt> colour;
colour.initialize(mesh, _with_nb_element = true);
/* ------------------------------------------------------------------------ */
/* Dumper creation */
/* ------------------------------------------------------------------------ */
// Creation of two DumperParaview. One for full mesh, one for a filtered
// mesh.
DumperParaview dumper("train", "./paraview/dumper", false);
DumperParaview wheels("wheels", "./paraview/dumper", false);
// Register the full mesh
dumper.registerMesh(mesh);
// Register a filtered mesh limited to nodes and elements from wheels groups
wheels.registerFilteredMesh(mesh, wheels_elements.getElements(),
wheels_elements.getNodes());
// Generate an output file of the two mesh registered.
dumper.dump();
wheels.dump();
/* At this stage no fields are attached to the two dumpers. To do so, a
dumper::Field object has to be created. Several types of dumper::Field
exist. In this example we present two of them.
NodalField to describe nodal displacements of our train.
ElementalField handling the color of our different part.
*/
// NodalField are constructed with an Array.
dumper::Field * displ_field = new dumper::NodalField<Real>(displacement);
dumper::Field * colour_field = new dumper::ElementalField<UInt>(colour);
// Register the freshly created fields to our dumper.
dumper.registerField("displacement", displ_field);
dumper.registerField("colour", colour_field);
// For the dumper wheels, fields have to be filtered at registration.
// Filtered NodalField can be simply registered by adding an Array<UInt>
// listing the nodes.
dumper::Field * displ_field_wheel = new dumper::NodalField<Real, true>(
displacement, 0, 0, &(wheels_elements.getNodes()));
wheels.registerField("displacement", displ_field_wheel);
// For the ElementalField, an ElementTypeMapArrayFilter has to be created.
ElementTypeMapArrayFilter<UInt> filtered_colour(
colour, wheels_elements.getElements());
dumper::Field * colour_field_wheel =
new dumper::ElementalField<UInt, Vector, true>(filtered_colour);
wheels.registerField("colour", colour_field_wheel);
/* ------------------------------------------------------------------------ */
// Now that the dumpers are created and the fields are associated, let's
// paint and move the train!
// Fill the ElementTypeMapArray colour according to mesh data information.
fillColour(mesh, colour);
// Apply displacement and wheels rotation.
Real tot_displacement = 50.;
Real radius = 1.;
UInt nb_steps = 100;
Real theta = tot_displacement / radius;
Vector<Real> l_center(3);
Vector<Real> r_center(3);
for (UInt i = 0; i < spatial_dimension; ++i) {
l_center(i) = nodes(14, i);
r_center(i) = nodes(2, i);
}
for (UInt i = 0; i < nb_steps; ++i) {
displacement.clear();
Real angle = (Real)i / (Real)nb_steps * theta;
applyRotation(l_center, angle, nodes, displacement, lnode_1);
applyRotation(l_center, angle, nodes, displacement, lnode_2);
applyRotation(r_center, angle, nodes, displacement, rnode_1);
applyRotation(r_center, angle, nodes, displacement, rnode_2);
for (UInt j = 0; j < nb_nodes; ++j) {
displacement(j, 0) += (Real)i / (Real)nb_steps * tot_displacement;
}
// Output results after each moving steps for main and wheel dumpers.
dumper.dump();
wheels.dump();
}
finalize();
return 0;
}
diff --git a/examples/io/dumper/locomotive_tools.cc b/examples/io/dumper/locomotive_tools.cc
index 12c5184a0..f2497bad0 100644
--- a/examples/io/dumper/locomotive_tools.cc
+++ b/examples/io/dumper/locomotive_tools.cc
@@ -1,93 +1,91 @@
/**
* @file locomotive_tools.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Mon Aug 17 2015
* @date last modification: Mon Jan 18 2016
*
* @brief Common functions for the dumper examples
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#include "locomotive_tools.hh"
/* -------------------------------------------------------------------------- */
-
using namespace akantu;
/* -------------------------------------------------------------------------- */
void applyRotation(const Vector<Real> & center, Real angle,
const Array<Real> & nodes, Array<Real> & displacement,
const Array<UInt> & node_group) {
- auto nodes_it =
- nodes.begin(nodes.getNbComponent());
+ auto nodes_it = nodes.begin(nodes.getNbComponent());
auto disp_it = displacement.begin(center.size());
Array<UInt>::const_scalar_iterator node_num_it = node_group.begin();
Array<UInt>::const_scalar_iterator node_num_end = node_group.end();
Vector<Real> pos_rel(center.size());
for (; node_num_it != node_num_end; ++node_num_it) {
const Vector<Real> pos = nodes_it[*node_num_it];
for (UInt i = 0; i < pos.size(); ++i)
pos_rel(i) = pos(i);
Vector<Real> dis = disp_it[*node_num_it];
pos_rel -= center;
Real radius = pos_rel.norm();
if (std::abs(radius) < Math::getTolerance())
continue;
Real phi_i = std::acos(pos_rel(_x) / radius);
if (pos_rel(_y) < 0)
phi_i *= -1;
dis(_x) = std::cos(phi_i - angle) * radius - pos_rel(_x);
dis(_y) = std::sin(phi_i - angle) * radius - pos_rel(_y);
}
}
/* -------------------------------------------------------------------------- */
void fillColour(const Mesh & mesh, ElementTypeMapArray<UInt> & colour) {
const ElementTypeMapArray<std::string> & phys_data =
mesh.getData<std::string>("physical_names");
const Array<std::string> & txt_colour = phys_data(_triangle_3);
Array<UInt> & id_colour = colour(_triangle_3);
for (UInt i = 0; i < txt_colour.size(); ++i) {
std::string phy_name = txt_colour(i);
if (phy_name == "red")
id_colour(i) = 3;
else if (phy_name == "white" || phy_name == "lwheel_1" ||
phy_name == "rwheel_1")
id_colour(i) = 2;
else
id_colour(i) = 1;
}
}
diff --git a/examples/io/parser/example_parser.cc b/examples/io/parser/example_parser.cc
index 92966c5ca..02e6a2f07 100644
--- a/examples/io/parser/example_parser.cc
+++ b/examples/io/parser/example_parser.cc
@@ -1,88 +1,88 @@
/**
* @file example_parser.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Mon Dec 14 2015
* @date last modification: Mon Jan 18 2016
*
* @brief Example on how to parse input text file
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
#include "non_linear_solver.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
// Precise in initialize the name of the text input file to parse.
initialize("input_file.dat", argc, argv);
// Get the user ParserSection.
const ParserSection & usersect = getUserParser();
// getParameterValue() allows to extract data associated to a given parameter
// name
// and cast it in the desired type set as template paramter.
Mesh mesh(usersect.getParameterValue<UInt>("spatial_dimension"));
mesh.read(usersect.getParameterValue<std::string>("mesh_file"));
// getParameter() can be used with variable declaration (destination type is
// explicitly known).
UInt max_iter = usersect.getParameter("max_nb_iterations");
Real precision = usersect.getParameter("precision");
// Following NumPy convention, data can be interpreted as Vector or Matrix
// structures.
Matrix<Real> eigen_stress = usersect.getParameter("stress");
SolidMechanicsModel model(mesh);
mesh.createGroupsFromMeshData<std::string>("physical_names");
model.initFull(SolidMechanicsModelOptions(_static));
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x),
usersect.getParameterValue<std::string>("outter_crust"));
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y),
usersect.getParameterValue<std::string>("outter_crust"));
model.applyBC(BC::Neumann::FromStress(eigen_stress),
usersect.getParameterValue<std::string>("inner_holes"));
model.setDirectory("./paraview");
model.setBaseName("swiss_cheese");
model.addDumpFieldVector("displacement");
auto & solver = model.getNonLinearSolver();
solver.set("max_iterations", max_iter);
solver.set("threshold", precision);
model.solveStep();
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/new_material/new_local_material.cc b/examples/new_material/new_local_material.cc
index b9430c60e..26dc9a14a 100644
--- a/examples/new_material/new_local_material.cc
+++ b/examples/new_material/new_local_material.cc
@@ -1,103 +1,103 @@
/**
* @file new_local_material.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Aug 06 2015
* @date last modification: Mon Jan 18 2016
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
#include "local_material_damage.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
#define bar_length 10.
#define bar_height 4.
akantu::Real eps = 1e-10;
int main(int argc, char * argv[]) {
akantu::initialize("material.dat", argc, argv);
UInt max_steps = 10000;
Real epot, ekin;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("barre_trou.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(_analysis_method = _explicit_lumped_mass);
std::cout << model.getMaterial(0) << std::endl;
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step / 10.);
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
// Neumann boundary condition
Matrix<Real> stress(2, 2);
stress.eye(3e2);
model.applyBC(BC::Neumann::FromStress(stress), "Traction");
model.setBaseName("local_material");
model.addDumpField("displacement");
model.addDumpField("velocity");
model.addDumpField("acceleration");
model.addDumpField("force");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("stress");
model.addDumpField("damage");
model.dump();
for (UInt s = 0; s < max_steps; ++s) {
model.solveStep();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
if (s % 100 == 0)
std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
<< std::endl;
if (s % 100 == 0)
model.dump();
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/parallel/parallel_2d.cc b/examples/parallel/parallel_2d.cc
index 19e52891e..9fac45757 100644
--- a/examples/parallel/parallel_2d.cc
+++ b/examples/parallel/parallel_2d.cc
@@ -1,106 +1,106 @@
/**
* @file parallel_2d.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jan 18 2016
*
* @brief Parallel example
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
#include "communicator.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
UInt spatial_dimension = 2;
UInt max_steps = 10000;
Real time_factor = 0.8;
Real max_disp = 1e-6;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int prank = comm.whoAmI();
if (prank == 0) {
// Read the mesh
mesh.read("square_2d.msh");
}
mesh.distribute();
SolidMechanicsModel model(mesh);
model.initFull();
if (prank == 0)
std::cout << model.getMaterial(0) << std::endl;
model.setBaseName("multi");
model.addDumpFieldVector("displacement");
model.addDumpFieldVector("velocity");
model.addDumpFieldVector("acceleration");
model.addDumpFieldTensor("stress");
model.addDumpFieldTensor("grad_u");
/// boundary conditions
Real eps = 1e-16;
const Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
Real left_side = mesh.getLowerBounds()(0);
Real right_side = mesh.getUpperBounds()(0);
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
if (std::abs(pos(i, 0) - left_side) < eps) {
disp(i, 0) = max_disp;
boun(i, 0) = true;
}
if (std::abs(pos(i, 0) - right_side) < eps) {
disp(i, 0) = -max_disp;
boun(i, 0) = true;
}
}
Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
model.dump();
for (UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
if (s % 200 == 0)
model.dump();
if (prank == 0 && s % 100 == 0)
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/static/static.cc b/examples/static/static.cc
index b0393137f..7c361969d 100644
--- a/examples/static/static.cc
+++ b/examples/static/static.cc
@@ -1,78 +1,78 @@
/**
* @file static.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jan 18 2016
*
* @brief This code refers to the implicit static example from the user manual
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
#include "non_linear_solver.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
#define bar_length 0.01
#define bar_height 0.01
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("square.msh");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(_analysis_method = _static);
model.setBaseName("static");
model.addDumpFieldVector("displacement");
model.addDumpField("external_force");
model.addDumpField("internal_force");
model.addDumpField("grad_u");
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
model.applyBC(BC::Dirichlet::FixedValue(0.0001, _y), "Traction");
model.dump();
auto & solver = model.getNonLinearSolver();
solver.set("max_iterations", 2);
solver.set("threshold", 2e-4);
solver.set("convergence_type", _scc_solution);
model.solveStep();
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/extra-materials/src/material_FE2/material_FE2.cc b/extra_packages/extra-materials/src/material_FE2/material_FE2.cc
index 56b4a96ce..afa105c00 100644
--- a/extra_packages/extra-materials/src/material_FE2/material_FE2.cc
+++ b/extra_packages/extra-materials/src/material_FE2/material_FE2.cc
@@ -1,200 +1,199 @@
/**
* @file material_FE2.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @brief Material for multi-scale simulations. It stores an
* underlying RVE on each integration point of the material.
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_FE2.hh"
#include "communicator.hh"
#include "solid_mechanics_model_RVE.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialFE2<spatial_dimension>::MaterialFE2(SolidMechanicsModel & model,
const ID & id)
: Parent(model, id), C("material_stiffness", *this) {
AKANTU_DEBUG_IN();
this->C.initialize(voigt_h::size * voigt_h::size);
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialFE2<spatial_dimension>::~MaterialFE2() = default;
/* -------------------------------------------------------------------------- */
template <UInt dim> void MaterialFE2<dim>::initialize() {
this->registerParam("element_type", el_type, _triangle_3,
_pat_parsable | _pat_modifiable,
"element type in RVE mesh");
this->registerParam("mesh_file", mesh_file, _pat_parsable | _pat_modifiable,
"the mesh file for the RVE");
this->registerParam("nb_gel_pockets", nb_gel_pockets,
_pat_parsable | _pat_modifiable,
"the number of gel pockets in each RVE");
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialFE2<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
Parent::initMaterial();
/// create a Mesh and SolidMechanicsModel on each integration point of the
/// material
auto C_it = this->C(this->el_type).begin(voigt_h::size, voigt_h::size);
for (auto && data :
enumerate(make_view(C(this->el_type), voigt_h::size, voigt_h::size))) {
auto q = std::get<0>(data);
auto & C = std::get<1>(data);
meshes.emplace_back(std::make_unique<Mesh>(
spatial_dimension, "RVE_mesh_" + std::to_string(q), q + 1));
auto & mesh = *meshes.back();
mesh.read(mesh_file);
RVEs.emplace_back(std::make_unique<SolidMechanicsModelRVE>(
mesh, true, this->nb_gel_pockets, _all_dimensions,
"SMM_RVE_" + std::to_string(q), q + 1));
auto & RVE = *RVEs.back();
RVE.initFull(_analysis_method = _static);
/// compute intial stiffness of the RVE
RVE.homogenizeStiffness(C);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialFE2<spatial_dimension>::computeStress(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
// Compute thermal stresses first
Parent::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator sigma_th_it =
this->sigma_th(el_type, ghost_type).begin();
// Wikipedia convention:
// 2*eps_ij (i!=j) = voigt_eps_I
// http://en.wikipedia.org/wiki/Voigt_notation
Array<Real>::const_matrix_iterator C_it =
this->C(el_type, ghost_type).begin(voigt_h::size, voigt_h::size);
// create vectors to store stress and strain in Voigt notation
// for efficient computation of stress
Vector<Real> voigt_strain(voigt_h::size);
Vector<Real> voigt_stress(voigt_h::size);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
const Matrix<Real> & C_mat = *C_it;
const Real & sigma_th = *sigma_th_it;
/// copy strains in Voigt notation
for (UInt I = 0; I < voigt_h::size; ++I) {
/// copy stress in
Real voigt_factor = voigt_h::factors[I];
UInt i = voigt_h::vec[I][0];
UInt j = voigt_h::vec[I][1];
voigt_strain(I) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.;
}
// compute stresses in Voigt notation
voigt_stress.mul<false>(C_mat, voigt_strain);
/// copy stresses back in full vectorised notation
for (UInt I = 0; I < voigt_h::size; ++I) {
UInt i = voigt_h::vec[I][0];
UInt j = voigt_h::vec[I][1];
sigma(i, j) = sigma(j, i) = voigt_stress(I) + (i == j) * sigma_th;
}
++C_it;
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialFE2<spatial_dimension>::computeTangentModuli(
const ElementType & el_type, Array<Real> & tangent_matrix,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::const_matrix_iterator C_it =
this->C(el_type, ghost_type).begin(voigt_h::size, voigt_h::size);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
tangent.copy(*C_it);
++C_it;
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialFE2<spatial_dimension>::advanceASR(
const Matrix<Real> & prestrain) {
AKANTU_DEBUG_IN();
for (auto && data :
zip(RVEs, make_view(this->gradu(this->el_type), spatial_dimension,
spatial_dimension),
make_view(this->eigengradu(this->el_type), spatial_dimension,
spatial_dimension),
make_view(this->C(this->el_type), voigt_h::size, voigt_h::size),
this->delta_T(this->el_type))) {
auto & RVE = *(std::get<0>(data));
/// apply boundary conditions based on the current macroscopic displ.
/// gradient
RVE.applyBoundaryConditions(std::get<1>(data));
/// apply homogeneous temperature field to each RVE to obtain thermoelastic
/// effect
RVE.applyHomogeneousTemperature(std::get<4>(data));
-
/// advance the ASR in every RVE
RVE.advanceASR(prestrain);
/// compute the average eigen_grad_u
RVE.homogenizeEigenGradU(std::get<2>(data));
/// compute the new effective stiffness of the RVE
RVE.homogenizeStiffness(std::get<3>(data));
}
AKANTU_DEBUG_OUT();
}
INSTANTIATE_MATERIAL(material_FE2, MaterialFE2);
} // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_FE2/material_FE2_inline_impl.cc b/extra_packages/extra-materials/src/material_FE2/material_FE2_inline_impl.cc
index 6445211c7..dc9e5e631 100644
--- a/extra_packages/extra-materials/src/material_FE2/material_FE2_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_FE2/material_FE2_inline_impl.cc
@@ -1,15 +1,14 @@
/**
* @file material_FE2_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Implementation of inline functions of the MaterialFE2
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
-
diff --git a/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.cc b/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.cc
index f30dec1bd..d6a8761b6 100644
--- a/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.cc
+++ b/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.cc
@@ -1,604 +1,604 @@
/**
* @file solid_mechanics_model_RVE.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Wed Jan 13 15:32:35 2016
*
* @brief Implementation of SolidMechanicsModelRVE
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_RVE.hh"
#include "element_group.hh"
#include "material_damage_iterative.hh"
#include "node_group.hh"
#include "non_linear_solver.hh"
#include "parser.hh"
#include "sparse_matrix.hh"
#include <string>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
SolidMechanicsModelRVE::SolidMechanicsModelRVE(Mesh & mesh,
bool use_RVE_mat_selector,
UInt nb_gel_pockets, UInt dim,
const ID & id,
const MemoryID & memory_id)
: SolidMechanicsModel(mesh, dim, id, memory_id), volume(0.),
use_RVE_mat_selector(use_RVE_mat_selector),
nb_gel_pockets(nb_gel_pockets), nb_dumps(0) {
AKANTU_DEBUG_IN();
/// find the four corner nodes of the RVE
findCornerNodes();
/// remove the corner nodes from the surface node groups:
/// This most be done because corner nodes a not periodic
mesh.getElementGroup("top").removeNode(corner_nodes(2));
mesh.getElementGroup("top").removeNode(corner_nodes(3));
mesh.getElementGroup("left").removeNode(corner_nodes(3));
mesh.getElementGroup("left").removeNode(corner_nodes(0));
mesh.getElementGroup("bottom").removeNode(corner_nodes(1));
mesh.getElementGroup("bottom").removeNode(corner_nodes(0));
mesh.getElementGroup("right").removeNode(corner_nodes(2));
mesh.getElementGroup("right").removeNode(corner_nodes(1));
const auto & bottom = mesh.getElementGroup("bottom").getNodeGroup();
bottom_nodes.insert(bottom.begin(), bottom.end());
const auto & left = mesh.getElementGroup("left").getNodeGroup();
left_nodes.insert(left.begin(), left.end());
// /// enforce periodicity on the displacement fluctuations
// auto surface_pair_1 = std::make_pair("top", "bottom");
// auto surface_pair_2 = std::make_pair("right", "left");
// SurfacePairList surface_pairs_list;
// surface_pairs_list.push_back(surface_pair_1);
// surface_pairs_list.push_back(surface_pair_2);
// TODO: To Nicolas correct the PBCs
// this->setPBC(surface_pairs_list);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModelRVE::~SolidMechanicsModelRVE() = default;
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::initFullImpl(const ModelOptions & options) {
AKANTU_DEBUG_IN();
auto options_cp(options);
options_cp.analysis_method = AnalysisMethod::_static;
SolidMechanicsModel::initFullImpl(options_cp);
- //this->initMaterials();
+ // this->initMaterials();
auto & fem = this->getFEEngine("SolidMechanicsFEEngine");
/// compute the volume of the RVE
GhostType gt = _not_ghost;
for (auto element_type :
this->mesh.elementTypes(spatial_dimension, gt, _ek_not_defined)) {
Array<Real> Volume(this->mesh.getNbElement(element_type) *
fem.getNbIntegrationPoints(element_type),
1, 1.);
this->volume = fem.integrate(Volume, element_type);
}
std::cout << "The volume of the RVE is " << this->volume << std::endl;
/// dumping
std::stringstream base_name;
base_name << this->id; // << this->memory_id - 1;
this->setBaseName(base_name.str());
this->addDumpFieldVector("displacement");
this->addDumpField("stress");
this->addDumpField("grad_u");
this->addDumpField("eigen_grad_u");
this->addDumpField("blocked_dofs");
this->addDumpField("material_index");
this->addDumpField("damage");
this->addDumpField("Sc");
this->addDumpField("external_force");
this->addDumpField("equivalent_stress");
this->addDumpField("internal_force");
this->addDumpField("delta_T");
this->dump();
this->nb_dumps += 1;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::applyBoundaryConditions(
const Matrix<Real> & displacement_gradient) {
AKANTU_DEBUG_IN();
/// get the position of the nodes
const Array<Real> & pos = mesh.getNodes();
/// storage for the coordinates of a given node and the displacement that will
/// be applied
Vector<Real> x(spatial_dimension);
Vector<Real> appl_disp(spatial_dimension);
/// fix top right node
UInt node = this->corner_nodes(2);
x(0) = pos(node, 0);
x(1) = pos(node, 1);
appl_disp.mul<false>(displacement_gradient, x);
(*this->blocked_dofs)(node, 0) = true;
(*this->displacement)(node, 0) = appl_disp(0);
(*this->blocked_dofs)(node, 1) = true;
(*this->displacement)(node, 1) = appl_disp(1);
// (*this->blocked_dofs)(node,0) = true; (*this->displacement)(node,0) = 0.;
// (*this->blocked_dofs)(node,1) = true; (*this->displacement)(node,1) = 0.;
/// apply Hx at all the other corner nodes; H: displ. gradient
node = this->corner_nodes(0);
x(0) = pos(node, 0);
x(1) = pos(node, 1);
appl_disp.mul<false>(displacement_gradient, x);
(*this->blocked_dofs)(node, 0) = true;
(*this->displacement)(node, 0) = appl_disp(0);
(*this->blocked_dofs)(node, 1) = true;
(*this->displacement)(node, 1) = appl_disp(1);
node = this->corner_nodes(1);
x(0) = pos(node, 0);
x(1) = pos(node, 1);
appl_disp.mul<false>(displacement_gradient, x);
(*this->blocked_dofs)(node, 0) = true;
(*this->displacement)(node, 0) = appl_disp(0);
(*this->blocked_dofs)(node, 1) = true;
(*this->displacement)(node, 1) = appl_disp(1);
node = this->corner_nodes(3);
x(0) = pos(node, 0);
x(1) = pos(node, 1);
appl_disp.mul<false>(displacement_gradient, x);
(*this->blocked_dofs)(node, 0) = true;
(*this->displacement)(node, 0) = appl_disp(0);
(*this->blocked_dofs)(node, 1) = true;
(*this->displacement)(node, 1) = appl_disp(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::applyHomogeneousTemperature(
const Real & temperature) {
for (UInt m = 0; m < this->getNbMaterials(); ++m) {
Material & mat = this->getMaterial(m);
const ElementTypeMapArray<UInt> & filter_map = mat.getElementFilter();
Mesh::type_iterator type_it = filter_map.firstType(spatial_dimension);
Mesh::type_iterator type_end = filter_map.lastType(spatial_dimension);
// Loop over all element types
for (; type_it != type_end; ++type_it) {
const Array<UInt> & filter = filter_map(*type_it);
if (filter.size() == 0)
continue;
Array<Real> & delta_T = mat.getArray<Real>("delta_T", *type_it);
Array<Real>::scalar_iterator delta_T_it = delta_T.begin();
Array<Real>::scalar_iterator delta_T_end = delta_T.end();
for (; delta_T_it != delta_T_end; ++delta_T_it) {
*delta_T_it = temperature;
}
}
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::findCornerNodes() {
AKANTU_DEBUG_IN();
// find corner nodes
const auto & position = mesh.getNodes();
const auto & lower_bounds = mesh.getLowerBounds();
const auto & upper_bounds = mesh.getUpperBounds();
AKANTU_DEBUG_ASSERT(spatial_dimension == 2, "This is 2D only!");
corner_nodes.resize(4);
corner_nodes.set(UInt(-1));
for (auto && data : enumerate(make_view(position, spatial_dimension))) {
auto node = std::get<0>(data);
const auto & X = std::get<1>(data);
auto distance = X.distance(lower_bounds);
// node 1
if (Math::are_float_equal(distance, 0)) {
corner_nodes(0) = node;
}
// node 2
else if (Math::are_float_equal(X(_x), upper_bounds(_x)) &&
Math::are_float_equal(X(_y), lower_bounds(_y))) {
corner_nodes(1) = node;
}
// node 3
else if (Math::are_float_equal(X(_x), upper_bounds(_x)) &&
Math::are_float_equal(X(_y), upper_bounds(_y))) {
corner_nodes(2) = node;
}
// node 4
else if (Math::are_float_equal(X(_x), lower_bounds(_x)) &&
Math::are_float_equal(X(_y), upper_bounds(_y))) {
corner_nodes(3) = node;
}
}
for (UInt i = 0; i < corner_nodes.size(); ++i) {
if (corner_nodes(i) == UInt(-1))
AKANTU_ERROR("The corner node " << i + 1 << " wasn't found");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::advanceASR(const Matrix<Real> & prestrain) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(spatial_dimension == 2, "This is 2D only!");
/// apply the new eigenstrain
for (auto element_type :
mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
Array<Real> & prestrain_vect =
const_cast<Array<Real> &>(this->getMaterial("gel").getInternal<Real>(
"eigen_grad_u")(element_type));
auto prestrain_it =
prestrain_vect.begin(spatial_dimension, spatial_dimension);
auto prestrain_end =
prestrain_vect.end(spatial_dimension, spatial_dimension);
for (; prestrain_it != prestrain_end; ++prestrain_it)
(*prestrain_it) = prestrain;
}
/// advance the damage
MaterialDamageIterative<2> & mat_paste =
dynamic_cast<MaterialDamageIterative<2> &>(*this->materials[1]);
MaterialDamageIterative<2> & mat_aggregate =
dynamic_cast<MaterialDamageIterative<2> &>(*this->materials[0]);
UInt nb_damaged_elements = 0;
Real max_eq_stress_aggregate = 0;
Real max_eq_stress_paste = 0;
auto & solver = this->getNonLinearSolver();
solver.set("max_iterations", 2);
solver.set("threshold", 1e-6);
solver.set("convergence_type", _scc_solution);
do {
this->solveStep();
/// compute damage
max_eq_stress_aggregate = mat_aggregate.getNormMaxEquivalentStress();
max_eq_stress_paste = mat_paste.getNormMaxEquivalentStress();
nb_damaged_elements = 0;
if (max_eq_stress_aggregate > max_eq_stress_paste)
nb_damaged_elements = mat_aggregate.updateDamage();
else if (max_eq_stress_aggregate < max_eq_stress_paste)
nb_damaged_elements = mat_paste.updateDamage();
else
nb_damaged_elements =
(mat_paste.updateDamage() + mat_aggregate.updateDamage());
std::cout << "the number of damaged elements is " << nb_damaged_elements
<< std::endl;
} while (nb_damaged_elements);
if (this->nb_dumps % 10 == 0) {
this->dump();
}
this->nb_dumps += 1;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModelRVE::averageTensorField(UInt row_index, UInt col_index,
const ID & field_type) {
AKANTU_DEBUG_IN();
auto & fem = this->getFEEngine("SolidMechanicsFEEngine");
Real average = 0;
GhostType gt = _not_ghost;
for (auto element_type :
mesh.elementTypes(spatial_dimension, gt, _ek_not_defined)) {
if (field_type == "stress") {
for (UInt m = 0; m < this->materials.size(); ++m) {
const auto & stress_vec = this->materials[m]->getStress(element_type);
const auto & elem_filter =
this->materials[m]->getElementFilter(element_type);
Array<Real> int_stress_vec(elem_filter.size(),
spatial_dimension * spatial_dimension,
"int_of_stress");
fem.integrate(stress_vec, int_stress_vec,
spatial_dimension * spatial_dimension, element_type,
_not_ghost, elem_filter);
for (UInt k = 0; k < elem_filter.size(); ++k)
- average += int_stress_vec(k, row_index * spatial_dimension +
- col_index); // 3 is the value
- // for the yy (in
- // 3D, the value is
- // 4)
+ average += int_stress_vec(
+ k, row_index * spatial_dimension + col_index); // 3 is the value
+ // for the yy (in
+ // 3D, the value is
+ // 4)
}
} else if (field_type == "strain") {
for (UInt m = 0; m < this->materials.size(); ++m) {
const auto & gradu_vec = this->materials[m]->getGradU(element_type);
const auto & elem_filter =
this->materials[m]->getElementFilter(element_type);
Array<Real> int_gradu_vec(elem_filter.size(),
spatial_dimension * spatial_dimension,
"int_of_gradu");
fem.integrate(gradu_vec, int_gradu_vec,
spatial_dimension * spatial_dimension, element_type,
_not_ghost, elem_filter);
for (UInt k = 0; k < elem_filter.size(); ++k)
/// averaging is done only for normal components, so stress and strain
/// are equal
average +=
0.5 *
(int_gradu_vec(k, row_index * spatial_dimension + col_index) +
int_gradu_vec(k, col_index * spatial_dimension + row_index));
}
} else if (field_type == "eigen_grad_u") {
for (UInt m = 0; m < this->materials.size(); ++m) {
const auto & eigen_gradu_vec =
this->materials[m]->getInternal<Real>("eigen_grad_u")(element_type);
const auto & elem_filter =
this->materials[m]->getElementFilter(element_type);
Array<Real> int_eigen_gradu_vec(elem_filter.size(),
spatial_dimension * spatial_dimension,
"int_of_gradu");
fem.integrate(eigen_gradu_vec, int_eigen_gradu_vec,
spatial_dimension * spatial_dimension, element_type,
_not_ghost, elem_filter);
for (UInt k = 0; k < elem_filter.size(); ++k)
/// averaging is done only for normal components, so stress and strain
/// are equal
average +=
int_eigen_gradu_vec(k, row_index * spatial_dimension + col_index);
}
} else {
AKANTU_ERROR("Averaging not implemented for this field!!!");
}
}
return average / this->volume;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::homogenizeStiffness(Matrix<Real> & C_macro) {
AKANTU_DEBUG_IN();
const UInt dim = 2;
AKANTU_DEBUG_ASSERT(this->spatial_dimension == dim,
"Is only implemented for 2D!!!");
/// apply three independent loading states to determine C
/// 1. eps_el = (1;0;0) 2. eps_el = (0,1,0) 3. eps_el = (0,0,0.5)
/// clear the eigenstrain
Matrix<Real> zero_eigengradu(dim, dim, 0.);
GhostType gt = _not_ghost;
for (auto element_type : mesh.elementTypes(dim, gt, _ek_not_defined)) {
auto & prestrain_vect =
const_cast<Array<Real> &>(this->getMaterial("gel").getInternal<Real>(
"eigen_grad_u")(element_type));
auto prestrain_it =
prestrain_vect.begin(spatial_dimension, spatial_dimension);
auto prestrain_end =
prestrain_vect.end(spatial_dimension, spatial_dimension);
for (; prestrain_it != prestrain_end; ++prestrain_it)
(*prestrain_it) = zero_eigengradu;
}
/// storage for results of 3 different loading states
UInt voigt_size = VoigtHelper<dim>::size;
Matrix<Real> stresses(voigt_size, voigt_size, 0.);
Matrix<Real> strains(voigt_size, voigt_size, 0.);
Matrix<Real> H(dim, dim, 0.);
/// save the damage state before filling up cracks
// ElementTypeMapReal saved_damage("saved_damage");
// saved_damage.initialize(getFEEngine(), _nb_component = 1, _default_value =
// 0);
// this->fillCracks(saved_damage);
/// virtual test 1:
H(0, 0) = 0.01;
this->performVirtualTesting(H, stresses, strains, 0);
/// virtual test 2:
H.clear();
H(1, 1) = 0.01;
this->performVirtualTesting(H, stresses, strains, 1);
/// virtual test 3:
H.clear();
H(0, 1) = 0.01;
this->performVirtualTesting(H, stresses, strains, 2);
/// drain cracks
// this->drainCracks(saved_damage);
/// compute effective stiffness
Matrix<Real> eps_inverse(voigt_size, voigt_size);
eps_inverse.inverse(strains);
C_macro.mul<false, false>(stresses, eps_inverse);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::performVirtualTesting(const Matrix<Real> & H,
Matrix<Real> & eff_stresses,
Matrix<Real> & eff_strains,
const UInt test_no) {
AKANTU_DEBUG_IN();
this->applyBoundaryConditions(H);
auto & solver = this->getNonLinearSolver();
solver.set("max_iterations", 2);
solver.set("threshold", 1e-6);
solver.set("convergence_type", _scc_solution);
this->solveStep();
/// get average stress and strain
eff_stresses(0, test_no) = this->averageTensorField(0, 0, "stress");
eff_strains(0, test_no) = this->averageTensorField(0, 0, "strain");
eff_stresses(1, test_no) = this->averageTensorField(1, 1, "stress");
eff_strains(1, test_no) = this->averageTensorField(1, 1, "strain");
eff_stresses(2, test_no) = this->averageTensorField(1, 0, "stress");
eff_strains(2, test_no) = 2. * this->averageTensorField(1, 0, "strain");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::homogenizeEigenGradU(
Matrix<Real> & eigen_gradu_macro) {
AKANTU_DEBUG_IN();
eigen_gradu_macro(0, 0) = this->averageTensorField(0, 0, "eigen_grad_u");
eigen_gradu_macro(1, 1) = this->averageTensorField(1, 1, "eigen_grad_u");
eigen_gradu_macro(0, 1) = this->averageTensorField(0, 1, "eigen_grad_u");
eigen_gradu_macro(1, 0) = this->averageTensorField(1, 0, "eigen_grad_u");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::initMaterials() {
AKANTU_DEBUG_IN();
// make sure the material are instantiated
if (!are_materials_instantiated)
instantiateMaterials();
if (use_RVE_mat_selector) {
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real box_size = std::abs(top - bottom);
Real eps = box_size * 1e-6;
auto tmp = std::make_shared<GelMaterialSelector>(*this, box_size, "gel",
this->nb_gel_pockets, eps);
tmp->setFallback(material_selector);
material_selector = tmp;
}
this->assignMaterialToElements();
// synchronize the element material arrays
this->synchronize(_gst_material_id);
for (auto & material : materials) {
/// init internals properties
const auto type = material->getID();
if (type.find("material_FE2") != std::string::npos)
continue;
material->initMaterial();
}
this->synchronize(_gst_smm_init_mat);
if (this->non_local_manager) {
this->non_local_manager->initialize();
}
- //SolidMechanicsModel::initMaterials();
+ // SolidMechanicsModel::initMaterials();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::fillCracks(ElementTypeMapReal & saved_damage) {
const auto & mat_gel = this->getMaterial("gel");
Real E_gel = mat_gel.get("E");
Real E_homogenized = 0.;
for (auto && mat : materials) {
if (mat->getName() == "gel" || mat->getName() == "FE2_mat")
continue;
Real E = mat->get("E");
auto & damage = mat->getInternal<Real>("damage");
for (auto && type : damage.elementTypes()) {
const auto & elem_filter = mat->getElementFilter(type);
auto nb_integration_point = getFEEngine().getNbIntegrationPoints(type);
auto sav_dam_it =
make_view(saved_damage(type), nb_integration_point).begin();
for (auto && data :
zip(elem_filter, make_view(damage(type), nb_integration_point))) {
auto el = std::get<0>(data);
auto & dam = std::get<1>(data);
Vector<Real> sav_dam = sav_dam_it[el];
sav_dam = dam;
for (auto q : arange(dam.size())) {
E_homogenized = (E_gel - E) * dam(q) + E;
dam(q) = 1. - (E_homogenized / E);
}
}
}
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelRVE::drainCracks(
const ElementTypeMapReal & saved_damage) {
for (auto && mat : materials) {
if (mat->getName() == "gel" || mat->getName() == "FE2_mat")
continue;
auto & damage = mat->getInternal<Real>("damage");
for (auto && type : damage.elementTypes()) {
const auto & elem_filter = mat->getElementFilter(type);
auto nb_integration_point = getFEEngine().getNbIntegrationPoints(type);
auto sav_dam_it =
make_view(saved_damage(type), nb_integration_point).begin();
for (auto && data :
zip(elem_filter, make_view(damage(type), nb_integration_point))) {
auto el = std::get<0>(data);
auto & dam = std::get<1>(data);
Vector<Real> sav_dam = sav_dam_it[el];
dam = sav_dam;
}
}
}
}
} // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.hh b/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.hh
index b509066c6..150ea6599 100644
--- a/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.hh
+++ b/extra_packages/extra-materials/src/material_FE2/solid_mechanics_model_RVE.hh
@@ -1,234 +1,233 @@
/**
* @file solid_mechanics_model_RVE.hh
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Wed Jan 13 14:54:18 2016
*
* @brief SMM for RVE computations in FE2 simulations
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_RVE_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_RVE_HH__
/* -------------------------------------------------------------------------- */
#include "aka_grid_dynamic.hh"
#include "solid_mechanics_model.hh"
#include <unordered_set>
/* -------------------------------------------------------------------------- */
namespace akantu {
class SolidMechanicsModelRVE : public SolidMechanicsModel {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SolidMechanicsModelRVE(Mesh & mesh, bool use_RVE_mat_selector = true,
UInt nb_gel_pockets = 400,
UInt spatial_dimension = _all_dimensions,
const ID & id = "solid_mechanics_model",
const MemoryID & memory_id = 0);
virtual ~SolidMechanicsModelRVE();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
void initFullImpl(const ModelOptions & option) override;
/// initialize the materials
void initMaterials() override;
public:
/// apply boundary contions based on macroscopic deformation gradient
virtual void
applyBoundaryConditions(const Matrix<Real> & displacement_gradient);
/// apply homogeneous temperature field from the macroscale level to the RVEs
- virtual void
- applyHomogeneousTemperature(const Real & temperature);
+ virtual void applyHomogeneousTemperature(const Real & temperature);
-/// advance the reactions -> grow gel and apply homogenized properties
+ /// advance the reactions -> grow gel and apply homogenized properties
void advanceASR(const Matrix<Real> & prestrain);
/// compute average stress or strain in the model
Real averageTensorField(UInt row_index, UInt col_index,
const ID & field_type);
/// compute effective stiffness of the RVE
void homogenizeStiffness(Matrix<Real> & C_macro);
/// compute average eigenstrain
void homogenizeEigenGradU(Matrix<Real> & eigen_gradu_macro);
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
inline void unpackData(CommunicationBuffer & buffer,
const Array<UInt> & index,
const SynchronizationTag & tag) override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(CornerNodes, corner_nodes, const Array<UInt> &);
AKANTU_GET_MACRO(Volume, volume, Real);
private:
/// find the corner nodes
void findCornerNodes();
/// perform virtual testing
void performVirtualTesting(const Matrix<Real> & H,
Matrix<Real> & eff_stresses,
Matrix<Real> & eff_strains, const UInt test_no);
void fillCracks(ElementTypeMapReal & saved_damage);
void drainCracks(const ElementTypeMapReal & saved_damage);
/* ------------------------------------------------------------------------ */
/* Members */
/* ------------------------------------------------------------------------ */
/// volume of the RVE
Real volume;
/// corner nodes 1, 2, 3, 4 (see Leonardo's thesis, page 98)
Array<UInt> corner_nodes;
/// bottom nodes
std::unordered_set<UInt> bottom_nodes;
/// left nodes
std::unordered_set<UInt> left_nodes;
/// standard mat selector or user one
bool use_RVE_mat_selector;
/// the number of gel pockets inside the RVE
UInt nb_gel_pockets;
/// dump counter
UInt nb_dumps;
};
inline void SolidMechanicsModelRVE::unpackData(CommunicationBuffer & buffer,
const Array<UInt> & index,
const SynchronizationTag & tag) {
SolidMechanicsModel::unpackData(buffer, index, tag);
-// if (tag == _gst_smm_uv) {
-// auto disp_it = displacement->begin(spatial_dimension);
-//
-// for (auto node : index) {
-// Vector<Real> current_disp(disp_it[node]);
-//
-// // if node is at the bottom, u_bottom = u_top +u_2 -u_3
-// if (bottom_nodes.count(node)) {
-// current_disp += Vector<Real>(disp_it[corner_nodes(1)]);
-// current_disp -= Vector<Real>(disp_it[corner_nodes(2)]);
-// }
-// // if node is at the left, u_left = u_right +u_4 -u_3
-// else if (left_nodes.count(node)) {
-// current_disp += Vector<Real>(disp_it[corner_nodes(3)]);
-// current_disp -= Vector<Real>(disp_it[corner_nodes(2)]);
-// }
-// }
-// }
+ // if (tag == _gst_smm_uv) {
+ // auto disp_it = displacement->begin(spatial_dimension);
+ //
+ // for (auto node : index) {
+ // Vector<Real> current_disp(disp_it[node]);
+ //
+ // // if node is at the bottom, u_bottom = u_top +u_2 -u_3
+ // if (bottom_nodes.count(node)) {
+ // current_disp += Vector<Real>(disp_it[corner_nodes(1)]);
+ // current_disp -= Vector<Real>(disp_it[corner_nodes(2)]);
+ // }
+ // // if node is at the left, u_left = u_right +u_4 -u_3
+ // else if (left_nodes.count(node)) {
+ // current_disp += Vector<Real>(disp_it[corner_nodes(3)]);
+ // current_disp -= Vector<Real>(disp_it[corner_nodes(2)]);
+ // }
+ // }
+ // }
}
/* -------------------------------------------------------------------------- */
/* ASR material selector */
/* -------------------------------------------------------------------------- */
class GelMaterialSelector : public MeshDataMaterialSelector<std::string> {
public:
GelMaterialSelector(SolidMechanicsModel & model, const Real box_size,
const std::string & gel_material,
const UInt nb_gel_pockets, Real /*tolerance*/ = 0.)
: MeshDataMaterialSelector<std::string>("physical_names", model),
model(model), gel_material(gel_material),
nb_gel_pockets(nb_gel_pockets), nb_placed_gel_pockets(0),
box_size(box_size) {
Mesh & mesh = this->model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
Element el{_triangle_3, 0, _not_ghost};
UInt nb_element = mesh.getNbElement(el.type, el.ghost_type);
Array<Real> barycenter(nb_element, spatial_dimension);
for (auto && data : enumerate(make_view(barycenter, spatial_dimension))) {
el.element = std::get<0>(data);
auto & bary = std::get<1>(data);
mesh.getBarycenter(el, bary);
}
/// generate the gel pockets
srand(0.);
Vector<Real> center(spatial_dimension);
UInt placed_gel_pockets = 0;
std::set<int> checked_baries;
while (placed_gel_pockets != nb_gel_pockets) {
/// get a random bary center
UInt bary_id = rand() % nb_element;
if (checked_baries.find(bary_id) != checked_baries.end())
continue;
checked_baries.insert(bary_id);
el.element = bary_id;
if (MeshDataMaterialSelector<std::string>::operator()(el) == 1)
continue; /// element belongs to paste
gel_pockets.push_back(el);
placed_gel_pockets += 1;
}
}
UInt operator()(const Element & elem) {
UInt temp_index = MeshDataMaterialSelector<std::string>::operator()(elem);
if (temp_index == 1)
return temp_index;
std::vector<Element>::const_iterator iit = gel_pockets.begin();
std::vector<Element>::const_iterator eit = gel_pockets.end();
if (std::find(iit, eit, elem) != eit) {
nb_placed_gel_pockets += 1;
std::cout << nb_placed_gel_pockets << " gelpockets placed" << std::endl;
return model.getMaterialIndex(gel_material);
;
}
return 0;
}
protected:
SolidMechanicsModel & model;
std::string gel_material;
std::vector<Element> gel_pockets;
UInt nb_gel_pockets;
UInt nb_placed_gel_pockets;
Real box_size;
};
} // namespace akantu
///#include "material_selector_tmpl.hh"
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_RVE_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle.cc b/extra_packages/extra-materials/src/material_damage/material_brittle.cc
index f3d03636f..6a114adfd 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle.cc
@@ -1,121 +1,124 @@
/**
* @file material_brittle.cc
*
* @author Aranda Ruiz Josue <josue.arandaruiz@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
*
* @brief Specialization of the material class for the brittle material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_brittle.hh"
#include "solid_mechanics_model.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
MaterialBrittle<spatial_dimension>::MaterialBrittle(SolidMechanicsModel & model,
- const ID & id):
- MaterialDamage<spatial_dimension>(model, id),
- strain_rate_brittle("strain_rate_brittle", *this){
+ const ID & id)
+ : MaterialDamage<spatial_dimension>(model, id),
+ strain_rate_brittle("strain_rate_brittle", *this) {
AKANTU_DEBUG_IN();
- this->registerParam("S_0", S_0, 157e6, _pat_parsable | _pat_modifiable);
- this->registerParam("E_0", E_0, 27e3, _pat_parsable, "Strain rate threshold");
- this->registerParam("A", A, 1.622e-5, _pat_parsable, "Polynome cubic constant");
- this->registerParam("B", B, -1.3274, _pat_parsable, "Polynome quadratic constant");
- this->registerParam("C", C, 3.6544e4, _pat_parsable, "Polynome linear constant");
- this->registerParam("D", D, -181.38e6, _pat_parsable, "Polynome constant");
+ this->registerParam("S_0", S_0, 157e6, _pat_parsable | _pat_modifiable);
+ this->registerParam("E_0", E_0, 27e3, _pat_parsable, "Strain rate threshold");
+ this->registerParam("A", A, 1.622e-5, _pat_parsable,
+ "Polynome cubic constant");
+ this->registerParam("B", B, -1.3274, _pat_parsable,
+ "Polynome quadratic constant");
+ this->registerParam("C", C, 3.6544e4, _pat_parsable,
+ "Polynome linear constant");
+ this->registerParam("D", D, -181.38e6, _pat_parsable, "Polynome constant");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialBrittle<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialDamage<spatial_dimension>::initMaterial();
this->strain_rate_brittle.initialize(spatial_dimension * spatial_dimension);
updateInternalParameters();
- //this->Yd.resize();
+ // this->Yd.resize();
// const Mesh & mesh = this->model.getFEEngine().getMesh();
// Mesh::type_iterator it = mesh.firstType(spatial_dimension);
// Mesh::type_iterator last_type = mesh.lastType(spatial_dimension);
// for(; it != last_type; ++it) {
// UInt nb_element = this->element_filter(*it).getSize();
// UInt nb_quad = this->model.getFEEngine().getNbQuadraturePoints(*it);
// Array <Real> & Yd_rand_vec = Yd_rand(*it);
// for(UInt e = 0; e < nb_element; ++e) {
// Real rand_part = (2 * drand48()-1) * Yd_randomness * Yd;
// for(UInt q = 0; q < nb_quad; ++q)
// Yd_rand_vec(nb_quad*e+q,0) = Yd + rand_part;
// }
// }
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialBrittle<spatial_dimension>::updateInternalParameters() {
MaterialDamage<spatial_dimension>::updateInternalParameters();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialBrittle<spatial_dimension>::computeStress(ElementType el_type,
- GhostType ghost_type) {
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(el_type, ghost_type).storage();
Array<Real> & velocity = this->model.getVelocity();
- Array<Real> & strain_rate_brittle = this->strain_rate_brittle(el_type, ghost_type);
+ Array<Real> & strain_rate_brittle =
+ this->strain_rate_brittle(el_type, ghost_type);
Array<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
- this->model.getFEEngine().gradientOnIntegrationPoints(velocity, strain_rate_brittle,
- spatial_dimension,
- el_type, ghost_type, elem_filter);
-
- Array<Real>::iterator< Matrix<Real> > strain_rate_it =
- this->strain_rate_brittle(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
+ this->model.getFEEngine().gradientOnIntegrationPoints(
+ velocity, strain_rate_brittle, spatial_dimension, el_type, ghost_type,
+ elem_filter);
+ Array<Real>::iterator<Matrix<Real>> strain_rate_it =
+ this->strain_rate_brittle(el_type, ghost_type)
+ .begin(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Real sigma_equivalent = 0;
Real fracture_stress = 0;
Matrix<Real> & grad_v = *strain_rate_it;
- computeStressOnQuad(grad_u, grad_v, sigma, *dam, sigma_equivalent, fracture_stress);
+ computeStressOnQuad(grad_u, grad_v, sigma, *dam, sigma_equivalent,
+ fracture_stress);
++strain_rate_it;
++dam;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(brittle, MaterialBrittle);
-
} // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle.hh b/extra_packages/extra-materials/src/material_damage/material_brittle.hh
index e86165c63..f7fcc7768 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle.hh
@@ -1,111 +1,111 @@
/**
* @file material_brittle.hh
*
* @author Aranda Ruiz Josue <josue.arandaruiz@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
*
* @brief Brittle damage law
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
#include "material_damage.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_BRITTLE_HH__
#define __AKANTU_MATERIAL_BRITTLE_HH__
namespace akantu {
/**
* Material brittle
*
* parameters in the material files :
* - S_0 : Critical stress at low strain rate (default: 157e6)
* - E_0 : Low strain rate threshold (default: 27e3)
* - A,B,C,D : Fitting parameters for the critical stress at high strain
* rates
* (default: 1.622e-11, -1.3274e-6, 3.6544e-2, -181.38)
*/
template <UInt spatial_dimension>
class MaterialBrittle : public MaterialDamage<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialBrittle(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initMaterial();
virtual void updateInternalParameters();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
protected:
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(Matrix<Real> & grad_u, Matrix<Real> & grad_v,
Matrix<Real> & sigma, Real & dam,
Real & sigma_equivalent,
Real & fracture_stress);
inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam,
Real & sigma_c,
Real & fracture_stress);
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline UInt getNbData(const Array<Element> & elements,
- const SynchronizationTag & tag) const override;
+ const SynchronizationTag & tag) const override;
inline void packData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- const SynchronizationTag & tag) const override;
+ const Array<Element> & elements,
+ const SynchronizationTag & tag) const override;
inline void unpackData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- const SynchronizationTag & tag) override;
+ const Array<Element> & elements,
+ const SynchronizationTag & tag) override;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// strain rate arrays ordered by element types
InternalField<Real> strain_rate_brittle;
// polynome constants for critical stress value
Real A;
Real B;
Real C;
Real D;
// minimum strain rate
Real E_0;
// Critical stress at low strain rates
Real S_0;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_brittle_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_brittle_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh
index b77c270fe..ac53464d8 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh
@@ -1,85 +1,89 @@
/**
* @file material_brittle_non_local.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
*
* @brief MaterialBrittleNonLocal header for non-local damage
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_brittle.hh"
#include "material_damage_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_BRITTLE_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_BRITTLE_NON_LOCAL_HH__
namespace akantu {
/**
* Material Brittle Non local
*
* parameters in the material files :
*/
-template<UInt spatial_dimension>
-class MaterialBrittleNonLocal : public MaterialDamageNonLocal<spatial_dimension, MaterialBrittle<spatial_dimension> > {
+template <UInt spatial_dimension>
+class MaterialBrittleNonLocal
+ : public MaterialDamageNonLocal<spatial_dimension,
+ MaterialBrittle<spatial_dimension>> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef MaterialDamageNonLocal<spatial_dimension, MaterialBrittle<spatial_dimension> > MaterialBrittleNonLocalParent;
+ typedef MaterialDamageNonLocal<spatial_dimension,
+ MaterialBrittle<spatial_dimension>>
+ MaterialBrittleNonLocalParent;
MaterialBrittleNonLocal(SolidMechanicsModel & model, const ID & id = "");
- virtual ~MaterialBrittleNonLocal() {};
+ virtual ~MaterialBrittleNonLocal(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void initMaterial();
protected:
/// constitutive law
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
- void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost);
+ void computeNonLocalStress(ElementType type,
+ GhostType ghost_type = _not_ghost);
/// associate the non-local variables of the material to their neighborhoods
virtual void nonLocalVariableToNeighborhood();
-private:
+private:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Sigma_max, Sigma_max, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
InternalField<Real> Sigma_max;
InternalField<Real> Sigma_maxnl;
InternalField<Real> Sigma_fracture;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_brittle_non_local_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_BRITTLE_NON_LOCAL_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.cc b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.cc
index 8c5261e5d..2ab9de3d2 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.cc
@@ -1,111 +1,117 @@
/**
* @file material_brittle_non_local_inline_impl.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
*
* @brief MaterialBrittleNonLocal inline function implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
} // namespace akantu
#if defined(AKANTU_DEBUG_TOOLS)
#include "aka_debug_tools.hh"
#include <string>
#endif
namespace akantu {
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-MaterialBrittleNonLocal<spatial_dimension>::MaterialBrittleNonLocal(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- MaterialBrittleNonLocalParent(model, id),
- Sigma_max("Sigma max", *this),
- Sigma_maxnl("Sigma_max non local", *this),
- Sigma_fracture("Sigma_fracture", *this){
+template <UInt spatial_dimension>
+MaterialBrittleNonLocal<spatial_dimension>::MaterialBrittleNonLocal(
+ SolidMechanicsModel & model, const ID & id)
+ : Material(model, id), MaterialBrittleNonLocalParent(model, id),
+ Sigma_max("Sigma max", *this), Sigma_maxnl("Sigma_max non local", *this),
+ Sigma_fracture("Sigma_fracture", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
this->Sigma_max.initialize(1);
this->Sigma_maxnl.initialize(1);
this->Sigma_fracture.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialBrittleNonLocal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
- this->model.getNonLocalManager().registerNonLocalVariable(this->Sigma_max.getName(), Sigma_maxnl.getName(),1);
+ this->model.getNonLocalManager().registerNonLocalVariable(
+ this->Sigma_max.getName(), Sigma_maxnl.getName(), 1);
MaterialBrittleNonLocalParent::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialBrittleNonLocal<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialBrittleNonLocal<spatial_dimension>::computeStress(
+ ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(el_type, ghost_type).storage();
- Real * Sigma_maxt = this->Sigma_max(el_type, ghost_type).storage();
- Real * fracture_stress = this->Sigma_fracture(el_type, ghost_type).storage();
+ Real * Sigma_maxt = this->Sigma_max(el_type, ghost_type).storage();
+ Real * fracture_stress = this->Sigma_fracture(el_type, ghost_type).storage();
Array<Real> & velocity = this->model.getVelocity();
- Array<Real> & strain_rate_brittle = this->strain_rate_brittle(el_type, ghost_type);
+ Array<Real> & strain_rate_brittle =
+ this->strain_rate_brittle(el_type, ghost_type);
Array<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
- this->model.getFEEngine().gradientOnIntegrationPoints(velocity, strain_rate_brittle,
- spatial_dimension,
- el_type, ghost_type, elem_filter);
+ this->model.getFEEngine().gradientOnIntegrationPoints(
+ velocity, strain_rate_brittle, spatial_dimension, el_type, ghost_type,
+ elem_filter);
- Array<Real>::iterator< Matrix<Real> > strain_rate_it =
- this->strain_rate_brittle(el_type, ghost_type).begin(spatial_dimension, spatial_dimension);
+ Array<Real>::iterator<Matrix<Real>> strain_rate_it =
+ this->strain_rate_brittle(el_type, ghost_type)
+ .begin(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & grad_v = *strain_rate_it;
- MaterialBrittle<spatial_dimension>::computeStressOnQuad(grad_u, grad_v, sigma, *dam, *Sigma_maxt, *fracture_stress);
+ MaterialBrittle<spatial_dimension>::computeStressOnQuad(
+ grad_u, grad_v, sigma, *dam, *Sigma_maxt, *fracture_stress);
++dam;
++strain_rate_it;
++Sigma_maxt;
++fracture_stress;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialBrittleNonLocal<spatial_dimension>::computeNonLocalStress(ElementType type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialBrittleNonLocal<spatial_dimension>::computeNonLocalStress(
+ ElementType type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
- Real * dam = this->damage(type, ghost_type).storage();
+ Real * dam = this->damage(type, ghost_type).storage();
Real * Sigma_maxnlt = this->Sigma_maxnl(type, ghost_type).storage();
Real * fracture_stress = this->Sigma_fracture(type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(type, ghost_type);
- this->computeDamageAndStressOnQuad(sigma, *dam, *Sigma_maxnlt, *fracture_stress);
+ this->computeDamageAndStressOnQuad(sigma, *dam, *Sigma_maxnlt,
+ *fracture_stress);
++dam;
++Sigma_maxnlt;
++fracture_stress;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialBrittleNonLocal<spatial_dimension>::nonLocalVariableToNeighborhood() {
- this->model.getNonLocalManager().nonLocalVariableToNeighborhood(Sigma_maxnl.getName(), this->name);
+template <UInt spatial_dimension>
+void MaterialBrittleNonLocal<
+ spatial_dimension>::nonLocalVariableToNeighborhood() {
+ this->model.getNonLocalManager().nonLocalVariableToNeighborhood(
+ Sigma_maxnl.getName(), this->name);
}
-
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc
index 485abb338..7f183501e 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc
@@ -1,40 +1,42 @@
/**
* @file material_damage_iterative.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
- * @brief Implementation of MaterialDamageIterativeNonLocal
+ * @brief Implementation of MaterialDamageIterativeNonLocal
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage_iterative_non_local.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialDamageIterativeNonLocal<spatial_dimension>::computeNonLocalStresses(GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialDamageIterativeNonLocal<
+ spatial_dimension>::computeNonLocalStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// reset normalized maximum equivalent stress
- if(ghost_type==_not_ghost)
+ if (ghost_type == _not_ghost)
this->norm_max_equivalent_stress = 0;
-
+
MaterialDamageIterativeNonLocalParent::computeNonLocalStresses(ghost_type);
/// find global Gauss point with highest stress
const auto & comm = this->model.getMesh().getCommunicator();
comm.allReduce(this->norm_max_equivalent_stress, SynchronizerOperation::_max);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-INSTANTIATE_MATERIAL(damage_iterative_non_local, MaterialDamageIterativeNonLocal);
+INSTANTIATE_MATERIAL(damage_iterative_non_local,
+ MaterialDamageIterativeNonLocal);
} // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh
index 3a8aee989..cb1b9af83 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh
@@ -1,80 +1,81 @@
/**
* @file material_damage_iterative_non_local.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief MaterialDamageIterativeNonLocal header for non-local damage
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_damage_iterative.hh"
#include "material_damage_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_DAMAGE_ITERATIVE_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_DAMAGE_ITERATIVE_NON_LOCAL_HH__
namespace akantu {
/**
* Material Damage Iterative Non local
*
* parameters in the material files :
*/
-template<UInt spatial_dimension>
-class MaterialDamageIterativeNonLocal : public MaterialDamageNonLocal<spatial_dimension,
- MaterialDamageIterative<spatial_dimension> > {
+template <UInt spatial_dimension>
+class MaterialDamageIterativeNonLocal
+ : public MaterialDamageNonLocal<
+ spatial_dimension, MaterialDamageIterative<spatial_dimension>> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef MaterialDamageNonLocal<spatial_dimension,
- MaterialDamageIterative<spatial_dimension> > MaterialDamageIterativeNonLocalParent;
- MaterialDamageIterativeNonLocal(SolidMechanicsModel & model, const ID & id = "");
+ MaterialDamageIterative<spatial_dimension>>
+ MaterialDamageIterativeNonLocalParent;
+ MaterialDamageIterativeNonLocal(SolidMechanicsModel & model,
+ const ID & id = "");
- virtual ~MaterialDamageIterativeNonLocal() {};
+ virtual ~MaterialDamageIterativeNonLocal(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void initMaterial();
virtual void computeNonLocalStresses(GhostType ghost_type);
protected:
void computeStress(ElementType type, GhostType ghost_type);
- void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost);
+ void computeNonLocalStress(ElementType type,
+ GhostType ghost_type = _not_ghost);
private:
-
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
- InternalField<Real> grad_u_nl;
+ InternalField<Real> grad_u_nl;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_damage_iterative_non_local_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_DAMAGE_ITERATIVE_NON_LOCAL_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.cc b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.cc
index dda04de6c..8a8fb90a4 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.cc
@@ -1,87 +1,89 @@
/**
* @file material_damage_iterative_non_local_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief MaterialDamageIterativeNonLocal inline function implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
} // namespace akantu
#if defined(AKANTU_DEBUG_TOOLS)
#include "aka_debug_tools.hh"
#include <string>
#endif
namespace akantu {
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-MaterialDamageIterativeNonLocal<spatial_dimension>::MaterialDamageIterativeNonLocal(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- MaterialDamageIterativeNonLocalParent(model, id),
- grad_u_nl("grad_u non local", *this) {
+template <UInt spatial_dimension>
+MaterialDamageIterativeNonLocal<spatial_dimension>::
+ MaterialDamageIterativeNonLocal(SolidMechanicsModel & model, const ID & id)
+ : Material(model, id), MaterialDamageIterativeNonLocalParent(model, id),
+ grad_u_nl("grad_u non local", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
- this->grad_u_nl.initialize(spatial_dimension*spatial_dimension);
- this->model.getNonLocalManager().registerNonLocalVariable(this->gradu.getName(), grad_u_nl.getName(), spatial_dimension*spatial_dimension);
+ this->grad_u_nl.initialize(spatial_dimension * spatial_dimension);
+ this->model.getNonLocalManager().registerNonLocalVariable(
+ this->gradu.getName(), grad_u_nl.getName(),
+ spatial_dimension * spatial_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialDamageIterativeNonLocal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialDamageIterativeNonLocalParent::initMaterial();
- this->model.getNonLocalManager().nonLocalVariableToNeighborhood(grad_u_nl.getName(), this->name);
+ this->model.getNonLocalManager().nonLocalVariableToNeighborhood(
+ grad_u_nl.getName(), this->name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialDamageIterativeNonLocal<spatial_dimension>::computeStress(ElementType type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialDamageIterativeNonLocal<spatial_dimension>::computeStress(
+ ElementType type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialDamageIterativeNonLocal<spatial_dimension>::computeNonLocalStress(ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialDamageIterativeNonLocal<spatial_dimension>::computeNonLocalStress(
+ ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
-
+
/// compute the stress (based on the elastic law)
MaterialDamage<spatial_dimension>::computeStress(el_type, ghost_type);
/// multiply the stress by (1-d) to get the effective stress
Real * dam = this->damage(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
- this->computeDamageAndStressOnQuad(sigma,*dam);
+ this->computeDamageAndStressOnQuad(sigma, *dam);
++dam;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
/// compute the normalized equivalent stress
- this->computeNormalizedEquivalentStress(this->grad_u_nl(el_type, ghost_type), el_type, ghost_type);
+ this->computeNormalizedEquivalentStress(this->grad_u_nl(el_type, ghost_type),
+ el_type, ghost_type);
/// find the maximum
this->norm_max_equivalent_stress = 0;
this->findMaxNormalizedEquivalentStress(el_type, ghost_type);
AKANTU_DEBUG_OUT();
}
-
-
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc b/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc
index 551e85f48..377c8ffae 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc
@@ -1,75 +1,74 @@
/**
* @file material_damage_linear.cc
*
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
*
*
* @brief Specialization of the material class for the damage material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage_linear.hh"
#include "solid_mechanics_model.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialDamageLinear<spatial_dimension>::MaterialDamageLinear(
SolidMechanicsModel & model, const ID & id)
- : MaterialDamage<spatial_dimension>(model, id),
- K("K", *this) {
+ : MaterialDamage<spatial_dimension>(model, id), K("K", *this) {
AKANTU_DEBUG_IN();
this->registerParam("Sigc", Sigc, 1e5, _pat_parsable, "Sigma Critique");
this->registerParam("Gc", Gc, 2., _pat_parsable, "Gc");
this->K.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialDamageLinear<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialDamage<spatial_dimension>::initMaterial();
Epsmin = Sigc / this->E;
Epsmax = 2 * Gc / Sigc + Epsmin;
this->K.setDefaultValue(Epsmin);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialDamageLinear<spatial_dimension>::computeStress(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(el_type, ghost_type).storage();
Real * K = this->K(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->computeStressOnQuad(grad_u, sigma, *dam, *K);
++dam;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(damage_linear, MaterialDamageLinear);
} // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh b/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh
index 9f1143f56..89faad2f5 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh
@@ -1,92 +1,86 @@
/**
* @file material_damage_linear.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
*
*
* @brief Material isotropic elastic + linear softening
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_damage.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_DAMAGE_LINEAR_HH__
#define __AKANTU_MATERIAL_DAMAGE_LINEAR_HH__
namespace akantu {
/**
* Material liner damage
*
* parameters in the material files :
* - Sigc : (default: 1e5)
* - Gc : (default: 2)
*/
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
class MaterialDamageLinear : public MaterialDamage<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialDamageLinear(SolidMechanicsModel & model, const ID & id = "");
- virtual ~MaterialDamageLinear() {};
+ virtual ~MaterialDamageLinear(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void initMaterial();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
protected:
/// constitutive law for a given quadrature point
- inline void computeStressOnQuad(Matrix<Real> & F,
- Matrix<Real> & sigma,
- Real & damage,
- Real &K);
+ inline void computeStressOnQuad(Matrix<Real> & F, Matrix<Real> & sigma,
+ Real & damage, Real & K);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// kind of toughness
Real Gc;
/// critical stress
Real Sigc;
/// damage internal variable
InternalField<Real> K;
Real Epsmin, Epsmax;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_damage_linear_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_DAMAGE_LINEAR_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.cc b/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.cc
index bfea5ce53..89bb2b501 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.cc
@@ -1,47 +1,44 @@
/**
* @file material_damage_linear_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
*
*
* @brief Implementation of the inline functions of the material damage linear
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void
-MaterialDamageLinear<spatial_dimension>::computeStressOnQuad(Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- Real & dam,
- Real & K) {
+template <UInt spatial_dimension>
+inline void MaterialDamageLinear<spatial_dimension>::computeStressOnQuad(
+ Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam, Real & K) {
Real Fdiag[3];
Real Fdiagp[3];
Math::matrix33_eigenvalues(grad_u.storage(), Fdiag);
Fdiagp[0] = std::max(0., Fdiag[0]);
Fdiagp[1] = std::max(0., Fdiag[1]);
Fdiagp[2] = std::max(0., Fdiag[2]);
- Real Ehat=sqrt(Fdiagp[0]*Fdiagp[0] + Fdiagp[1]*Fdiagp[1] + Fdiagp[2]*Fdiagp[2]);
+ Real Ehat = sqrt(Fdiagp[0] * Fdiagp[0] + Fdiagp[1] * Fdiagp[1] +
+ Fdiagp[2] * Fdiagp[2]);
MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
- Real Fd = Ehat-K;
+ Real Fd = Ehat - K;
if (Fd > 0) {
- dam = (Ehat - Epsmin) / (Epsmax-Epsmin)*(Ehat/Epsmax);
+ dam = (Ehat - Epsmin) / (Epsmax - Epsmin) * (Ehat / Epsmax);
dam = std::min(dam, 1.);
- K=Ehat;
+ K = Ehat;
}
- sigma *= 1-dam;
+ sigma *= 1 - dam;
}
-
diff --git a/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh b/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh
index 8a3bdb015..48565bd34 100644
--- a/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh
@@ -1,105 +1,105 @@
/**
* @file material_iterative_stiffness_reduction.hh
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Feb 18 15:25:05 2016
*
* @brief Damage material with constant stiffness reduction
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage_iterative.hh"
/* -------------------------------------------------------------------------- */
- #ifndef __AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH__
- #define __AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH__
+#ifndef __AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH__
+#define __AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH__
namespace akantu {
/**
* Material damage iterative
*
* parameters in the material files :
* - Gfx
* - h
- * - Sc
+ * - Sc
*/
-/// Proposed by Rots and Invernizzi, 2004: Regularized sequentially linear
+/// Proposed by Rots and Invernizzi, 2004: Regularized sequentially linear
// saw-tooth softening model (section 4.2)
-template<UInt spatial_dimension>
-class MaterialIterativeStiffnessReduction : public MaterialDamageIterative<spatial_dimension> {
+template <UInt spatial_dimension>
+class MaterialIterativeStiffnessReduction
+ : public MaterialDamageIterative<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
+ MaterialIterativeStiffnessReduction(SolidMechanicsModel & model,
+ const ID & id = "");
- MaterialIterativeStiffnessReduction(SolidMechanicsModel & model, const ID & id = "");
-
- virtual ~MaterialIterativeStiffnessReduction() {};
+ virtual ~MaterialIterativeStiffnessReduction(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// init the material
virtual void initMaterial();
- ///compute the equivalent stress on each Gauss point (i.e. the max prinicpal stress) and normalize it by the tensile stiffness
- virtual void computeNormalizedEquivalentStress(const Array<Real> & grad_u,
- ElementType el_type, GhostType ghost_type = _not_ghost);
+ /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
+ /// stress) and normalize it by the tensile stiffness
+ virtual void
+ computeNormalizedEquivalentStress(const Array<Real> & grad_u,
+ ElementType el_type,
+ GhostType ghost_type = _not_ghost);
/// update internal field damage
virtual UInt updateDamage();
-
+
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// the ultimate strain
InternalField<Real> eps_u;
/// the tangent of the tensile stress-strain softening
InternalField<Real> D;
/// fracture energy
Real Gf;
/// crack_band_width for normalization of fracture energy
Real crack_band_width;
/// the reduction constant (denoated by a in the paper of rots)
Real reduction_constant;
};
-
} // namespace akantu
#endif /* __AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage.hh b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage.hh
index 4084cd3bb..afd4555ce 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage.hh
@@ -1,143 +1,147 @@
/**
* @file material_orthotropic_damage.hh
* @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Sun Mar 8 12:49:56 2015
*
* @brief Material for orthotropic damage
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_elastic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_HH__
#define __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_HH__
namespace akantu {
-template<UInt spatial_dimension, template<UInt> class Parent = MaterialElastic>
+template <UInt spatial_dimension,
+ template <UInt> class Parent = MaterialElastic>
class MaterialOrthotropicDamage : public Parent<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialOrthotropicDamage(SolidMechanicsModel & model, const ID & id = "");
- virtual ~MaterialOrthotropicDamage() {};
+ virtual ~MaterialOrthotropicDamage(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
virtual void initMaterial();
/// compute the tangent stiffness matrix for an element type
virtual void computeTangentModuli(const ElementType & el_type,
- Array<Real> & tangent_matrix,
- GhostType ghost_type = _not_ghost);
+ Array<Real> & tangent_matrix,
+ GhostType ghost_type = _not_ghost);
protected:
- /// update the dissipated energy, must be called after the stress have been computed
+ /// update the dissipated energy, must be called after the stress have been
+ /// computed
virtual void updateEnergies(ElementType el_type, GhostType ghost_type);
/// compute the tangent stiffness matrix for a given quadrature point
- inline void computeTangentModuliOnQuad(Matrix<Real> & tangent,
- const Matrix<Real> C,
- const Matrix<Real> & dam,
- const Matrix<Real> & dam_directions,
- Matrix<Real> & O_prime,
- Matrix<Real> & S_prime,
- Matrix<Real> & O,
- Matrix<Real> & S,
- Matrix<Real> & rotation_tmp);
-
- inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Matrix<Real> & one_minus_D, Matrix<Real> & root_one_minus_D, Matrix<Real> & damage, Matrix<Real> & first_term, Matrix<Real> & third_term);
-
- /// rotate a Matrix of size dim*dim into the coordinate system of the FE computation
+ inline void computeTangentModuliOnQuad(
+ Matrix<Real> & tangent, const Matrix<Real> C, const Matrix<Real> & dam,
+ const Matrix<Real> & dam_directions, Matrix<Real> & O_prime,
+ Matrix<Real> & S_prime, Matrix<Real> & O, Matrix<Real> & S,
+ Matrix<Real> & rotation_tmp);
+
+ inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma,
+ Matrix<Real> & one_minus_D,
+ Matrix<Real> & root_one_minus_D,
+ Matrix<Real> & damage,
+ Matrix<Real> & first_term,
+ Matrix<Real> & third_term);
+
+ /// rotate a Matrix of size dim*dim into the coordinate system of the FE
+ /// computation
inline void rotateIntoComputationFrame(const Matrix<Real> & to_rotate,
- Matrix<Real> & rotated,
- const Matrix<Real> & damage_directions, Matrix<Real> & rotation_tmp);
+ Matrix<Real> & rotated,
+ const Matrix<Real> & damage_directions,
+ Matrix<Real> & rotation_tmp);
/// rotate a Matrix of size dim*dim into the coordinate system of the damage
inline void rotateIntoNewFrame(const Matrix<Real> & to_rotate,
- Matrix<Real> & rotated,
- const Matrix<Real> & damage_directions,
- Matrix<Real> & rotation_tmp);
+ Matrix<Real> & rotated,
+ const Matrix<Real> & damage_directions,
+ Matrix<Real> & rotation_tmp);
/// compute (1-D)
- inline void computeOneMinusD(Matrix<Real> & one_minus_D, const Matrix<Real> & damage);
-
+ inline void computeOneMinusD(Matrix<Real> & one_minus_D,
+ const Matrix<Real> & damage);
+
/// compute (1-D)^(1/2)
- inline void computeSqrtOneMinusD(const Matrix<Real> & one_minus_D, Matrix<Real> & sqrt_one_minus_D);
+ inline void computeSqrtOneMinusD(const Matrix<Real> & one_minus_D,
+ Matrix<Real> & sqrt_one_minus_D);
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// give the dissipated energy for the time step
Real getDissipatedEnergy() const;
// virtual Real getEnergy(std::string type);
- // virtual Real getEnergy(std::string energy_id, ElementType type, UInt index) {
+ // virtual Real getEnergy(std::string energy_id, ElementType type, UInt index)
+ // {
// return Parent<spatial_dimension>::getEnergy(energy_id, type, index);
// };
AKANTU_GET_MACRO_NOT_CONST(Damage, damage, ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(Damage, damage, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real)
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// damage internal variable
InternalField<Real> damage;
/// dissipated energy
InternalField<Real> dissipated_energy;
- /// contain the current value of @f$ \int_0^{\epsilon}\sigma(\omega)d\omega @f$ the dissipated energy
+ /// contain the current value of @f$ \int_0^{\epsilon}\sigma(\omega)d\omega
+ /// @f$ the dissipated energy
InternalField<Real> int_sigma;
/// direction vectors for the damage frame
- InternalField<Real> damage_dir_vecs;
+ InternalField<Real> damage_dir_vecs;
Real eta;
/// maximum damage value
Real max_damage;
-
-
};
} // namespace akantu
#include "material_orthotropic_damage_tmpl.hh"
#endif /* __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc
index aab883b2e..73d3cc282 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc
@@ -1,379 +1,378 @@
/**
* @file material_damage_iterative.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date Sun Mar 8 12:54:30 2015
*
* @brief Specialization of the class material damage to damage only one gauss
* point at a time and propagate damage in a linear way. Max principal stress
* criterion is used as a failure criterion.
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_orthotropic_damage_iterative.hh"
#include "communicator.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialOrthotropicDamageIterative<spatial_dimension>::
MaterialOrthotropicDamageIterative(SolidMechanicsModel & model,
const ID & id)
: MaterialOrthotropicDamage<spatial_dimension>(model, id), Sc("Sc", *this),
equivalent_stress("equivalent_stress", *this),
stress_dir("equiv_stress_dir", *this), norm_max_equivalent_stress(0) {
AKANTU_DEBUG_IN();
this->registerParam("Sc", Sc, _pat_parsable, "critical stress threshold");
this->registerParam("prescribed_dam", prescribed_dam, 0.1,
_pat_parsable | _pat_modifiable,
"increase of damage in every step");
this->registerParam(
"dam_threshold", dam_threshold, 0.8, _pat_parsable | _pat_modifiable,
"damage threshold at which damage damage will be set to 1");
this->use_previous_stress = true;
this->use_previous_gradu = true;
this->Sc.initialize(1);
this->equivalent_stress.initialize(1);
this->stress_dir.initialize(spatial_dimension * spatial_dimension);
/// the Gauss point with the highest stress can only be of type _not_ghost
q_max.ghost_type = _not_ghost;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialOrthotropicDamageIterative<spatial_dimension>::
computeNormalizedEquivalentStress(const Array<Real> & grad_u,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// Vector to store eigenvalues of current stress tensor
Vector<Real> eigenvalues(spatial_dimension);
auto Sc_it = Sc(el_type).begin();
- auto equivalent_stress_it =
- equivalent_stress(el_type).begin();
+ auto equivalent_stress_it = equivalent_stress(el_type).begin();
Array<Real>::const_matrix_iterator grad_u_it =
grad_u.begin(spatial_dimension, spatial_dimension);
Array<Real>::const_matrix_iterator grad_u_end =
grad_u.end(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator stress_dir_it =
this->stress_dir(el_type).begin(spatial_dimension, spatial_dimension);
/// initialize matrix to store the stress for the criterion (only different in
/// non-local)
Matrix<Real> sigma(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator damage_iterator =
this->damage(el_type, ghost_type)
.begin(this->spatial_dimension, this->spatial_dimension);
Array<Real>::matrix_iterator damage_dir_it =
this->damage_dir_vecs(el_type, ghost_type)
.begin(this->spatial_dimension, this->spatial_dimension);
/// for the computation of the Cauchy stress the matrices (1-D) and
/// (1-D)^(1/2) are needed. For the formulation see Engineering
/// Damage Mechanics by Lemaitre and Desmorat.
Matrix<Real> one_minus_D(this->spatial_dimension, this->spatial_dimension);
Matrix<Real> sqrt_one_minus_D(this->spatial_dimension,
this->spatial_dimension);
Matrix<Real> one_minus_D_rotated(this->spatial_dimension,
this->spatial_dimension);
Matrix<Real> sqrt_one_minus_D_rotated(this->spatial_dimension,
this->spatial_dimension);
Matrix<Real> rotation_tmp(this->spatial_dimension, this->spatial_dimension);
/// create matrix to store the first term of the computation of the
/// Cauchy stress
Matrix<Real> first_term(this->spatial_dimension, this->spatial_dimension);
Matrix<Real> third_term(this->spatial_dimension, this->spatial_dimension);
for (; grad_u_it != grad_u_end;
++Sc_it, ++equivalent_stress_it, ++stress_dir_it, ++grad_u_it) {
sigma.clear();
MaterialOrthotropicDamage<spatial_dimension>::computeStressOnQuad(
*grad_u_it, sigma, 0.);
/// rotate the tensors from the damage principal coordinate system to the CS
/// of the computation
if (!(Math::are_float_equal((*damage_iterator).trace(), 0))) {
/// compute (1-D) and (1-D)^1/2
this->computeOneMinusD(one_minus_D, *damage_iterator);
this->computeSqrtOneMinusD(one_minus_D, sqrt_one_minus_D);
this->rotateIntoComputationFrame(one_minus_D, one_minus_D_rotated,
*damage_dir_it, rotation_tmp);
this->rotateIntoComputationFrame(sqrt_one_minus_D,
sqrt_one_minus_D_rotated, *damage_dir_it,
rotation_tmp);
} else {
this->computeOneMinusD(one_minus_D_rotated, *damage_iterator);
this->computeSqrtOneMinusD(one_minus_D_rotated, sqrt_one_minus_D_rotated);
}
computeDamageAndStressOnQuad(sigma, one_minus_D_rotated,
sqrt_one_minus_D_rotated, *damage_iterator,
first_term, third_term);
/// compute the maximum principal stresses and their directions
sigma.eig(eigenvalues, *stress_dir_it);
*equivalent_stress_it = eigenvalues(0) / *(Sc_it);
++damage_dir_it;
++damage_iterator;
}
// for(;sigma_it != sigma_end; ++sigma_it,
// ++Sc_it, ++equivalent_stress_it, ++stress_dir_it) {
// /// compute the maximum principal stresses and their directions
// (*sigma_it).eig(eigenvalues, *stress_dir_it);
// *equivalent_stress_it = eigenvalues(0) / *(Sc_it);
// }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialOrthotropicDamageIterative<spatial_dimension>::computeAllStresses(
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// reset normalized maximum equivalent stress
if (ghost_type == _not_ghost)
norm_max_equivalent_stress = 0;
MaterialOrthotropicDamage<spatial_dimension>::computeAllStresses(ghost_type);
/// find global Gauss point with highest stress
this->model.getMesh().getCommunicator().allReduce(
norm_max_equivalent_stress, SynchronizerOperation::_max);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialOrthotropicDamageIterative<spatial_dimension>::
findMaxNormalizedEquivalentStress(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
if (ghost_type == _not_ghost) {
/// initialize the iterators for the equivalent stress and the damage
const Array<Real> & e_stress = equivalent_stress(el_type);
auto equivalent_stress_it = e_stress.begin();
auto equivalent_stress_end = e_stress.end();
Array<Real> & dam = this->damage(el_type);
auto dam_it = dam.begin(this->spatial_dimension, this->spatial_dimension);
auto damage_directions_it =
this->damage_dir_vecs(el_type, _not_ghost)
.begin(this->spatial_dimension, this->spatial_dimension);
auto stress_dir_it = this->stress_dir(el_type, _not_ghost)
.begin(spatial_dimension, spatial_dimension);
/// initialize the matrices for damage rotation results
Matrix<Real> tmp(spatial_dimension, spatial_dimension);
Matrix<Real> dam_in_computation_frame(spatial_dimension, spatial_dimension);
Matrix<Real> dam_in_stress_frame(spatial_dimension, spatial_dimension);
for (; equivalent_stress_it != equivalent_stress_end;
++equivalent_stress_it, ++dam_it, ++damage_directions_it,
++stress_dir_it) {
/// check if max equivalent stress for this element type is greater than
/// the current norm_max_eq_stress
if (*equivalent_stress_it > norm_max_equivalent_stress &&
(spatial_dimension * this->max_damage - (*dam_it).trace() >
Math::getTolerance())) {
if (Math::are_float_equal((*dam_it).trace(), 0)) {
/// gauss point has not been damaged yet
norm_max_equivalent_stress = *equivalent_stress_it;
q_max.type = el_type;
q_max.global_num = equivalent_stress_it - e_stress.begin();
}
else {
/// find the damage increment on this Gauss point
/// rotate damage into stress frame
this->rotateIntoComputationFrame(*dam_it, dam_in_computation_frame,
*damage_directions_it, tmp);
this->rotateIntoNewFrame(dam_in_computation_frame,
dam_in_stress_frame, *stress_dir_it, tmp);
/// add damage increment
dam_in_stress_frame(0, 0) += prescribed_dam;
/// find new principal directions of damage
Vector<Real> dam_eigenvalues(spatial_dimension);
dam_in_stress_frame.eig(dam_eigenvalues);
bool limit_reached = false;
for (UInt i = 0; i < spatial_dimension; ++i) {
if (dam_eigenvalues(i) + Math::getTolerance() > this->max_damage)
limit_reached = true;
}
if (!limit_reached) {
norm_max_equivalent_stress = *equivalent_stress_it;
q_max.type = el_type;
q_max.global_num = equivalent_stress_it - e_stress.begin();
}
}
} /// end if equiv_stress > max_equiv_stress
} /// end loop over all gauss points of this element type
} // end if(_not_ghost)
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialOrthotropicDamageIterative<spatial_dimension>::computeStress(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialOrthotropicDamage<spatial_dimension>::computeStress(el_type,
ghost_type);
auto damage_iterator =
this->damage(el_type, ghost_type)
.begin(this->spatial_dimension, this->spatial_dimension);
auto damage_dir_it =
this->damage_dir_vecs(el_type, ghost_type)
.begin(this->spatial_dimension, this->spatial_dimension);
/// for the computation of the Cauchy stress the matrices (1-D) and
/// (1-D)^(1/2) are needed. For the formulation see Engineering
/// Damage Mechanics by Lemaitre and Desmorat.
Matrix<Real> one_minus_D(this->spatial_dimension, this->spatial_dimension);
Matrix<Real> sqrt_one_minus_D(this->spatial_dimension,
this->spatial_dimension);
Matrix<Real> one_minus_D_rotated(this->spatial_dimension,
this->spatial_dimension);
Matrix<Real> sqrt_one_minus_D_rotated(this->spatial_dimension,
this->spatial_dimension);
Matrix<Real> rotation_tmp(this->spatial_dimension, this->spatial_dimension);
/// create matrix to store the first term of the computation of the
/// Cauchy stress
Matrix<Real> first_term(this->spatial_dimension, this->spatial_dimension);
Matrix<Real> third_term(this->spatial_dimension, this->spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
/// rotate the tensors from the damage principal coordinate system to the CS
/// of the computation
if (!(Math::are_float_equal((*damage_iterator).trace(), 0))) {
/// compute (1-D) and (1-D)^1/2
this->computeOneMinusD(one_minus_D, *damage_iterator);
this->computeSqrtOneMinusD(one_minus_D, sqrt_one_minus_D);
this->rotateIntoComputationFrame(one_minus_D, one_minus_D_rotated,
*damage_dir_it, rotation_tmp);
this->rotateIntoComputationFrame(sqrt_one_minus_D, sqrt_one_minus_D_rotated,
*damage_dir_it, rotation_tmp);
} else {
this->computeOneMinusD(one_minus_D_rotated, *damage_iterator);
this->computeSqrtOneMinusD(one_minus_D_rotated, sqrt_one_minus_D_rotated);
}
computeDamageAndStressOnQuad(sigma, one_minus_D_rotated,
sqrt_one_minus_D_rotated, *damage_iterator,
first_term, third_term);
++damage_dir_it;
++damage_iterator;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
computeNormalizedEquivalentStress(this->gradu(el_type, ghost_type), el_type,
ghost_type);
norm_max_equivalent_stress = 0;
findMaxNormalizedEquivalentStress(el_type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
UInt MaterialOrthotropicDamageIterative<spatial_dimension>::updateDamage() {
UInt nb_damaged_elements = 0;
AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
"Your prescribed damage must be greater than zero");
if (norm_max_equivalent_stress >= 1.) {
AKANTU_DEBUG_IN();
/// get the arrays and iterators for the element_type of the highest
/// quadrature point
ElementType el_type = q_max.type;
UInt q_global_num = q_max.global_num;
Array<Real> & dam = this->damage(el_type, _not_ghost);
auto dam_it = dam.begin(this->spatial_dimension, this->spatial_dimension);
auto damage_directions_it =
this->damage_dir_vecs(el_type, _not_ghost)
.begin(this->spatial_dimension, this->spatial_dimension);
auto stress_dir_it = this->stress_dir(el_type, _not_ghost)
.begin(spatial_dimension, spatial_dimension);
/// initialize the matrices for damage rotation results
Matrix<Real> tmp(spatial_dimension, spatial_dimension);
Matrix<Real> dam_in_computation_frame(spatial_dimension, spatial_dimension);
Matrix<Real> dam_in_stress_frame(spatial_dimension, spatial_dimension);
/// references to damage and directions of highest Gauss point
Matrix<Real> q_dam = dam_it[q_global_num];
Matrix<Real> q_dam_dir = damage_directions_it[q_global_num];
Matrix<Real> q_stress_dir = stress_dir_it[q_global_num];
/// increment damage
/// find the damage increment on this Gauss point
/// rotate damage into stress frame
this->rotateIntoComputationFrame(q_dam, dam_in_computation_frame, q_dam_dir,
tmp);
this->rotateIntoNewFrame(dam_in_computation_frame, dam_in_stress_frame,
q_stress_dir, tmp);
/// add damage increment
dam_in_stress_frame(0, 0) += prescribed_dam;
/// find new principal directions of damage
Vector<Real> dam_eigenvalues(spatial_dimension);
dam_in_stress_frame.eig(dam_eigenvalues, q_dam_dir);
for (UInt i = 0; i < spatial_dimension; ++i) {
q_dam(i, i) = dam_eigenvalues(i);
if (q_dam(i, i) + Math::getTolerance() >= dam_threshold)
q_dam(i, i) = this->max_damage;
}
nb_damaged_elements += 1;
}
this->model.getMesh().getCommunicator().allReduce(
nb_damaged_elements, SynchronizerOperation::_sum);
AKANTU_DEBUG_OUT();
return nb_damaged_elements;
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialOrthotropicDamageIterative<
spatial_dimension>::updateEnergiesAfterDamage(ElementType el_type,
GhostType ghost_type) {
MaterialOrthotropicDamage<spatial_dimension>::updateEnergies(el_type,
ghost_type);
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(orthotropic_damage_iterative,
MaterialOrthotropicDamageIterative);
} // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.cc b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.cc
index 530e2b503..0a3d1ce81 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.cc
@@ -1,69 +1,70 @@
/**
* @file material_damage_iterative_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date Sun Mar 8 12:54:30 2015
*
* @brief Implementation of inline functions of the material damage iterative
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void MaterialOrthotropicDamageIterative<spatial_dimension>
-::computeDamageAndStressOnQuad(Matrix<Real> & sigma,
- Matrix<Real> & one_minus_D,
- Matrix<Real> & sqrt_one_minus_D,
- Matrix<Real> & damage,
- Matrix<Real> & first_term,
- Matrix<Real> & third_term) {
+template <UInt spatial_dimension>
+inline void MaterialOrthotropicDamageIterative<spatial_dimension>::
+ computeDamageAndStressOnQuad(Matrix<Real> & sigma,
+ Matrix<Real> & one_minus_D,
+ Matrix<Real> & sqrt_one_minus_D,
+ Matrix<Real> & damage,
+ Matrix<Real> & first_term,
+ Matrix<Real> & third_term) {
- //Real dmax = *(std::max_element(damage.storage(), damage.storage() + spatial_dimension*spatial_dimension) );
- Real eta_effective = 0;
+ // Real dmax = *(std::max_element(damage.storage(), damage.storage() +
+ // spatial_dimension*spatial_dimension) );
+ Real eta_effective = 0;
- // if ( (1 - dmax*dmax) < (1 - this->eta / spatial_dimension * damage.trace()) ) {
+ // if ( (1 - dmax*dmax) < (1 - this->eta / spatial_dimension *
+ // damage.trace()) ) {
// eta_effective = this->spatial_dimension * dmax * dmax / damage.trace();
-
- // }
+
+ // }
// else
eta_effective = this->eta;
/// hydrostatic sensitivity parameter
- //Real eta = 3.;
+ // Real eta = 3.;
/// Definition of Cauchy stress based on second order damage tensor:
/// "Anisotropic damage modelling of biaxial behaviour and rupture
/// of concrete strucutres", Ragueneau et al., 2008, Eq. 7
first_term.mul<false, false>(sqrt_one_minus_D, sigma);
first_term *= sqrt_one_minus_D;
Real second_term = 0;
for (UInt i = 0; i < this->spatial_dimension; ++i) {
for (UInt j = 0; j < this->spatial_dimension; ++j)
- second_term += sigma(i,j) * one_minus_D(i,j);
- }
+ second_term += sigma(i, j) * one_minus_D(i, j);
+ }
second_term /= (this->spatial_dimension - damage.trace());
// for (UInt i = 0; i < this->spatial_dimension; ++i) {
// for (UInt j = 0; j < this->spatial_dimension; ++j)
// one_minus_D(i,j) *= second_term;
// }
one_minus_D *= second_term;
- third_term.eye( 1. / this->spatial_dimension * sigma.trace() *
- (1 - std::min(eta_effective/(this->spatial_dimension)
- * damage.trace(), this->max_damage) ) );
+ third_term.eye(
+ 1. / this->spatial_dimension * sigma.trace() *
+ (1 - std::min(eta_effective / (this->spatial_dimension) * damage.trace(),
+ this->max_damage)));
sigma.copy(first_term);
sigma -= one_minus_D;
sigma += third_term;
-
- }
-
+}
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh
index d69e6c8b8..7dfd2605d 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh
@@ -1,81 +1,85 @@
/**
* @file material_orthotropic_damage_iterative_non_local.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
- * @brief MaterialOrthotropicDamageIterativeNonLocal header for non-local damage
+ * @brief MaterialOrthotropicDamageIterativeNonLocal header for non-local
+ * damage
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "material_orthotropic_damage_iterative.hh"
#include "material_damage_non_local.hh"
+#include "material_orthotropic_damage_iterative.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_NON_LOCAL_HH__
namespace akantu {
/**
* Material Damage Iterative Non local
*
* parameters in the material files :
*/
-template<UInt spatial_dimension>
-class MaterialOrthotropicDamageIterativeNonLocal : public MaterialDamageNonLocal<spatial_dimension,
- MaterialOrthotropicDamageIterative<spatial_dimension> > {
+template <UInt spatial_dimension>
+class MaterialOrthotropicDamageIterativeNonLocal
+ : public MaterialDamageNonLocal<
+ spatial_dimension,
+ MaterialOrthotropicDamageIterative<spatial_dimension>> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef MaterialDamageNonLocal<spatial_dimension,
- MaterialOrthotropicDamageIterative<spatial_dimension> > MaterialOrthotropicDamageIterativeNonLocalParent;
- MaterialOrthotropicDamageIterativeNonLocal(SolidMechanicsModel & model, const ID & id = "");
+ typedef MaterialDamageNonLocal<
+ spatial_dimension, MaterialOrthotropicDamageIterative<spatial_dimension>>
+ MaterialOrthotropicDamageIterativeNonLocalParent;
+ MaterialOrthotropicDamageIterativeNonLocal(SolidMechanicsModel & model,
+ const ID & id = "");
- virtual ~MaterialOrthotropicDamageIterativeNonLocal() {};
+ virtual ~MaterialOrthotropicDamageIterativeNonLocal(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void initMaterial();
protected:
void computeStress(ElementType type, GhostType ghost_type);
- void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost);
+ void computeNonLocalStress(ElementType type,
+ GhostType ghost_type = _not_ghost);
/// associate the non-local variables of the material to their neighborhoods
virtual void nonLocalVariableToNeighborhood();
-private:
+private:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
- InternalField<Real> grad_u_nl;
+ InternalField<Real> grad_u_nl;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_orthotropic_damage_iterative_non_local_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_NON_LOCAL_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.cc b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.cc
index 73e149644..4a3db56f0 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.cc
@@ -1,129 +1,141 @@
/**
* @file material_orthotropic_damage_iterative_non_local_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief MaterialOrthotropicDamageIterativeNonLocal inline function
* implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
} // namespace akantu
#if defined(AKANTU_DEBUG_TOOLS)
#include "aka_debug_tools.hh"
#include <string>
#endif
namespace akantu {
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-MaterialOrthotropicDamageIterativeNonLocal<spatial_dimension>::MaterialOrthotropicDamageIterativeNonLocal(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- MaterialOrthotropicDamageIterativeNonLocalParent(model, id),
- grad_u_nl("grad_u non local", *this) {
+template <UInt spatial_dimension>
+MaterialOrthotropicDamageIterativeNonLocal<spatial_dimension>::
+ MaterialOrthotropicDamageIterativeNonLocal(SolidMechanicsModel & model,
+ const ID & id)
+ : Material(model, id),
+ MaterialOrthotropicDamageIterativeNonLocalParent(model, id),
+ grad_u_nl("grad_u non local", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
- this->grad_u_nl.initialize(spatial_dimension*spatial_dimension);
+ this->grad_u_nl.initialize(spatial_dimension * spatial_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialOrthotropicDamageIterativeNonLocal<spatial_dimension>::initMaterial() {
+template <UInt spatial_dimension>
+void MaterialOrthotropicDamageIterativeNonLocal<
+ spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
- this->model.getNonLocalManager().registerNonLocalVariable(this->gradu.getName(), grad_u_nl.getName(), spatial_dimension*spatial_dimension);
+ this->model.getNonLocalManager().registerNonLocalVariable(
+ this->gradu.getName(), grad_u_nl.getName(),
+ spatial_dimension * spatial_dimension);
MaterialOrthotropicDamageIterativeNonLocalParent::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialOrthotropicDamageIterativeNonLocal<spatial_dimension>::computeStress(ElementType type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialOrthotropicDamageIterativeNonLocal<
+ spatial_dimension>::computeStress(ElementType type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialOrthotropicDamageIterativeNonLocal<spatial_dimension>::computeNonLocalStress(ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialOrthotropicDamageIterativeNonLocal<
+ spatial_dimension>::computeNonLocalStress(ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
-
- MaterialOrthotropicDamage<spatial_dimension>::computeStress(el_type, ghost_type);
- Array<Real>::matrix_iterator damage_iterator = this->damage(el_type, ghost_type).begin(this->spatial_dimension, this->spatial_dimension);
- Array<Real>::matrix_iterator damage_dir_it = this->damage_dir_vecs(el_type, ghost_type).begin(this->spatial_dimension, this->spatial_dimension);
+ MaterialOrthotropicDamage<spatial_dimension>::computeStress(el_type,
+ ghost_type);
+
+ Array<Real>::matrix_iterator damage_iterator =
+ this->damage(el_type, ghost_type)
+ .begin(this->spatial_dimension, this->spatial_dimension);
+ Array<Real>::matrix_iterator damage_dir_it =
+ this->damage_dir_vecs(el_type, ghost_type)
+ .begin(this->spatial_dimension, this->spatial_dimension);
/// for the computation of the Cauchy stress the matrices (1-D) and
/// (1-D)^(1/2) are needed. For the formulation see Engineering
/// Damage Mechanics by Lemaitre and Desmorat.
Matrix<Real> one_minus_D(this->spatial_dimension, this->spatial_dimension);
- Matrix<Real> sqrt_one_minus_D(this->spatial_dimension, this->spatial_dimension);
- Matrix<Real> one_minus_D_rotated(this->spatial_dimension, this->spatial_dimension);
- Matrix<Real> sqrt_one_minus_D_rotated(this->spatial_dimension, this->spatial_dimension);
+ Matrix<Real> sqrt_one_minus_D(this->spatial_dimension,
+ this->spatial_dimension);
+ Matrix<Real> one_minus_D_rotated(this->spatial_dimension,
+ this->spatial_dimension);
+ Matrix<Real> sqrt_one_minus_D_rotated(this->spatial_dimension,
+ this->spatial_dimension);
Matrix<Real> rotation_tmp(this->spatial_dimension, this->spatial_dimension);
/// create matrix to store the first term of the computation of the
/// Cauchy stress
Matrix<Real> first_term(this->spatial_dimension, this->spatial_dimension);
Matrix<Real> third_term(this->spatial_dimension, this->spatial_dimension);
-
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
- /// rotate the tensors from the damage principal coordinate system to the CS of the computation
- if ( !(Math::are_float_equal((*damage_iterator).trace(), 0)) ) {
+ /// rotate the tensors from the damage principal coordinate system to the CS
+ /// of the computation
+ if (!(Math::are_float_equal((*damage_iterator).trace(), 0))) {
/// compute (1-D) and (1-D)^1/2
this->computeOneMinusD(one_minus_D, *damage_iterator);
this->computeSqrtOneMinusD(one_minus_D, sqrt_one_minus_D);
- this->rotateIntoComputationFrame(one_minus_D,
- one_minus_D_rotated,
- *damage_dir_it,
- rotation_tmp);
+ this->rotateIntoComputationFrame(one_minus_D, one_minus_D_rotated,
+ *damage_dir_it, rotation_tmp);
- this->rotateIntoComputationFrame(sqrt_one_minus_D,
- sqrt_one_minus_D_rotated,
- *damage_dir_it,
- rotation_tmp);
+ this->rotateIntoComputationFrame(sqrt_one_minus_D, sqrt_one_minus_D_rotated,
+ *damage_dir_it, rotation_tmp);
} else {
- MaterialOrthotropicDamage<spatial_dimension>::computeOneMinusD(one_minus_D_rotated, *damage_iterator);
- MaterialOrthotropicDamage<spatial_dimension>::computeSqrtOneMinusD(one_minus_D_rotated, sqrt_one_minus_D_rotated);
+ MaterialOrthotropicDamage<spatial_dimension>::computeOneMinusD(
+ one_minus_D_rotated, *damage_iterator);
+ MaterialOrthotropicDamage<spatial_dimension>::computeSqrtOneMinusD(
+ one_minus_D_rotated, sqrt_one_minus_D_rotated);
}
- this->computeDamageAndStressOnQuad(sigma,
- one_minus_D_rotated,
- sqrt_one_minus_D_rotated,
- *damage_iterator,
- first_term,
- third_term);
+ this->computeDamageAndStressOnQuad(sigma, one_minus_D_rotated,
+ sqrt_one_minus_D_rotated, *damage_iterator,
+ first_term, third_term);
++damage_dir_it;
++damage_iterator;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
- this->computeNormalizedEquivalentStress(this->grad_u_nl(el_type, ghost_type), el_type, ghost_type);
+ this->computeNormalizedEquivalentStress(this->grad_u_nl(el_type, ghost_type),
+ el_type, ghost_type);
this->norm_max_equivalent_stress = 0;
this->findMaxNormalizedEquivalentStress(el_type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialOrthotropicDamageIterativeNonLocal<spatial_dimension>::nonLocalVariableToNeighborhood() {
- this->model.getNonLocalManager().nonLocalVariableToNeighborhood(grad_u_nl.getName(), this->name);
+template <UInt spatial_dimension>
+void MaterialOrthotropicDamageIterativeNonLocal<
+ spatial_dimension>::nonLocalVariableToNeighborhood() {
+ this->model.getNonLocalManager().nonLocalVariableToNeighborhood(
+ grad_u_nl.getName(), this->name);
}
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_non_local.hh
index 7fd3e780b..73a955988 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_non_local.hh
@@ -1,100 +1,104 @@
/**
* @file material_orthotropic_damage_non_local.hh
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Sun Mar 22 21:10:27 2015
*
* @brief interface for non local orthotropic damage material
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_NON_LOCAL_HH__
namespace akantu {
-template<UInt spatial_dimension,
- class MaterialOrthotropicDamageLocal>
-class MaterialOrthotropicDamageNonLocal : public MaterialOrthotropicDamageLocal,
- public MaterialNonLocal<spatial_dimension> {
+template <UInt spatial_dimension, class MaterialOrthotropicDamageLocal>
+class MaterialOrthotropicDamageNonLocal
+ : public MaterialOrthotropicDamageLocal,
+ public MaterialNonLocal<spatial_dimension> {
public:
typedef MaterialNonLocal<spatial_dimension> MaterialNonLocalParent;
typedef MaterialOrthotropicDamageLocal MaterialOrthotropicDamageParent;
- MaterialOrthotropicDamageNonLocal(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- MaterialOrthotropicDamageParent(model, id), MaterialNonLocalParent(model, id) { };
+ MaterialOrthotropicDamageNonLocal(SolidMechanicsModel & model, const ID & id)
+ : Material(model, id), MaterialOrthotropicDamageParent(model, id),
+ MaterialNonLocalParent(model, id){};
/* ------------------------------------------------------------------------ */
virtual void initMaterial() {
MaterialOrthotropicDamageParent::initMaterial();
MaterialNonLocalParent::initMaterial();
}
protected:
- /* -------------------------------------------------------------------------- */
- virtual void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost) = 0;
+ /* --------------------------------------------------------------------------
+ */
+ virtual void computeNonLocalStress(ElementType type,
+ GhostType ghost_type = _not_ghost) = 0;
/* ------------------------------------------------------------------------ */
void computeNonLocalStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
- Mesh::type_iterator it = this->model.getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = this->model.getFEEngine().getMesh().lastType(spatial_dimension, ghost_type);
- for(; it != last_type; ++it) {
+ Mesh::type_iterator it = this->model.getFEEngine().getMesh().firstType(
+ spatial_dimension, ghost_type);
+ Mesh::type_iterator last_type =
+ this->model.getFEEngine().getMesh().lastType(spatial_dimension,
+ ghost_type);
+ for (; it != last_type; ++it) {
computeNonLocalStress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
public:
/* ------------------------------------------------------------------------ */
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
- SynchronizationTag tag) const {
+ SynchronizationTag tag) const {
return MaterialNonLocalParent::getNbDataForElements(elements, tag) +
- MaterialOrthotropicDamageParent::getNbDataForElements(elements, tag);
+ MaterialOrthotropicDamageParent::getNbDataForElements(elements, tag);
}
virtual inline void packElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) const {
+ const Array<Element> & elements,
+ SynchronizationTag tag) const {
MaterialNonLocalParent::packElementData(buffer, elements, tag);
MaterialOrthotropicDamageParent::packElementData(buffer, elements, tag);
}
virtual inline void unpackElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) {
+ const Array<Element> & elements,
+ SynchronizationTag tag) {
MaterialNonLocalParent::unpackElementData(buffer, elements, tag);
MaterialOrthotropicDamageParent::unpackElementData(buffer, elements, tag);
}
-
};
} // namespace akantu
#endif /* __AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_NON_LOCAL_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings.hh b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings.hh
index 38b28c615..60797f3c4 100644
--- a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings.hh
@@ -1,146 +1,142 @@
/**
* @file material_vreepeerlings.hh
*
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
*
* @brief Specialization of the material class for the VreePeerlings material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_damage.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_VREEPEERLINGS_HH__
#define __AKANTU_MATERIAL_VREEPEERLINGS_HH__
namespace akantu {
/**
* Material vreepeerlings
*
* parameters in the material files :
- * - Kapaoi : (default: 0.0001) Initial threshold (of the equivalent strain) >= Crate
+ * - Kapaoi : (default: 0.0001) Initial threshold (of the equivalent strain)
+ * >= Crate
* - Kapac : (default: 0.0002) Final threshold (of the equivalent strain)
- * - Arate : (default: 1.) Fitting parameter (must be close to 1 to do tend to 0 the stress in the damaged element)
- * - Brate : (default: 1.) This parameter determines the rate at which the damage grows
- * - Crate : (default: 0.0001) This parameter determines the rate at which the damage grows
+ * - Arate : (default: 1.) Fitting parameter (must be close to 1 to do tend
+ * to 0 the stress in the damaged element)
+ * - Brate : (default: 1.) This parameter determines the rate at which the
+ * damage grows
+ * - Crate : (default: 0.0001) This parameter determines the rate at which
+ * the damage grows
* - Kct : (default: 1.) Ratio between compressive and tensile strength
*/
-template<UInt spatial_dimension, template <UInt> class MatParent = MaterialElastic>
-class MaterialVreePeerlings : public MaterialDamage<spatial_dimension,
- MatParent> {
+template <UInt spatial_dimension,
+ template <UInt> class MatParent = MaterialElastic>
+class MaterialVreePeerlings
+ : public MaterialDamage<spatial_dimension, MatParent> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef MaterialDamage<spatial_dimension,
- MatParent> MaterialVreePeerlingsParent;
+ typedef MaterialDamage<spatial_dimension, MatParent>
+ MaterialVreePeerlingsParent;
MaterialVreePeerlings(SolidMechanicsModel & model, const ID & id = "");
- virtual ~MaterialVreePeerlings() {};
+ virtual ~MaterialVreePeerlings(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void initMaterial();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
protected:
/// constitutive law for a given quadrature point
- inline void computeStressOnQuad(Matrix<Real> & F,
- Matrix<Real> & sigma,
- Real & dam,
- Real & Equistrain_rate,
- Real & Equistrain,
- Real & Kapaq,
- Real dt,
- Matrix<Real> & strain_rate_vrpgls,
- Real & FullDam_ValStrain,
- Real & FullDam_ValStrain_rate,
- Real & Nb_damage);
-
- inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma,
- Real & dam,
- Real & Equistrain_rate,
- Real & Equistrain,
- Real & Kapaq,
- Real dt,
- Real & FullDam_Valstrain,
- Real & FullDam_Valstrain_rate,
- Real & Nb_damage);
+ inline void computeStressOnQuad(Matrix<Real> & F, Matrix<Real> & sigma,
+ Real & dam, Real & Equistrain_rate,
+ Real & Equistrain, Real & Kapaq, Real dt,
+ Matrix<Real> & strain_rate_vrpgls,
+ Real & FullDam_ValStrain,
+ Real & FullDam_ValStrain_rate,
+ Real & Nb_damage);
+
+ inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam,
+ Real & Equistrain_rate,
+ Real & Equistrain, Real & Kapaq,
+ Real dt, Real & FullDam_Valstrain,
+ Real & FullDam_Valstrain_rate,
+ Real & Nb_damage);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Initial threshold (of the equivalent strain) (used in the initial step)
Real Kapaoi;
/// Final threshold (of the equivalent strain) (used in the initial step)
Real Kapac;
/// This parameter determines the rate at which the damage grows
Real Arate;
- /// This parameter determines the rate at which the damage grows
+ /// This parameter determines the rate at which the damage grows
Real Brate;
- /// This parameter determines the rate at which the damage grows
+ /// This parameter determines the rate at which the damage grows
Real Crate;
/// Ratio between compressive and tensile strength
Real Kct;
/// Randomness on Kapaoi
Real Kapao_randomness;
/// Kapa vector which contains the initial damage threshold
RandomInternalField<Real> Kapa;
/// Strain rate tensor to compute the rate dependent damage law
InternalField<Real> strain_rate_vreepeerlings;
/// Value of the equivalent strain when damage = 1
InternalField<Real> Full_dam_value_strain;
/// Value of the equivalent strain rate when damage = 1
InternalField<Real> Full_dam_value_strain_rate;
- /// Count the number of times that the material is damaged to damage = 0 until damage = 1
+ /// Count the number of times that the material is damaged to damage = 0 until
+ /// damage = 1
InternalField<Real> Number_damage;
/// Equivalent strain used to compute the damage evolution
InternalField<Real> equi_strain;
/// Equivalent strain rate used to compute the damage evolution
InternalField<Real> equi_strain_rate;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_vreepeerlings_inline_impl.cc"
#include "material_vreepeerlings_tmpl.hh"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_VREEPEERLINGS_HH__ */
-
diff --git a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_inline_impl.cc b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_inline_impl.cc
index 8b15de85b..c261a91fa 100644
--- a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_inline_impl.cc
@@ -1,177 +1,185 @@
/**
* @file material_vreepeerlings_inline_impl.cc
*
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
*
* @brief Specialization of the material class for the VreePeerlings material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
+template <UInt spatial_dimension, template <UInt> class MatParent>
inline void
-MaterialVreePeerlings<spatial_dimension, MatParent>::computeStressOnQuad(Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- Real & dam,
- Real & Equistrain,
- Real & Equistrain_rate,
- Real & Kapaq,
- Real dt,
- Matrix<Real> & strain_rate_vrplgs,
- Real & FullDam_ValStrain,
- Real & FullDam_ValStrain_rate,
- Real & Nb_damage) {
-
-
- Real I1=0.; /// trace initialization of the strain tensor
- Real J2=0.; /// J2 [J2=1/6(3 strain:strain - I1*I1)] initialization
- Real I1rate=0.; /// trace initialization of the strain rate tensor
- Real J2rate=0.; /// J2 [J2=1/3(3 strain:strainrate - I1*I1rate)] initialization
-
- if (spatial_dimension == 1){
+MaterialVreePeerlings<spatial_dimension, MatParent>::computeStressOnQuad(
+ Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam, Real & Equistrain,
+ Real & Equistrain_rate, Real & Kapaq, Real dt,
+ Matrix<Real> & strain_rate_vrplgs, Real & FullDam_ValStrain,
+ Real & FullDam_ValStrain_rate, Real & Nb_damage) {
+
+ Real I1 = 0.; /// trace initialization of the strain tensor
+ Real J2 = 0.; /// J2 [J2=1/6(3 strain:strain - I1*I1)] initialization
+ Real I1rate = 0.; /// trace initialization of the strain rate tensor
+ Real J2rate =
+ 0.; /// J2 [J2=1/3(3 strain:strainrate - I1*I1rate)] initialization
+
+ if (spatial_dimension == 1) {
I1 = grad_u.trace();
- J2 = .5*grad_u(0,0)*grad_u(0,0) - I1 * I1/6.;
+ J2 = .5 * grad_u(0, 0) * grad_u(0, 0) - I1 * I1 / 6.;
I1rate = strain_rate_vrplgs.trace();
- J2rate = grad_u(0,0)*strain_rate_vrplgs(0,0) -I1 * I1rate/6.;
- }
- else {
+ J2rate = grad_u(0, 0) * strain_rate_vrplgs(0, 0) - I1 * I1rate / 6.;
+ } else {
// if(this->plane_stress) {
// Real tmp = this->nu/(this->nu - 1);
// tmp *= tmp;
// I1 = (grad_u(0,0) + grad_u(1,1))*(1 - 2*this->nu)/(1 - this->nu);
// J2 = .5*(grad_u(0,0)*grad_u(0,0) +
// grad_u(1,1)*grad_u(1,1) +
// tmp*(grad_u(0,0) + grad_u(1,1))*(grad_u(0,0) + grad_u(1,1)) +
// .5*(grad_u(0,1) + grad_u(1,0))*(grad_u(0,1) + grad_u(1,0))) -
// I1*I1/6.;
- // I1rate = (strain_rate_vrplgs(0,0) + strain_rate_vrplgs(1,1))*(1 - 2*this->nu)/(1 - this->nu);
+ // I1rate = (strain_rate_vrplgs(0,0) + strain_rate_vrplgs(1,1))*(1 -
+ // 2*this->nu)/(1 - this->nu);
// J2rate = (grad_u(0,0)*strain_rate_vrplgs(0,0) +
// grad_u(1,1)*strain_rate_vrplgs(1,1) +
- // tmp*(grad_u(0,0) + grad_u(1,1))*(strain_rate_vrplgs(0,0) + strain_rate_vrplgs(1,1)) +
- // (grad_u(0,1)*strain_rate_vrplgs(1,0)) + (grad_u(0,1)*strain_rate_vrplgs(1,0))) -
+ // tmp*(grad_u(0,0) + grad_u(1,1))*(strain_rate_vrplgs(0,0) +
+ // strain_rate_vrplgs(1,1)) +
+ // (grad_u(0,1)*strain_rate_vrplgs(1,0)) +
+ // (grad_u(0,1)*strain_rate_vrplgs(1,0))) -
// I1*I1rate/3.;
// }
// else {
- I1 = grad_u.trace();
- for(UInt i=0; i<spatial_dimension; ++i )
- for(UInt j=i; j<spatial_dimension; ++j )
- J2 += 0.5*( (i==j)*grad_u(i,i)*grad_u(i,i) +0.5*(1- (i==j))*( (grad_u(i,j) + grad_u(j,i))*(grad_u(i,j) + grad_u(j,i)) ));
-
- J2-= I1 * I1/6.;
+ I1 = grad_u.trace();
+ for (UInt i = 0; i < spatial_dimension; ++i)
+ for (UInt j = i; j < spatial_dimension; ++j)
+ J2 += 0.5 * ((i == j) * grad_u(i, i) * grad_u(i, i) +
+ 0.5 * (1 - (i == j)) * ((grad_u(i, j) + grad_u(j, i)) *
+ (grad_u(i, j) + grad_u(j, i))));
- I1rate = strain_rate_vrplgs.trace();
- bool is3D= spatial_dimension==3;
- J2rate = (grad_u(0,0)*strain_rate_vrplgs(0,0) +
- grad_u(1,1)*strain_rate_vrplgs(1,1) +
- is3D * grad_u(2,2)*strain_rate_vrplgs(2,2) +
- (grad_u(0,1)*strain_rate_vrplgs(1,0)) + (grad_u(0,1)*strain_rate_vrplgs(1,0)) +
- is3D * (grad_u(1,2)*strain_rate_vrplgs(2,1)) + is3D * (grad_u(1,2)*strain_rate_vrplgs(2,1)) +
- is3D * (grad_u(2,0)*strain_rate_vrplgs(0,2)) + is3D * (grad_u(2,0)*strain_rate_vrplgs(0,2))) -
- I1 * I1rate/3.;
+ J2 -= I1 * I1 / 6.;
- // }
+ I1rate = strain_rate_vrplgs.trace();
+ bool is3D = spatial_dimension == 3;
+ J2rate = (grad_u(0, 0) * strain_rate_vrplgs(0, 0) +
+ grad_u(1, 1) * strain_rate_vrplgs(1, 1) +
+ is3D * grad_u(2, 2) * strain_rate_vrplgs(2, 2) +
+ (grad_u(0, 1) * strain_rate_vrplgs(1, 0)) +
+ (grad_u(0, 1) * strain_rate_vrplgs(1, 0)) +
+ is3D * (grad_u(1, 2) * strain_rate_vrplgs(2, 1)) +
+ is3D * (grad_u(1, 2) * strain_rate_vrplgs(2, 1)) +
+ is3D * (grad_u(2, 0) * strain_rate_vrplgs(0, 2)) +
+ is3D * (grad_u(2, 0) * strain_rate_vrplgs(0, 2))) -
+ I1 * I1rate / 3.;
+
+ // }
}
- Real tmp_1 = (Kct - 1)/(1 - 2*this->nu);
- Real tmp_2 = (12 * Kct)/((1 + this->nu)*(1 + this->nu));
+ Real tmp_1 = (Kct - 1) / (1 - 2 * this->nu);
+ Real tmp_2 = (12 * Kct) / ((1 + this->nu) * (1 + this->nu));
- Equistrain = tmp_1 * I1 / (2*Kct) + 1./(2*Kct) * std::sqrt(tmp_1*tmp_1*I1*I1 + tmp_2*J2);
+ Equistrain = tmp_1 * I1 / (2 * Kct) +
+ 1. / (2 * Kct) * std::sqrt(tmp_1 * tmp_1 * I1 * I1 + tmp_2 * J2);
- if(I1 * I1rate > 0 || J2rate > 0){
- Equistrain_rate =tmp_1 * std::abs(I1rate) / (2*Kct) + 1./(4*Kct)*(2*tmp_1*tmp_1*I1*I1rate + tmp_2*J2rate) / std::sqrt(tmp_1*tmp_1*I1*I1 + tmp_2*J2);
- }else{
+ if (I1 * I1rate > 0 || J2rate > 0) {
+ Equistrain_rate = tmp_1 * std::abs(I1rate) / (2 * Kct) +
+ 1. / (4 * Kct) *
+ (2 * tmp_1 * tmp_1 * I1 * I1rate + tmp_2 * J2rate) /
+ std::sqrt(tmp_1 * tmp_1 * I1 * I1 + tmp_2 * J2);
+ } else {
AKANTU_ERROR("This instruction here was commented but has to be checked");
- //Equistrain_rate = Equistrain_rate;
+ // Equistrain_rate = Equistrain_rate;
}
- if(!this->is_non_local) {
- computeDamageAndStressOnQuad(sigma, dam, Equistrain, Equistrain_rate, Kapaq, dt, FullDam_ValStrain, FullDam_ValStrain_rate, Nb_damage);
+ if (!this->is_non_local) {
+ computeDamageAndStressOnQuad(sigma, dam, Equistrain, Equistrain_rate, Kapaq,
+ dt, FullDam_ValStrain, FullDam_ValStrain_rate,
+ Nb_damage);
}
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
-inline void
-MaterialVreePeerlings<spatial_dimension, MatParent>::computeDamageAndStressOnQuad(Matrix<Real> & sigma,
- Real & dam,
- Real & Equistrain,
- Real & Equistrain_rate,
- Real & Kapaq,
- Real dt,
- Real & FullDam_ValStrain,
- Real & FullDam_ValStrain_rate,
- Real & Nb_damage) {
-
+template <UInt spatial_dimension, template <UInt> class MatParent>
+inline void MaterialVreePeerlings<spatial_dimension, MatParent>::
+ computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam,
+ Real & Equistrain, Real & Equistrain_rate,
+ Real & Kapaq, Real dt,
+ Real & FullDam_ValStrain,
+ Real & FullDam_ValStrain_rate,
+ Real & Nb_damage) {
//---------------------------------------------------------------------------------------
// rate-dependence model
//
//---------------------------------------------------------------------------------------
- Real Kapao = Crate*(1.+(std::pow(std::abs(Equistrain_rate)*Arate,Brate)))*(1.-Kapao_randomness) + Kapao_randomness*Kapaq;
- Real Kapac_99 = Kapac*.99;
+ Real Kapao = Crate *
+ (1. + (std::pow(std::abs(Equistrain_rate) * Arate, Brate))) *
+ (1. - Kapao_randomness) +
+ Kapao_randomness * Kapaq;
+ Real Kapac_99 = Kapac * .99;
Real Kapaodyn = 0;
if (Kapao > Kapaoi) {
if (Kapao < Kapac_99) {
Kapaodyn = Kapao;
} else {
Kapaodyn = Kapac_99;
}
} else {
Kapaodyn = Kapaoi;
}
Real Fd1 = Equistrain - Kapaoi;
- if (Fd1 > 0)
- {
- Real dam1 = 1. - Kapaodyn/Equistrain * ((Kapac - Equistrain)/(Kapac - Kapaodyn));
- if (dam1 > dam){
- dam = std::min(dam1,1.);
- Nb_damage = Nb_damage + 1.;
-
- if (dam >= 1.){
- FullDam_ValStrain = Equistrain;
- FullDam_ValStrain_rate = Equistrain_rate;
- }
+ if (Fd1 > 0) {
+ Real dam1 =
+ 1. -
+ Kapaodyn / Equistrain * ((Kapac - Equistrain) / (Kapac - Kapaodyn));
+ if (dam1 > dam) {
+ dam = std::min(dam1, 1.);
+ Nb_damage = Nb_damage + 1.;
+
+ if (dam >= 1.) {
+ FullDam_ValStrain = Equistrain;
+ FullDam_ValStrain_rate = Equistrain_rate;
}
}
+ }
//---------------------------------------------------------------------------------------
// delayed damage (see Marions thesis page 68)
//---------------------------------------------------------------------------------------
// Real viscosity = 10.;
// Real damRateInfini = 10000000.;
- // Real gequi = 1. - Kapaq/Equistrain * ((Kapac-Equistrain)/(Kapac - Kapaq));
+ // Real gequi = 1. - Kapaq/Equistrain * ((Kapac-Equistrain)/(Kapac -
+ // Kapaq));
// if (gequi - dam > 0){
//
- // Real damRate = damRateInfini * (1. - std::exp(-1*viscosity * (gequi - dam)));
+ // Real damRate = damRateInfini * (1. - std::exp(-1*viscosity * (gequi -
+ // dam)));
// if (damrate > 0){
//
// if (dam < 1.){
// dam = dam + damRate*dt;
// } else {
// dam = 1.;
// }
// }
// }
//
//---------------------------------------------------------------------------------------
- sigma *= 1-dam;
+ sigma *= 1 - dam;
}
/* -------------------------------------------------------------------------- */
diff --git a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.cc b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.cc
index 72f5a0ba5..c5e093d1e 100644
--- a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.cc
@@ -1,28 +1,27 @@
/**
* @file material_vreepeerlings_non_local.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
*
- * @brief Specialization of the material class for the non-local Vree-Peerlings material
+ * @brief Specialization of the material class for the non-local Vree-Peerlings
+ * material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_vreepeerlings_non_local.hh"
#include "solid_mechanics_model.hh"
-
namespace akantu {
-
/* -------------------------------------------------------------------------- */
-//INSTANTIATE_MATERIAL(MaterialVreePeerlingsNonLocal);
+// INSTANTIATE_MATERIAL(MaterialVreePeerlingsNonLocal);
} // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.hh
index d0979b9ce..abcebc7b1 100644
--- a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local.hh
@@ -1,91 +1,90 @@
/**
* @file material_vreepeerlings_non_local.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
*
* @brief MaterialVreePeerlings header for non-local damage
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "material_vreepeerlings.hh"
#include "material_damage_non_local.hh"
+#include "material_vreepeerlings.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_VREEPEERLINGS_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_VREEPEERLINGS_NON_LOCAL_HH__
namespace akantu {
/**
* Material VreePeerlings Non local
*
* parameters in the material files :
*/
-template<UInt spatial_dimension,
- template <UInt> class MatParent = MaterialElastic>
-class MaterialVreePeerlingsNonLocal : public MaterialDamageNonLocal<spatial_dimension,
- MaterialVreePeerlings<spatial_dimension,
- MatParent> > {
+template <UInt spatial_dimension,
+ template <UInt> class MatParent = MaterialElastic>
+class MaterialVreePeerlingsNonLocal
+ : public MaterialDamageNonLocal<
+ spatial_dimension,
+ MaterialVreePeerlings<spatial_dimension, MatParent>> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef MaterialVreePeerlings<spatial_dimension, MatParent> Parent;
- typedef MaterialDamageNonLocal<spatial_dimension, Parent> MaterialVreePeerlingsNonLocalParent;
+ typedef MaterialDamageNonLocal<spatial_dimension, Parent>
+ MaterialVreePeerlingsNonLocalParent;
- MaterialVreePeerlingsNonLocal(SolidMechanicsModel & model, const ID & id = "");
+ MaterialVreePeerlingsNonLocal(SolidMechanicsModel & model,
+ const ID & id = "");
- virtual ~MaterialVreePeerlingsNonLocal() {};
+ virtual ~MaterialVreePeerlingsNonLocal(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void initMaterial();
/// constitutive law for all element of a type
- //void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
+ // void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// constitutive law
virtual void computeNonLocalStress(ElementType el_type,
- GhostType ghost_type = _not_ghost);
+ GhostType ghost_type = _not_ghost);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
-
/// non local version of equivalent strain
InternalField<Real> equi_strain_non_local;
/// non local version of equivalent strain rate
InternalField<Real> equi_strain_rate_non_local;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_vreepeerlings_non_local_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_VREEPEERLINGS_NON_LOCAL_HH__ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local_inline_impl.cc b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local_inline_impl.cc
index 7a5f1f8ee..a044edc5f 100644
--- a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_non_local_inline_impl.cc
@@ -1,145 +1,160 @@
/**
* @file material_vreepeerlings_non_local_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
*
- * @brief Specialization of the material class for the non-local Vree-Peerlings material
+ * @brief Specialization of the material class for the non-local Vree-Peerlings
+ * material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
-MaterialVreePeerlingsNonLocal<spatial_dimension, MatParent>::MaterialVreePeerlingsNonLocal(SolidMechanicsModel & model,
- const ID & id) :
- Material(model, id),
- MaterialVreePeerlingsNonLocalParent(model, id),
- equi_strain_non_local("equi-strain_non_local", *this),
- equi_strain_rate_non_local("equi-strain-rate_non_local", *this) {
+template <UInt spatial_dimension, template <UInt> class MatParent>
+MaterialVreePeerlingsNonLocal<spatial_dimension, MatParent>::
+ MaterialVreePeerlingsNonLocal(SolidMechanicsModel & model, const ID & id)
+ : Material(model, id), MaterialVreePeerlingsNonLocalParent(model, id),
+ equi_strain_non_local("equi-strain_non_local", *this),
+ equi_strain_rate_non_local("equi-strain-rate_non_local", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
this->equi_strain_non_local.initialize(1);
this->equi_strain_rate_non_local.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
-void MaterialVreePeerlingsNonLocal<spatial_dimension, MatParent>::initMaterial() {
+template <UInt spatial_dimension, template <UInt> class MatParent>
+void MaterialVreePeerlingsNonLocal<spatial_dimension,
+ MatParent>::initMaterial() {
AKANTU_DEBUG_IN();
- this->registerNonLocalVariable(this->equi_strain, this->equi_strain_non_local, 1);
- this->registerNonLocalVariable(this->equi_strain_rate, this->equi_strain_rate_non_local, 1);
+ this->registerNonLocalVariable(this->equi_strain, this->equi_strain_non_local,
+ 1);
+ this->registerNonLocalVariable(this->equi_strain_rate,
+ this->equi_strain_rate_non_local, 1);
MaterialVreePeerlingsNonLocalParent::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-//template<UInt spatial_dimension, class WeigthFunction, template <UInt> class MatParent>
-//void MaterialVreePeerlingsNonLocal<spatial_dimension, WeigthFunction, MatParent>::computeStress(ElementType el_type,
+// template<UInt spatial_dimension, class WeigthFunction, template <UInt> class
+// MatParent>
+// void MaterialVreePeerlingsNonLocal<spatial_dimension, WeigthFunction,
+// MatParent>::computeStress(ElementType el_type,
// GhostType ghost_type) {
// AKANTU_DEBUG_IN();
//
// Real * dam = this->damage(el_type, ghost_type).storage();
// Real * equi_straint = equi_strain(el_type, ghost_type).storage();
// Real * equi_straint_rate = equi_strain_rate(el_type, ghost_type).storage();
// Real * Kapaq = this->Kapa(el_type, ghost_type).storage();
// Real * crit_strain = this->critical_strain(el_type, ghost_type).storage();
-// Real * crit_strain_rate = this->critical_strain_rate(el_type, ghost_type).storage();
+// Real * crit_strain_rate = this->critical_strain_rate(el_type,
+// ghost_type).storage();
// Real * rdr_damage = this->recorder_damage(el_type, ghost_type).storage();
// Real * nb_damage = this->number_damage(el_type, ghost_type).storage();
// Real dt = this->model.getTimeStep();
//
// Vector<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
// Vector<Real> & velocity = this->model.getVelocity();
-// Vector<Real> & strain_rate_vrplgs = this->strain_rate_vreepeerlings(el_type, ghost_type);
+// Vector<Real> & strain_rate_vrplgs = this->strain_rate_vreepeerlings(el_type,
+// ghost_type);
//
//
-// this->model.getFEEngine().gradientOnQuadraturePoints(velocity, strain_rate_vrplgs,
+// this->model.getFEEngine().gradientOnQuadraturePoints(velocity,
+// strain_rate_vrplgs,
// spatial_dimension,
// el_type, ghost_type, &elem_filter);
//
// Vector<Real>::iterator<types::RMatrix> strain_rate_vrplgs_it =
// strain_rate_vrplgs.begin(spatial_dimension, spatial_dimension);
//
//
// MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
//
// types::RMatrix & strain_rate = *strain_rate_vrplgs_it;
//
//
//
// MaterialVreePeerlings<spatial_dimension>::computeStressOnQuad(grad_u, sigma,
// *dam,
// *equi_straint,
// *equi_straint_rate,
// *Kapaq,
// dt,
// strain_rate,
// *crit_strain,
// *crit_strain_rate,
// *rdr_damage,
// *nb_damage);
// ++dam;
// ++equi_straint;
// ++equi_straint_rate;
// ++Kapaq;
// ++strain_rate_vrplgs_it;
// ++crit_strain;
// ++crit_strain_rate;
// ++rdr_damage;
// ++nb_damage;
//
// MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
//
// AKANTU_DEBUG_OUT();
//}
//
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
-void MaterialVreePeerlingsNonLocal<spatial_dimension, MatParent>::computeNonLocalStress(ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension, template <UInt> class MatParent>
+void MaterialVreePeerlingsNonLocal<
+ spatial_dimension, MatParent>::computeNonLocalStress(ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
- Real * dam = this->damage(el_type, ghost_type).storage();
+ Real * dam = this->damage(el_type, ghost_type).storage();
Real * Kapaq = this->Kapa(el_type, ghost_type).storage();
- Real * equi_strain_nl = this->equi_strain_non_local(el_type, ghost_type).storage();
- Real * equi_strain_rate_nl = this->equi_strain_rate_non_local(el_type, ghost_type).storage();
- //Real * equi_strain_rate_nl = this->equi_strain_rate(el_type, ghost_type).storage();
+ Real * equi_strain_nl =
+ this->equi_strain_non_local(el_type, ghost_type).storage();
+ Real * equi_strain_rate_nl =
+ this->equi_strain_rate_non_local(el_type, ghost_type).storage();
+ // Real * equi_strain_rate_nl = this->equi_strain_rate(el_type,
+ // ghost_type).storage();
Real dt = this->model.getTimeStep();
- Real * FullDam_Valstrain = this->Full_dam_value_strain(el_type, ghost_type).storage();
- Real * FullDam_Valstrain_rate = this->Full_dam_value_strain_rate(el_type, ghost_type).storage();
- Real * Nb_damage = this->Number_damage(el_type, ghost_type).storage();
+ Real * FullDam_Valstrain =
+ this->Full_dam_value_strain(el_type, ghost_type).storage();
+ Real * FullDam_Valstrain_rate =
+ this->Full_dam_value_strain_rate(el_type, ghost_type).storage();
+ Real * Nb_damage = this->Number_damage(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
- this->computeDamageAndStressOnQuad(sigma, *dam, *equi_strain_nl, *equi_strain_rate_nl, *Kapaq, dt, *FullDam_Valstrain, *FullDam_Valstrain_rate, *Nb_damage);
+ this->computeDamageAndStressOnQuad(
+ sigma, *dam, *equi_strain_nl, *equi_strain_rate_nl, *Kapaq, dt,
+ *FullDam_Valstrain, *FullDam_Valstrain_rate, *Nb_damage);
++dam;
++equi_strain_nl;
++equi_strain_rate_nl;
++Kapaq;
++FullDam_Valstrain;
++FullDam_Valstrain_rate;
++Nb_damage;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
-
diff --git a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_tmpl.hh b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_tmpl.hh
index b211f6077..8dbee348a 100644
--- a/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_tmpl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_vreepeerlings_tmpl.hh
@@ -1,112 +1,107 @@
/**
* @file material_vreepeerlings_tmpl.hh
*
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
*
* @brief Specialization of the material class for the VreePeerlings material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
-MaterialVreePeerlings<spatial_dimension, MatParent>::MaterialVreePeerlings(SolidMechanicsModel & model,
- const ID & id) :
- Material(model, id),
- MaterialVreePeerlingsParent(model, id),
- Kapa("Kapa", *this),
- strain_rate_vreepeerlings("strain-rate-vreepeerlings", *this),
- Full_dam_value_strain("fulldam-valstrain", *this),
- Full_dam_value_strain_rate("fulldam-valstrain-rate", *this),
- Number_damage("number-damage", *this),
- equi_strain("equi-strain", *this),
- equi_strain_rate("equi-strain-rate", *this) {
+template <UInt spatial_dimension, template <UInt> class MatParent>
+MaterialVreePeerlings<spatial_dimension, MatParent>::MaterialVreePeerlings(
+ SolidMechanicsModel & model, const ID & id)
+ : Material(model, id), MaterialVreePeerlingsParent(model, id),
+ Kapa("Kapa", *this),
+ strain_rate_vreepeerlings("strain-rate-vreepeerlings", *this),
+ Full_dam_value_strain("fulldam-valstrain", *this),
+ Full_dam_value_strain_rate("fulldam-valstrain-rate", *this),
+ Number_damage("number-damage", *this), equi_strain("equi-strain", *this),
+ equi_strain_rate("equi-strain-rate", *this) {
AKANTU_DEBUG_IN();
- this->registerParam("Kapaoi" , Kapaoi , 0.0001, _pat_parsable);
- this->registerParam("Kapac" , Kapac , 0.0002, _pat_parsable);
- this->registerParam("Arate" , Arate , 0. , _pat_parsable);
- this->registerParam("Brate" , Brate , 1. , _pat_parsable);
- this->registerParam("Crate" , Brate , 1. , _pat_parsable);
- this->registerParam("Kct" , Kct , 1. , _pat_parsable);
- this->registerParam("Kapao_randomness", Kapao_randomness, 0. , _pat_parsable);
+ this->registerParam("Kapaoi", Kapaoi, 0.0001, _pat_parsable);
+ this->registerParam("Kapac", Kapac, 0.0002, _pat_parsable);
+ this->registerParam("Arate", Arate, 0., _pat_parsable);
+ this->registerParam("Brate", Brate, 1., _pat_parsable);
+ this->registerParam("Crate", Brate, 1., _pat_parsable);
+ this->registerParam("Kct", Kct, 1., _pat_parsable);
+ this->registerParam("Kapao_randomness", Kapao_randomness, 0., _pat_parsable);
this->Kapa.initialize(1);
this->equi_strain.initialize(1);
this->equi_strain_rate.initialize(1);
this->Full_dam_value_strain.initialize(1);
this->Full_dam_value_strain_rate.initialize(1);
this->Number_damage.initialize(1);
- this->strain_rate_vreepeerlings.initialize(spatial_dimension * spatial_dimension);
+ this->strain_rate_vreepeerlings.initialize(spatial_dimension *
+ spatial_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
+template <UInt spatial_dimension, template <UInt> class MatParent>
void MaterialVreePeerlings<spatial_dimension, MatParent>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialVreePeerlingsParent::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class MatParent>
-void MaterialVreePeerlings<spatial_dimension, MatParent>::computeStress(ElementType el_type, GhostType ghost_type) {
+template <UInt spatial_dimension, template <UInt> class MatParent>
+void MaterialVreePeerlings<spatial_dimension, MatParent>::computeStress(
+ ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialVreePeerlingsParent::computeStress(el_type, ghost_type);
Real * dam = this->damage(el_type, ghost_type).storage();
Real * equi_straint = equi_strain(el_type, ghost_type).storage();
Real * equi_straint_rate = equi_strain_rate(el_type, ghost_type).storage();
Real * Kapaq = Kapa(el_type, ghost_type).storage();
- Real * FullDam_Valstrain = Full_dam_value_strain(el_type, ghost_type).storage();
- Real * FullDam_Valstrain_rate = Full_dam_value_strain_rate(el_type, ghost_type).storage();
+ Real * FullDam_Valstrain =
+ Full_dam_value_strain(el_type, ghost_type).storage();
+ Real * FullDam_Valstrain_rate =
+ Full_dam_value_strain_rate(el_type, ghost_type).storage();
Real * Nb_damage = Number_damage(el_type, ghost_type).storage();
Real dt = this->model.getTimeStep();
Array<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
Array<Real> & velocity = this->model.getVelocity();
- Array<Real> & strain_rate_vrplgs = this->strain_rate_vreepeerlings(el_type, ghost_type);
+ Array<Real> & strain_rate_vrplgs =
+ this->strain_rate_vreepeerlings(el_type, ghost_type);
- this->model.getFEEngine().gradientOnIntegrationPoints(velocity, strain_rate_vrplgs,
- spatial_dimension,
- el_type, ghost_type, elem_filter);
+ this->model.getFEEngine().gradientOnIntegrationPoints(
+ velocity, strain_rate_vrplgs, spatial_dimension, el_type, ghost_type,
+ elem_filter);
Array<Real>::matrix_iterator strain_rate_vrplgs_it =
- strain_rate_vrplgs.begin(spatial_dimension, spatial_dimension);
+ strain_rate_vrplgs.begin(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & strain_rate = *strain_rate_vrplgs_it;
- computeStressOnQuad(grad_u, sigma,
- *dam,
- *equi_straint,
- *equi_straint_rate,
- *Kapaq,
- dt,
- strain_rate,
- *FullDam_Valstrain,
- *FullDam_Valstrain_rate,
- *Nb_damage);
+ computeStressOnQuad(grad_u, sigma, *dam, *equi_straint, *equi_straint_rate,
+ *Kapaq, dt, strain_rate, *FullDam_Valstrain,
+ *FullDam_Valstrain_rate, *Nb_damage);
++dam;
++equi_straint;
++equi_straint_rate;
++Kapaq;
++strain_rate_vrplgs_it;
++FullDam_Valstrain;
++FullDam_Valstrain_rate;
++Nb_damage;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
-
diff --git a/extra_packages/extra-materials/src/material_extra_includes.hh b/extra_packages/extra-materials/src/material_extra_includes.hh
index ed0c97cab..788a89959 100644
--- a/extra_packages/extra-materials/src/material_extra_includes.hh
+++ b/extra_packages/extra-materials/src/material_extra_includes.hh
@@ -1,69 +1,70 @@
/**
* @file material_extra_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Extra list of materials
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_EXTRA_INCLUDES_HH__
#define __AKANTU_MATERIAL_EXTRA_INCLUDES_HH__
#ifndef AKANTU_CMAKE_LIST_MATERIALS
// visco-elastic materials
#include "material_stiffness_proportional.hh"
// damage materials
#include "material_brittle.hh"
#include "material_damage_iterative.hh"
-#include "material_iterative_stiffness_reduction.hh"
#include "material_damage_linear.hh"
-#include "material_vreepeerlings.hh"
+#include "material_iterative_stiffness_reduction.hh"
#include "material_orthotropic_damage_iterative.hh"
+#include "material_vreepeerlings.hh"
// plasticity
#include "material_viscoplastic.hh"
// multi-scale simulations
#include "material_FE2.hh"
#endif
#if defined(AKANTU_DAMAGE_NON_LOCAL)
#ifndef AKANTU_CMAKE_LIST_MATERIALS
-# include "material_vreepeerlings_non_local.hh"
-# include "material_brittle_non_local.hh"
-# include "material_damage_iterative_non_local.hh"
-# include "material_orthotropic_damage_iterative_non_local.hh"
-# include "material_orthotropic_damage_non_local.hh"
+#include "material_brittle_non_local.hh"
+#include "material_damage_iterative_non_local.hh"
+#include "material_orthotropic_damage_iterative_non_local.hh"
+#include "material_orthotropic_damage_non_local.hh"
+#include "material_vreepeerlings_non_local.hh"
#endif
-#define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_EXTRA_LIST \
- ((2, (brittle_non_local , MaterialBrittleNonLocal))) \
- ((2, (damage_iterative_non_local , MaterialDamageIterativeNonLocal))) \
- ((2, (damage_orthotropic_iterative_non_local , MaterialOrthotropicDamageIterativeNonLocal)))
+#define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_EXTRA_LIST \
+ ((2, (brittle_non_local, MaterialBrittleNonLocal)))( \
+ (2, (damage_iterative_non_local, MaterialDamageIterativeNonLocal)))( \
+ (2, (damage_orthotropic_iterative_non_local, \
+ MaterialOrthotropicDamageIterativeNonLocal)))
#else
-# define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_EXTRA_LIST
+#define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_EXTRA_LIST
#endif
-#define AKANTU_EXTRA_MATERIAL_LIST \
- ((2, (damage_linear , MaterialDamageLinear ))) \
- ((2, (brittle , MaterialBrittle ))) \
- ((2, (material_FE2 , MaterialFE2 ))) \
- ((2, (damage_iterative , MaterialDamageIterative ))) \
- ((2, (iterative_stiffness_reduction , MaterialIterativeStiffnessReduction ))) \
- ((2, (vreepeerlings , MaterialVreePeerlings ))) \
- ((2, (ve_stiffness_prop , MaterialStiffnessProportional ))) \
- ((2, (visco_plastic , MaterialViscoPlastic ))) \
- ((2, (orthotropic_damage_iterative , MaterialOrthotropicDamageIterative )))
+#define AKANTU_EXTRA_MATERIAL_LIST \
+ ((2, (damage_linear, MaterialDamageLinear)))( \
+ (2, (brittle, MaterialBrittle)))((2, (material_FE2, MaterialFE2)))( \
+ (2, (damage_iterative, MaterialDamageIterative)))( \
+ (2, \
+ (iterative_stiffness_reduction, MaterialIterativeStiffnessReduction)))( \
+ (2, (vreepeerlings, MaterialVreePeerlings)))( \
+ (2, (ve_stiffness_prop, MaterialStiffnessProportional)))( \
+ (2, (visco_plastic, MaterialViscoPlastic)))( \
+ (2, (orthotropic_damage_iterative, MaterialOrthotropicDamageIterative)))
#endif /* __AKANTU_MATERIAL_EXTRA_INCLUDES_HH__ */
diff --git a/extra_packages/extra-materials/src/material_non_local_extra_includes.hh b/extra_packages/extra-materials/src/material_non_local_extra_includes.hh
index 96af8b4a6..2ab4cfc42 100644
--- a/extra_packages/extra-materials/src/material_non_local_extra_includes.hh
+++ b/extra_packages/extra-materials/src/material_non_local_extra_includes.hh
@@ -1,17 +1,16 @@
/**
* @file material_non_local_extra_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Non local materials includes
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-
diff --git a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh
index 4559397a4..428fda2ae 100644
--- a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh
+++ b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh
@@ -1,104 +1,100 @@
/**
* @file material_viscoplastic.hh
*
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
*
*
* @brief Specialization of the material class for
* MaterialLinearIsotropicHardening to include viscous effects (small
* deformation)
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "material_plastic.hh"
#include "aka_voigthelper.hh"
+#include "material_plastic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_VISCOPLASTIC_HH__
#define __AKANTU_MATERIAL_VISCOPLASTIC_HH__
namespace akantu {
/**
* Material plastic isotropic
*
* parameters in the material files :
* - h : Hardening parameter (default: 0)
* - sigmay : Yield stress
* - rate : Rate sensitivity
* - edot0 : Reference strain rate
*
* - ts: Time step
*/
-
template <UInt spatial_dimension>
class MaterialViscoPlastic : public MaterialPlastic<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialViscoPlastic(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// constitutive law for all element of a type
- virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
+ virtual void computeStress(ElementType el_type,
+ GhostType ghost_type = _not_ghost);
/// compute the tangent stiffness matrix for an element type
void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
protected:
- inline void computeStressOnQuad(const Matrix<Real> & grad_u,
- const Matrix<Real> & previous_grad_u,
- Matrix<Real> & sigma,
- const Matrix<Real> & previous_sigma,
- Matrix<Real> & inelastic_strain,
- const Matrix<Real> & previous_inelastic_strain,
- Real & iso_hardening) const;
-
- inline void computeTangentModuliOnQuad(Matrix<Real> & tangent,
- const Matrix<Real> & grad_u,
- const Matrix<Real> & previous_grad_u,
- const Matrix<Real> & sigma_tensor,
- const Matrix<Real> & previous_sigma_tensor,
- const Real & iso_hardening) const;
+ inline void
+ computeStressOnQuad(const Matrix<Real> & grad_u,
+ const Matrix<Real> & previous_grad_u,
+ Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
+ Matrix<Real> & inelastic_strain,
+ const Matrix<Real> & previous_inelastic_strain,
+ Real & iso_hardening) const;
+
+ inline void computeTangentModuliOnQuad(
+ Matrix<Real> & tangent, const Matrix<Real> & grad_u,
+ const Matrix<Real> & previous_grad_u, const Matrix<Real> & sigma_tensor,
+ const Matrix<Real> & previous_sigma_tensor,
+ const Real & iso_hardening) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// Rate sensitivity component (rate)
Real rate;
/// Reference strain rate (edot0)
Real edot0;
/// Time step (ts)
Real ts;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_viscoplastic_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_VISCOPLASTIC_HH__ */
diff --git a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.cc b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.cc
index fcb55190a..3ae29b693 100644
--- a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.cc
+++ b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.cc
@@ -1,92 +1,90 @@
/**
* @file material_viscoplastic_inline_impl.cc
*
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
*
*
* @brief Implementation of the inline functions of the material viscoplastic
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
-#include <cmath>
#include "material_viscoplastic.hh"
-
+#include <cmath>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-inline void MaterialViscoPlastic<dim>::computeStressOnQuad(const Matrix<Real> & grad_u,
- const Matrix<Real> & previous_grad_u,
- Matrix<Real> & sigma,
- const Matrix<Real> & previous_sigma,
- Matrix<Real> & inelastic_strain,
- const Matrix<Real> & previous_inelastic_strain,
- Real & iso_hardening) const {
+template <UInt dim>
+inline void MaterialViscoPlastic<dim>::computeStressOnQuad(
+ const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
+ Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
+ Matrix<Real> & inelastic_strain,
+ const Matrix<Real> & previous_inelastic_strain,
+ Real & iso_hardening) const {
// Infinitesimal plastic
// Compute stress magnitude
Real s = sigma.doubleDot(sigma);
- Real sigma_mag=sqrt(s);
+ Real sigma_mag = sqrt(s);
// Compute plastic strain increment
Real factor = (this->ts * this->edot0 * pow(sigma_mag, (this->rate - 1.)) /
pow(this->sigma_y + iso_hardening, this->rate));
Matrix<Real> delta_inelastic_strain(sigma);
delta_inelastic_strain *= factor;
// Compute plastic strain increment magnitude
s = delta_inelastic_strain.doubleDot(delta_inelastic_strain);
Real dep_mag = std::sqrt(s);
Matrix<Real> grad_delta_u(grad_u);
grad_delta_u -= previous_grad_u;
// Update stress and plastic strain
Matrix<Real> grad_u_elastic(dim, dim);
grad_u_elastic = grad_delta_u;
grad_u_elastic -= delta_inelastic_strain;
Matrix<Real> sigma_elastic(dim, dim);
MaterialElastic<dim>::computeStressOnQuad(grad_u_elastic, sigma_elastic);
sigma += sigma_elastic;
inelastic_strain += delta_inelastic_strain;
- //Update resistance stress
+ // Update resistance stress
iso_hardening = iso_hardening + this->h * dep_mag;
- MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(grad_delta_u, sigma, previous_sigma,
- inelastic_strain, previous_inelastic_strain,
- delta_inelastic_strain);
-
+ MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
+ grad_delta_u, sigma, previous_sigma, inelastic_strain,
+ previous_inelastic_strain, delta_inelastic_strain);
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-inline void MaterialViscoPlastic<dim>::computeTangentModuliOnQuad(Matrix<Real> & tangent,
- const Matrix<Real> & /*grad_u*/,
- const Matrix<Real> & /*previous_grad_u*/,
- const Matrix<Real> & /*sigma_tensor*/,
- const Matrix<Real> & /*previous_sigma_tensor*/,
- const Real & /*iso_hardening*/) const {
+template <UInt dim>
+inline void MaterialViscoPlastic<dim>::computeTangentModuliOnQuad(
+ Matrix<Real> & tangent, const Matrix<Real> & /*grad_u*/,
+ const Matrix<Real> & /*previous_grad_u*/,
+ const Matrix<Real> & /*sigma_tensor*/,
+ const Matrix<Real> & /*previous_sigma_tensor*/,
+ const Real & /*iso_hardening*/) const {
UInt cols = tangent.cols();
UInt rows = tangent.rows();
for (UInt m = 0; m < rows; ++m) {
UInt i = VoigtHelper<dim>::vec[m][0];
UInt j = VoigtHelper<dim>::vec[m][1];
for (UInt n = 0; n < cols; ++n) {
UInt k = VoigtHelper<dim>::vec[n][0];
UInt l = VoigtHelper<dim>::vec[n][1];
- tangent(m,n) = (i==k) * (j==l) * 2. * this->mu + (i==j) * (k==l) * this->lambda;
- tangent(m,n) -= (m==n) * (m>=dim) * this->mu;
+ tangent(m, n) = (i == k) * (j == l) * 2. * this->mu +
+ (i == j) * (k == l) * this->lambda;
+ tangent(m, n) -= (m == n) * (m >= dim) * this->mu;
}
}
}
diff --git a/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh b/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh
index 43779d0b5..181e3c872 100644
--- a/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh
+++ b/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh
@@ -1,102 +1,100 @@
/**
* @file material_stiffness_proportional.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Material isotropic visco-elastic with viscosity proportional to the
* stiffness
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
#include "material_elastic.hh"
/* -------------------------------------------------------------------------- */
-
#ifndef __AKANTU_MATERIAL_STIFFNESS_PROPORTIONAL_HH__
#define __AKANTU_MATERIAL_STIFFNESS_PROPORTIONAL_HH__
namespace akantu {
/**
- * Material visco-elastic @f[\sigma = E\epsilon + \alpha E* \frac{d\epsilon}{dt}@f]
+ * Material visco-elastic @f[\sigma = E\epsilon + \alpha E*
+ * \frac{d\epsilon}{dt}@f]
* it can be seen as a Kelvin-Voigt solid with @f[\eta = \alpha E @f]
*
* The material satisfies the Caughey condition, the visco-elastic solid has the
* same eigen-modes as the elastic one. (T.K. Caughey 1960 - Journal of Applied
* Mechanics 27, 269-271. Classical normal modes in damped linear systems.)
*
* parameters in the material files :
* - rho : density (default: 0)
* - E : Young's modulus (default: 0)
* - nu : Poisson's ratio (default: 1/2)
* - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
* - alpha : viscous ratio
*/
-template<UInt spatial_dimension>
-class MaterialStiffnessProportional : public MaterialElastic<spatial_dimension> {
+template <UInt spatial_dimension>
+class MaterialStiffnessProportional
+ : public MaterialElastic<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
+ MaterialStiffnessProportional(SolidMechanicsModel & model,
+ const ID & id = "");
- MaterialStiffnessProportional(SolidMechanicsModel & model, const ID & id = "");
-
- virtual ~MaterialStiffnessProportional() {};
+ virtual ~MaterialStiffnessProportional(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void initMaterial();
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the potential energy for all elements
- virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost);
+ virtual void computePotentialEnergy(ElementType el_type,
+ GhostType ghost_type = _not_ghost);
protected:
/// constitutive law for a given quadrature point
- //inline void computeStress(Real * F, Real * sigma);
+ // inline void computeStress(Real * F, Real * sigma);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
-
/// stress due to viscosity
InternalField<Real> stress_viscosity;
/// stress due to elasticity
InternalField<Real> stress_elastic;
/// viscous ratio
Real alpha;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "material_elastic_caughey_inline_impl.cc"
} // namespace akantu
#endif /* __AKANTU_MATERIAL_STIFFNESS_PROPORTIONAL_HH__ */
diff --git a/extra_packages/extra-materials/test/test_material_FE2/test_elastic_homogenization.cc b/extra_packages/extra-materials/test/test_material_FE2/test_elastic_homogenization.cc
index 702ba9f5c..ab4e17647 100644
--- a/extra_packages/extra-materials/test/test_material_FE2/test_elastic_homogenization.cc
+++ b/extra_packages/extra-materials/test/test_material_FE2/test_elastic_homogenization.cc
@@ -1,82 +1,89 @@
/**
* @file test_elastic_homogenization.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Mon Jan 25 18:32:09 2016
*
* @brief Test elastic homogenization of stiffness tensor
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_RVE.hh"
#include "material_elastic_linear_anisotropic.hh"
+#include "solid_mechanics_model_RVE.hh"
using namespace akantu;
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize("material_orthotropic.dat", argc, argv);
const UInt spatial_dimension = 2;
const ElementType element_type = _triangle_3;
const GhostType ghost_type = _not_ghost;
Mesh mesh(spatial_dimension);
mesh.read("homogenized_plate.msh");
SolidMechanicsModelRVE model(mesh, false);
/// model initialization
model.initFull();
/// apply eigenstrain
- Array<Real> & prestrain_vect = const_cast<Array<Real> &>(model.getMaterial(0).getInternal<Real>("eigen_grad_u")(element_type, ghost_type));
- Array<Real>::iterator< Matrix<Real> > prestrain_it = prestrain_vect.begin(spatial_dimension, spatial_dimension);
- Array<Real>::iterator< Matrix<Real> > prestrain_end = prestrain_vect.end(spatial_dimension, spatial_dimension);
-
+ Array<Real> & prestrain_vect =
+ const_cast<Array<Real> &>(model.getMaterial(0).getInternal<Real>(
+ "eigen_grad_u")(element_type, ghost_type));
+ Array<Real>::iterator<Matrix<Real>> prestrain_it =
+ prestrain_vect.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::iterator<Matrix<Real>> prestrain_end =
+ prestrain_vect.end(spatial_dimension, spatial_dimension);
+
//(*prestrain_it)(0,0) = 0.2;
//(*prestrain_it)(1,1) = 0.2;
- for (; prestrain_it != prestrain_end; ++prestrain_it)
+ for (; prestrain_it != prestrain_end; ++prestrain_it)
(*prestrain_it) += 1.0;
/// storage for results of 3 different loading states
UInt voigt_size = VoigtHelper<spatial_dimension>::size;
- MaterialElasticLinearAnisotropic<spatial_dimension> & mat = dynamic_cast<MaterialElasticLinearAnisotropic<spatial_dimension> & >(model.getMaterial(0));
+ MaterialElasticLinearAnisotropic<spatial_dimension> & mat =
+ dynamic_cast<MaterialElasticLinearAnisotropic<spatial_dimension> &>(
+ model.getMaterial(0));
Matrix<Real> voigt_stiffness = mat.getVoigtStiffness();
- /// homogenize
+ /// homogenize
Matrix<Real> C(voigt_size, voigt_size);
model.homogenizeStiffness(C);
- for(UInt i = 0; i < voigt_size; ++i) {
+ for (UInt i = 0; i < voigt_size; ++i) {
for (UInt j = 0; j < voigt_size; ++j) {
- std::cout << "exact: " << voigt_stiffness(i,j) << " approximated: " << C(i,j) << std::endl;
- if(std::abs(voigt_stiffness(i,j) - C(i,j)) > 1.e-10) {
- std::cout << "The material homogenization failed" << std::endl;
- finalize();
- return EXIT_FAILURE;
+ std::cout << "exact: " << voigt_stiffness(i, j)
+ << " approximated: " << C(i, j) << std::endl;
+ if (std::abs(voigt_stiffness(i, j) - C(i, j)) > 1.e-10) {
+ std::cout << "The material homogenization failed" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
}
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_parallel.cc b/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_parallel.cc
index 515f5b8ba..62c306e01 100644
--- a/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_parallel.cc
+++ b/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_parallel.cc
@@ -1,357 +1,360 @@
/**
* @file test_material_damage_iterative_non_local_parallel.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 26 12:20:15 2015
*
* @brief test the material damage iterative non local in parallel
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage_iterative.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-bool checkDisplacement(SolidMechanicsModel & model,
- ElementType type,
- std::ofstream & error_output,
- UInt step,
- bool barycenters);
+bool checkDisplacement(SolidMechanicsModel & model, ElementType type,
+ std::ofstream & error_output, UInt step,
+ bool barycenters);
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
debug::setDebugLevel(dblWarning);
ElementType element_type = _triangle_3;
- initialize("two_materials.dat" ,argc, argv);
-
+ initialize("two_materials.dat", argc, argv);
+
const UInt spatial_dimension = 2;
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partion it
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("one_circular_inclusion.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModel model(mesh);
model.initParallel(partition);
delete partition;
-
/// assign the material
MeshDataMaterialSelector<std::string> * mat_selector;
- mat_selector = new MeshDataMaterialSelector<std::string>("physical_names", model);
+ mat_selector =
+ new MeshDataMaterialSelector<std::string>("physical_names", model);
model.setMaterialSelector(*mat_selector);
- mesh.createGroupsFromMeshData<std::string>("physical_names"); // creates groups from mesh names
+ mesh.createGroupsFromMeshData<std::string>(
+ "physical_names"); // creates groups from mesh names
/// initialization of the model
model.initFull(SolidMechanicsModelOptions(_static));
/// boundary conditions
/// Dirichlet BC
model.applyBC(BC::Dirichlet::FixedValue(0, _x), "left");
model.applyBC(BC::Dirichlet::FixedValue(0, _y), "bottom");
model.applyBC(BC::Dirichlet::FixedValue(2., _y), "top");
/// add fields that should be dumped
model.setBaseName("material_damage_iterative_test");
- model.addDumpFieldVector("displacement");;
+ model.addDumpFieldVector("displacement");
+ ;
model.addDumpField("stress");
model.addDumpField("blocked_dofs");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("damage");
model.addDumpField("partitions");
model.addDumpField("material_index");
model.addDumpField("Sc");
model.addDumpField("force");
model.addDumpField("equivalent_stress");
model.dump();
std::stringstream error_stream;
- error_stream << "error" << ".csv";
+ error_stream << "error"
+ << ".csv";
std::ofstream error_output;
error_output.open(error_stream.str().c_str());
error_output << "# Step, Average, Max, Min" << std::endl;
checkDisplacement(model, element_type, error_output, 0, true);
- MaterialDamageIterative<spatial_dimension> & aggregate = dynamic_cast<MaterialDamageIterative<spatial_dimension> & >(model.getMaterial(0));
- MaterialDamageIterative<spatial_dimension> & paste = dynamic_cast<MaterialDamageIterative<spatial_dimension> & >(model.getMaterial(1));
-
+ MaterialDamageIterative<spatial_dimension> & aggregate =
+ dynamic_cast<MaterialDamageIterative<spatial_dimension> &>(
+ model.getMaterial(0));
+ MaterialDamageIterative<spatial_dimension> & paste =
+ dynamic_cast<MaterialDamageIterative<spatial_dimension> &>(
+ model.getMaterial(1));
+
Real error;
bool converged = false;
UInt nb_damaged_elements = 0;
Real max_eq_stress_agg = 0;
Real max_eq_stress_paste = 0;
/// solve the system
- converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, error, 2);
+ converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-12, error, 2);
if (converged == false) {
std::cout << "The error is: " << error << std::endl;
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
}
if (!checkDisplacement(model, element_type, error_output, 1, false)) {
finalize();
return EXIT_FAILURE;
}
- model.dump();
-
+ model.dump();
+
/// get the maximum equivalent stress in both materials
max_eq_stress_agg = aggregate.getNormMaxEquivalentStress();
max_eq_stress_paste = paste.getNormMaxEquivalentStress();
-
+
nb_damaged_elements = 0;
if (max_eq_stress_agg > max_eq_stress_paste)
nb_damaged_elements = aggregate.updateDamage();
else
nb_damaged_elements = paste.updateDamage();
- if (prank == 0 && nb_damaged_elements)
- std::cout << nb_damaged_elements << " elements damaged" << std::endl;
-
+ if (prank == 0 && nb_damaged_elements)
+ std::cout << nb_damaged_elements << " elements damaged" << std::endl;
+
/// resolve the system
- converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, error, 2);
+ converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-12, error, 2);
if (converged == false) {
std::cout << "The error is: " << error << std::endl;
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
}
-
if (!checkDisplacement(model, element_type, error_output, 2, false)) {
finalize();
return EXIT_FAILURE;
}
-
- model.dump();
-
+
+ model.dump();
+
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
-bool checkDisplacement(SolidMechanicsModel & model,
- ElementType type,
- std::ofstream & error_output,
- UInt step,
- bool barycenters) {
+bool checkDisplacement(SolidMechanicsModel & model, ElementType type,
+ std::ofstream & error_output, UInt step,
+ bool barycenters) {
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
const Array<UInt> & connectivity = mesh.getConnectivity(type);
const Array<Real> & displacement = model.getDisplacement();
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_elem = Mesh::getNbNodesPerElement(type);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
if (psize == 1) {
std::stringstream displacement_file;
- displacement_file << "displacement/displacement_"
- << std::setfill('0') << std::setw(6)
- << step;
+ displacement_file << "displacement/displacement_" << std::setfill('0')
+ << std::setw(6) << step;
std::ofstream displacement_output;
displacement_output.open(displacement_file.str().c_str());
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
- UInt node = connectivity(el, n);
+ UInt node = connectivity(el, n);
- for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- displacement_output << std::setprecision(15)
- << displacement(node, dim) << " ";
- }
- displacement_output << std::endl;
+ for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+ displacement_output << std::setprecision(15)
+ << displacement(node, dim) << " ";
+ }
+ displacement_output << std::endl;
}
}
displacement_output.close();
if (barycenters) {
std::stringstream barycenter_file;
barycenter_file << "displacement/barycenters";
std::ofstream barycenter_output;
barycenter_output.open(barycenter_file.str().c_str());
Element element(type, 0);
Vector<Real> bary(spatial_dimension);
for (UInt el = 0; el < nb_element; ++el) {
- element.element = el;
- mesh.getBarycenter(element, bary);
-
- for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- barycenter_output << std::setprecision(15)
- << bary(dim) << " ";
- }
- barycenter_output << std::endl;
+ element.element = el;
+ mesh.getBarycenter(element, bary);
+
+ for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+ barycenter_output << std::setprecision(15) << bary(dim) << " ";
+ }
+ barycenter_output << std::endl;
}
barycenter_output.close();
}
- }
- else {
+ } else {
- if (barycenters) return true;
+ if (barycenters)
+ return true;
/// read data
std::stringstream displacement_file;
- displacement_file << "displacement/displacement_"
- << std::setfill('0') << std::setw(6)
- << step;
+ displacement_file << "displacement/displacement_" << std::setfill('0')
+ << std::setw(6) << step;
std::ifstream displacement_input;
displacement_input.open(displacement_file.str().c_str());
Array<Real> displacement_serial(0, spatial_dimension);
Vector<Real> disp_tmp(spatial_dimension);
while (displacement_input.good()) {
for (UInt i = 0; i < spatial_dimension; ++i)
- displacement_input >> disp_tmp(i);
+ displacement_input >> disp_tmp(i);
displacement_serial.push_back(disp_tmp);
}
std::stringstream barycenter_file;
barycenter_file << "displacement/barycenters";
std::ifstream barycenter_input;
barycenter_input.open(barycenter_file.str().c_str());
Array<Real> barycenter_serial(0, spatial_dimension);
while (barycenter_input.good()) {
for (UInt dim = 0; dim < spatial_dimension; ++dim)
- barycenter_input >> disp_tmp(dim);
+ barycenter_input >> disp_tmp(dim);
barycenter_serial.push_back(disp_tmp);
}
Element element(type, 0);
Vector<Real> bary(spatial_dimension);
- Array<Real>::iterator<Vector<Real> > it;
- Array<Real>::iterator<Vector<Real> > begin
- = barycenter_serial.begin(spatial_dimension);
- Array<Real>::iterator<Vector<Real> > end
- = barycenter_serial.end(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> it;
+ Array<Real>::iterator<Vector<Real>> begin =
+ barycenter_serial.begin(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> end =
+ barycenter_serial.end(spatial_dimension);
- Array<Real>::const_iterator<Vector<Real> > disp_it;
- Array<Real>::iterator<Vector<Real> > disp_serial_it;
+ Array<Real>::const_iterator<Vector<Real>> disp_it;
+ Array<Real>::iterator<Vector<Real>> disp_serial_it;
Vector<Real> difference(spatial_dimension);
Array<Real> error;
/// compute error
for (UInt el = 0; el < nb_element; ++el) {
element.element = el;
mesh.getBarycenter(element, bary);
/// find element
for (it = begin; it != end; ++it) {
- UInt matched_dim = 0;
+ UInt matched_dim = 0;
- while (matched_dim < spatial_dimension &&
- Math::are_float_equal(bary(matched_dim), (*it)(matched_dim)))
- ++matched_dim;
+ while (matched_dim < spatial_dimension &&
+ Math::are_float_equal(bary(matched_dim), (*it)(matched_dim)))
+ ++matched_dim;
- if (matched_dim == spatial_dimension) break;
+ if (matched_dim == spatial_dimension)
+ break;
}
if (it == end) {
- std::cout << "Element barycenter not found!" << std::endl;
- return false;
+ std::cout << "Element barycenter not found!" << std::endl;
+ return false;
}
UInt matched_el = it - begin;
- disp_serial_it = displacement_serial.begin(spatial_dimension)
- + matched_el * nb_nodes_per_elem;
+ disp_serial_it = displacement_serial.begin(spatial_dimension) +
+ matched_el * nb_nodes_per_elem;
for (UInt n = 0; n < nb_nodes_per_elem; ++n, ++disp_serial_it) {
- UInt node = connectivity(el, n);
- if (!mesh.isLocalOrMasterNode(node)) continue;
+ UInt node = connectivity(el, n);
+ if (!mesh.isLocalOrMasterNode(node))
+ continue;
- disp_it = displacement.begin(spatial_dimension) + node;
+ disp_it = displacement.begin(spatial_dimension) + node;
- difference = *disp_it;
- difference -= *disp_serial_it;
+ difference = *disp_it;
+ difference -= *disp_serial_it;
- error.push_back(difference.norm());
+ error.push_back(difference.norm());
}
}
/// compute average error
Real average_error = std::accumulate(error.begin(), error.end(), 0.);
comm.allReduce(&average_error, 1, _so_sum);
UInt error_size = error.getSize();
comm.allReduce(&error_size, 1, _so_sum);
average_error /= error_size;
/// compute maximum and minimum
Real max_error = *std::max_element(error.begin(), error.end());
comm.allReduce(&max_error, 1, _so_max);
Real min_error = *std::min_element(error.begin(), error.end());
comm.allReduce(&min_error, 1, _so_min);
/// output data
if (prank == 0) {
- error_output << step << ", "
- << average_error << ", "
- << max_error << ", "
- << min_error << std::endl;
+ error_output << step << ", " << average_error << ", " << max_error << ", "
+ << min_error << std::endl;
}
if (max_error > 1.e-9) {
- std::cout << "Displacement error of " << max_error << " is too big!" << std::endl;
+ std::cout << "Displacement error of " << max_error << " is too big!"
+ << std::endl;
return false;
}
}
return true;
}
-
-
diff --git a/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc b/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc
index be7949b0c..3cd3f8724 100644
--- a/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc
+++ b/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc
@@ -1,224 +1,236 @@
/**
* @file test_material_damage_iterative_non_local_serial.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 26 12:20:15 2015
*
* @brief test the material damage iterative non local in serial
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage_iterative_non_local.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
Math::setTolerance(1e-13);
debug::setDebugLevel(dblWarning);
- initialize("material_non_local.dat" ,argc, argv);
-
+ initialize("material_non_local.dat", argc, argv);
+
const UInt spatial_dimension = 2;
ElementType element_type = _triangle_3;
/// read the mesh and partion it
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// initialization of the model
model.initFull(SolidMechanicsModelOptions(_static));
/// boundary conditions
/// Dirichlet BC
- mesh.createGroupsFromMeshData<std::string>("physical_names"); // creates groups from mesh names
+ mesh.createGroupsFromMeshData<std::string>(
+ "physical_names"); // creates groups from mesh names
model.applyBC(BC::Dirichlet::FixedValue(0, _x), "left");
model.applyBC(BC::Dirichlet::FixedValue(0, _y), "bottom");
model.applyBC(BC::Dirichlet::FixedValue(2., _y), "top");
/// add fields that should be dumped
model.setBaseName("material_damage_iterative_test");
- model.addDumpFieldVector("displacement");;
+ model.addDumpFieldVector("displacement");
+ ;
model.addDumpField("stress");
model.addDumpField("blocked_dofs");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("grad_u non local");
model.addDumpField("damage");
model.addDumpField("partitions");
model.addDumpField("material_index");
model.addDumpField("Sc");
model.addDumpField("force");
model.addDumpField("equivalent_stress");
model.dump();
-
- MaterialDamageIterativeNonLocal<spatial_dimension> & material = dynamic_cast<MaterialDamageIterativeNonLocal<spatial_dimension> & >(model.getMaterial(0));
-
+
+ MaterialDamageIterativeNonLocal<spatial_dimension> & material =
+ dynamic_cast<MaterialDamageIterativeNonLocal<spatial_dimension> &>(
+ model.getMaterial(0));
+
Real error;
bool converged = false;
Real max_eq_stress = 0;
/// solve the system
- converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-4, error, 2);
+ converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-4, error, 2);
if (converged == false) {
std::cout << "The error is: " << error << std::endl;
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
}
- model.dump();
+ model.dump();
/// check the non-local grad_u: since grad_u is constant everywhere
/// also the grad_u non-local has to be constant
- Array<Real> & grad_u_nl = material.getInternal<Real>("grad_u non local")(element_type, _not_ghost);
- Array<Real>::const_matrix_iterator grad_u_nl_it = grad_u_nl.begin(spatial_dimension,spatial_dimension);
- Array<Real>::const_matrix_iterator grad_u_nl_end = grad_u_nl.end(spatial_dimension,spatial_dimension);
+ Array<Real> & grad_u_nl =
+ material.getInternal<Real>("grad_u non local")(element_type, _not_ghost);
+ Array<Real>::const_matrix_iterator grad_u_nl_it =
+ grad_u_nl.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::const_matrix_iterator grad_u_nl_end =
+ grad_u_nl.end(spatial_dimension, spatial_dimension);
Real diff = 0.;
Matrix<Real> diff_matrix(spatial_dimension, spatial_dimension);
Matrix<Real> const_grad_u(spatial_dimension, spatial_dimension, 0.);
- const_grad_u(1,1) = 1.;
+ const_grad_u(1, 1) = 1.;
for (; grad_u_nl_it != grad_u_nl_end; ++grad_u_nl_it) {
diff_matrix = (*grad_u_nl_it) - const_grad_u;
diff += diff_matrix.norm<L_2>();
- }
-
+ }
+
if (diff > 10.e-13) {
std::cout << "Error in the non-local grad_u computation" << std::endl;
return EXIT_FAILURE;
}
-
/// change the displacement in one node to modify grad_u
Array<Real> & displ = model.getDisplacement();
- displ(0,1) = 2.6;
-
+ displ(0, 1) = 2.6;
/// compute stresses: this will average grad_u and compute the max. eq. stress
model.updateResidual();
model.dump();
/// due to the change in the displacement element 33 and 37 will
/// have a grad_u different then one
- const Array<Real> & grad_u = material.getInternal<Real>("grad_u")(element_type, _not_ghost);
- Array<Real>::const_matrix_iterator grad_u_it = grad_u.begin(spatial_dimension,spatial_dimension);
- Array<Real>::const_matrix_iterator grad_u_end = grad_u.end(spatial_dimension,spatial_dimension);
+ const Array<Real> & grad_u =
+ material.getInternal<Real>("grad_u")(element_type, _not_ghost);
+ Array<Real>::const_matrix_iterator grad_u_it =
+ grad_u.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::const_matrix_iterator grad_u_end =
+ grad_u.end(spatial_dimension, spatial_dimension);
diff = 0.;
diff_matrix.clear();
-
+
UInt counter = 0;
for (; grad_u_it != grad_u_end; ++grad_u_it) {
diff_matrix = (*grad_u_it) - const_grad_u;
if (counter == 34 || counter == 38) {
if ((diff_matrix.norm<L_2>()) < 0.1) {
- std::cout << "Error in the grad_u computation" << std::endl;
- return EXIT_FAILURE;
- }
- }
- else
+ std::cout << "Error in the grad_u computation" << std::endl;
+ return EXIT_FAILURE;
+ }
+ } else
diff += diff_matrix.norm<L_2>();
++counter;
- }
+ }
if (diff > 10.e-13) {
std::cout << "Error in the grad_u computation" << std::endl;
return EXIT_FAILURE;
}
-
/// check that the non-local grad_u
diff = 0.;
diff_matrix.clear();
Real nl_radius = 1.0; /// same values as in material file
- grad_u_nl_it = grad_u_nl.begin(spatial_dimension,spatial_dimension);
+ grad_u_nl_it = grad_u_nl.begin(spatial_dimension, spatial_dimension);
ElementTypeMapReal quad_coords("quad_coords");
- mesh.initElementTypeMapArray(quad_coords, spatial_dimension, spatial_dimension, false, _ek_regular, true);
+ mesh.initElementTypeMapArray(quad_coords, spatial_dimension,
+ spatial_dimension, false, _ek_regular, true);
model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
UInt nb_elements = mesh.getNbElement(element_type, _not_ghost);
UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(element_type);
Array<Real> & coords = quad_coords(element_type, _not_ghost);
auto coord_it = coords.begin(spatial_dimension);
Vector<Real> q1(spatial_dimension);
Vector<Real> q2(spatial_dimension);
q1 = coord_it[34];
q2 = coord_it[38];
for (UInt e = 0; e < nb_elements; ++e) {
for (UInt q = 0; q < nb_quads; ++q, ++coord_it, ++grad_u_nl_it) {
diff_matrix = (*grad_u_nl_it) - const_grad_u;
- if ((q1.distance(*coord_it) <= (nl_radius + Math::getTolerance())) ||
- (q2.distance(*coord_it) <= (nl_radius + Math::getTolerance()))) {
- if ((diff_matrix.norm<L_2>()) < 1.e-6) {
- std::cout << (diff_matrix.norm<L_2>()) << std::endl;
- std::cout << "Error in the non-local grad_u computation" << std::endl;
- return EXIT_FAILURE;
- }
- }
- else
- diff += diff_matrix.norm<L_2>();
+ if ((q1.distance(*coord_it) <= (nl_radius + Math::getTolerance())) ||
+ (q2.distance(*coord_it) <= (nl_radius + Math::getTolerance()))) {
+ if ((diff_matrix.norm<L_2>()) < 1.e-6) {
+ std::cout << (diff_matrix.norm<L_2>()) << std::endl;
+ std::cout << "Error in the non-local grad_u computation" << std::endl;
+ return EXIT_FAILURE;
+ }
+ } else
+ diff += diff_matrix.norm<L_2>();
}
}
if (diff > 10.e-13) {
std::cout << "Error in the non-local grad_u computation" << std::endl;
return EXIT_FAILURE;
}
-
/// make sure that the normalized equivalent stress is based on the
/// non-local grad_u for this test check the elements that have the
/// constant stress of 1 but different non-local gradu because they
/// are in the neighborhood of the modified elements
coord_it = coords.begin(spatial_dimension);
- const Array<Real> & eq_stress = material.getInternal<Real>("equivalent_stress")(element_type, _not_ghost);
+ const Array<Real> & eq_stress =
+ material.getInternal<Real>("equivalent_stress")(element_type, _not_ghost);
Array<Real>::const_scalar_iterator eq_stress_it = eq_stress.begin();
counter = 0;
for (UInt e = 0; e < nb_elements; ++e) {
- for (UInt q = 0; q < nb_quads; ++q, ++coord_it, ++grad_u_nl_it, ++eq_stress_it) {
+ for (UInt q = 0; q < nb_quads;
+ ++q, ++coord_it, ++grad_u_nl_it, ++eq_stress_it) {
if (counter == 34 || counter == 38)
- continue;
- if (((q1.distance(*coord_it) <= (nl_radius + Math::getTolerance())) ||
- (q2.distance(*coord_it) <= (nl_radius + Math::getTolerance()))) && Math::are_float_equal(*eq_stress_it, 0.1)) {
- std::cout << "the normalized equivalent stress is most likely based on the local, not the non-local grad_u!!!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
+ continue;
+ if (((q1.distance(*coord_it) <= (nl_radius + Math::getTolerance())) ||
+ (q2.distance(*coord_it) <= (nl_radius + Math::getTolerance()))) &&
+ Math::are_float_equal(*eq_stress_it, 0.1)) {
+ std::cout << "the normalized equivalent stress is most likely based on "
+ "the local, not the non-local grad_u!!!!"
+ << std::endl;
+ finalize();
+ return EXIT_FAILURE;
}
++counter;
}
}
- max_eq_stress = material.getNormMaxEquivalentStress();
-
- if (!Math::are_float_equal(max_eq_stress, 0.1311267235941873)){
+ max_eq_stress = material.getNormMaxEquivalentStress();
+
+ if (!Math::are_float_equal(max_eq_stress, 0.1311267235941873)) {
std::cout << "the maximum equivalent stress is wrong" << std::endl;
finalize();
return EXIT_FAILURE;
}
- model.dump();
+ model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/igfem/src/dumper_igfem_connectivity.hh b/extra_packages/igfem/src/dumper_igfem_connectivity.hh
index 8a7172dbc..12894131d 100644
--- a/extra_packages/igfem/src/dumper_igfem_connectivity.hh
+++ b/extra_packages/igfem/src/dumper_igfem_connectivity.hh
@@ -1,119 +1,117 @@
/**
* @file dumper_igfem_connectivity.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Iterator for the IGFEM connectivity
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#ifndef __AKANTU_DUMPER_IGFEM_CONNECTIVITY_HH__
#define __AKANTU_DUMPER_IGFEM_CONNECTIVITY_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_igfem_element_iterator.hh"
#include "dumper_igfem_generic_elemental_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class types>
-class igfem_connectivity_field_iterator
- : public igfem_element_iterator<types, igfem_connectivity_field_iterator> {
+class igfem_connectivity_field_iterator
+ : public igfem_element_iterator<types, igfem_connectivity_field_iterator> {
public:
-
/* ------------------------------------------------------------------------ */
/* Typedefs */
- /* ------------------------------------------------------------------------ */
-
+ /* ------------------------------------------------------------------------ */
- typedef igfem_element_iterator<types, dumper::igfem_connectivity_field_iterator> parent;
+ typedef igfem_element_iterator<types,
+ dumper::igfem_connectivity_field_iterator>
+ parent;
typedef typename types::return_type return_type;
typedef typename types::field_type field_type;
typedef typename types::array_iterator array_iterator;
public:
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
- igfem_connectivity_field_iterator(const field_type & field,
- const typename field_type::type_iterator & t_it,
- const typename field_type::type_iterator & t_it_end,
- const array_iterator & array_it,
- const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost,
- UInt sub_element = 0) :
- parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type, sub_element) { }
+ igfem_connectivity_field_iterator(
+ const field_type & field, const typename field_type::type_iterator & t_it,
+ const typename field_type::type_iterator & t_it_end,
+ const array_iterator & array_it, const array_iterator & array_it_end,
+ const GhostType ghost_type = _not_ghost, UInt sub_element = 0)
+ : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type,
+ sub_element) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
- return_type operator*(){
+ return_type operator*() {
const Vector<UInt> & element_connect = *this->array_it;
/// get the local sub_element connectivity and the nodes per sub-element
- UInt * sub_connec_ptr = IGFEMHelper::getSubElementConnectivity(*this->tit, this->sub_element);
- UInt nb_nodes_sub_el = IGFEMHelper::getNbNodesPerSubElement(*this->tit, this->sub_element);
-
+ UInt * sub_connec_ptr =
+ IGFEMHelper::getSubElementConnectivity(*this->tit, this->sub_element);
+ UInt nb_nodes_sub_el =
+ IGFEMHelper::getNbNodesPerSubElement(*this->tit, this->sub_element);
+
/// get the global sub element connectivity
Vector<UInt> sub_element_connect(nb_nodes_sub_el);
for (UInt i = 0; i < nb_nodes_sub_el; ++i) {
UInt lc = sub_connec_ptr[i];
sub_element_connect(i) = element_connect(lc);
}
return sub_element_connect;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
-private:
+private:
};
/* -------------------------------------------------------------------------- */
-class IGFEMConnectivityField :
- public IGFEMGenericElementalField<SingleType<UInt,Vector,false>,
- igfem_connectivity_field_iterator> {
+class IGFEMConnectivityField
+ : public IGFEMGenericElementalField<SingleType<UInt, Vector, false>,
+ igfem_connectivity_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------ */
public:
-
- typedef SingleType<UInt,Vector,false> types;
+ typedef SingleType<UInt, Vector, false> types;
typedef igfem_connectivity_field_iterator<types> iterator;
typedef types::field_type field_type;
- typedef IGFEMGenericElementalField<types,igfem_connectivity_field_iterator> parent;
+ typedef IGFEMGenericElementalField<types, igfem_connectivity_field_iterator>
+ parent;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
IGFEMConnectivityField(const field_type & field,
- UInt spatial_dimension = _all_dimensions,
- GhostType ghost_type = _not_ghost) :
- parent(field, spatial_dimension, ghost_type) { }
+ UInt spatial_dimension = _all_dimensions,
+ GhostType ghost_type = _not_ghost)
+ : parent(field, spatial_dimension, ghost_type) {}
};
-
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
/* -------------------------------------------------------------------------- */
#endif /*__AKANTU_DUMPER_IGFEM_CONNECTIVITY_HH__ */
diff --git a/extra_packages/igfem/src/dumper_igfem_element_iterator.hh b/extra_packages/igfem/src/dumper_igfem_element_iterator.hh
index e79fd4985..fc9bdd3f2 100644
--- a/extra_packages/igfem/src/dumper_igfem_element_iterator.hh
+++ b/extra_packages/igfem/src/dumper_igfem_element_iterator.hh
@@ -1,196 +1,182 @@
/**
* @file dumper_igfem_element_iterator.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Iterators for IGFEM elemental fields
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#ifndef __AKANTU_DUMPER_IGFEM_ELEMENT_ITERATOR_HH__
#define __AKANTU_DUMPER_IGFEM_ELEMENT_ITERATOR_HH__
/* -------------------------------------------------------------------------- */
#include "element.hh"
#include "igfem_helper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template<class types, template <class> class final_iterator>
+template <class types, template <class> class final_iterator>
class igfem_element_iterator {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
-
- typedef typename types::it_type it_type;
+ typedef typename types::it_type it_type;
typedef typename types::field_type field_type;
typedef typename types::array_type array_type;
typedef typename types::array_iterator array_iterator;
typedef final_iterator<types> iterator;
public:
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
igfem_element_iterator(const field_type & field,
- const typename field_type::type_iterator & t_it,
- const typename field_type::type_iterator & t_it_end,
- const array_iterator & array_it,
- const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost,
- UInt sub_element = 0)
- : field(field),
- tit(t_it),
- tit_end(t_it_end),
- array_it(array_it),
- array_it_end(array_it_end),
- ghost_type(ghost_type),
- sub_element(sub_element) {
- }
+ const typename field_type::type_iterator & t_it,
+ const typename field_type::type_iterator & t_it_end,
+ const array_iterator & array_it,
+ const array_iterator & array_it_end,
+ const GhostType ghost_type = _not_ghost,
+ UInt sub_element = 0)
+ : field(field), tit(t_it), tit_end(t_it_end), array_it(array_it),
+ array_it_end(array_it_end), ghost_type(ghost_type),
+ sub_element(sub_element) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
bool operator!=(const iterator & it) const {
- return (ghost_type != it.ghost_type)
- || (tit != it.tit || ((array_it != it.array_it) || sub_element != it.sub_element) );
+ return (ghost_type != it.ghost_type) ||
+ (tit != it.tit ||
+ ((array_it != it.array_it) || sub_element != it.sub_element));
}
-
iterator & operator++() {
if (!this->sub_element)
this->sub_element += 1;
else {
++array_it;
this->sub_element = 0;
- while(array_it == array_it_end && tit != tit_end) {
- ++tit;
- if(tit != tit_end) {
- const array_type & vect = field(*tit, ghost_type);
- UInt _nb_data_per_elem = getNbDataPerElem(*tit);
- UInt nb_component = vect.getNbComponent();
- UInt size = (vect.getSize() * nb_component) / _nb_data_per_elem;
-
- array_it = vect.begin_reinterpret(_nb_data_per_elem,size);
- array_it_end = vect.end_reinterpret (_nb_data_per_elem,size);
- }
+ while (array_it == array_it_end && tit != tit_end) {
+ ++tit;
+ if (tit != tit_end) {
+ const array_type & vect = field(*tit, ghost_type);
+ UInt _nb_data_per_elem = getNbDataPerElem(*tit);
+ UInt nb_component = vect.getNbComponent();
+ UInt size = (vect.getSize() * nb_component) / _nb_data_per_elem;
+
+ array_it = vect.begin_reinterpret(_nb_data_per_elem, size);
+ array_it_end = vect.end_reinterpret(_nb_data_per_elem, size);
+ }
}
}
return *(static_cast<iterator *>(this));
}
- ElementType getType() {
+ ElementType getType() {
ElementType sub_type = IGFEMHelper::getSubElementType(*tit, sub_element);
return sub_type;
}
/// get IOHelperType for sub-element
UInt element_type() { return getIOHelperType(this->getType()); }
/// get current parent element????
- Element getCurrentElement(){
- return Element(*tit,array_it.getCurrentIndex());
+ Element getCurrentElement() {
+ return Element(*tit, array_it.getCurrentIndex());
}
UInt getNbDataPerElem(const ElementType & type) const {
/// nb of data per parent element!
if (!nb_data_per_elem.exists(type, ghost_type))
- return field(type,ghost_type).getNbComponent();
-
- return nb_data_per_elem(type,ghost_type);
+ return field(type, ghost_type).getNbComponent();
+
+ return nb_data_per_elem(type, ghost_type);
}
- void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data){
+ void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) {
/// nb of data per parent element!
this->nb_data_per_elem = nb_data;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// the field to iterate on
const field_type & field;
/// field iterator
typename field_type::type_iterator tit;
/// field iterator end
typename field_type::type_iterator tit_end;
/// array iterator
array_iterator array_it;
/// internal iterator end
array_iterator array_it_end;
/// ghost type identification
const GhostType ghost_type;
/// number of data per element
ElementTypeMap<UInt> nb_data_per_elem;
/// index of sub-element
UInt sub_element;
/// sub_element end
UInt sub_element_end;
};
/* -------------------------------------------------------------------------- */
-template<typename types>
+template <typename types>
class igfem_elemental_field_iterator
- : public igfem_element_iterator<types, igfem_elemental_field_iterator> {
+ : public igfem_element_iterator<types, igfem_elemental_field_iterator> {
public:
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
- typedef igfem_element_iterator<types, ::akantu::dumper::igfem_elemental_field_iterator> parent;
- typedef typename types::it_type it_type;
+ typedef igfem_element_iterator<
+ types, ::akantu::dumper::igfem_elemental_field_iterator>
+ parent;
+ typedef typename types::it_type it_type;
typedef typename types::return_type return_type;
- typedef typename types::field_type field_type;
+ typedef typename types::field_type field_type;
typedef typename types::array_iterator array_iterator;
public:
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
- igfem_elemental_field_iterator(const field_type & field,
- const typename field_type::type_iterator & t_it,
- const typename field_type::type_iterator & t_it_end,
- const array_iterator & array_it,
- const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost,
- UInt sub_element = 0) :
- parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type, sub_element) { }
+ igfem_elemental_field_iterator(
+ const field_type & field, const typename field_type::type_iterator & t_it,
+ const typename field_type::type_iterator & t_it_end,
+ const array_iterator & array_it, const array_iterator & array_it_end,
+ const GhostType ghost_type = _not_ghost, UInt sub_element = 0)
+ : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type,
+ sub_element) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
- return_type operator*(){
- return *this->array_it;
- }
+ return_type operator*() { return *this->array_it; }
private:
-
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
/* -------------------------------------------------------------------------- */
-
-
#endif /* __AKANTU_DUMPER_IGFEM_ELEMENT_ITERATOR_HH__ */
diff --git a/extra_packages/igfem/src/dumper_igfem_element_partition.hh b/extra_packages/igfem/src/dumper_igfem_element_partition.hh
index 2d1cd0989..25a1a5ba7 100644
--- a/extra_packages/igfem/src/dumper_igfem_element_partition.hh
+++ b/extra_packages/igfem/src/dumper_igfem_element_partition.hh
@@ -1,107 +1,104 @@
/**
* @file dumper_igfem_element_partition.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Element partition field for IGFEM sub-elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template<class types>
+template <class types>
class igfem_element_partition_field_iterator
- : public igfem_element_iterator<types, igfem_element_partition_field_iterator> {
+ : public igfem_element_iterator<types,
+ igfem_element_partition_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
- typedef igfem_element_iterator<types, dumper::igfem_element_partition_field_iterator> parent;
+ typedef igfem_element_iterator<types,
+ dumper::igfem_element_partition_field_iterator>
+ parent;
typedef typename types::return_type return_type;
typedef typename types::array_iterator array_iterator;
typedef typename types::field_type field_type;
-
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- igfem_element_partition_field_iterator(const field_type & field,
- const typename field_type::type_iterator & t_it,
- const typename field_type::type_iterator & t_it_end,
- const array_iterator & array_it,
- const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost,
- UInt sub_element = 0) :
- parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type, sub_element) {
+ igfem_element_partition_field_iterator(
+ const field_type & field, const typename field_type::type_iterator & t_it,
+ const typename field_type::type_iterator & t_it_end,
+ const array_iterator & array_it, const array_iterator & array_it_end,
+ const GhostType ghost_type = _not_ghost, UInt sub_element = 0)
+ : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type,
+ sub_element) {
prank = StaticCommunicator::getStaticCommunicator().whoAmI();
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- return_type operator*() {
- return return_type(1, prank);
- }
+ return_type operator*() { return return_type(1, prank); }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
UInt prank;
};
-
/* -------------------------------------------------------------------------- */
-template<bool filtered = false>
-class IGFEMElementPartitionField :
- public IGFEMGenericElementalField<SingleType<UInt,Vector,filtered>,
- igfem_element_partition_field_iterator> {
+template <bool filtered = false>
+class IGFEMElementPartitionField : public IGFEMGenericElementalField<
+ SingleType<UInt, Vector, filtered>,
+ igfem_element_partition_field_iterator> {
public:
-
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
- typedef SingleType<UInt,Vector,filtered> types;
+ typedef SingleType<UInt, Vector, filtered> types;
typedef igfem_element_partition_field_iterator<types> iterator;
- typedef IGFEMGenericElementalField<types,igfem_element_partition_field_iterator> parent;
+ typedef IGFEMGenericElementalField<types,
+ igfem_element_partition_field_iterator>
+ parent;
typedef typename types::field_type field_type;
public:
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
IGFEMElementPartitionField(const field_type & field,
- UInt spatial_dimension = _all_dimensions,
- GhostType ghost_type = _not_ghost,
- ElementKind kind = _ek_igfem) :
- parent(field, spatial_dimension, ghost_type, kind) {
+ UInt spatial_dimension = _all_dimensions,
+ GhostType ghost_type = _not_ghost,
+ ElementKind kind = _ek_igfem)
+ : parent(field, spatial_dimension, ghost_type, kind) {
this->homogeneous = true;
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
UInt getDim() { return 1; }
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
diff --git a/extra_packages/igfem/src/dumper_igfem_elemental_field.hh b/extra_packages/igfem/src/dumper_igfem_elemental_field.hh
index 9477ee5e3..85a4b0a1e 100644
--- a/extra_packages/igfem/src/dumper_igfem_elemental_field.hh
+++ b/extra_packages/igfem/src/dumper_igfem_elemental_field.hh
@@ -1,60 +1,57 @@
/**
* @file dumper_igfem_elemental_field.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief description of IGFEM elemental fields
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#ifndef __AKANTU_DUMPER_IGFEM_ELEMENTAL_FIELD_HH__
#define __AKANTU_DUMPER_IGFEM_ELEMENTAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
-#include "static_communicator.hh"
#include "dumper_field.hh"
#include "dumper_igfem_generic_elemental_field.hh"
+#include "static_communicator.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-
-template<typename T, template <class> class ret = Vector,bool filtered = false>
+template <typename T, template <class> class ret = Vector,
+ bool filtered = false>
class IGFEMElementalField
- : public IGFEMGenericElementalField<SingleType<T,ret,filtered>,
- igfem_elemental_field_iterator> {
+ : public IGFEMGenericElementalField<SingleType<T, ret, filtered>,
+ igfem_elemental_field_iterator> {
public:
-
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
- typedef SingleType<T,ret,filtered> types;
+ typedef SingleType<T, ret, filtered> types;
typedef typename types::field_type field_type;
typedef elemental_field_iterator<types> iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
IGFEMElementalField(const field_type & field,
- UInt spatial_dimension = _all_dimensions,
- GhostType ghost_type = _not_ghost,
- ElementKind element_kind = _ek_igfem) :
- IGFEMGenericElementalField<types,igfem_elemental_field_iterator>(field,
- spatial_dimension,
- ghost_type, element_kind) { }
+ UInt spatial_dimension = _all_dimensions,
+ GhostType ghost_type = _not_ghost,
+ ElementKind element_kind = _ek_igfem)
+ : IGFEMGenericElementalField<types, igfem_elemental_field_iterator>(
+ field, spatial_dimension, ghost_type, element_kind) {}
};
-
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_IGFEM_ELEMENTAL_FIELD_HH__ */
diff --git a/extra_packages/igfem/src/dumper_igfem_generic_elemental_field.hh b/extra_packages/igfem/src/dumper_igfem_generic_elemental_field.hh
index f10c06d13..4b544135a 100644
--- a/extra_packages/igfem/src/dumper_igfem_generic_elemental_field.hh
+++ b/extra_packages/igfem/src/dumper_igfem_generic_elemental_field.hh
@@ -1,142 +1,144 @@
/**
* @file dumper_igfem_generic_elemental_field.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief generic interface IGFEM elemental fields
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_IGFEM_GENERIC_ELEMENTAL_FIELD_HH__
#define __AKANTU_DUMPER_IGFEM_GENERIC_ELEMENTAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_generic_elemental_field.hh"
#include "dumper_igfem_element_iterator.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template<class _types, template <class> class iterator_type>
-class IGFEMGenericElementalField : public GenericElementalField<_types, iterator_type>
-{
+template <class _types, template <class> class iterator_type>
+class IGFEMGenericElementalField
+ : public GenericElementalField<_types, iterator_type> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
-
typedef _types types;
typedef typename types::data_type data_type;
typedef typename types::it_type it_type;
typedef typename types::field_type field_type;
typedef typename types::array_type array_type;
typedef typename types::array_iterator array_iterator;
typedef typename field_type::type_iterator field_type_iterator;
typedef iterator_type<types> iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
IGFEMGenericElementalField(const field_type & field,
- UInt spatial_dimension = _all_dimensions,
- GhostType ghost_type = _not_ghost,
- ElementKind kind = _ek_igfem) :
+ UInt spatial_dimension = _all_dimensions,
+ GhostType ghost_type = _not_ghost,
+ ElementKind kind = _ek_igfem)
+ :
- GenericElementalField<types, iterator_type>(field, spatial_dimension, ghost_type, kind) {
+ GenericElementalField<types, iterator_type>(field, spatial_dimension,
+ ghost_type, kind) {
this->checkHomogeneity();
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
-
public:
/// return the size of the contained data: i.e. the number of elements ?
virtual UInt size() {
this->checkHomogeneity();
return ((this->nb_total_element) * 2);
}
-
+
virtual iterator begin() {
field_type_iterator tit;
field_type_iterator end;
UInt sub_element = 0;
/// type iterators on the elemental field
- tit = this->field.firstType(this->spatial_dimension, this->ghost_type, this->element_kind);
- end = this->field.lastType(this->spatial_dimension, this->ghost_type, this->element_kind);
+ tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
+ this->element_kind);
+ end = this->field.lastType(this->spatial_dimension, this->ghost_type,
+ this->element_kind);
/// skip all types without data
ElementType type = *tit;
- for (;tit != end && this->field(*tit, this->ghost_type).getSize() == 0; ++tit) { }
+ for (; tit != end && this->field(*tit, this->ghost_type).getSize() == 0;
+ ++tit) {
+ }
type = *tit;
if (tit == end)
return this->end();
/// getting information for the field of the given type
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data_per_elem = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.getSize() * nb_component) / nb_data_per_elem;
/// define element-wise iterator
array_iterator it = vect.begin_reinterpret(nb_data_per_elem, size);
array_iterator it_end = vect.end_reinterpret(nb_data_per_elem, size);
/// define data iterator
- iterator rit = iterator(this->field, tit, end, it, it_end, this->ghost_type, sub_element);
+ iterator rit = iterator(this->field, tit, end, it, it_end, this->ghost_type,
+ sub_element);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
- virtual iterator end () {
+ virtual iterator end() {
field_type_iterator tit;
field_type_iterator end;
UInt sub_element = 0;
- tit = this->field.firstType(this->spatial_dimension, this->ghost_type, this->element_kind);
- end = this->field.lastType(this->spatial_dimension, this->ghost_type, this->element_kind);
+ tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
+ this->element_kind);
+ end = this->field.lastType(this->spatial_dimension, this->ghost_type,
+ this->element_kind);
ElementType type = *tit;
- for (; tit != end; ++tit) type = *tit;
+ for (; tit != end; ++tit)
+ type = *tit;
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.getSize() * nb_component) / nb_data;
array_iterator it = vect.end_reinterpret(nb_data, size);
- iterator rit = iterator(this->field, end, end, it, it, this->ghost_type, sub_element);
+ iterator rit =
+ iterator(this->field, end, end, it, it, this->ghost_type, sub_element);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
-
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
-
};
-
__END_AKANTU_DUMPER__
__END_AKANTU__
-
#endif /* __AKANTU_DUMPER_IGFEM_GENERIC_ELEMENTAL_FIELD_HH__ */
diff --git a/extra_packages/igfem/src/dumper_igfem_material_internal_field.hh b/extra_packages/igfem/src/dumper_igfem_material_internal_field.hh
index 2224f241d..704e1f8b6 100644
--- a/extra_packages/igfem/src/dumper_igfem_material_internal_field.hh
+++ b/extra_packages/igfem/src/dumper_igfem_material_internal_field.hh
@@ -1,58 +1,54 @@
/**
* @file dumper_igfem_material_internal_field.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief description of IGFEM material internal field
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#ifndef __AKANTU_DUMPER_IGFEM_MATERIAL_INTERNAL_FIELD_HH__
#define __AKANTU_DUMPER_IGFEM_MATERIAL_INTERNAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_igfem_quadrature_points_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template<typename T, bool filtered = false>
+template <typename T, bool filtered = false>
class IGFEMInternalMaterialField
- : public IGFEMGenericElementalField<SingleType<T,Vector,filtered>,
- igfem_quadrature_point_iterator> {
+ : public IGFEMGenericElementalField<SingleType<T, Vector, filtered>,
+ igfem_quadrature_point_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
-
- typedef SingleType<T,Vector,filtered> types;
- typedef IGFEMGenericElementalField<types,igfem_quadrature_point_iterator> parent;
+ typedef SingleType<T, Vector, filtered> types;
+ typedef IGFEMGenericElementalField<types, igfem_quadrature_point_iterator>
+ parent;
typedef typename types::field_type field_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
IGFEMInternalMaterialField(const field_type & field,
- UInt spatial_dimension = _all_dimensions,
- GhostType ghost_type = _not_ghost,
- ElementKind kind =_ek_igfem) :
- parent(field, spatial_dimension, ghost_type, kind){}
-
-
+ UInt spatial_dimension = _all_dimensions,
+ GhostType ghost_type = _not_ghost,
+ ElementKind kind = _ek_igfem)
+ : parent(field, spatial_dimension, ghost_type, kind) {}
};
-
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_IGFEM_MATERIAL_INTERNAL_FIELD_HH__ */
diff --git a/extra_packages/igfem/src/dumper_igfem_quadrature_points_field.hh b/extra_packages/igfem/src/dumper_igfem_quadrature_points_field.hh
index 6b1f936b4..918e611ad 100644
--- a/extra_packages/igfem/src/dumper_igfem_quadrature_points_field.hh
+++ b/extra_packages/igfem/src/dumper_igfem_quadrature_points_field.hh
@@ -1,132 +1,141 @@
/**
* @file dumper_igfem_quadrature_points_field.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief description of IGFEM quadrature points field
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#ifndef __AKANTU_DUMPER_IGFEM_QUADRATURE_POINTS_FIELD_HH__
#define __AKANTU_DUMPER_IGFEM_QUADRATURE_POINTS_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_igfem_elemental_field.hh"
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template<typename types>
+template <typename types>
class igfem_quadrature_point_iterator
- : public igfem_element_iterator<types, igfem_quadrature_point_iterator> {
+ : public igfem_element_iterator<types, igfem_quadrature_point_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
-
- typedef igfem_element_iterator<types, dumper::igfem_quadrature_point_iterator> parent;
- typedef typename types::data_type data_type;
+ typedef igfem_element_iterator<types, dumper::igfem_quadrature_point_iterator>
+ parent;
+ typedef typename types::data_type data_type;
typedef typename types::return_type return_type;
- typedef typename types::field_type field_type;
+ typedef typename types::field_type field_type;
typedef typename types::array_iterator array_iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- igfem_quadrature_point_iterator(const field_type & field,
- const typename field_type::type_iterator & t_it,
- const typename field_type::type_iterator & t_it_end,
- const array_iterator & array_it,
- const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost,
- UInt sub_element = 0) :
- parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type, sub_element) { }
+ igfem_quadrature_point_iterator(
+ const field_type & field, const typename field_type::type_iterator & t_it,
+ const typename field_type::type_iterator & t_it_end,
+ const array_iterator & array_it, const array_iterator & array_it_end,
+ const GhostType ghost_type = _not_ghost, UInt sub_element = 0)
+ : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type,
+ sub_element) {}
return_type operator*() {
const Vector<data_type> & mat_internal_field = *this->array_it;
/// get nb data per sub element
- UInt nb_sub_1_internal_points = IGFEMHelper::getNbQuadraturePoints(*this->tit, 0);
- UInt nb_sub_2_internal_points = IGFEMHelper::getNbQuadraturePoints(*this->tit, 1);
-
- UInt nb_data = this->getNbDataPerElem(*(this->tit)) / (nb_sub_1_internal_points + nb_sub_2_internal_points);
+ UInt nb_sub_1_internal_points =
+ IGFEMHelper::getNbQuadraturePoints(*this->tit, 0);
+ UInt nb_sub_2_internal_points =
+ IGFEMHelper::getNbQuadraturePoints(*this->tit, 1);
+
+ UInt nb_data = this->getNbDataPerElem(*(this->tit)) /
+ (nb_sub_1_internal_points + nb_sub_2_internal_points);
UInt nb_sub_components = 0;
if (!(this->sub_element))
nb_sub_components = nb_data * nb_sub_1_internal_points;
else
nb_sub_components = nb_data * nb_sub_2_internal_points;
-
+
Vector<data_type> sub_mat_internal_field(nb_sub_components);
if (!(this->sub_element)) {
- for (UInt i = 0; i < nb_sub_components; ++i)
- sub_mat_internal_field(i) = mat_internal_field(i);
- }
- else {
- for (UInt i = 0; i < nb_sub_components; ++i)
- sub_mat_internal_field(i) = mat_internal_field(nb_data *nb_sub_1_internal_points + i);
+ for (UInt i = 0; i < nb_sub_components; ++i)
+ sub_mat_internal_field(i) = mat_internal_field(i);
+ } else {
+ for (UInt i = 0; i < nb_sub_components; ++i)
+ sub_mat_internal_field(i) =
+ mat_internal_field(nb_data * nb_sub_1_internal_points + i);
}
return sub_mat_internal_field;
}
};
- // /* -------------------------------------------------------------------------- */
- // /* Fields type description */
- // /* -------------------------------------------------------------------------- */
- // template<class types, template <class> class iterator_type>
- // class GenericQuadraturePointsField :
- // public GenericElementalField<types,iterator_type> {
-
- // public:
-
- // /* ------------------------------------------------------------------------ */
- // /* Typedefs */
- // /* ------------------------------------------------------------------------ */
-
-
- // typedef iterator_type<types> iterator;
- // typedef typename types::field_type field_type;
- // typedef typename iterator::it_type T;
- // typedef GenericElementalField<types,iterator_type> parent;
-
- // /* ------------------------------------------------------------------------ */
- // /* Constructors/Destructors */
- // /* ------------------------------------------------------------------------ */
-
- // GenericQuadraturePointsField(const field_type & field,
- // UInt spatial_dimension = _all_dimensions,
- // GhostType ghost_type = _not_ghost,
- // ElementKind element_kind = _ek_not_defined) :
- // parent(field, spatial_dimension, ghost_type, element_kind) { }
-
- // /* ------------------------------------------------------------------------ */
- // /* Methods */
- // /* ------------------------------------------------------------------------ */
-
- // virtual iterator begin() {
- // iterator it = parent::begin();
- // return it;
- // }
-
- // virtual iterator end () {
- // iterator it = parent::end();
- // return it;
- // }
-
- // };
+// /* --------------------------------------------------------------------------
+// */
+// /* Fields type description */
+// /* --------------------------------------------------------------------------
+// */
+// template<class types, template <class> class iterator_type>
+// class GenericQuadraturePointsField :
+// public GenericElementalField<types,iterator_type> {
+
+// public:
+
+// /* ------------------------------------------------------------------------
+// */
+// /* Typedefs */
+// /* ------------------------------------------------------------------------
+// */
+
+// typedef iterator_type<types> iterator;
+// typedef typename types::field_type field_type;
+// typedef typename iterator::it_type T;
+// typedef GenericElementalField<types,iterator_type> parent;
+
+// /* ------------------------------------------------------------------------
+// */
+// /* Constructors/Destructors */
+// /* ------------------------------------------------------------------------
+// */
+
+// GenericQuadraturePointsField(const field_type & field,
+// UInt spatial_dimension = _all_dimensions,
+// GhostType ghost_type = _not_ghost,
+// ElementKind element_kind = _ek_not_defined) :
+// parent(field, spatial_dimension, ghost_type, element_kind) { }
+
+// /* ------------------------------------------------------------------------
+// */
+// /* Methods */
+// /* ------------------------------------------------------------------------
+// */
+
+// virtual iterator begin() {
+// iterator it = parent::begin();
+// return it;
+// }
+
+// virtual iterator end () {
+// iterator it = parent::end();
+// return it;
+// }
+
+// };
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_IGFEM_QUADRATURE_POINTS_FIELD_HH__ */
diff --git a/extra_packages/igfem/src/element_class_igfem.cc b/extra_packages/igfem/src/element_class_igfem.cc
index 892906335..3a3b27af6 100644
--- a/extra_packages/igfem/src/element_class_igfem.cc
+++ b/extra_packages/igfem/src/element_class_igfem.cc
@@ -1,56 +1,69 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Specialization for interface-enriched finite elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// #include "element_class.hh"
// __BEGIN_AKANTU__
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// template<> UInt ElementClass<_igfem_segment_3>::nb_sub_elements = 2;
// template<> UInt ElementClass<_igfem_triangle_4>::nb_sub_elements = 2;
// template<> UInt ElementClass<_igfem_triangle_5>::nb_sub_elements = 2;
-// /* !!! stored as a matrix nb_subelements X nb_nodes_per_subelement in COL MAJOR */
-// /* -------------------------------------------------------------------------- */
-// template<> UInt ElementClass<_igfem_segment_3>::sub_element_connectivity_vect[] = { 0, // first type
+// /* !!! stored as a matrix nb_subelements X nb_nodes_per_subelement in COL
+// MAJOR */
+// /* --------------------------------------------------------------------------
+// */
+// template<> UInt
+// ElementClass<_igfem_segment_3>::sub_element_connectivity_vect[] = { 0, //
+// first type
// 2,
// 2, // second type
// 1};
-// template<> UInt ElementClass<_igfem_triangle_4>::sub_element_connectivity_vect[] = { 0, // first type
+// template<> UInt
+// ElementClass<_igfem_triangle_4>::sub_element_connectivity_vect[] = { 0, //
+// first type
// 1,
// 3,
// 0, // second type
// 3,
// 2};
-// template<> UInt ElementClass<_igfem_triangle_5>::sub_element_connectivity_vect[] = { 0, // first type
-// 3,
-// 4,
+// template<> UInt
+// ElementClass<_igfem_triangle_5>::sub_element_connectivity_vect[] = { 0, //
+// first type
+// 3,
+// 4,
// 3, // second type
-// 1,
-// 2,
+// 1,
+// 2,
// 4};
-// template<> UInt * ElementClass<_igfem_segment_3>::sub_element_connectivity[] = { &sub_element_connectivity_vect[0],
+// template<> UInt * ElementClass<_igfem_segment_3>::sub_element_connectivity[]
+// = { &sub_element_connectivity_vect[0],
// &sub_element_connectivity_vect[2] };
-// template<> UInt * ElementClass<_igfem_triangle_4>::sub_element_connectivity[] = { &sub_element_connectivity_vect[0],
+// template<> UInt * ElementClass<_igfem_triangle_4>::sub_element_connectivity[]
+// = { &sub_element_connectivity_vect[0],
// &sub_element_connectivity_vect[3] };
-// template<> UInt * ElementClass<_igfem_triangle_5>::sub_element_connectivity[] = { &sub_element_connectivity_vect[0],
+// template<> UInt * ElementClass<_igfem_triangle_5>::sub_element_connectivity[]
+// = { &sub_element_connectivity_vect[0],
// &sub_element_connectivity_vect[3] };
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// __END_AKANTU__
diff --git a/extra_packages/igfem/src/element_class_igfem.hh b/extra_packages/igfem/src/element_class_igfem.hh
index c9e55881e..4b197cf56 100644
--- a/extra_packages/igfem/src/element_class_igfem.hh
+++ b/extra_packages/igfem/src/element_class_igfem.hh
@@ -1,277 +1,339 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Specialization for interface-enriched finite elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#include "aka_common.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-#define AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY(itp_type, \
- itp_kind, \
- nb_nodes, \
- ndim, \
- parent_itp_type, \
- sub_itp_type_1, \
- sub_itp_type_2) \
- template<> \
- struct InterpolationPorperty<itp_type> { \
- static const InterpolationKind kind = itp_kind; \
- static const UInt nb_nodes_per_element = nb_nodes; \
- static const UInt natural_space_dimension = ndim; \
- static const InterpolationType parent_interpolation_type = parent_itp_type; \
- static const InterpolationType sub_iterpolation_type_1 = sub_itp_type_1; \
- static const InterpolationType sub_interpolation_type_2 = sub_itp_type_2; \
+#define AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY( \
+ itp_type, itp_kind, nb_nodes, ndim, parent_itp_type, sub_itp_type_1, \
+ sub_itp_type_2) \
+ template <> struct InterpolationPorperty<itp_type> { \
+ static const InterpolationKind kind = itp_kind; \
+ static const UInt nb_nodes_per_element = nb_nodes; \
+ static const UInt natural_space_dimension = ndim; \
+ static const InterpolationType parent_interpolation_type = \
+ parent_itp_type; \
+ static const InterpolationType sub_iterpolation_type_1 = sub_itp_type_1; \
+ static const InterpolationType sub_interpolation_type_2 = sub_itp_type_2; \
}
/* -------------------------------------------------------------------------- */
-template<InterpolationType interpolation_type>
+template <InterpolationType interpolation_type>
class InterpolationElement<interpolation_type, _itk_igfem> {
public:
typedef InterpolationPorperty<interpolation_type> interpolation_property;
-/* -------------------------------------------------------------------------- */
-/* Member functions */
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Member functions */
+ /* --------------------------------------------------------------------------
+ */
public:
- static void assembleShapes(const Vector<Real> & parent_interpolation, const Vector<Real> & sub_interpolation, Vector<Real> & interpolation, UInt sub_element = 0) {
+ static void assembleShapes(const Vector<Real> & parent_interpolation,
+ const Vector<Real> & sub_interpolation,
+ Vector<Real> & interpolation,
+ UInt sub_element = 0) {
/// N1, N2, N3 of parent triangle
- UInt nb_nodes_parent = InterpolationElement<interpolation_property::parent_interpolation_type>::getShapeSize();
+ UInt nb_nodes_parent = InterpolationElement<
+ interpolation_property::parent_interpolation_type>::getShapeSize();
for (UInt i = 0; i < nb_nodes_parent; ++i) {
interpolation(i) = parent_interpolation(i);
}
/// add the enrichment
UInt * enriched_node = enrichments[sub_element];
for (UInt e = 0; e < nb_enrichments; ++e) {
interpolation(nb_nodes_parent + e) = sub_interpolation(enriched_node[e]);
}
}
- static void assembleShapeDerivatives(const Matrix<Real> & parent_interpolation, const Matrix<Real> & sub_interpolation, Matrix<Real> & interpolation, UInt sub_element = 0) {
+ static void
+ assembleShapeDerivatives(const Matrix<Real> & parent_interpolation,
+ const Matrix<Real> & sub_interpolation,
+ Matrix<Real> & interpolation, UInt sub_element = 0) {
/// N1, N2, N3 of parent triangle
- UInt nb_nodes_parent = InterpolationElement<interpolation_property::parent_interpolation_type>::getShapeSize();
-
+ UInt nb_nodes_parent = InterpolationElement<
+ interpolation_property::parent_interpolation_type>::getShapeSize();
+
for (UInt i = 0; i < nb_nodes_parent; ++i) {
Vector<Real> ip(interpolation(i));
ip = parent_interpolation(i);
}
/// add the enrichment
UInt * enriched_node = enrichments[sub_element];
for (UInt e = 0; e < nb_enrichments; ++e) {
Vector<Real> ip(interpolation(nb_nodes_parent + e));
ip = sub_interpolation(enriched_node[e]);
}
}
static void interpolate(const Matrix<Real> & nodal_values,
- const Vector<Real> & shapes,
- Vector<Real> & interpolated) {
+ const Vector<Real> & shapes,
+ Vector<Real> & interpolated) {
Matrix<Real> interpm(interpolated.storage(), nodal_values.rows(), 1);
- Matrix<Real> shapesm(shapes.storage(), InterpolationPorperty<interpolation_type>::nb_nodes_per_element, 1);
+ Matrix<Real> shapesm(
+ shapes.storage(),
+ InterpolationPorperty<interpolation_type>::nb_nodes_per_element, 1);
interpm.mul<false, false>(nodal_values, shapesm);
}
public:
- static AKANTU_GET_MACRO_NOT_CONST(ShapeSize, interpolation_property::nb_nodes_per_element, UInt);
- static AKANTU_GET_MACRO_NOT_CONST(ShapeDerivativesSize, (interpolation_property::nb_nodes_per_element * interpolation_property::natural_space_dimension), UInt);
- static AKANTU_GET_MACRO_NOT_CONST(NaturalSpaceDimension, interpolation_property::natural_space_dimension, UInt);
- static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerInterpolationElement, InterpolationPorperty<interpolation_type>::nb_nodes_per_element, UInt);
+ static AKANTU_GET_MACRO_NOT_CONST(
+ ShapeSize, interpolation_property::nb_nodes_per_element, UInt);
+ static AKANTU_GET_MACRO_NOT_CONST(
+ ShapeDerivativesSize, (interpolation_property::nb_nodes_per_element *
+ interpolation_property::natural_space_dimension),
+ UInt);
+ static AKANTU_GET_MACRO_NOT_CONST(
+ NaturalSpaceDimension, interpolation_property::natural_space_dimension,
+ UInt);
+ static AKANTU_GET_MACRO_NOT_CONST(
+ NbNodesPerInterpolationElement,
+ InterpolationPorperty<interpolation_type>::nb_nodes_per_element, UInt);
static AKANTU_GET_MACRO_NOT_CONST(NbSubElements, nb_sub_elements, UInt);
- static UInt * getSubElementConnectivity(UInt t = 0) {return sub_element_connectivity[t];};
- static UInt getNbEnrichments() {return nb_enrichments;};
- static UInt * getSubElementEnrichments(UInt t = 0) {return enrichments[t];};
-
+ static UInt * getSubElementConnectivity(UInt t = 0) {
+ return sub_element_connectivity[t];
+ };
+ static UInt getNbEnrichments() { return nb_enrichments; };
+ static UInt * getSubElementEnrichments(UInt t = 0) { return enrichments[t]; };
protected:
/// storage of the subelement local connectivity
static UInt sub_element_connectivity_vect[];
/// local connectivity of subelements
static UInt * sub_element_connectivity[];
/// nb of subelements
static UInt nb_sub_elements;
/// storage of enrichments
static UInt enrichment_vect[];
static UInt * enrichments[];
static UInt nb_enrichments;
};
#if defined(AKANTU_IGFEM)
-# include "interpolation_element_igfem_tmpl.hh"
+#include "interpolation_element_igfem_tmpl.hh"
#endif
/* -------------------------------------------------------------------------- */
-#define AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY(elem_type, \
- geom_type, \
- interp_type, \
- parent_el_type, \
- sub_el_type_1, \
- sub_el_type_2, \
- elem_kind, \
- sp, \
- min_int_order) \
- template<> \
- struct ElementClassProperty<elem_type> { \
- static const GeometricalType geometrical_type = geom_type; \
- static const InterpolationType interpolation_type = interp_type; \
- static const ElementType parent_element_type = parent_el_type; \
- static const ElementType sub_element_type_1 = sub_el_type_1; \
- static const ElementType sub_element_type_2 = sub_el_type_2; \
- static const ElementKind element_kind = elem_kind; \
- static const UInt spatial_dimension = sp; \
- static const UInt minimal_integration_order = min_int_order; \
+#define AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY( \
+ elem_type, geom_type, interp_type, parent_el_type, sub_el_type_1, \
+ sub_el_type_2, elem_kind, sp, min_int_order) \
+ template <> struct ElementClassProperty<elem_type> { \
+ static const GeometricalType geometrical_type = geom_type; \
+ static const InterpolationType interpolation_type = interp_type; \
+ static const ElementType parent_element_type = parent_el_type; \
+ static const ElementType sub_element_type_1 = sub_el_type_1; \
+ static const ElementType sub_element_type_2 = sub_el_type_2; \
+ static const ElementKind element_kind = elem_kind; \
+ static const UInt spatial_dimension = sp; \
+ static const UInt minimal_integration_order = min_int_order; \
}
-
/* -------------------------------------------------------------------------- */
// // template <ElementType type, UInt sub_element>
// struct return_sub_element_type {
// enum { value = _not_defined };
// };
// /// specializations
// template<ElementType type>
// struct return_sub_element_type<type, 0> {
// enum { value = ElementClassProperty<type>::sub_element_type_1 };
// };
// template<ElementType type>
// struct return_sub_element_type<type, 1> {
// enum { value = ElementClassProperty<type>::sub_element_type_2 };
// };
/* -------------------------------------------------------------------------- */
-template<ElementType element_type>
-class ElementClass<element_type, _ek_igfem> :
- public GeometricalElement<ElementClassProperty<element_type>::geometrical_type>,
- public InterpolationElement<ElementClassProperty<element_type>::interpolation_type> {
+template <ElementType element_type>
+class ElementClass<element_type, _ek_igfem>
+ : public GeometricalElement<
+ ElementClassProperty<element_type>::geometrical_type>,
+ public InterpolationElement<
+ ElementClassProperty<element_type>::interpolation_type> {
protected:
- typedef GeometricalElement<ElementClassProperty<element_type>::geometrical_type> geometrical_element;
- typedef InterpolationElement<ElementClassProperty<element_type>::interpolation_type> interpolation_element;
- typedef ElementClass<ElementClassProperty<element_type>::parent_element_type> parent_element;
+ typedef GeometricalElement<
+ ElementClassProperty<element_type>::geometrical_type>
+ geometrical_element;
+ typedef InterpolationElement<
+ ElementClassProperty<element_type>::interpolation_type>
+ interpolation_element;
+ typedef ElementClass<ElementClassProperty<element_type>::parent_element_type>
+ parent_element;
typedef ElementClassProperty<element_type> element_property;
- typedef typename interpolation_element::interpolation_property interpolation_property;
-
-/* -------------------------------------------------------------------------- */
-/* Member functions */
-/* -------------------------------------------------------------------------- */
+ typedef typename interpolation_element::interpolation_property
+ interpolation_property;
+
+ /* --------------------------------------------------------------------------
+ */
+ /* Member functions */
+ /* --------------------------------------------------------------------------
+ */
public:
// static const ElementType getSubElementType(const UInt sub_element) {
// switch(sub_element) {
// case 0: return return_sub_element_type<element_type, 0>(); break;
// case 1: return return_sub_element_type<element_type, 1>(); break;
// default: return _not_defined;
// }
// }
-
-
- static void getSubElementCoords(const Matrix<Real> & element_coords, Matrix<Real> & sub_coords,
- const UInt sub_element) {
+ static void getSubElementCoords(const Matrix<Real> & element_coords,
+ Matrix<Real> & sub_coords,
+ const UInt sub_element) {
/// get the sub_element_type
/// constexrp ElementType sub_el_type = getSubElementType(sub_element);
UInt nb_nodes_sub_el = 0;
- switch (sub_element){
- case 0: nb_nodes_sub_el = ElementClass<ElementClassProperty<element_type>::sub_element_type_1>::getNbNodesPerInterpolationElement(); break;
- case 1: nb_nodes_sub_el = ElementClass<ElementClassProperty<element_type>::sub_element_type_2>::getNbNodesPerInterpolationElement(); break;
+ switch (sub_element) {
+ case 0:
+ nb_nodes_sub_el =
+ ElementClass<ElementClassProperty<element_type>::sub_element_type_1>::
+ getNbNodesPerInterpolationElement();
+ break;
+ case 1:
+ nb_nodes_sub_el =
+ ElementClass<ElementClassProperty<element_type>::sub_element_type_2>::
+ getNbNodesPerInterpolationElement();
+ break;
}
for (UInt i = 0; i < nb_nodes_sub_el; ++i) {
- UInt lc = InterpolationElement<ElementClassProperty<element_type>::interpolation_type>::sub_element_connectivity[sub_element][i];
+ UInt lc = InterpolationElement<
+ ElementClassProperty<element_type>::interpolation_type>::
+ sub_element_connectivity[sub_element][i];
Vector<Real> sub_c(sub_coords(i));
sub_c = element_coords(lc);
- }
+ }
}
- static void getParentCoords(const Matrix<Real> & element_coords, Matrix<Real> & parent_coords) {
- const ElementType parent_type = ElementClassProperty<element_type>::parent_element_type;
- UInt nb_nodes_parent_el = ElementClass<parent_type>::getNbNodesPerInterpolationElement();
+ static void getParentCoords(const Matrix<Real> & element_coords,
+ Matrix<Real> & parent_coords) {
+ const ElementType parent_type =
+ ElementClassProperty<element_type>::parent_element_type;
+ UInt nb_nodes_parent_el =
+ ElementClass<parent_type>::getNbNodesPerInterpolationElement();
for (UInt i = 0; i < nb_nodes_parent_el; ++i) {
Vector<Real> parent_c(parent_coords(i));
parent_c = element_coords(i);
- }
- }
+ }
+ }
- /// map the points from the reference domain of the subelement to the physical domain
- static void mapToPhysicalDomain(const Matrix<Real> & element_coords, Matrix<Real> & sub_coords, Matrix<Real> & sub_shapes, Matrix<Real> & physical_points, UInt sub_element = 0) {
+ /// map the points from the reference domain of the subelement to the physical
+ /// domain
+ static void mapToPhysicalDomain(const Matrix<Real> & element_coords,
+ Matrix<Real> & sub_coords,
+ Matrix<Real> & sub_shapes,
+ Matrix<Real> & physical_points,
+ UInt sub_element = 0) {
/// get the sub_element_type
-
+
getSubElementCoords(element_coords, sub_coords, sub_element);
- /// map the points of the subelements in the physical domain
- switch (sub_element){
- case 0: ElementClass<ElementClassProperty<element_type>::sub_element_type_1>::interpolate(sub_coords, sub_shapes, physical_points); break;
- case 1: ElementClass<ElementClassProperty<element_type>::sub_element_type_2>::interpolate(sub_coords, sub_shapes, physical_points); break;
- }
-
+ /// map the points of the subelements in the physical domain
+ switch (sub_element) {
+ case 0:
+ ElementClass<ElementClassProperty<element_type>::sub_element_type_1>::
+ interpolate(sub_coords, sub_shapes, physical_points);
+ break;
+ case 1:
+ ElementClass<ElementClassProperty<element_type>::sub_element_type_2>::
+ interpolate(sub_coords, sub_shapes, physical_points);
+ break;
+ }
}
/// map the points from the physical domain to the parent reference domain
- static void mapToParentRefDomain(const Matrix<Real> & element_coords, Matrix<Real> & parent_coords, Matrix<Real> & physical_points, Matrix<Real> & natural_coords) {
- const ElementType parent_type = ElementClassProperty<element_type>::parent_element_type;
+ static void mapToParentRefDomain(const Matrix<Real> & element_coords,
+ Matrix<Real> & parent_coords,
+ Matrix<Real> & physical_points,
+ Matrix<Real> & natural_coords) {
+ const ElementType parent_type =
+ ElementClassProperty<element_type>::parent_element_type;
getParentCoords(element_coords, parent_coords);
- /// map the points from the physical domain into the parent reference domain
- ElementClass<parent_type>::inverseMap(physical_points,
- parent_coords,
- natural_coords);
-
+ /// map the points from the physical domain into the parent reference domain
+ ElementClass<parent_type>::inverseMap(physical_points, parent_coords,
+ natural_coords);
}
- /// map the points from the subelement reference domain to the parent reference domain
- static void mapFromSubRefToParentRef(const Matrix<Real> & element_coords, Matrix<Real> & parent_coords, Matrix<Real> & sub_coords, Matrix<Real> & sub_shapes, Matrix<Real> & physical_points, Matrix<Real> & natural_points, UInt nb_points, UInt sub_element) {
- mapToPhysicalDomain(element_coords, sub_coords, sub_shapes, physical_points, sub_element);
- mapToParentRefDomain(element_coords, parent_coords, physical_points, natural_points);
+ /// map the points from the subelement reference domain to the parent
+ /// reference domain
+ static void mapFromSubRefToParentRef(const Matrix<Real> & element_coords,
+ Matrix<Real> & parent_coords,
+ Matrix<Real> & sub_coords,
+ Matrix<Real> & sub_shapes,
+ Matrix<Real> & physical_points,
+ Matrix<Real> & natural_points,
+ UInt nb_points, UInt sub_element) {
+ mapToPhysicalDomain(element_coords, sub_coords, sub_shapes, physical_points,
+ sub_element);
+ mapToParentRefDomain(element_coords, parent_coords, physical_points,
+ natural_points);
}
- static void mapFromSubRefToParentRef(const Matrix<Real> & element_coords, Matrix<Real> & sub_coords, Matrix<Real> & parent_coords, Matrix<Real> & sub_shapes, Matrix<Real> & physical_points, Matrix<Real> & parent_el_natural_coords, UInt sub_element) {
- mapToPhysicalDomain(element_coords, sub_coords, sub_shapes, physical_points, sub_element);
- mapToParentRefDomain(element_coords, parent_coords, physical_points, parent_el_natural_coords);
+ static void mapFromSubRefToParentRef(const Matrix<Real> & element_coords,
+ Matrix<Real> & sub_coords,
+ Matrix<Real> & parent_coords,
+ Matrix<Real> & sub_shapes,
+ Matrix<Real> & physical_points,
+ Matrix<Real> & parent_el_natural_coords,
+ UInt sub_element) {
+ mapToPhysicalDomain(element_coords, sub_coords, sub_shapes, physical_points,
+ sub_element);
+ mapToParentRefDomain(element_coords, parent_coords, physical_points,
+ parent_el_natural_coords);
}
/// compute the normal of a surface defined by the function f
- static inline void computeNormalsOnNaturalCoordinates(const Matrix<Real> & coord,
- Matrix<Real> & f,
- Matrix<Real> & normals) {
+ static inline void
+ computeNormalsOnNaturalCoordinates(const Matrix<Real> & coord,
+ Matrix<Real> & f, Matrix<Real> & normals) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// determine orientation of the element with respect to the interface
static inline UInt getOrientation(const Vector<bool> & is_inside);
-
-
-/* -------------------------------------------------------------------------- */
-/* Accessors */
-/* -------------------------------------------------------------------------- */
+
+ /* --------------------------------------------------------------------------
+ */
+ /* Accessors */
+ /* --------------------------------------------------------------------------
+ */
public:
static AKANTU_GET_MACRO_NOT_CONST(Kind, _ek_igfem, ElementKind);
- static ElementType getP1ElementType(){AKANTU_DEBUG_TO_IMPLEMENT();};
- static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension, ElementClassProperty<element_type>::spatial_dimension, UInt);
+ static ElementType getP1ElementType() { AKANTU_DEBUG_TO_IMPLEMENT(); };
+ static AKANTU_GET_MACRO_NOT_CONST(
+ SpatialDimension, ElementClassProperty<element_type>::spatial_dimension,
+ UInt);
static ElementType & getFacetType(UInt t = 0) { AKANTU_DEBUG_TO_IMPLEMENT(); }
static ElementType * getFacetTypeInternal() { AKANTU_DEBUG_TO_IMPLEMENT(); }
+
private:
/// Type of the facet elements
/// static ElementType facet_type[];
/// type of element P1 associated
/// static ElementType p1_type;
-
-
};
#include "element_classes_igfem/element_class_igfem_segment_3_inline_impl.cc"
#include "element_classes_igfem/element_class_igfem_triangle_4_inline_impl.cc"
#include "element_classes_igfem/element_class_igfem_triangle_5_inline_impl.cc"
__END_AKANTU__
diff --git a/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_segment_3_inline_impl.cc b/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_segment_3_inline_impl.cc
index 4a8e66838..c7bb6b895 100644
--- a/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_segment_3_inline_impl.cc
+++ b/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_segment_3_inline_impl.cc
@@ -1,99 +1,93 @@
/**
* @file element_class_igfem_triangle_5_inline_impl.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Tue May 5 14:57:51 2015
*
* @brief Specialization of the element_class class for the type
* _igfem_triangle_5
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*
* @section DESCRIPTION
*
* @verbatim
\eta
- ^
- |
- x (0,0,1)
- |`
- | `
- |` q `
- | ` ° `
- x--------x-----> \xi
+ ^
+ |
+ x (0,0,1)
+ |`
+ | `
+ |` q `
+ | ` ° `
+ x--------x-----> \xi
(1,0,0) (0,1,0)
@endverbatim
*
* @subsection shapes shape functions
* Parent:
* @f{eqnarray*}{
* N1 &=& 1 - \xi - \eta \\
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
* Sub 1:
* @f{eqnarray*}{
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
* Sub 2:
* @f[
* \begin{array}{lll}
* N3 = (1 + \xi) (1 + \eta) / 4 \\
* & \frac{\partial N3}{\partial \xi} = (1 + \eta) / 4
* & \frac{\partial N3}{\partial \eta} = (1 + \xi) / 4 \\
* N4 = (1 - \xi) (1 + \eta) / 4
* & \frac{\partial N4}{\partial \xi} = - (1 + \eta) / 4
* & \frac{\partial N4}{\partial \eta} = (1 - \xi) / 4 \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 1/3 \qquad \eta_{q0} = 1/3
* @f}
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY(_igfem_segment_3, \
- _gt_igfem_segment_3, \
- _itp_igfem_segment_3, \
- _segment_2, \
- _segment_2, \
- _segment_2, \
- _ek_igfem, \
- 1, \
- 1);
+AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY(_igfem_segment_3,
+ _gt_igfem_segment_3,
+ _itp_igfem_segment_3, _segment_2,
+ _segment_2, _segment_2, _ek_igfem, 1,
+ 1);
/* -------------------------------------------------------------------------- */
-template<>
-inline UInt ElementClass<_igfem_segment_3>::getOrientation(const Vector<bool> & is_inside) {
+template <>
+inline UInt
+ElementClass<_igfem_segment_3>::getOrientation(const Vector<bool> & is_inside) {
UInt sub_el_is_inside = false;
if (is_inside(0)) {
sub_el_is_inside = true;
- AKANTU_DEBUG_ASSERT(!is_inside(1),
- "orientation not determinable");
- }
- else
- AKANTU_DEBUG_ASSERT(is_inside(2),
- "orientation not determinable");
+ AKANTU_DEBUG_ASSERT(!is_inside(1), "orientation not determinable");
+ } else
+ AKANTU_DEBUG_ASSERT(is_inside(2), "orientation not determinable");
return sub_el_is_inside;
}
diff --git a/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_4_inline_impl.cc b/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_4_inline_impl.cc
index c32f9fc4b..3b3130a3a 100644
--- a/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_4_inline_impl.cc
+++ b/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_4_inline_impl.cc
@@ -1,103 +1,98 @@
/**
* @file element_class_igfem_triangle_5_inline_impl.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Tue May 5 14:57:51 2015
*
* @brief Specialization of the element_class class for the type
* _igfem_triangle_5
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*
* @section DESCRIPTION
*
* @verbatim
\eta
- ^
- |
- x (0,0,1)
- |`
- | `
- |` q `
- | ` ° `
- x--------x-----> \xi
+ ^
+ |
+ x (0,0,1)
+ |`
+ | `
+ |` q `
+ | ` ° `
+ x--------x-----> \xi
(1,0,0) (0,1,0)
@endverbatim
*
* @subsection shapes shape functions
* Parent:
* @f{eqnarray*}{
* N1 &=& 1 - \xi - \eta \\
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
* Sub 1:
* @f{eqnarray*}{
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
* Sub 2:
* @f[
* \begin{array}{lll}
* N3 = (1 + \xi) (1 + \eta) / 4 \\
* & \frac{\partial N3}{\partial \xi} = (1 + \eta) / 4
* & \frac{\partial N3}{\partial \eta} = (1 + \xi) / 4 \\
* N4 = (1 - \xi) (1 + \eta) / 4
* & \frac{\partial N4}{\partial \xi} = - (1 + \eta) / 4
* & \frac{\partial N4}{\partial \eta} = (1 - \xi) / 4 \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 1/3 \qquad \eta_{q0} = 1/3
* @f}
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY(_igfem_triangle_4, \
- _gt_igfem_triangle_4, \
- _itp_igfem_triangle_4, \
- _triangle_3, \
- _triangle_3, \
- _triangle_3, \
- _ek_igfem, \
- 2, \
- 1);
+AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY(_igfem_triangle_4,
+ _gt_igfem_triangle_4,
+ _itp_igfem_triangle_4, _triangle_3,
+ _triangle_3, _triangle_3, _ek_igfem,
+ 2, 1);
/* -------------------------------------------------------------------------- */
-template<>
-inline UInt ElementClass<_igfem_triangle_4>::getOrientation(const Vector<bool> & is_inside) {
+template <>
+inline UInt ElementClass<_igfem_triangle_4>::getOrientation(
+ const Vector<bool> & is_inside) {
UInt orientation = 0;
- if (is_inside(1) && !is_inside(2))
+ if (is_inside(1) && !is_inside(2))
orientation = 0;
-
- else if (!is_inside(1) && is_inside(2))
+
+ else if (!is_inside(1) && is_inside(2))
orientation = 1;
-
- else if (is_inside(1) && is_inside(2))
+ else if (is_inside(1) && is_inside(2))
orientation = 2;
-
- else if (!is_inside(1) && !is_inside(2))
+ else if (!is_inside(1) && !is_inside(2))
orientation = 3;
-
+
return orientation;
}
diff --git a/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_5_inline_impl.cc b/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_5_inline_impl.cc
index bb7c02794..c0ba76910 100644
--- a/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_5_inline_impl.cc
+++ b/extra_packages/igfem/src/element_classes_igfem/element_class_igfem_triangle_5_inline_impl.cc
@@ -1,101 +1,96 @@
/**
* @file element_class_igfem_triangle_5_inline_impl.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Tue May 5 14:57:51 2015
*
* @brief Specialization of the element_class class for the type
* _igfem_triangle_5
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*
* @section DESCRIPTION
*
* @verbatim
\eta
- ^
- |
- x (0,0,1)
- |`
- | `
- |` q `
- | ` ° `
- x--------x-----> \xi
+ ^
+ |
+ x (0,0,1)
+ |`
+ | `
+ |` q `
+ | ` ° `
+ x--------x-----> \xi
(1,0,0) (0,1,0)
@endverbatim
*
* @subsection shapes shape functions
* Parent:
* @f{eqnarray*}{
* N1 &=& 1 - \xi - \eta \\
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
* Sub 1:
* @f{eqnarray*}{
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
* Sub 2:
* @f[
* \begin{array}{lll}
* N3 = (1 + \xi) (1 + \eta) / 4 \\
* & \frac{\partial N3}{\partial \xi} = (1 + \eta) / 4
* & \frac{\partial N3}{\partial \eta} = (1 + \xi) / 4 \\
* N4 = (1 - \xi) (1 + \eta) / 4
* & \frac{\partial N4}{\partial \xi} = - (1 + \eta) / 4
* & \frac{\partial N4}{\partial \eta} = (1 - \xi) / 4 \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 1/3 \qquad \eta_{q0} = 1/3
* @f}
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY(_igfem_triangle_5, \
- _gt_igfem_triangle_5, \
- _itp_igfem_triangle_5, \
- _triangle_3, \
- _triangle_3, \
- _quadrangle_4, \
- _ek_igfem, \
- 2, \
- 1);
+AKANTU_DEFINE_IGFEM_ELEMENT_CLASS_PROPERTY(_igfem_triangle_5,
+ _gt_igfem_triangle_5,
+ _itp_igfem_triangle_5, _triangle_3,
+ _triangle_3, _quadrangle_4,
+ _ek_igfem, 2, 1);
/* -------------------------------------------------------------------------- */
-template<>
-inline UInt ElementClass<_igfem_triangle_5>::getOrientation(const Vector<bool> & is_inside) {
+template <>
+inline UInt ElementClass<_igfem_triangle_5>::getOrientation(
+ const Vector<bool> & is_inside) {
UInt sub_el_is_inside = 0;
if (is_inside(0)) {
sub_el_is_inside = 0;
- AKANTU_DEBUG_ASSERT(!(is_inside(1) || is_inside(2)) ,
- "orientation not determinable");
- }
- else {
+ AKANTU_DEBUG_ASSERT(!(is_inside(1) || is_inside(2)),
+ "orientation not determinable");
+ } else {
sub_el_is_inside = 1;
- AKANTU_DEBUG_ASSERT((is_inside(2) && is_inside(2)) ,
- "orientation not determinable");
-
+ AKANTU_DEBUG_ASSERT((is_inside(2) && is_inside(2)),
+ "orientation not determinable");
}
return sub_el_is_inside;
}
diff --git a/extra_packages/igfem/src/geometrical_element_igfem.cc b/extra_packages/igfem/src/geometrical_element_igfem.cc
index 8a3541d17..7ed852931 100644
--- a/extra_packages/igfem/src/geometrical_element_igfem.cc
+++ b/extra_packages/igfem/src/geometrical_element_igfem.cc
@@ -1,68 +1,84 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Specialization for interface-enriched finite elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_igfem_segment_3>::spatial_dimension = 1;
-template<> UInt GeometricalElement<_gt_igfem_segment_3>::nb_nodes_per_element = 3;
-template<> UInt GeometricalElement<_gt_igfem_segment_3>::nb_facets[] = { 2 };
+template <> UInt GeometricalElement<_gt_igfem_segment_3>::spatial_dimension = 1;
+template <>
+UInt GeometricalElement<_gt_igfem_segment_3>::nb_nodes_per_element = 3;
+template <> UInt GeometricalElement<_gt_igfem_segment_3>::nb_facets[] = {2};
/* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_igfem_triangle_4>::spatial_dimension = 2;
-template<> UInt GeometricalElement<_gt_igfem_triangle_4>::nb_nodes_per_element = 4;
-template<> UInt GeometricalElement<_gt_igfem_triangle_4>::nb_facets[] = { 3 };
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_4>::spatial_dimension = 2;
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_4>::nb_nodes_per_element = 4;
+template <> UInt GeometricalElement<_gt_igfem_triangle_4>::nb_facets[] = {3};
/* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_igfem_triangle_5>::spatial_dimension = 2;
-template<> UInt GeometricalElement<_gt_igfem_triangle_5>::nb_nodes_per_element = 5;
-template<> UInt GeometricalElement<_gt_igfem_triangle_5>::nb_facets[] = { 3 };
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_5>::spatial_dimension = 2;
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_5>::nb_nodes_per_element = 5;
+template <> UInt GeometricalElement<_gt_igfem_triangle_5>::nb_facets[] = {3};
/* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_igfem_segment_3>::nb_nodes_per_facet[] = { 1 };
-template<> UInt GeometricalElement<_gt_igfem_triangle_4>::nb_nodes_per_facet[] = { 2, 3 };
-template<> UInt GeometricalElement<_gt_igfem_triangle_5>::nb_nodes_per_facet[] = { 2, 3 };
+template <>
+UInt GeometricalElement<_gt_igfem_segment_3>::nb_nodes_per_facet[] = {1};
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_4>::nb_nodes_per_facet[] = {2, 3};
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_5>::nb_nodes_per_facet[] = {2, 3};
/* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_igfem_segment_3>::nb_facet_types = 1;
-template<> UInt GeometricalElement<_gt_igfem_triangle_4>::nb_facet_types = 2;
-template<> UInt GeometricalElement<_gt_igfem_triangle_5>::nb_facet_types = 2;
+template <> UInt GeometricalElement<_gt_igfem_segment_3>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_igfem_triangle_4>::nb_facet_types = 2;
+template <> UInt GeometricalElement<_gt_igfem_triangle_5>::nb_facet_types = 2;
/* !!! stored as a matrix nb_facets X nb_nodes_per_facet in COL MAJOR */
/* -------------------------------------------------------------------------- */
-/* f1|f2|f3|f4|f5|f6 */
-template<> UInt GeometricalElement<_gt_igfem_segment_3>::facet_connectivity_vect[] = {0, 1};
-template<> UInt GeometricalElement<_gt_igfem_triangle_4>::facet_connectivity_vect[] = {// first type
- 0, 2,
- 1, 0,
- // second type
- 1,
- 2,
- 3};
-template<> UInt GeometricalElement<_gt_igfem_triangle_5>::facet_connectivity_vect[] = {// first type
- 1,
- 2,
- // second type
- 0, 2,
- 1, 0,
- 3, 4};
+/* f1|f2|f3|f4|f5|f6
+ */
+template <>
+UInt GeometricalElement<_gt_igfem_segment_3>::facet_connectivity_vect[] = {0,
+ 1};
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_4>::facet_connectivity_vect[] =
+ { // first type
+ 0, 2, 1, 0,
+ // second type
+ 1, 2, 3};
+template <>
+UInt GeometricalElement<_gt_igfem_triangle_5>::facet_connectivity_vect[] =
+ { // first type
+ 1, 2,
+ // second type
+ 0, 2, 1, 0, 3, 4};
-template<> UInt * GeometricalElement<_gt_igfem_segment_3>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-template<> UInt * GeometricalElement<_gt_igfem_triangle_4>::facet_connectivity[] = { &facet_connectivity_vect[0], &facet_connectivity_vect[4] };
-template<> UInt * GeometricalElement<_gt_igfem_triangle_5>::facet_connectivity[] = { &facet_connectivity_vect[0], &facet_connectivity_vect[2] };;
+template <>
+UInt * GeometricalElement<_gt_igfem_segment_3>::facet_connectivity[] = {
+ &facet_connectivity_vect[0]};
+template <>
+UInt * GeometricalElement<_gt_igfem_triangle_4>::facet_connectivity[] = {
+ &facet_connectivity_vect[0], &facet_connectivity_vect[4]};
+template <>
+UInt * GeometricalElement<_gt_igfem_triangle_5>::facet_connectivity[] = {
+ &facet_connectivity_vect[0], &facet_connectivity_vect[2]};
+;
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/extra_packages/igfem/src/igfem_enrichment.cc b/extra_packages/igfem/src/igfem_enrichment.cc
index 3d0098a4a..04234b782 100644
--- a/extra_packages/igfem/src/igfem_enrichment.cc
+++ b/extra_packages/igfem/src/igfem_enrichment.cc
@@ -1,98 +1,101 @@
/**
* @file igfem_enrichment.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Implementation of IGFEM enrichment
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "igfem_enrichment.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-IGFEMEnrichment::IGFEMEnrichment(Mesh & mesh) : intersector_sphere(mesh) {
-}
+IGFEMEnrichment::IGFEMEnrichment(Mesh & mesh) : intersector_sphere(mesh) {}
/* -------------------------------------------------------------------------- */
-void IGFEMEnrichment::initialize(){
- intersector_sphere.init();
-}
+void IGFEMEnrichment::initialize() { intersector_sphere.init(); }
/* -------------------------------------------------------------------------- */
void IGFEMEnrichment::update(ID domain) {
- if (domain == "") domain = default_geometry;
+ if (domain == "")
+ domain = default_geometry;
Geometry & geometry = getGeometry(domain);
intersector_sphere.buildIGFEMMeshFromSpheres(geometry);
}
/* -------------------------------------------------------------------------- */
-void IGFEMEnrichment::unRegisterGeometryObject(const ID & domain){
-
+void IGFEMEnrichment::unRegisterGeometryObject(const ID & domain) {
+
GeometryMap::iterator it = geometries.find(domain);
- AKANTU_DEBUG_ASSERT(it != geometries.end(), "Geometry object with domain "
- << domain << " was not found");
+ AKANTU_DEBUG_ASSERT(it != geometries.end(),
+ "Geometry object with domain " << domain
+ << " was not found");
geometries.erase(it);
if (!geometries.empty())
default_geometry = (*geometries.begin()).first;
}
/* -------------------------------------------------------------------------- */
void IGFEMEnrichment::registerGeometryObject(Geometry & geometry,
- const ID & domain){
- if (geometries.size() == 0) default_geometry = domain;
+ const ID & domain) {
+ if (geometries.size() == 0)
+ default_geometry = domain;
#ifndef AKANTU_NDEBUG
GeometryMap::iterator it = geometries.find(domain);
- AKANTU_DEBUG_ASSERT(it == geometries.end(), "Geometry object with domain "
- << domain << " was already created");
+ AKANTU_DEBUG_ASSERT(it == geometries.end(),
+ "Geometry object with domain " << domain
+ << " was already created");
#endif
- std::stringstream sstr; sstr << "geometry:" << domain;
+ std::stringstream sstr;
+ sstr << "geometry:" << domain;
geometries[domain] = &geometry;
-
}
/* -------------------------------------------------------------------------- */
-IGFEMEnrichment::Geometry & IGFEMEnrichment::getGeometry(ID & domain) const{
+IGFEMEnrichment::Geometry & IGFEMEnrichment::getGeometry(ID & domain) const {
AKANTU_DEBUG_IN();
- if (domain == "") domain = default_geometry;
+ if (domain == "")
+ domain = default_geometry;
GeometryMap::const_iterator it = geometries.find(domain);
- AKANTU_DEBUG_ASSERT(it != geometries.end(), "The geometry " << domain << " is not registered");
+ AKANTU_DEBUG_ASSERT(it != geometries.end(),
+ "The geometry " << domain << " is not registered");
AKANTU_DEBUG_OUT();
return *(it->second);
}
/* -------------------------------------------------------------------------- */
void IGFEMEnrichment::moveInterface(Real new_position, ID domain) {
- if (domain == "") domain = default_geometry;
+ if (domain == "")
+ domain = default_geometry;
Geometry & geometry = getGeometry(domain);
- /// for this type of IGFEM enrichment the geometry consists of a list of spheres
- /// -> need to loop over spheres and change their radius,
+ /// for this type of IGFEM enrichment the geometry consists of a list of
+ /// spheres
+ /// -> need to loop over spheres and change their radius,
/// which specifies the position of interfaces
- Geometry::const_iterator query_it = geometry.begin();
+ Geometry::const_iterator query_it = geometry.begin();
Geometry sphere_list;
- for (; query_it != geometry.end() ; ++query_it) {
- SK::Sphere_3 sphere(query_it->center(),
- new_position * new_position);
+ for (; query_it != geometry.end(); ++query_it) {
+ SK::Sphere_3 sphere(query_it->center(), new_position * new_position);
sphere_list.push_back(sphere);
}
geometry.clear();
geometry = sphere_list;
-
+
this->update(domain);
}
-
__END_AKANTU__
diff --git a/extra_packages/igfem/src/igfem_enrichment.hh b/extra_packages/igfem/src/igfem_enrichment.hh
index 90dfc460b..e12548f29 100644
--- a/extra_packages/igfem/src/igfem_enrichment.hh
+++ b/extra_packages/igfem/src/igfem_enrichment.hh
@@ -1,105 +1,102 @@
/**
* @file igfem_enrichment.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
- * @brief IGFEM enrichment: handles geometries of interfaces and advancement with time
+ * @brief IGFEM enrichment: handles geometries of interfaces and advancement
+ * with time
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_IGFEM_ENRICHMENT_HH__
#define __AKANTU_IGFEM_ENRICHMENT_HH__
-#include "mesh_sphere_intersector.hh"
#include "mesh_igfem_spherical_growing_gel.hh"
+#include "mesh_sphere_intersector.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class IGFEMEnrichment {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-public:
+public:
IGFEMEnrichment(Mesh & mesh);
- virtual ~IGFEMEnrichment() {};
+ virtual ~IGFEMEnrichment(){};
private:
typedef std::list<Spherical::Sphere_3> Geometry;
typedef std::map<std::string, Geometry *> GeometryMap;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /// create the mesh primitives
+ /// create the mesh primitives
void initialize();
/// get a geometry from the geometry map
virtual Geometry & getGeometry(ID & domain) const;
/// detect the interface
virtual void update(ID domain = "");
/// remove geometry
virtual void unRegisterGeometryObject(const ID & domain = "");
/// insert new geometry
- virtual void registerGeometryObject(Geometry & geometry, const ID & domain = "");
+ virtual void registerGeometryObject(Geometry & geometry,
+ const ID & domain = "");
/// check if a point is in a given domain
inline bool isInside(const Vector<Real> & point, ID domain = "") const;
/// move the interface, in this case grow the gel pockets
virtual void moveInterface(Real new_position, ID domain = "");
- /* -------------------------------------------------------------------------- */
- /* Accessors */
- /* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Accessors */
+ /* --------------------------------------------------------------------------
+ */
public:
UInt getNbStandardNodes() {
return this->intersector_sphere.getNbStandardNodes();
}
UInt getNbEnrichedNodes() {
return this->intersector_sphere.getNbEnrichedNodes();
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
MeshIgfemSphericalGrowingGel<2> intersector_sphere;
GeometryMap geometries;
/// default geometry object
std::string default_geometry;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "igfem_enrichment_inline_impl.cc"
-
-
-
__END_AKANTU__
/* -------------------------------------------------------------------------- */
-
-
#endif /* __AKANTU_IGFEM_ENRICHMENT_HH__ */
diff --git a/extra_packages/igfem/src/igfem_enrichment_inline_impl.cc b/extra_packages/igfem/src/igfem_enrichment_inline_impl.cc
index f3684ec96..638a91919 100644
--- a/extra_packages/igfem/src/igfem_enrichment_inline_impl.cc
+++ b/extra_packages/igfem/src/igfem_enrichment_inline_impl.cc
@@ -1,36 +1,36 @@
/**
* @file igfem_enrichment_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief inline implementation of IGFEM enrichment
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
__END_AKANTU__
/// place here includes
__BEGIN_AKANTU__
-
/* -------------------------------------------------------------------------- */
-inline bool IGFEMEnrichment::isInside(const Vector<Real> & point, ID domain) const {
- if (domain == "") domain = default_geometry;
+inline bool IGFEMEnrichment::isInside(const Vector<Real> & point,
+ ID domain) const {
+ if (domain == "")
+ domain = default_geometry;
Geometry & spheres = this->getGeometry(domain);
SK::Point_3 p(point(0), point(1), 0.);
std::list<Spherical::Sphere_3>::const_iterator begin = spheres.begin();
std::list<Spherical::Sphere_3>::const_iterator end = spheres.end();
- for ( ; begin != end; ++begin) {
+ for (; begin != end; ++begin) {
if (!(begin->has_on_unbounded_side(p)))
return true;
}
return false;
}
-
diff --git a/extra_packages/igfem/src/igfem_helper.cc b/extra_packages/igfem/src/igfem_helper.cc
index 0fec721d1..7184488ae 100644
--- a/extra_packages/igfem/src/igfem_helper.cc
+++ b/extra_packages/igfem/src/igfem_helper.cc
@@ -1,77 +1,105 @@
/**
* @file igfem_helper.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Fri Jul 3 15:49:55 2015
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "igfem_helper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-template<> ElementType ElementTypeIGFEMData<_not_defined>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_not_defined>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_point_1>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_point_1>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_segment_2>::igfem_element_types[] = {_igfem_segment_3};
-template<> UInt ElementTypeIGFEMData<_segment_2>::nb_igfem_types = 1;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_segment_3>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_segment_3>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_triangle_3>::igfem_element_types[] = {_igfem_triangle_4, _igfem_triangle_5};
-template<> UInt ElementTypeIGFEMData<_triangle_3>::nb_igfem_types = 2;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_triangle_6>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_triangle_6>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_tetrahedron_4>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_tetrahedron_4>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_tetrahedron_10>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_tetrahedron_10>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_quadrangle_4>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_quadrangle_4>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_quadrangle_8>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_quadrangle_8>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_hexahedron_8>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_hexahedron_8>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_hexahedron_20>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_hexahedron_20>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_pentahedron_6>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_pentahedron_6>::nb_igfem_types = 0;
-/* -------------------------------------------------------------------------- */
-template<> ElementType ElementTypeIGFEMData<_pentahedron_15>::igfem_element_types[] = {_not_defined};
-template<> UInt ElementTypeIGFEMData<_pentahedron_15>::nb_igfem_types = 0;
+template <>
+ElementType ElementTypeIGFEMData<_not_defined>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_not_defined>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_point_1>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_point_1>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_segment_2>::igfem_element_types[] = {
+ _igfem_segment_3};
+template <> UInt ElementTypeIGFEMData<_segment_2>::nb_igfem_types = 1;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_segment_3>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_segment_3>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_triangle_3>::igfem_element_types[] = {
+ _igfem_triangle_4, _igfem_triangle_5};
+template <> UInt ElementTypeIGFEMData<_triangle_3>::nb_igfem_types = 2;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_triangle_6>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_triangle_6>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_tetrahedron_4>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_tetrahedron_4>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_tetrahedron_10>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_tetrahedron_10>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_quadrangle_4>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_quadrangle_4>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_quadrangle_8>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_quadrangle_8>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_hexahedron_8>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_hexahedron_8>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_hexahedron_20>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_hexahedron_20>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_pentahedron_6>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_pentahedron_6>::nb_igfem_types = 0;
+/* -------------------------------------------------------------------------- */
+template <>
+ElementType ElementTypeIGFEMData<_pentahedron_15>::igfem_element_types[] = {
+ _not_defined};
+template <> UInt ElementTypeIGFEMData<_pentahedron_15>::nb_igfem_types = 0;
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/extra_packages/igfem/src/igfem_helper.hh b/extra_packages/igfem/src/igfem_helper.hh
index 330be5b73..9ec1f1d88 100644
--- a/extra_packages/igfem/src/igfem_helper.hh
+++ b/extra_packages/igfem/src/igfem_helper.hh
@@ -1,136 +1,149 @@
/**
* @file dumper_igfem_element_iterator.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Helper class to return sub element information
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#ifndef __AKANTU_IGFEM_HELPER_HH__
#define __AKANTU_IGFEM_HELPER_HH__
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-class FEEngine;
+class FEEngine;
-template<ElementType type>
-struct ElementTypeIGFEMData {
+template <ElementType type> struct ElementTypeIGFEMData {
static ElementType igfem_element_types[];
static UInt nb_igfem_types;
};
struct IGFEMHelper {
- template<ElementType type>
+ template <ElementType type>
static VectorProxy<ElementType> getIGFEMElementTypes() {
- return VectorProxy<ElementType>(ElementTypeIGFEMData<type>::igfem_element_types,
- ElementTypeIGFEMData<type>::nb_igfem_types );
+ return VectorProxy<ElementType>(
+ ElementTypeIGFEMData<type>::igfem_element_types,
+ ElementTypeIGFEMData<type>::nb_igfem_types);
}
/// get the number of nodes for a given sub-element
- static UInt getNbNodesPerSubElement(const ElementType & type, const UInt sub_element) {
+ static UInt getNbNodesPerSubElement(const ElementType & type,
+ const UInt sub_element) {
UInt nb_nodes_per_sub_element = 0;
-#define GET_NB_NODES_PER_SUB_ELEMENT(type) \
- switch (sub_element) { \
- case 0: \
- nb_nodes_per_sub_element = ElementClass<ElementClassProperty<type>::sub_element_type_1>::getNbNodesPerInterpolationElement(); break; \
- case 1: \
- nb_nodes_per_sub_element = ElementClass<ElementClassProperty<type>::sub_element_type_2>::getNbNodesPerInterpolationElement(); break; \
- }
+#define GET_NB_NODES_PER_SUB_ELEMENT(type) \
+ switch (sub_element) { \
+ case 0: \
+ nb_nodes_per_sub_element = \
+ ElementClass<ElementClassProperty<type>::sub_element_type_1>:: \
+ getNbNodesPerInterpolationElement(); \
+ break; \
+ case 1: \
+ nb_nodes_per_sub_element = \
+ ElementClass<ElementClassProperty<type>::sub_element_type_2>:: \
+ getNbNodesPerInterpolationElement(); \
+ break; \
+ }
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_NB_NODES_PER_SUB_ELEMENT);
#undef GET_NB_NODES_PER_SUB_ELEMENT
return nb_nodes_per_sub_element;
}
/// get the connectivity for a given sub-element
- static UInt * getSubElementConnectivity(const ElementType & type, const UInt sub_element) {
+ static UInt * getSubElementConnectivity(const ElementType & type,
+ const UInt sub_element) {
UInt * sub_element_connectivity = NULL;
-#define GET_SUB_ELEMENT_CONNECTIVITY(type) \
- sub_element_connectivity = ElementClass<type>::getSubElementConnectivity(sub_element);
+#define GET_SUB_ELEMENT_CONNECTIVITY(type) \
+ sub_element_connectivity = \
+ ElementClass<type>::getSubElementConnectivity(sub_element);
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_SUB_ELEMENT_CONNECTIVITY);
#undef GET_SUB_ELEMENT_CONNECTIVITY
return sub_element_connectivity;
}
/// get the sub-element type
- static ElementType getSubElementType(const ElementType & type, const UInt sub_element) {
+ static ElementType getSubElementType(const ElementType & type,
+ const UInt sub_element) {
ElementType sub_type = _not_defined;
-#define GET_SUB_ELEMENT_TYPE(type) \
- switch (sub_element) { \
- case 0: \
- sub_type = ElementClassProperty<type>::sub_element_type_1; break; \
- case 1: \
- sub_type = ElementClassProperty<type>::sub_element_type_2; break; \
- }
- AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_SUB_ELEMENT_TYPE);
-#undef GET_SUB_ELEMENT_TYPE
+#define GET_SUB_ELEMENT_TYPE(type) \
+ switch (sub_element) { \
+ case 0: \
+ sub_type = ElementClassProperty<type>::sub_element_type_1; \
+ break; \
+ case 1: \
+ sub_type = ElementClassProperty<type>::sub_element_type_2; \
+ break; \
+ }
+ AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_SUB_ELEMENT_TYPE);
+#undef GET_SUB_ELEMENT_TYPE
return sub_type;
}
/// get the nb of quads for one sub element type
- static UInt getNbQuadraturePoints(const ElementType & type, const UInt sub_element) {
+ static UInt getNbQuadraturePoints(const ElementType & type,
+ const UInt sub_element) {
UInt nb_quad_points = 0;
-#define GET_NB_QUADS(type) \
- switch (sub_element) { \
- case 0: \
- nb_quad_points = GaussIntegrationElement<ElementClassProperty<type>::sub_element_type_1>::getNbQuadraturePoints(); break; \
- case 1: \
- nb_quad_points = GaussIntegrationElement<ElementClassProperty<type>::sub_element_type_2>::getNbQuadraturePoints(); break; \
- }
+#define GET_NB_QUADS(type) \
+ switch (sub_element) { \
+ case 0: \
+ nb_quad_points = GaussIntegrationElement<ElementClassProperty< \
+ type>::sub_element_type_1>::getNbQuadraturePoints(); \
+ break; \
+ case 1: \
+ nb_quad_points = GaussIntegrationElement<ElementClassProperty< \
+ type>::sub_element_type_2>::getNbQuadraturePoints(); \
+ break; \
+ }
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_NB_QUADS);
#undef GET_NB_QUADS
return nb_quad_points;
}
/// get the nb of parent nodes of a given igfem element type
static UInt getNbParentNodes(const ElementType & type) {
UInt nb_parent_nodes = 0;
-#define GET_NB_PARENT_NODES(type) \
- nb_parent_nodes = ElementClass<ElementClassProperty<type>::parent_element_type>::getNbNodesPerInterpolationElement();
+#define GET_NB_PARENT_NODES(type) \
+ nb_parent_nodes = \
+ ElementClass<ElementClassProperty<type>::parent_element_type>:: \
+ getNbNodesPerInterpolationElement();
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_NB_PARENT_NODES);
#undef GET_NB_PARENT_NODES
return nb_parent_nodes;
}
/// get the nb of parent nodes of a given igfem element type
static UInt getNbEnrichedNodes(const ElementType & type) {
UInt nb_enriched_nodes = 0;
-#define GET_NB_ENRICHED_NODES(type) \
- nb_enriched_nodes = ElementClass<type>::getNbEnrichments();
+#define GET_NB_ENRICHED_NODES(type) \
+ nb_enriched_nodes = ElementClass<type>::getNbEnrichments();
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_NB_ENRICHED_NODES);
#undef GET_NB_ENRICHED_NODES
return nb_enriched_nodes;
}
/// get the nb of quads for one sub element type
- static UInt getElementOrientation(const ElementType & type, const Vector<bool> & is_inside) {
+ static UInt getElementOrientation(const ElementType & type,
+ const Vector<bool> & is_inside) {
UInt orientation = 0;
-#define GET_ORIENTATION(type) \
- orientation = ElementClass<type>::getOrientation(is_inside);
+#define GET_ORIENTATION(type) \
+ orientation = ElementClass<type>::getOrientation(is_inside);
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_ORIENTATION);
#undef GET_ORIENTATION
return orientation;
}
-
-
};
__END_AKANTU__
#endif /* __AKANTU_IGFEM_HELPER_HH__ */
-
-
-
-
-
diff --git a/extra_packages/igfem/src/integrator_gauss_igfem.hh b/extra_packages/igfem/src/integrator_gauss_igfem.hh
index 5f385e498..027b13d44 100644
--- a/extra_packages/igfem/src/integrator_gauss_igfem.hh
+++ b/extra_packages/igfem/src/integrator_gauss_igfem.hh
@@ -1,123 +1,125 @@
/**
* @file integrator_gauss_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Gauss integration facilities for IGFEM
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTEGRATOR_IGFEM_HH__
#define __AKANTU_INTEGRATOR_IGFEM_HH__
/* -------------------------------------------------------------------------- */
#include "integrator.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
template <class IOF> class IntegratorGauss<_ek_igfem, IOF> : public Integrator {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegratorGauss(const Mesh & mesh, const ID & id = "integrator_gauss",
const MemoryID & memory_id = 0);
virtual ~IntegratorGauss(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline void initIntegrator(const Array<Real> & nodes,
const ElementType & type,
const GhostType & ghost_type);
/// precompute jacobians on elements of type "type"
template <ElementType type>
void precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
const GhostType & ghost_type);
/// integrate f on the element "elem" of type "type"
template <ElementType type>
inline void integrateOnElement(const Array<Real> & f, Real * intf,
UInt nb_degree_of_freedom, const UInt elem,
const GhostType & ghost_type) const;
/// integrate f for all elements of type "type"
template <ElementType type>
void integrate(const Array<Real> & in_f, Array<Real> & intf,
UInt nb_degree_of_freedom, const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// integrate one element scalar value on all elements of type "type"
template <ElementType type>
Real integrate(const Vector<Real> & in_f, UInt index,
const GhostType & ghost_type) const;
/// integrate scalar field in_f
template <ElementType type>
Real integrate(const Array<Real> & in_f, const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// integrate partially around a quadrature point (@f$ intf_q = f_q * J_q *
/// w_q @f$)
template <ElementType type>
void integrateOnIntegrationPoints(const Array<Real> & in_f,
Array<Real> & intf,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// return a vector with quadrature points natural coordinates
template <ElementType type>
const Matrix<Real> & getIntegrationPoints(const GhostType & ghost_type) const;
/// return the number of quadrature points for a given element type
- template <ElementType type> inline UInt getNbIntegrationPoints(const GhostType & ghost_type = _not_ghost) const;
+ template <ElementType type>
+ inline UInt
+ getNbIntegrationPoints(const GhostType & ghost_type = _not_ghost) const;
/// compute the vector of quadrature points natural coordinates
template <ElementType type>
void computeQuadraturePoints(const GhostType & ghost_type);
/// check that the jacobians are not negative
template <ElementType type>
void checkJacobians(const GhostType & ghost_type) const;
public:
/// compute the jacobians on quad points for a given element
template <ElementType type>
void computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
Vector<Real> & jacobians);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
inline void integrate(Real * f, Real * jac, Real * inte,
UInt nb_degree_of_freedom,
UInt nb_quadrature_points) const;
private:
- ElementTypeMap<Matrix<Real> > quadrature_points;
+ ElementTypeMap<Matrix<Real>> quadrature_points;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "integrator_gauss_igfem_inline_impl.cc"
__END_AKANTU__
#endif /*__AKANTU_INTEGRATOR_IGFEM_HH__ */
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
diff --git a/extra_packages/igfem/src/interpolation_element_igfem.cc b/extra_packages/igfem/src/interpolation_element_igfem.cc
index 275a88386..25ef812b7 100644
--- a/extra_packages/igfem/src/interpolation_element_igfem.cc
+++ b/extra_packages/igfem/src/interpolation_element_igfem.cc
@@ -1,76 +1,93 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Specialization for interface-enriched finite elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<> UInt InterpolationElement<_itp_igfem_segment_3>::nb_sub_elements = 2;
-template<> UInt InterpolationElement<_itp_igfem_triangle_4>::nb_sub_elements = 2;
-template<> UInt InterpolationElement<_itp_igfem_triangle_5>::nb_sub_elements = 2;
+template <>
+UInt InterpolationElement<_itp_igfem_segment_3>::nb_sub_elements = 2;
+template <>
+UInt InterpolationElement<_itp_igfem_triangle_4>::nb_sub_elements = 2;
+template <>
+UInt InterpolationElement<_itp_igfem_triangle_5>::nb_sub_elements = 2;
-/* !!! stored as a matrix nb_subelements X nb_nodes_per_subelement in COL MAJOR */
+/* !!! stored as a matrix nb_subelements X nb_nodes_per_subelement in COL MAJOR
+ */
/* -------------------------------------------------------------------------- */
-template<> UInt InterpolationElement<_itp_igfem_segment_3>::sub_element_connectivity_vect[] = { 0, // first type
- 2,
- 2, // second type
- 1};
-template<> UInt InterpolationElement<_itp_igfem_triangle_4>::sub_element_connectivity_vect[] = { 0, // first type
- 1,
- 3,
- 0, // second type
- 3,
- 2};
-template<> UInt InterpolationElement<_itp_igfem_triangle_5>::sub_element_connectivity_vect[] = { 0, // first type
- 3,
- 4,
- 3, // second type
- 1,
- 2,
- 4};
+template <>
+UInt InterpolationElement<
+ _itp_igfem_segment_3>::sub_element_connectivity_vect[] = {0, // first type
+ 2,
+ 2, // second type
+ 1};
+template <>
+UInt InterpolationElement<
+ _itp_igfem_triangle_4>::sub_element_connectivity_vect[] = {0, // first type
+ 1, 3,
+ 0, // second type
+ 3, 2};
+template <>
+UInt InterpolationElement<
+ _itp_igfem_triangle_5>::sub_element_connectivity_vect[] = {0, // first type
+ 3, 4,
+ 3, // second type
+ 1, 2, 4};
-template<> UInt * InterpolationElement<_itp_igfem_segment_3>::sub_element_connectivity[] = { &sub_element_connectivity_vect[0],
- &sub_element_connectivity_vect[2] };
-template<> UInt * InterpolationElement<_itp_igfem_triangle_4>::sub_element_connectivity[] = { &sub_element_connectivity_vect[0],
- &sub_element_connectivity_vect[3] };
-template<> UInt * InterpolationElement<_itp_igfem_triangle_5>::sub_element_connectivity[] = { &sub_element_connectivity_vect[0],
- &sub_element_connectivity_vect[3] };
+template <>
+UInt * InterpolationElement<_itp_igfem_segment_3>::sub_element_connectivity[] =
+ {&sub_element_connectivity_vect[0], &sub_element_connectivity_vect[2]};
+template <>
+UInt * InterpolationElement<_itp_igfem_triangle_4>::sub_element_connectivity[] =
+ {&sub_element_connectivity_vect[0], &sub_element_connectivity_vect[3]};
+template <>
+UInt * InterpolationElement<_itp_igfem_triangle_5>::sub_element_connectivity[] =
+ {&sub_element_connectivity_vect[0], &sub_element_connectivity_vect[3]};
/* -------------------------------------------------------------------------- */
-template<> UInt InterpolationElement<_itp_igfem_segment_3>::nb_enrichments = 1;
-template<> UInt InterpolationElement<_itp_igfem_triangle_4>::nb_enrichments = 1;
-template<> UInt InterpolationElement<_itp_igfem_triangle_5>::nb_enrichments = 2;
+template <> UInt InterpolationElement<_itp_igfem_segment_3>::nb_enrichments = 1;
+template <>
+UInt InterpolationElement<_itp_igfem_triangle_4>::nb_enrichments = 1;
+template <>
+UInt InterpolationElement<_itp_igfem_triangle_5>::nb_enrichments = 2;
-template<> UInt InterpolationElement<_itp_igfem_segment_3>::enrichment_vect[] = { 1, // on first subelement
- 0}; // on second subelement
-template<> UInt InterpolationElement<_itp_igfem_triangle_4>::enrichment_vect[] = { 2, // on first subelement
- 1}; // on second subelement
-template<> UInt InterpolationElement<_itp_igfem_triangle_5>::enrichment_vect[] = { 1, // on first subelement
- 2,
- 0,
- 3}; // on second subelement
+template <>
+UInt InterpolationElement<_itp_igfem_segment_3>::enrichment_vect[] = {
+ 1, // on first subelement
+ 0}; // on second subelement
+template <>
+UInt InterpolationElement<_itp_igfem_triangle_4>::enrichment_vect[] = {
+ 2, // on first subelement
+ 1}; // on second subelement
+template <>
+UInt InterpolationElement<_itp_igfem_triangle_5>::enrichment_vect[] = {
+ 1, // on first subelement
+ 2, 0, 3}; // on second subelement
-template<> UInt * InterpolationElement<_itp_igfem_segment_3>::enrichments[] = { &enrichment_vect[0],
- &enrichment_vect[1]};
-template<> UInt * InterpolationElement<_itp_igfem_triangle_4>::enrichments[] = { &enrichment_vect[0],
- &enrichment_vect[1]};
-template<> UInt * InterpolationElement<_itp_igfem_triangle_5>::enrichments[] = { &enrichment_vect[0],
- &enrichment_vect[2]};
+template <>
+UInt * InterpolationElement<_itp_igfem_segment_3>::enrichments[] = {
+ &enrichment_vect[0], &enrichment_vect[1]};
+template <>
+UInt * InterpolationElement<_itp_igfem_triangle_4>::enrichments[] = {
+ &enrichment_vect[0], &enrichment_vect[1]};
+template <>
+UInt * InterpolationElement<_itp_igfem_triangle_5>::enrichments[] = {
+ &enrichment_vect[0], &enrichment_vect[2]};
__END_AKANTU__
diff --git a/extra_packages/igfem/src/interpolation_element_igfem_tmpl.hh b/extra_packages/igfem/src/interpolation_element_igfem_tmpl.hh
index 2d60afdb5..9b6d2a58b 100644
--- a/extra_packages/igfem/src/interpolation_element_igfem_tmpl.hh
+++ b/extra_packages/igfem/src/interpolation_element_igfem_tmpl.hh
@@ -1,26 +1,38 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Interpolation property description for IGFEM
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* IGFEM elements */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
-AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY(_itp_igfem_segment_3, _itk_igfem, 3, 1, _itp_lagrange_segment_2, _itp_lagrange_segment_2, _itp_lagrange_segment_2);
-AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY(_itp_igfem_triangle_4, _itk_igfem, 4, 2, _itp_lagrange_triangle_3, _itp_lagrange_triangle_3, _itp_lagrange_triangle_3);
-AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY(_itp_igfem_triangle_5, _itk_igfem, 5, 2, _itp_lagrange_triangle_3, _itp_lagrange_triangle_3, _itp_lagrange_quadrangle_4);
+AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY(_itp_igfem_segment_3,
+ _itk_igfem, 3, 1,
+ _itp_lagrange_segment_2,
+ _itp_lagrange_segment_2,
+ _itp_lagrange_segment_2);
+AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY(_itp_igfem_triangle_4,
+ _itk_igfem, 4, 2,
+ _itp_lagrange_triangle_3,
+ _itp_lagrange_triangle_3,
+ _itp_lagrange_triangle_3);
+AKANTU_DEFINE_IGFEM_INTERPOLATION_TYPE_PROPERTY(_itp_igfem_triangle_5,
+ _itk_igfem, 5, 2,
+ _itp_lagrange_triangle_3,
+ _itp_lagrange_triangle_3,
+ _itp_lagrange_quadrangle_4);
#endif
diff --git a/extra_packages/igfem/src/material_igfem/igfem_internal_field.hh b/extra_packages/igfem/src/material_igfem/igfem_internal_field.hh
index 93d278021..d0512e32a 100644
--- a/extra_packages/igfem/src/material_igfem/igfem_internal_field.hh
+++ b/extra_packages/igfem/src/material_igfem/igfem_internal_field.hh
@@ -1,34 +1,31 @@
/**
* @file igfem_internal_field.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief IGFEM internal field
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#include "internal_field.hh"
#ifndef __AKANTU_IGFEM_INTERNAL_FIELD_HH__
#define __AKANTU_IGFEM_INTERNAL_FIELD_HH__
__BEGIN_AKANTU__
-template<typename T>
-class IGFEMInternalField : public InternalField<T> {
+template <typename T> class IGFEMInternalField : public InternalField<T> {
public:
IGFEMInternalField(const ID & id, Material & material);
virtual ~IGFEMInternalField();
-
};
-
__END_AKANTU__
#endif /* __AKANTU_IGFEM_INTERNAL_FIELD_HH__ */
diff --git a/extra_packages/igfem/src/material_igfem/igfem_internal_field_tmpl.hh b/extra_packages/igfem/src/material_igfem/igfem_internal_field_tmpl.hh
index a06d0063d..b1e61d815 100644
--- a/extra_packages/igfem/src/material_igfem/igfem_internal_field_tmpl.hh
+++ b/extra_packages/igfem/src/material_igfem/igfem_internal_field_tmpl.hh
@@ -1,34 +1,34 @@
/**
* @file igfem_internal_field_tmpl.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Implementation of IGFEM internal field
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#ifndef __AKANTU_IGFEM_INTERNAL_FIELD_TMPL_HH__
#define __AKANTU_IGFEM_INTERNAL_FIELD_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<typename T>
-IGFEMInternalField<T>::IGFEMInternalField(const ID & id, Material & material) :
- InternalField<T>(id, material, material.getModel().getFEEngine("IGFEMFEEngine"),
- dynamic_cast<MaterialIGFEM &>(material).getElementFilter()) {
+template <typename T>
+IGFEMInternalField<T>::IGFEMInternalField(const ID & id, Material & material)
+ : InternalField<T>(
+ id, material, material.getModel().getFEEngine("IGFEMFEEngine"),
+ dynamic_cast<MaterialIGFEM &>(material).getElementFilter()) {
this->element_kind = _ek_igfem;
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-IGFEMInternalField<T>::~IGFEMInternalField() { };
+template <typename T> IGFEMInternalField<T>::~IGFEMInternalField(){};
__END_AKANTU__
#endif /* __AKANTU_IGFEM_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem.cc b/extra_packages/igfem/src/material_igfem/material_igfem.cc
index a7c8d5402..0ff84b1da 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem.cc
@@ -1,344 +1,368 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Implementation parent material for IGFEM
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#include "material_igfem.hh"
#include "aka_math.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-MaterialIGFEM::MaterialIGFEM(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- nb_sub_materials(2),
- sub_material("sub_material", *this),
- name_sub_mat_1(""),
- name_sub_mat_2("") {
+MaterialIGFEM::MaterialIGFEM(SolidMechanicsModel & model, const ID & id)
+ : Material(model, id), nb_sub_materials(2),
+ sub_material("sub_material", *this), name_sub_mat_1(""),
+ name_sub_mat_2("") {
AKANTU_DEBUG_IN();
- this->model = dynamic_cast<SolidMechanicsModelIGFEM*>(&model);
+ this->model = dynamic_cast<SolidMechanicsModelIGFEM *>(&model);
this->fem = &(model.getFEEngineClass<MyFEEngineIGFEMType>("IGFEMFEEngine"));
-
- this->model->getMesh().initElementTypeMapArray(element_filter,
- 1,
- spatial_dimension,
- false,
- _ek_igfem);
+
+ this->model->getMesh().initElementTypeMapArray(
+ element_filter, 1, spatial_dimension, false, _ek_igfem);
this->initialize();
AKANTU_DEBUG_OUT();
};
/* -------------------------------------------------------------------------- */
MaterialIGFEM::~MaterialIGFEM() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialIGFEM::initialize() {
this->gradu.setElementKind(_ek_igfem);
this->stress.setElementKind(_ek_igfem);
this->eigengradu.setElementKind(_ek_igfem);
this->gradu.setFEEngine(*fem);
this->stress.setFEEngine(*fem);
this->eigengradu.setFEEngine(*fem);
- registerParam("name_sub_mat_1" , name_sub_mat_1 , std::string(), _pat_parsable | _pat_readable);
- registerParam("name_sub_mat_2" , name_sub_mat_2 , std::string(), _pat_parsable | _pat_readable);
+ registerParam("name_sub_mat_1", name_sub_mat_1, std::string(),
+ _pat_parsable | _pat_readable);
+ registerParam("name_sub_mat_2", name_sub_mat_2, std::string(),
+ _pat_parsable | _pat_readable);
this->sub_material.initialize(1);
-
}
/* -------------------------------------------------------------------------- */
-void MaterialIGFEM::computeQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type) const {
+void MaterialIGFEM::computeQuadraturePointsCoordinates(
+ ElementTypeMapArray<Real> & quadrature_points_coordinates,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
/// compute quadrature points position in undeformed configuration
Array<Real> & nodes_coordinates = this->fem->getMesh().getNodes();
- Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_igfem);
- Mesh::type_iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
- for(; it != last_type; ++it) {
+ Mesh::type_iterator it =
+ this->element_filter.firstType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator last_type =
+ this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
+ for (; it != last_type; ++it) {
const Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
- UInt nb_element = elem_filter.getSize();
- if(nb_element) {
- UInt nb_tot_quad = this->fem->getNbIntegrationPoints(*it, ghost_type) * nb_element;
+ UInt nb_element = elem_filter.getSize();
+ if (nb_element) {
+ UInt nb_tot_quad =
+ this->fem->getNbIntegrationPoints(*it, ghost_type) * nb_element;
Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
quads.resize(nb_tot_quad);
- this->model->getFEEngine("IGFEMFEEngine").interpolateOnIntegrationPoints(nodes_coordinates,
- quads, spatial_dimension,
- *it, ghost_type, elem_filter);
+ this->model->getFEEngine("IGFEMFEEngine")
+ .interpolateOnIntegrationPoints(nodes_coordinates, quads,
+ spatial_dimension, *it, ghost_type,
+ elem_filter);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the stress from the gradu
*
* @param[in] current_position nodes postition + displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void MaterialIGFEM::computeAllStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
- Mesh::type_iterator it = this->fem->getMesh().firstType(spatial_dimension, ghost_type, _ek_igfem);
- Mesh::type_iterator last_type = this->fem->getMesh().lastType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator it =
+ this->fem->getMesh().firstType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator last_type =
+ this->fem->getMesh().lastType(spatial_dimension, ghost_type, _ek_igfem);
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
if (elem_filter.getSize()) {
Array<Real> & gradu_vect = gradu(*it, ghost_type);
/// compute @f$\nabla u@f$
- this->fem->gradientOnIntegrationPoints(model->getDisplacement(), gradu_vect,
- spatial_dimension,
- *it, ghost_type, elem_filter);
+ this->fem->gradientOnIntegrationPoints(model->getDisplacement(),
+ gradu_vect, spatial_dimension, *it,
+ ghost_type, elem_filter);
gradu_vect -= eigengradu(*it, ghost_type);
/// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$
computeStress(*it, ghost_type);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/// extrapolate internal values
-void MaterialIGFEM::extrapolateInternal(const ID & id, const Element & element, const Matrix<Real> & point, Matrix<Real> & extrapolated) {
+void MaterialIGFEM::extrapolateInternal(const ID & id, const Element & element,
+ const Matrix<Real> & point,
+ Matrix<Real> & extrapolated) {
if (this->isInternal<Real>(id, element.kind)) {
- UInt nb_element = this->element_filter(element.type, element.ghost_type).getSize();
- const ID name = this->getID() + ":" + id;
- UInt nb_quads = this->internal_vectors_real[name]->getFEEngine().getNbIntegrationPoints(element.type, element.ghost_type);
- const Array<Real> & internal = this->getArray<Real>(id, element.type, element.ghost_type);
+ UInt nb_element =
+ this->element_filter(element.type, element.ghost_type).getSize();
+ const ID name = this->getID() + ":" + id;
+ UInt nb_quads =
+ this->internal_vectors_real[name]->getFEEngine().getNbIntegrationPoints(
+ element.type, element.ghost_type);
+ const Array<Real> & internal =
+ this->getArray<Real>(id, element.type, element.ghost_type);
UInt nb_component = internal.getNbComponent();
- Array<Real>::const_matrix_iterator internal_it = internal.begin_reinterpret(nb_component, nb_quads, nb_element);
+ Array<Real>::const_matrix_iterator internal_it =
+ internal.begin_reinterpret(nb_component, nb_quads, nb_element);
Element local_element = this->convertToLocalElement(element);
/// instead of really extrapolating, here the value of the first GP
/// is copied into the result vector. This works only for linear
/// elements
/// @todo extrapolate!!!!
AKANTU_DEBUG_WARNING("This is a fix, values are not truly extrapolated");
const Matrix<Real> & values = internal_it[local_element.element];
UInt index = 0;
Vector<Real> tmp(nb_component);
for (UInt j = 0; j < values.cols(); ++j) {
tmp = values(j);
if (tmp.norm() > Math::getTolerance()) {
index = j;
break;
}
}
for (UInt i = 0; i < extrapolated.size(); ++i) {
extrapolated(i) = values(index);
}
- }
- else {
+ } else {
Matrix<Real> default_values(extrapolated.rows(), extrapolated.cols(), 0.);
extrapolated = default_values;
}
}
/* -------------------------------------------------------------------------- */
-template<ElementType type>
-void MaterialIGFEM::setSubMaterial(const Array<Element> & element_list, GhostType ghost_type) {
+template <ElementType type>
+void MaterialIGFEM::setSubMaterial(const Array<Element> & element_list,
+ GhostType ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
-
/* -------------------------------------------------------------------------- */
-template<>
-void MaterialIGFEM::setSubMaterial<_igfem_triangle_5>(const Array<Element> & element_list, GhostType ghost_type) {
- SolidMechanicsModelIGFEM * igfem_model = static_cast<SolidMechanicsModelIGFEM*>(this->model);
+template <>
+void MaterialIGFEM::setSubMaterial<_igfem_triangle_5>(
+ const Array<Element> & element_list, GhostType ghost_type) {
+ SolidMechanicsModelIGFEM * igfem_model =
+ static_cast<SolidMechanicsModelIGFEM *>(this->model);
Vector<UInt> sub_material_index(this->nb_sub_materials);
Array<Element>::const_iterator<Element> el_begin = element_list.begin();
- Array<Element>::const_iterator<Element> el_end = element_list.end();
+ Array<Element>::const_iterator<Element> el_end = element_list.end();
const Mesh & mesh = this->model->getMesh();
Array<Real> nodes_coordinates(mesh.getNodes(), true);
- Array<Real>::const_vector_iterator nodes_it = nodes_coordinates.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator nodes_it =
+ nodes_coordinates.begin(spatial_dimension);
Element el;
el.kind = _ek_igfem;
el.type = _igfem_triangle_5;
el.ghost_type = ghost_type;
UInt nb_nodes_per_el = mesh.getNbNodesPerElement(el.type);
UInt nb_parent_nodes = IGFEMHelper::getNbParentNodes(el.type);
Vector<bool> is_inside(nb_parent_nodes);
const Array<UInt> & connectivity = mesh.getConnectivity(el.type, ghost_type);
- Array<UInt>::const_vector_iterator connec_it = connectivity.begin(nb_nodes_per_el);
-
+ Array<UInt>::const_vector_iterator connec_it =
+ connectivity.begin(nb_nodes_per_el);
+
/// get the number of quadrature points for the two sub-elements
UInt quads_1 = IGFEMHelper::getNbQuadraturePoints(el.type, 0);
UInt quads_2 = IGFEMHelper::getNbQuadraturePoints(el.type, 1);
UInt nb_total_quads = quads_1 + quads_2;
UInt * sub_mat_ptr = this->sub_material(el.type, ghost_type).storage();
/// loop all elements for the given type
- const Array<UInt> & filter = this->element_filter(el.type,ghost_type);
+ const Array<UInt> & filter = this->element_filter(el.type, ghost_type);
UInt nb_elements = filter.getSize();
for (UInt e = 0; e < nb_elements; ++e, ++connec_it) {
el.element = filter(e);
- if(std::find(el_begin, el_end, el) == el_end) {
+ if (std::find(el_begin, el_end, el) == el_end) {
sub_mat_ptr += nb_total_quads;
continue;
}
for (UInt i = 0; i < nb_parent_nodes; ++i) {
Vector<Real> node = nodes_it[(*connec_it)(i)];
is_inside(i) = igfem_model->isInside(node, this->name_sub_mat_1);
}
UInt orientation = IGFEMHelper::getElementOrientation(el.type, is_inside);
switch (orientation) {
case 0: {
sub_material_index(0) = 0;
sub_material_index(1) = 1;
break;
}
case 1: {
sub_material_index(0) = 1;
sub_material_index(1) = 0;
break;
}
-
+
case 2: {
sub_material_index(0) = 0;
sub_material_index(1) = 0;
break;
}
case 3: {
sub_material_index(0) = 1;
sub_material_index(0) = 1;
break;
}
}
for (UInt q = 0; q < quads_1; ++q, ++sub_mat_ptr) {
UInt index = sub_material_index(0);
*sub_mat_ptr = index;
}
for (UInt q = 0; q < quads_2; ++q, ++sub_mat_ptr) {
UInt index = sub_material_index(1);
- *sub_mat_ptr = index;
+ *sub_mat_ptr = index;
}
}
}
/* -------------------------------------------------------------------------- */
-template<>
-void MaterialIGFEM::setSubMaterial<_igfem_triangle_4>(const Array<Element> & element_list, GhostType ghost_type) {
- SolidMechanicsModelIGFEM * igfem_model = static_cast<SolidMechanicsModelIGFEM*>(this->model);
+template <>
+void MaterialIGFEM::setSubMaterial<_igfem_triangle_4>(
+ const Array<Element> & element_list, GhostType ghost_type) {
+ SolidMechanicsModelIGFEM * igfem_model =
+ static_cast<SolidMechanicsModelIGFEM *>(this->model);
Vector<UInt> sub_material_index(this->nb_sub_materials);
Array<Element>::const_iterator<Element> el_begin = element_list.begin();
- Array<Element>::const_iterator<Element> el_end = element_list.end();
+ Array<Element>::const_iterator<Element> el_end = element_list.end();
const Mesh & mesh = this->model->getMesh();
Element el;
el.kind = _ek_igfem;
el.ghost_type = ghost_type;
el.type = _igfem_triangle_4;
UInt nb_nodes_per_el = mesh.getNbNodesPerElement(el.type);
Vector<Real> barycenter(spatial_dimension);
const Array<UInt> & connectivity = mesh.getConnectivity(el.type, ghost_type);
- Array<UInt>::const_vector_iterator connec_it = connectivity.begin(nb_nodes_per_el);
-
+ Array<UInt>::const_vector_iterator connec_it =
+ connectivity.begin(nb_nodes_per_el);
+
/// get the number of quadrature points for the two sub-elements
UInt quads_1 = IGFEMHelper::getNbQuadraturePoints(el.type, 0);
UInt quads_2 = IGFEMHelper::getNbQuadraturePoints(el.type, 1);
UInt nb_total_quads = quads_1 + quads_2;
UInt * sub_mat_ptr = this->sub_material(el.type, ghost_type).storage();
/// loop all elements for the given type
- const Array<UInt> & filter = this->element_filter(el.type,ghost_type);
+ const Array<UInt> & filter = this->element_filter(el.type, ghost_type);
UInt nb_elements = filter.getSize();
for (UInt e = 0; e < nb_elements; ++e, ++connec_it) {
el.element = filter(e);
- if(std::find(el_begin, el_end, el) == el_end) {
+ if (std::find(el_begin, el_end, el) == el_end) {
sub_mat_ptr += nb_total_quads;
continue;
}
for (UInt s = 0; s < this->nb_sub_materials; ++s) {
- igfem_model->getSubElementBarycenter(el.element, s, el.type, barycenter, ghost_type);
- sub_material_index(s) = 1 - igfem_model->isInside(barycenter, this->name_sub_mat_1);
+ igfem_model->getSubElementBarycenter(el.element, s, el.type, barycenter,
+ ghost_type);
+ sub_material_index(s) =
+ 1 - igfem_model->isInside(barycenter, this->name_sub_mat_1);
}
-
+
for (UInt q = 0; q < quads_1; ++q, ++sub_mat_ptr) {
UInt index = sub_material_index(0);
*sub_mat_ptr = index;
}
-
+
for (UInt q = 0; q < quads_2; ++q, ++sub_mat_ptr) {
UInt index = sub_material_index(1);
- *sub_mat_ptr = index;
+ *sub_mat_ptr = index;
}
}
}
/* -------------------------------------------------------------------------- */
-void MaterialIGFEM::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & id, const GhostType ghost_type) {
+void MaterialIGFEM::applyEigenGradU(
+ const Matrix<Real> & prescribed_eigen_grad_u, const ID & id,
+ const GhostType ghost_type) {
- std::map<UInt, ID>::const_iterator sub_mat_it = this->sub_material_names.begin();
+ std::map<UInt, ID>::const_iterator sub_mat_it =
+ this->sub_material_names.begin();
for (; sub_mat_it != sub_material_names.end(); ++sub_mat_it) {
if (sub_mat_it->second == id) {
UInt sub_element_index = sub_mat_it->first;
- ElementTypeMapArray<UInt>::type_iterator it
- = this->element_filter.firstType(_all_dimensions, ghost_type, _ek_not_defined);
- ElementTypeMapArray<UInt>::type_iterator end
- = element_filter.lastType(_all_dimensions, ghost_type, _ek_not_defined);
-
- for(; it != end; ++it) {
- ElementType type = *it;
- if (!element_filter(type, ghost_type).getSize())
- continue;
- Array<Real>::matrix_iterator eigen_it = this->eigengradu(type, ghost_type).begin(spatial_dimension,
- spatial_dimension);
- Array<Real>::matrix_iterator eigen_end = this->eigengradu(type, ghost_type).end(spatial_dimension,
- spatial_dimension);
- UInt * sub_mat_ptr = this->sub_material(type, ghost_type).storage();
-
- for(; eigen_it != eigen_end; ++eigen_it, ++sub_mat_ptr) {
- if(*sub_mat_ptr == sub_element_index) {
- Matrix<Real> & current_eigengradu = *eigen_it;
- current_eigengradu = prescribed_eigen_grad_u;
- }
- }
+ ElementTypeMapArray<UInt>::type_iterator it =
+ this->element_filter.firstType(_all_dimensions, ghost_type,
+ _ek_not_defined);
+ ElementTypeMapArray<UInt>::type_iterator end =
+ element_filter.lastType(_all_dimensions, ghost_type, _ek_not_defined);
+
+ for (; it != end; ++it) {
+ ElementType type = *it;
+ if (!element_filter(type, ghost_type).getSize())
+ continue;
+ Array<Real>::matrix_iterator eigen_it =
+ this->eigengradu(type, ghost_type)
+ .begin(spatial_dimension, spatial_dimension);
+ Array<Real>::matrix_iterator eigen_end =
+ this->eigengradu(type, ghost_type)
+ .end(spatial_dimension, spatial_dimension);
+ UInt * sub_mat_ptr = this->sub_material(type, ghost_type).storage();
+
+ for (; eigen_it != eigen_end; ++eigen_it, ++sub_mat_ptr) {
+ if (*sub_mat_ptr == sub_element_index) {
+ Matrix<Real> & current_eigengradu = *eigen_it;
+ current_eigengradu = prescribed_eigen_grad_u;
+ }
+ }
}
}
}
}
__END_AKANTU__
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem.hh b/extra_packages/igfem/src/material_igfem/material_igfem.hh
index e78bb6d10..5ced4940f 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem.hh
@@ -1,140 +1,135 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Parent material for IGFEM
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "material.hh"
#include "igfem_internal_field.hh"
+#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_IGFEM_HH__
#define __AKANTU_MATERIAL_IGFEM_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
- class SolidMechanicsModelIGFEM;
+class SolidMechanicsModelIGFEM;
}
__BEGIN_AKANTU__
-
class MaterialIGFEM : public virtual Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- typedef FEEngineTemplate<IntegratorGauss,
- ShapeLagrange, _ek_igfem> MyFEEngineIGFEMType;
+ typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem>
+ MyFEEngineIGFEMType;
MaterialIGFEM(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialIGFEM();
protected:
-
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
- virtual void extrapolateInternal(const ID & id, const Element & element,
- const Matrix<Real> & point, Matrix<Real> & extrapolated);
+ virtual void extrapolateInternal(const ID & id, const Element & element,
+ const Matrix<Real> & point,
+ Matrix<Real> & extrapolated);
/// apply a constant eigengrad_u everywhere in the material
- virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & sub_mat_name, const GhostType = _not_ghost);
+ virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
+ const ID & sub_mat_name,
+ const GhostType = _not_ghost);
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
- virtual void computeQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type) const;
+ virtual void computeQuadraturePointsCoordinates(
+ ElementTypeMapArray<Real> & quadrature_points_coordinates,
+ const GhostType & ghost_type) const;
// virtual void onElementsAdded(const Array<Element> & element_list,
// const NewElementsEvent & event) {};
// virtual void onElementsRemoved(const Array<Element> & element_list,
- // const ElementTypeMapArray<UInt> & new_numbering,
+ // const ElementTypeMapArray<UInt> &
+ // new_numbering,
// const RemovedElementsEvent & event) {};
protected:
-
/// constitutive law
virtual void computeStress(__attribute__((unused)) ElementType el_type,
- __attribute__((unused)) GhostType ghost_type = _not_ghost) {
-
- }
+ __attribute__((unused))
+ GhostType ghost_type = _not_ghost) {}
void initialize();
-
- template<ElementType type>
- void setSubMaterial(const Array<Element> & element_list, GhostType ghost_type);
+ template <ElementType type>
+ void setSubMaterial(const Array<Element> & element_list,
+ GhostType ghost_type);
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
const UInt nb_sub_materials;
/// pointer to the solid mechanics model for igfem elements
SolidMechanicsModelIGFEM * model;
- ///internal field of bool to know to which sub-material a quad point belongs
- IGFEMInternalField<UInt> sub_material;
+ /// internal field of bool to know to which sub-material a quad point belongs
+ IGFEMInternalField<UInt> sub_material;
/// material name of first sub-material
std::string name_sub_mat_1;
/// material name of first sub-material
std::string name_sub_mat_2;
-
+
/// map the index of the sub-materials to the names
std::map<UInt, ID> sub_material_names;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_igfem_inline_impl.cc"
-
-
__END_AKANTU__
#include "igfem_internal_field_tmpl.hh"
#endif /* __AKANTU_MATERIAL_IGFEM_HH__ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc
index e20c0edd9..20f8ef6d2 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc
@@ -1,234 +1,243 @@
/**
* @file material_igfem_elastic.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Specializaton of material class for the igfem elastic material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_igfem_elastic.hh"
#include "material_elastic.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-MaterialIGFEMElastic<dim>::MaterialIGFEMElastic(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- Parent(model, id),
- lambda("lambda", *this),
- mu("mu", *this),
- kpa("kappa", *this) {
+template <UInt dim>
+MaterialIGFEMElastic<dim>::MaterialIGFEMElastic(SolidMechanicsModel & model,
+ const ID & id)
+ : Material(model, id), Parent(model, id), lambda("lambda", *this),
+ mu("mu", *this), kpa("kappa", *this) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-void MaterialIGFEMElastic<dim>::initialize() {
- this->lambda .initialize(1);
- this->mu .initialize(1);
- this->kpa .initialize(1);
+template <UInt dim> void MaterialIGFEMElastic<dim>::initialize() {
+ this->lambda.initialize(1);
+ this->mu.initialize(1);
+ this->kpa.initialize(1);
}
-
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-void MaterialIGFEMElastic<dim>::initMaterial() {
+template <UInt dim> void MaterialIGFEMElastic<dim>::initMaterial() {
AKANTU_DEBUG_IN();
Parent::initMaterial();
/// insert the sub_material names into the map
this->sub_material_names[0] = this->name_sub_mat_1;
this->sub_material_names[1] = this->name_sub_mat_2;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMElastic<spatial_dimension>::updateElasticInternals(const Array<Element> & element_list) {
+template <UInt spatial_dimension>
+void MaterialIGFEMElastic<spatial_dimension>::updateElasticInternals(
+ const Array<Element> & element_list) {
/// compute the Lamé constants for both sub-materials
Vector<Real> lambda_per_sub_mat(this->nb_sub_materials);
Vector<Real> mu_per_sub_mat(this->nb_sub_materials);
Vector<Real> kpa_per_sub_mat(this->nb_sub_materials);
for (UInt i = 0; i < this->nb_sub_materials; ++i) {
ID mat_name = this->sub_material_names[i];
- const MaterialElastic<spatial_dimension> & mat = dynamic_cast<MaterialElastic<spatial_dimension> & >(this->model->getMaterial(mat_name));
+ const MaterialElastic<spatial_dimension> & mat =
+ dynamic_cast<MaterialElastic<spatial_dimension> &>(
+ this->model->getMaterial(mat_name));
lambda_per_sub_mat(i) = mat.getLambda();
mu_per_sub_mat(i) = mat.getMu();
kpa_per_sub_mat(i) = mat.getKappa();
}
-
- for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) {
+
+ for (ghost_type_t::iterator g = ghost_type_t::begin();
+ g != ghost_type_t::end(); ++g) {
GhostType ghost_type = *g;
/// loop over all types in the material
- typedef ElementTypeMapArray<UInt>:: type_iterator iterator;
- iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_igfem);
- iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
+ typedef ElementTypeMapArray<UInt>::type_iterator iterator;
+ iterator it = this->element_filter.firstType(spatial_dimension, ghost_type,
+ _ek_igfem);
+ iterator last_type =
+ this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
/// loop over all types in the filter
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
ElementType el_type = *it;
if (el_type == _igfem_triangle_4)
- this->template setSubMaterial<_igfem_triangle_4>(element_list, ghost_type);
+ this->template setSubMaterial<_igfem_triangle_4>(element_list,
+ ghost_type);
else if (el_type == _igfem_triangle_5)
- this->template setSubMaterial<_igfem_triangle_5>(element_list, ghost_type);
+ this->template setSubMaterial<_igfem_triangle_5>(element_list,
+ ghost_type);
else
- AKANTU_DEBUG_ERROR("There is currently no other IGFEM type implemented");
-
+ AKANTU_DEBUG_ERROR(
+ "There is currently no other IGFEM type implemented");
+
UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
UInt nb_quads = this->fem->getNbIntegrationPoints(el_type);
/// get pointer to internals for given type
Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
Real * mu_ptr = this->mu(el_type, ghost_type).storage();
Real * kpa_ptr = this->kpa(el_type, ghost_type).storage();
UInt * sub_mat_ptr = this->sub_material(el_type, ghost_type).storage();
- for (UInt q = 0; q < nb_element * nb_quads; ++q, ++lambda_ptr, ++mu_ptr, ++kpa_ptr, ++sub_mat_ptr) {
- UInt index = *sub_mat_ptr;
- *lambda_ptr = lambda_per_sub_mat(index);
- *mu_ptr = mu_per_sub_mat(index);
- *kpa_ptr = kpa_per_sub_mat(index);
+ for (UInt q = 0; q < nb_element * nb_quads;
+ ++q, ++lambda_ptr, ++mu_ptr, ++kpa_ptr, ++sub_mat_ptr) {
+ UInt index = *sub_mat_ptr;
+ *lambda_ptr = lambda_per_sub_mat(index);
+ *mu_ptr = mu_per_sub_mat(index);
+ *kpa_ptr = kpa_per_sub_mat(index);
}
}
}
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMElastic<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMElastic<spatial_dimension>::computeStress(
+ ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Parent::computeStress(el_type, ghost_type);
if (!this->finite_deformation) {
/// get pointer to internals
Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
Real * mu_ptr = this->mu(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->computeStressOnQuad(grad_u, sigma, *lambda_ptr, *mu_ptr);
++lambda_ptr;
++mu_ptr;
- MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
+ MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
} else {
AKANTU_DEBUG_TO_IMPLEMENT();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMElastic<spatial_dimension>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
- Array<Real> & tangent_matrix,
- __attribute__((unused)) GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMElastic<spatial_dimension>::computeTangentModuli(
+ __attribute__((unused)) const ElementType & el_type,
+ Array<Real> & tangent_matrix,
+ __attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// get pointer to internals
Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
Real * mu_ptr = this->mu(el_type, ghost_type).storage();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
this->computeTangentModuliOnQuad(tangent, *lambda_ptr, *mu_ptr);
++lambda_ptr;
++mu_ptr;
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMElastic<spatial_dimension>::computePotentialEnergy(ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMElastic<spatial_dimension>::computePotentialEnergy(
+ ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
- // MaterialThermal<spatial_dimension>::computePotentialEnergy(el_type, ghost_type);
+ // MaterialThermal<spatial_dimension>::computePotentialEnergy(el_type,
+ // ghost_type);
// if(ghost_type != _not_ghost) return;
- // Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
+ // Array<Real>::scalar_iterator epot = this->potential_energy(el_type,
+ // ghost_type).begin();
// if (!this->finite_deformation) {
// MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
// this->computePotentialEnergyOnQuad(grad_u, sigma, *epot);
// ++epot;
// MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
// } else {
// Matrix<Real> E(spatial_dimension, spatial_dimension);
// MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
// this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
// this->computePotentialEnergyOnQuad(E, sigma, *epot);
// ++epot;
// MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
// }
AKANTU_DEBUG_TO_IMPLEMENT();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMElastic<spatial_dimension>::computePotentialEnergyByElement(ElementType type, UInt index,
- Vector<Real> & epot_on_quad_points) {
+template <UInt spatial_dimension>
+void MaterialIGFEMElastic<spatial_dimension>::computePotentialEnergyByElement(
+ ElementType type, UInt index, Vector<Real> & epot_on_quad_points) {
// Array<Real>::matrix_iterator gradu_it =
// this->gradu(type).begin(spatial_dimension,
// spatial_dimension);
// Array<Real>::matrix_iterator gradu_end =
// this->gradu(type).begin(spatial_dimension,
// spatial_dimension);
// Array<Real>::matrix_iterator stress_it =
// this->stress(type).begin(spatial_dimension,
// spatial_dimension);
// if (this->finite_deformation)
// stress_it = this->piola_kirchhoff_2(type).begin(spatial_dimension,
// spatial_dimension);
- // UInt nb_quadrature_points = this->model->getFEEngine().getNbQuadraturePoints(type);
+ // UInt nb_quadrature_points =
+ // this->model->getFEEngine().getNbQuadraturePoints(type);
// gradu_it += index*nb_quadrature_points;
// gradu_end += (index+1)*nb_quadrature_points;
// stress_it += index*nb_quadrature_points;
// Real * epot_quad = epot_on_quad_points.storage();
// Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
// for(;gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
// if (this->finite_deformation)
- // this->template gradUToGreenStrain<spatial_dimension>(*gradu_it, grad_u);
+ // this->template gradUToGreenStrain<spatial_dimension>(*gradu_it,
+ // grad_u);
// else
// grad_u.copy(*gradu_it);
// this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
// }
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMElastic<spatial_dimension>::onElementsAdded(const Array<Element> & element_list,
- const NewElementsEvent & event) {
-
+template <UInt spatial_dimension>
+void MaterialIGFEMElastic<spatial_dimension>::onElementsAdded(
+ const Array<Element> & element_list, const NewElementsEvent & event) {
+
Parent::onElementsAdded(element_list, event);
updateElasticInternals(element_list);
-
};
INSTANTIATE_MATERIAL(MaterialIGFEMElastic);
__END_AKANTU__
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh
index e9299734e..d340dd36f 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh
@@ -1,136 +1,130 @@
/**
* @file element_class_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
*
* @brief Material isotropic elastic for IGFEM
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_igfem.hh"
#include "plane_stress_toolbox.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_IGFEM_ELASTIC_HH__
#define __AKANTU_MATERIAL_IGFEM_ELASTIC_HH__
__BEGIN_AKANTU__
/**
* Material elastic isotropic
*
* parameters in the material files :
* - E : Young's modulus (default: 0)
* - nu : Poisson's ratio (default: 1/2)
* - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
*/
-template<UInt spatial_dimension>
-class MaterialIGFEMElastic : public PlaneStressToolbox< spatial_dimension,
- MaterialIGFEM > {
+template <UInt spatial_dimension>
+class MaterialIGFEMElastic
+ : public PlaneStressToolbox<spatial_dimension, MaterialIGFEM> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
private:
- typedef PlaneStressToolbox< spatial_dimension, MaterialIGFEM > Parent;
-public:
+ typedef PlaneStressToolbox<spatial_dimension, MaterialIGFEM> Parent;
+public:
MaterialIGFEMElastic(SolidMechanicsModel & model, const ID & id = "");
- MaterialIGFEMElastic(SolidMechanicsModel & model,
- UInt dim,
- const Mesh & mesh,
- FEEngine & fe_engine,
- const ID & id = "");
+ MaterialIGFEMElastic(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
+ FEEngine & fe_engine, const ID & id = "");
virtual ~MaterialIGFEMElastic() {}
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
virtual void initMaterial();
/// constitutive law for all element of a type
- virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
+ virtual void computeStress(ElementType el_type,
+ GhostType ghost_type = _not_ghost);
/// compute the tangent stiffness matrix for an element type
virtual void computeTangentModuli(const ElementType & el_type,
- Array<Real> & tangent_matrix,
- GhostType ghost_type = _not_ghost);
+ Array<Real> & tangent_matrix,
+ GhostType ghost_type = _not_ghost);
/// compute the elastic potential energy
virtual void computePotentialEnergy(ElementType el_type,
- GhostType ghost_type = _not_ghost);
+ GhostType ghost_type = _not_ghost);
- virtual void computePotentialEnergyByElement(ElementType type, UInt index,
- Vector<Real> & epot_on_quad_points);
+ virtual void
+ computePotentialEnergyByElement(ElementType type, UInt index,
+ Vector<Real> & epot_on_quad_points);
void updateElasticInternals(const Array<Element> & element_list);
-
protected:
-
/// constitutive law for a given quadrature point
inline void computeStressOnQuad(const Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- __attribute__((unused)) const Real lambda,
- const Real mu) const;
+ Matrix<Real> & sigma,
+ __attribute__((unused)) const Real lambda,
+ const Real mu) const;
/// compute the tangent stiffness matrix for an element
inline void computeTangentModuliOnQuad(Matrix<Real> & tangent,
- __attribute__((unused)) const Real lambda,
- const Real mu) const;
+ __attribute__((unused))
+ const Real lambda,
+ const Real mu) const;
static inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
- const Matrix<Real> & sigma,
- Real & epot);
+ const Matrix<Real> & sigma,
+ Real & epot);
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
virtual void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// First Lamé coefficient
IGFEMInternalField<Real> lambda;
/// Second Lamé coefficient (shear modulus)
IGFEMInternalField<Real> mu;
/// Bulk modulus
IGFEMInternalField<Real> kpa;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_igfem_elastic_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_IGFEM_ELASTIC_HH__ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.cc b/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.cc
index 2dd4d98c7..f958cfa38 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.cc
@@ -1,96 +1,92 @@
/**
* @file material_igfem_elastic_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Implementation of the inline functions of the material igfem elastic
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(const Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- const Real lambda,
- const Real mu) const {
+template <UInt spatial_dimension>
+inline void MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(
+ const Matrix<Real> & grad_u, Matrix<Real> & sigma, const Real lambda,
+ const Real mu) const {
Real trace = grad_u.trace(); // trace = (\nabla u)_{kk}
- // \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla u_{ij} + \nabla u_{ji})
+ // \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
+ // u_{ij} + \nabla u_{ji})
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
- sigma(i, j) = (i == j)*lambda*trace + mu*(grad_u(i, j) + grad_u(j, i));
+ sigma(i, j) =
+ (i == j) * lambda * trace + mu * (grad_u(i, j) + grad_u(j, i));
}
}
-
}
/* -------------------------------------------------------------------------- */
-template<>
-inline void MaterialIGFEMElastic<1>::computeStressOnQuad(const Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- const Real lambda,
- const Real mu) const {
+template <>
+inline void MaterialIGFEMElastic<1>::computeStressOnQuad(
+ const Matrix<Real> & grad_u, Matrix<Real> & sigma, const Real lambda,
+ const Real mu) const {
sigma(0, 0) = 2 * mu * grad_u(0, 0);
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void MaterialIGFEMElastic<spatial_dimension>::computeTangentModuliOnQuad(Matrix<Real> & tangent,
- const Real lambda,
- const Real mu) const {
+template <UInt spatial_dimension>
+inline void MaterialIGFEMElastic<spatial_dimension>::computeTangentModuliOnQuad(
+ Matrix<Real> & tangent, const Real lambda, const Real mu) const {
UInt n = tangent.cols();
- //Real Ep = E/((1+nu)*(1-2*nu));
- Real Miiii = lambda + 2*mu;
+ // Real Ep = E/((1+nu)*(1-2*nu));
+ Real Miiii = lambda + 2 * mu;
Real Miijj = lambda;
Real Mijij = mu;
- if(spatial_dimension == 1)
+ if (spatial_dimension == 1)
tangent(0, 0) = 3 * mu;
else
tangent(0, 0) = Miiii;
- // test of dimension should by optimized out by the compiler due to the template
- if(spatial_dimension >= 2) {
+ // test of dimension should by optimized out by the compiler due to the
+ // template
+ if (spatial_dimension >= 2) {
tangent(1, 1) = Miiii;
tangent(0, 1) = Miijj;
tangent(1, 0) = Miijj;
tangent(n - 1, n - 1) = Mijij;
}
- if(spatial_dimension == 3) {
+ if (spatial_dimension == 3) {
tangent(2, 2) = Miiii;
tangent(0, 2) = Miijj;
tangent(1, 2) = Miijj;
tangent(2, 0) = Miijj;
tangent(2, 1) = Miijj;
tangent(3, 3) = Mijij;
tangent(4, 4) = Mijij;
}
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-inline void MaterialIGFEMElastic<dim>::computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
- const Matrix<Real> & sigma,
- Real & epot) {
+template <UInt dim>
+inline void MaterialIGFEMElastic<dim>::computePotentialEnergyOnQuad(
+ const Matrix<Real> & grad_u, const Matrix<Real> & sigma, Real & epot) {
AKANTU_DEBUG_TO_IMPLEMENT();
/// epot = .5 * sigma.doubleDot(grad_u);
}
/* -------------------------------------------------------------------------- */
-template<>
-inline void MaterialIGFEMElastic<1>::computeTangentModuliOnQuad(Matrix<Real> & tangent,
- const Real lambda,
- const Real mu) const {
+template <>
+inline void MaterialIGFEMElastic<1>::computeTangentModuliOnQuad(
+ Matrix<Real> & tangent, const Real lambda, const Real mu) const {
tangent(0, 0) = 2 * mu;
}
-
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_includes.hh b/extra_packages/igfem/src/material_igfem/material_igfem_includes.hh
index d7aae56bf..4e9179fad 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_includes.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_includes.hh
@@ -1,27 +1,28 @@
/**
* @file material_igfem_includes.hh
*
* @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief list of IGFEM materials
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
#include "material_igfem.hh"
#include "material_igfem_elastic.hh"
-#include "material_igfem_saw_tooth_damage.hh"
#include "material_igfem_iterative_stiffness_reduction.hh"
+#include "material_igfem_saw_tooth_damage.hh"
#endif
-#define AKANTU_IGFEM_MATERIAL_LIST \
- ((2, (igfem_elastic, MaterialIGFEMElastic ))) \
- ((2, (igfem_saw_tooth_damage, MaterialIGFEMSawToothDamage))) \
- ((2, (igfem_iterative_stiffness_reduction, MaterialIGFEMIterativeStiffnessReduction)))
+#define AKANTU_IGFEM_MATERIAL_LIST \
+ ((2, (igfem_elastic, MaterialIGFEMElastic)))( \
+ (2, (igfem_saw_tooth_damage, MaterialIGFEMSawToothDamage)))( \
+ (2, (igfem_iterative_stiffness_reduction, \
+ MaterialIGFEMIterativeStiffnessReduction)))
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_inline_impl.cc b/extra_packages/igfem/src/material_igfem/material_igfem_inline_impl.cc
index 06edbd69e..fc3380c57 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_inline_impl.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_inline_impl.cc
@@ -1,61 +1,62 @@
/**
* @file material_igfem_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Implementation of the inline functions of the parent
* material for IGFEM
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
__END_AKANTU__
-#include "solid_mechanics_model_igfem.hh"
#include "igfem_helper.hh"
+#include "solid_mechanics_model_igfem.hh"
#include <iostream>
__BEGIN_AKANTU__
-
/* -------------------------------------------------------------------------- */
inline UInt MaterialIGFEM::getNbDataForElements(const Array<Element> & elements,
- SynchronizationTag tag) const {
- if(tag == _gst_smm_stress) {
- return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension * spatial_dimension *
- sizeof(Real) * this->getModel().getNbIntegrationPoints(elements, "IGFEMFEEngine");
+ SynchronizationTag tag) const {
+ if (tag == _gst_smm_stress) {
+ return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension *
+ spatial_dimension * sizeof(Real) *
+ this->getModel().getNbIntegrationPoints(elements, "IGFEMFEEngine");
}
return 0;
}
-
/* -------------------------------------------------------------------------- */
inline void MaterialIGFEM::packElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) const {
- if(tag == _gst_smm_stress) {
- if(this->isFiniteDeformation()) {
- packElementDataHelper(piola_kirchhoff_2, buffer, elements, "IGFEMFEEngine");
+ const Array<Element> & elements,
+ SynchronizationTag tag) const {
+ if (tag == _gst_smm_stress) {
+ if (this->isFiniteDeformation()) {
+ packElementDataHelper(piola_kirchhoff_2, buffer, elements,
+ "IGFEMFEEngine");
packElementDataHelper(gradu, buffer, elements, "IGFEMFEEngine");
}
packElementDataHelper(stress, buffer, elements, "IGFEMFEEngine");
}
}
/* -------------------------------------------------------------------------- */
inline void MaterialIGFEM::unpackElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) {
- if(tag == _gst_smm_stress) {
- if(this->isFiniteDeformation()) {
- unpackElementDataHelper(piola_kirchhoff_2, buffer, elements, "IGFEMFEEngine");
+ const Array<Element> & elements,
+ SynchronizationTag tag) {
+ if (tag == _gst_smm_stress) {
+ if (this->isFiniteDeformation()) {
+ unpackElementDataHelper(piola_kirchhoff_2, buffer, elements,
+ "IGFEMFEEngine");
unpackElementDataHelper(gradu, buffer, elements, "IGFEMFEEngine");
}
unpackElementDataHelper(stress, buffer, elements, "IGFEMFEEngine");
}
}
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc
index e97ac1c62..ff05539c6 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc
@@ -1,257 +1,289 @@
/**
* @file material_igfem_iterative_stiffness_reduction.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Mar 10 08:37:43 2016
*
* @brief Implementation of igfem material iterative stiffness reduction
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_igfem_iterative_stiffness_reduction.hh"
#include <math.h>
__BEGIN_AKANTU__
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
/* -------------------------------------------------------------------------- */
-MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::MaterialIGFEMIterativeStiffnessReduction(SolidMechanicsModel & model,
- const ID & id) :
- Material(model, id),
- MaterialIGFEMSawToothDamage<spatial_dimension>(model, id),
- eps_u("ultimate_strain", *this),
- reduction_step("damage_step", *this),
- D("tangent", *this),
- Gf(0.),
- crack_band_width(0.),
- max_reductions(0),
- reduction_constant(0.) {
+MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::
+ MaterialIGFEMIterativeStiffnessReduction(SolidMechanicsModel & model,
+ const ID & id)
+ : Material(model, id), MaterialIGFEMSawToothDamage<spatial_dimension>(model,
+ id),
+ eps_u("ultimate_strain", *this), reduction_step("damage_step", *this),
+ D("tangent", *this), Gf(0.), crack_band_width(0.), max_reductions(0),
+ reduction_constant(0.) {
AKANTU_DEBUG_IN();
this->eps_u.initialize(1);
this->D.initialize(1);
this->reduction_step.initialize(1);
-
+
this->internals_to_transfer.push_back("ultimate_strain");
this->internals_to_transfer.push_back("tangent");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
+template <UInt dim>
void MaterialIGFEMIterativeStiffnessReduction<dim>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialIGFEMSawToothDamage<dim>::initMaterial();
/// get the parameters for the sub-material that can be damaged
ID mat_name = this->sub_material_names[1];
- const Material & mat = this->model->getMaterial(mat_name);
+ const Material & mat = this->model->getMaterial(mat_name);
this->crack_band_width = mat.getParam<Real>("crack_band_width");
this->max_reductions = mat.getParam<UInt>("max_reductions");
this->reduction_constant = mat.getParam<Real>("reduction_constant");
this->Gf = mat.getParam<Real>("Gf");
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::computeNormalizedEquivalentStress(const Array<Real> & grad_u,
- ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::
+ computeNormalizedEquivalentStress(const Array<Real> & grad_u,
+ ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// storage for the current stress
Matrix<Real> sigma(spatial_dimension, spatial_dimension);
/// Vector to store eigenvalues of current stress tensor
Vector<Real> eigenvalues(spatial_dimension);
/// iterators on the needed internal fields
- Array<Real>::const_scalar_iterator Sc_it = this->Sc(el_type, ghost_type).begin();
- Array<Real>::scalar_iterator dam_it = this->damage(el_type, ghost_type).begin();
- Array<Real>::scalar_iterator equivalent_stress_it = this->equivalent_stress(el_type, ghost_type).begin();
- Array<Real>::const_matrix_iterator grad_u_it = grad_u.begin(spatial_dimension,
- spatial_dimension);
- Array<Real>::const_matrix_iterator grad_u_end = grad_u.end(spatial_dimension,
- spatial_dimension);
+ Array<Real>::const_scalar_iterator Sc_it =
+ this->Sc(el_type, ghost_type).begin();
+ Array<Real>::scalar_iterator dam_it =
+ this->damage(el_type, ghost_type).begin();
+ Array<Real>::scalar_iterator equivalent_stress_it =
+ this->equivalent_stress(el_type, ghost_type).begin();
+ Array<Real>::const_matrix_iterator grad_u_it =
+ grad_u.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::const_matrix_iterator grad_u_end =
+ grad_u.end(spatial_dimension, spatial_dimension);
Real * mu_ptr = this->mu(el_type, ghost_type).storage();
Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
-
+
/// loop over all the quadrature points and compute the equivalent stress
- for(;grad_u_it != grad_u_end; ++grad_u_it) {
+ for (; grad_u_it != grad_u_end; ++grad_u_it) {
/// compute the stress
sigma.clear();
- MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(*grad_u_it, sigma, *lambda_ptr, *mu_ptr);
- MaterialIGFEMSawToothDamage<spatial_dimension>::computeDamageAndStressOnQuad(sigma, *dam_it);
+ MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(
+ *grad_u_it, sigma, *lambda_ptr, *mu_ptr);
+ MaterialIGFEMSawToothDamage<
+ spatial_dimension>::computeDamageAndStressOnQuad(sigma, *dam_it);
/// compute eigenvalues
sigma.eig(eigenvalues);
/// find max eigenvalue and normalize by tensile strength
- *equivalent_stress_it = *(std::max_element(eigenvalues.storage(),
- eigenvalues.storage() + spatial_dimension)) / (*Sc_it);
+ *equivalent_stress_it =
+ *(std::max_element(eigenvalues.storage(),
+ eigenvalues.storage() + spatial_dimension)) /
+ (*Sc_it);
++Sc_it;
++equivalent_stress_it;
++dam_it;
++lambda_ptr;
++mu_ptr;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-UInt MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::updateDamage() {
+template <UInt spatial_dimension>
+UInt MaterialIGFEMIterativeStiffnessReduction<
+ spatial_dimension>::updateDamage() {
UInt nb_damaged_elements = 0;
if (this->norm_max_equivalent_stress >= 1.) {
AKANTU_DEBUG_IN();
- /// update the damage only on non-ghosts elements! Doesn't make sense to update on ghost.
- GhostType ghost_type = _not_ghost;;
+ /// update the damage only on non-ghosts elements! Doesn't make sense to
+ /// update on ghost.
+ GhostType ghost_type = _not_ghost;
+ ;
- Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type, _ek_igfem);
- Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(
+ spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator last_type =
+ this->model->getFEEngine().getMesh().lastType(spatial_dimension,
+ ghost_type, _ek_igfem);
- /// get the Young's modulus of the damageable sub-material
+ /// get the Young's modulus of the damageable sub-material
ID mat_name = this->sub_material_names[1];
Real E = this->model->getMaterial(mat_name).template getParam<Real>("E");
-
+
/// loop over all the elements
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
ElementType el_type = *it;
/// get iterators on the needed internal fields
const Array<UInt> & sub_mat = this->sub_material(el_type, ghost_type);
Array<UInt>::const_scalar_iterator sub_mat_it = sub_mat.begin();
- Array<Real>::const_scalar_iterator equivalent_stress_it = this->equivalent_stress(el_type, ghost_type).begin();
- Array<Real>::const_scalar_iterator equivalent_stress_end = this->equivalent_stress(el_type, ghost_type).end();
- Array<Real>::scalar_iterator dam_it = this->damage(el_type, ghost_type).begin();
- Array<UInt>::scalar_iterator reduction_it = this->reduction_step(el_type, ghost_type).begin();
- Array<Real>::const_scalar_iterator eps_u_it = this->eps_u(el_type, ghost_type).begin();
- Array<Real>::scalar_iterator Sc_it = this->Sc(el_type, ghost_type).begin();
- Array<Real>::const_scalar_iterator D_it = this->D(el_type, ghost_type).begin();
+ Array<Real>::const_scalar_iterator equivalent_stress_it =
+ this->equivalent_stress(el_type, ghost_type).begin();
+ Array<Real>::const_scalar_iterator equivalent_stress_end =
+ this->equivalent_stress(el_type, ghost_type).end();
+ Array<Real>::scalar_iterator dam_it =
+ this->damage(el_type, ghost_type).begin();
+ Array<UInt>::scalar_iterator reduction_it =
+ this->reduction_step(el_type, ghost_type).begin();
+ Array<Real>::const_scalar_iterator eps_u_it =
+ this->eps_u(el_type, ghost_type).begin();
+ Array<Real>::scalar_iterator Sc_it =
+ this->Sc(el_type, ghost_type).begin();
+ Array<Real>::const_scalar_iterator D_it =
+ this->D(el_type, ghost_type).begin();
/// loop over all the elements of the given type
UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
UInt nb_quads = this->fem->getNbIntegrationPoints(el_type, ghost_type);
bool damage_element = false;
for (UInt e = 0; e < nb_element; ++e) {
- damage_element = false;
- /// check if damage occurs in the element
- for (UInt q = 0; q < nb_quads; ++q, ++reduction_it, ++sub_mat_it, ++equivalent_stress_it) {
- if (*equivalent_stress_it >= (1 - this->dam_tolerance) * this->norm_max_equivalent_stress && *sub_mat_it != 0) {
- /// check if this element can still be damaged
- if (*reduction_it == this->max_reductions)
- continue;
- damage_element = true;
- }
- }
-
- if (damage_element) {
- /// damage the element
- nb_damaged_elements += 1;
- sub_mat_it -= nb_quads;
- reduction_it -= nb_quads;
- for (UInt q = 0; q < nb_quads; ++q) {
- if (*sub_mat_it) {
- /// increment the counter of stiffness reduction steps
- *reduction_it += 1;
- if (*reduction_it == this->max_reductions)
- *dam_it = this->max_damage;
- else {
- /// update the damage on this quad
- *dam_it = 1. - (1./std::pow(this->reduction_constant, *reduction_it));
- /// update the stiffness on this quad
- *Sc_it = (*eps_u_it) * (1. - (*dam_it) ) * E * (*D_it)/ ((1. - (*dam_it) ) * E + (*D_it));
- }
- }
- ++sub_mat_it;
- ++dam_it;
- ++reduction_it;
- ++eps_u_it;
- ++Sc_it;
- ++D_it;
- }
- }
- else {
- dam_it += nb_quads;
- eps_u_it += nb_quads;
- Sc_it += nb_quads;
- D_it +=nb_quads;
- }
+ damage_element = false;
+ /// check if damage occurs in the element
+ for (UInt q = 0; q < nb_quads;
+ ++q, ++reduction_it, ++sub_mat_it, ++equivalent_stress_it) {
+ if (*equivalent_stress_it >= (1 - this->dam_tolerance) *
+ this->norm_max_equivalent_stress &&
+ *sub_mat_it != 0) {
+ /// check if this element can still be damaged
+ if (*reduction_it == this->max_reductions)
+ continue;
+ damage_element = true;
+ }
+ }
+
+ if (damage_element) {
+ /// damage the element
+ nb_damaged_elements += 1;
+ sub_mat_it -= nb_quads;
+ reduction_it -= nb_quads;
+ for (UInt q = 0; q < nb_quads; ++q) {
+ if (*sub_mat_it) {
+ /// increment the counter of stiffness reduction steps
+ *reduction_it += 1;
+ if (*reduction_it == this->max_reductions)
+ *dam_it = this->max_damage;
+ else {
+ /// update the damage on this quad
+ *dam_it = 1. - (1. / std::pow(this->reduction_constant,
+ *reduction_it));
+ /// update the stiffness on this quad
+ *Sc_it = (*eps_u_it) * (1. - (*dam_it)) * E * (*D_it) /
+ ((1. - (*dam_it)) * E + (*D_it));
+ }
+ }
+ ++sub_mat_it;
+ ++dam_it;
+ ++reduction_it;
+ ++eps_u_it;
+ ++Sc_it;
+ ++D_it;
+ }
+ } else {
+ dam_it += nb_quads;
+ eps_u_it += nb_quads;
+ Sc_it += nb_quads;
+ D_it += nb_quads;
+ }
}
}
}
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
comm.allReduce(&nb_damaged_elements, 1, _so_sum);
AKANTU_DEBUG_OUT();
return nb_damaged_elements;
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::onElementsAdded(__attribute__((unused)) const Array<Element> & element_list,
- __attribute__((unused)) const NewElementsEvent & event) {
+template <UInt spatial_dimension>
+void MaterialIGFEMIterativeStiffnessReduction<
+ spatial_dimension>::onElementsAdded(__attribute__((unused))
+ const Array<Element> & element_list,
+ __attribute__((unused))
+ const NewElementsEvent & event) {
- MaterialIGFEMSawToothDamage<spatial_dimension>::onElementsAdded(element_list, event);
+ MaterialIGFEMSawToothDamage<spatial_dimension>::onElementsAdded(element_list,
+ event);
/// set the correct damage iteration step (is UInt->cannot be interpolated)
Real val = 0.;
- for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) {
+ for (ghost_type_t::iterator g = ghost_type_t::begin();
+ g != ghost_type_t::end(); ++g) {
GhostType ghost_type = *g;
/// loop over all types in the material
- typedef ElementTypeMapArray<UInt>:: type_iterator iterator;
- iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_igfem);
- iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
+ typedef ElementTypeMapArray<UInt>::type_iterator iterator;
+ iterator it = this->element_filter.firstType(spatial_dimension, ghost_type,
+ _ek_igfem);
+ iterator last_type =
+ this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
/// loop over all types in the filter
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
const ElementType el_type = *it;
- Array<Real>::scalar_iterator dam_it = this->damage(el_type, ghost_type).begin();
- Array<UInt>::scalar_iterator reduction_it = this->reduction_step(el_type, ghost_type).begin();
+ Array<Real>::scalar_iterator dam_it =
+ this->damage(el_type, ghost_type).begin();
+ Array<UInt>::scalar_iterator reduction_it =
+ this->reduction_step(el_type, ghost_type).begin();
UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
UInt nb_quads = this->fem->getNbIntegrationPoints(el_type);
UInt * sub_mat_ptr = this->sub_material(el_type, ghost_type).storage();
- for (UInt q = 0; q < nb_element * nb_quads; ++q, ++sub_mat_ptr, ++dam_it, ++reduction_it) {
- if (*sub_mat_ptr) {
- if (Math::are_float_equal(*dam_it, this->max_damage))
- *reduction_it = this->max_reductions;
- else {
- for (UInt i = 0; i < this->max_reductions; ++i) {
- val = 1 - (1./std::pow(this->reduction_constant, i));
- if (Math::are_float_equal(val, *dam_it))
- *reduction_it = i;
- }
- }
- }
+ for (UInt q = 0; q < nb_element * nb_quads;
+ ++q, ++sub_mat_ptr, ++dam_it, ++reduction_it) {
+ if (*sub_mat_ptr) {
+ if (Math::are_float_equal(*dam_it, this->max_damage))
+ *reduction_it = this->max_reductions;
+ else {
+ for (UInt i = 0; i < this->max_reductions; ++i) {
+ val = 1 - (1. / std::pow(this->reduction_constant, i));
+ if (Math::are_float_equal(val, *dam_it))
+ *reduction_it = i;
+ }
+ }
+ }
}
}
}
}
/* -------------------------------------------------------------------------- */
-
-INSTANTIATE_MATERIAL(MaterialIGFEMIterativeStiffnessReduction);
+INSTANTIATE_MATERIAL(MaterialIGFEMIterativeStiffnessReduction);
__END_AKANTU__
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh
index 752e715c0..824f55b29 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh
@@ -1,113 +1,114 @@
/**
* @file material_igfem_iterative_stiffness_reduction.hh
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Wed Mar 9 19:44:22 2016
*
* @brief Material for iterative stiffness reduction by contant factor
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_igfem_saw_tooth_damage.hh"
/* -------------------------------------------------------------------------- */
- #ifndef __AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH__
- #define __AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH__
+#ifndef __AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH__
+#define __AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH__
__BEGIN_AKANTU__
/**
* Material damage iterative
*
* parameters in the material files :
* - Gfx
* - h
- * - Sc
+ * - Sc
*/
-/// Proposed by Rots and Invernizzi, 2004: Regularized sequentially linear
+/// Proposed by Rots and Invernizzi, 2004: Regularized sequentially linear
// saw-tooth softening model (section 4.2)
-template<UInt spatial_dimension>
-class MaterialIGFEMIterativeStiffnessReduction : public MaterialIGFEMSawToothDamage<spatial_dimension> {
+template <UInt spatial_dimension>
+class MaterialIGFEMIterativeStiffnessReduction
+ : public MaterialIGFEMSawToothDamage<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
+ MaterialIGFEMIterativeStiffnessReduction(SolidMechanicsModel & model,
+ const ID & id = "");
- MaterialIGFEMIterativeStiffnessReduction(SolidMechanicsModel & model, const ID & id = "");
-
- virtual ~MaterialIGFEMIterativeStiffnessReduction() {};
+ virtual ~MaterialIGFEMIterativeStiffnessReduction(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// set the material parameters
virtual void initMaterial();
- ///compute the equivalent stress on each Gauss point (i.e. the max prinicpal stress) and normalize it by the tensile stiffness
- virtual void computeNormalizedEquivalentStress(const Array<Real> & grad_u,
- ElementType el_type, GhostType ghost_type = _not_ghost);
+ /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
+ /// stress) and normalize it by the tensile stiffness
+ virtual void
+ computeNormalizedEquivalentStress(const Array<Real> & grad_u,
+ ElementType el_type,
+ GhostType ghost_type = _not_ghost);
/// update internal field damage
virtual UInt updateDamage();
- virtual void onElementsAdded(const Array<Element> & element_list, const NewElementsEvent & event);
+ virtual void onElementsAdded(const Array<Element> & element_list,
+ const NewElementsEvent & event);
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// the ultimate strain
IGFEMInternalField<Real> eps_u;
/// the reduction
IGFEMInternalField<UInt> reduction_step;
/// the tangent of the tensile stress-strain softening
IGFEMInternalField<Real> D;
/// fracture energy
Real Gf;
/// crack band width for normalization of fracture energy
Real crack_band_width;
/// the number of total reductions steps until complete failure
UInt max_reductions;
/// the reduction constant (denoated by a in the paper of rots)
Real reduction_constant;
};
-
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH__ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc
index 7cf894b69..45be83bda 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc
@@ -1,418 +1,468 @@
/**
* @file material_igfem_saw_tooth_damage.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
- * @brief Implementation of the squentially linear saw-tooth damage model for IGFEM elements
+ * @brief Implementation of the squentially linear saw-tooth damage model for
+ * IGFEM elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_igfem_saw_tooth_damage.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-MaterialIGFEMSawToothDamage<dim>::MaterialIGFEMSawToothDamage(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- Parent(model, id),
- Sc("Sc", *this),
- equivalent_stress("equivalent_stress", *this),
- norm_max_equivalent_stress(0) {
+template <UInt dim>
+MaterialIGFEMSawToothDamage<dim>::MaterialIGFEMSawToothDamage(
+ SolidMechanicsModel & model, const ID & id)
+ : Material(model, id), Parent(model, id), Sc("Sc", *this),
+ equivalent_stress("equivalent_stress", *this),
+ norm_max_equivalent_stress(0) {
AKANTU_DEBUG_IN();
this->Sc.initialize(1);
this->equivalent_stress.initialize(1);
this->damage.setElementKind(_ek_igfem);
this->damage.setFEEngine(*(this->fem));
this->internals_to_transfer.push_back("damage");
this->internals_to_transfer.push_back("Sc");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-void MaterialIGFEMSawToothDamage<dim>::initMaterial() {
+template <UInt dim> void MaterialIGFEMSawToothDamage<dim>::initMaterial() {
AKANTU_DEBUG_IN();
Parent::initMaterial();
/// get the parameters for the sub-material that can be damaged
ID mat_name = this->sub_material_names[1];
- const Material & mat = this->model->getMaterial(mat_name);
+ const Material & mat = this->model->getMaterial(mat_name);
this->prescribed_dam = mat.getParam<Real>("prescribed_dam");
this->dam_threshold = mat.getParam<Real>("dam_threshold");
this->dam_tolerance = mat.getParam<Real>("dam_tolerance");
this->max_damage = mat.getParam<Real>("max_damage");
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMSawToothDamage<spatial_dimension>::computeNormalizedEquivalentStress(const Array<Real> & grad_u,
- ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMSawToothDamage<spatial_dimension>::
+ computeNormalizedEquivalentStress(const Array<Real> & grad_u,
+ ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// Vector to store eigenvalues of current stress tensor
Vector<Real> eigenvalues(spatial_dimension);
Array<Real>::const_iterator<Real> Sc_it = Sc(el_type, ghost_type).begin();
- Array<Real>::iterator<Real> equivalent_stress_it = equivalent_stress(el_type, ghost_type).begin();
+ Array<Real>::iterator<Real> equivalent_stress_it =
+ equivalent_stress(el_type, ghost_type).begin();
- Array<Real>::const_matrix_iterator grad_u_it = grad_u.begin(spatial_dimension,
- spatial_dimension);
- Array<Real>::const_matrix_iterator grad_u_end = grad_u.end(spatial_dimension,
- spatial_dimension);
+ Array<Real>::const_matrix_iterator grad_u_it =
+ grad_u.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::const_matrix_iterator grad_u_end =
+ grad_u.end(spatial_dimension, spatial_dimension);
/// get pointer to internals
Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
Real * mu_ptr = this->mu(el_type, ghost_type).storage();
Real * dam = this->damage(el_type, ghost_type).storage();
Matrix<Real> sigma(spatial_dimension, spatial_dimension);
- for(;grad_u_it != grad_u_end; ++ grad_u_it) {
+ for (; grad_u_it != grad_u_end; ++grad_u_it) {
sigma.clear();
- MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(*grad_u_it, sigma, *lambda_ptr, *mu_ptr);
- computeDamageAndStressOnQuad(sigma,*dam);
+ MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(
+ *grad_u_it, sigma, *lambda_ptr, *mu_ptr);
+ computeDamageAndStressOnQuad(sigma, *dam);
/// compute eigenvalues
sigma.eig(eigenvalues);
/// find max eigenvalue and normalize by tensile strength
- *equivalent_stress_it = *(std::max_element(eigenvalues.storage(),
- eigenvalues.storage() + spatial_dimension)) / *(Sc_it);
+ *equivalent_stress_it =
+ *(std::max_element(eigenvalues.storage(),
+ eigenvalues.storage() + spatial_dimension)) /
+ *(Sc_it);
++Sc_it;
++equivalent_stress_it;
++dam;
++lambda_ptr;
++mu_ptr;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMSawToothDamage<spatial_dimension>::computeAllStresses(GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMSawToothDamage<spatial_dimension>::computeAllStresses(
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// reset normalized maximum equivalent stress
- if(ghost_type==_not_ghost)
+ if (ghost_type == _not_ghost)
norm_max_equivalent_stress = 0;
-
+
Parent::computeAllStresses(ghost_type);
/// find global Gauss point with highest stress
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
comm.allReduce(&norm_max_equivalent_stress, 1, _so_max);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMSawToothDamage<spatial_dimension>::findMaxNormalizedEquivalentStress(ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMSawToothDamage<spatial_dimension>::
+ findMaxNormalizedEquivalentStress(ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
- if(ghost_type==_not_ghost) {
+ if (ghost_type == _not_ghost) {
const Array<Real> & e_stress = equivalent_stress(el_type);
Array<Real>::const_iterator<Real> equivalent_stress_it = e_stress.begin();
Array<Real>::const_iterator<Real> equivalent_stress_end = e_stress.end();
Array<Real> & dam = this->damage(el_type);
Array<Real>::iterator<Real> dam_it = dam.begin();
Array<UInt> & sub_mat = this->sub_material(el_type);
Array<UInt>::iterator<UInt> sub_mat_it = sub_mat.begin();
- for (; equivalent_stress_it != equivalent_stress_end; ++equivalent_stress_it, ++dam_it, ++sub_mat_it ) {
- /// check if max equivalent stress for this element type is greater than the current norm_max_eq_stress and if the element is not already fully damaged
- if ( (*equivalent_stress_it > norm_max_equivalent_stress && *dam_it < max_damage) && *sub_mat_it != 0) {
- norm_max_equivalent_stress = *equivalent_stress_it;
+ for (; equivalent_stress_it != equivalent_stress_end;
+ ++equivalent_stress_it, ++dam_it, ++sub_mat_it) {
+ /// check if max equivalent stress for this element type is greater than
+ /// the current norm_max_eq_stress and if the element is not already fully
+ /// damaged
+ if ((*equivalent_stress_it > norm_max_equivalent_stress &&
+ *dam_it < max_damage) &&
+ *sub_mat_it != 0) {
+ norm_max_equivalent_stress = *equivalent_stress_it;
}
-
}
-
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMSawToothDamage<spatial_dimension>::computeStress(ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialIGFEMSawToothDamage<spatial_dimension>::computeStress(
+ ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
-
Parent::computeStress(el_type, ghost_type);
Real * dam = this->damage(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
- computeDamageAndStressOnQuad(sigma,*dam);
+ computeDamageAndStressOnQuad(sigma, *dam);
++dam;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
- computeNormalizedEquivalentStress(this->gradu(el_type, ghost_type), el_type, ghost_type);
+ computeNormalizedEquivalentStress(this->gradu(el_type, ghost_type), el_type,
+ ghost_type);
norm_max_equivalent_stress = 0;
findMaxNormalizedEquivalentStress(el_type, ghost_type);
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
UInt MaterialIGFEMSawToothDamage<spatial_dimension>::updateDamage() {
UInt nb_damaged_elements = 0;
AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
- "Your prescribed damage must be greater than zero");
+ "Your prescribed damage must be greater than zero");
if (norm_max_equivalent_stress >= 1.) {
AKANTU_DEBUG_IN();
- GhostType ghost_type = _not_ghost;;
+ GhostType ghost_type = _not_ghost;
+ ;
- Mesh::type_iterator it = this->model->getMesh().firstType(spatial_dimension, ghost_type, _ek_igfem);
- Mesh::type_iterator last_type = this->model->getMesh().lastType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator it = this->model->getMesh().firstType(
+ spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator last_type = this->model->getMesh().lastType(
+ spatial_dimension, ghost_type, _ek_igfem);
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
ElementType el_type = *it;
Array<UInt> & sub_mat = this->sub_material(el_type);
Array<UInt>::iterator<UInt> sub_mat_it = sub_mat.begin();
const Array<Real> & e_stress = equivalent_stress(el_type);
Array<Real>::const_iterator<Real> equivalent_stress_it = e_stress.begin();
Array<Real>::const_iterator<Real> equivalent_stress_end = e_stress.end();
Array<Real> & dam = this->damage(el_type);
Array<Real>::iterator<Real> dam_it = dam.begin();
/// loop over all the elements of the given type
UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
UInt nb_quads = this->fem->getNbIntegrationPoints(el_type, ghost_type);
bool damage_element = false;
for (UInt e = 0; e < nb_element; ++e) {
- damage_element = false;
- /// check if damage occurs in the element
- for (UInt q = 0; q < nb_quads; ++q) {
- if (*equivalent_stress_it >= (1-dam_tolerance)*norm_max_equivalent_stress && *sub_mat_it != 0) {
- damage_element = true;
- }
- ++sub_mat_it;
- ++equivalent_stress_it;
- }
-
- if (damage_element) {
- nb_damaged_elements += 1;
- /// damage the element
- sub_mat_it -= nb_quads;
- for (UInt q = 0; q < nb_quads; ++q) {
- if (*sub_mat_it) {
- if (*dam_it < dam_threshold)
- *dam_it +=prescribed_dam;
- else *dam_it = max_damage;
- }
- ++sub_mat_it;
- ++dam_it;
- }
- }
- else {
- dam_it += nb_quads;
- }
+ damage_element = false;
+ /// check if damage occurs in the element
+ for (UInt q = 0; q < nb_quads; ++q) {
+ if (*equivalent_stress_it >=
+ (1 - dam_tolerance) * norm_max_equivalent_stress &&
+ *sub_mat_it != 0) {
+ damage_element = true;
+ }
+ ++sub_mat_it;
+ ++equivalent_stress_it;
+ }
+
+ if (damage_element) {
+ nb_damaged_elements += 1;
+ /// damage the element
+ sub_mat_it -= nb_quads;
+ for (UInt q = 0; q < nb_quads; ++q) {
+ if (*sub_mat_it) {
+ if (*dam_it < dam_threshold)
+ *dam_it += prescribed_dam;
+ else
+ *dam_it = max_damage;
+ }
+ ++sub_mat_it;
+ ++dam_it;
+ }
+ } else {
+ dam_it += nb_quads;
+ }
}
}
}
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
comm.allReduce(&nb_damaged_elements, 1, _so_sum);
AKANTU_DEBUG_OUT();
return nb_damaged_elements;
}
/* -------------------------------------------------------------------------- */
// template<UInt spatial_dimension>
-// void MaterialIGFEMSawToothDamage<spatial_dimension>::updateEnergiesAfterDamage(ElementType el_type, GhostType ghost_type) {
+// void
+// MaterialIGFEMSawToothDamage<spatial_dimension>::updateEnergiesAfterDamage(ElementType
+// el_type, GhostType ghost_type) {
// MaterialDamage<spatial_dimension>::updateEnergies(el_type, ghost_type);
// }
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialIGFEMSawToothDamage<spatial_dimension>::onElementsAdded(__attribute__((unused)) const Array<Element> & element_list,
- __attribute__((unused)) const NewElementsEvent & event) {
+template <UInt spatial_dimension>
+void MaterialIGFEMSawToothDamage<spatial_dimension>::onElementsAdded(
+ __attribute__((unused)) const Array<Element> & element_list,
+ __attribute__((unused)) const NewElementsEvent & event) {
/// update elastic constants
MaterialIGFEMElastic<spatial_dimension>::onElementsAdded(element_list, event);
- IGFEMInternalField<Real> quadrature_points_coordinates("quadrature_points_coordinates", *this);
+ IGFEMInternalField<Real> quadrature_points_coordinates(
+ "quadrature_points_coordinates", *this);
quadrature_points_coordinates.initialize(spatial_dimension);
- this->computeQuadraturePointsCoordinates(quadrature_points_coordinates, _not_ghost);
- this->computeQuadraturePointsCoordinates(quadrature_points_coordinates, _ghost);
+ this->computeQuadraturePointsCoordinates(quadrature_points_coordinates,
+ _not_ghost);
+ this->computeQuadraturePointsCoordinates(quadrature_points_coordinates,
+ _ghost);
Array<Element>::const_iterator<Element> el_begin = element_list.begin();
- Array<Element>::const_iterator<Element> el_end = element_list.end();
+ Array<Element>::const_iterator<Element> el_end = element_list.end();
Element el;
el.kind = _ek_igfem;
/// loop over all the elements in the filter
- for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) {
+ for (ghost_type_t::iterator g = ghost_type_t::begin();
+ g != ghost_type_t::end(); ++g) {
GhostType ghost_type = *g;
/// loop over all types in the material
- typedef ElementTypeMapArray<UInt>:: type_iterator iterator;
- iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_igfem);
- iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
+ typedef ElementTypeMapArray<UInt>::type_iterator iterator;
+ iterator it = this->element_filter.firstType(spatial_dimension, ghost_type,
+ _ek_igfem);
+ iterator last_type =
+ this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
for (; it != last_type; ++it) {
/// store the elements added to this material
std::vector<Element> new_elements;
Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
- UInt nb_quads = quadrature_points_coordinates.getFEEngine().getNbIntegrationPoints(*it, ghost_type);
+ UInt nb_quads =
+ quadrature_points_coordinates.getFEEngine().getNbIntegrationPoints(
+ *it, ghost_type);
Array<Real> added_quads(0, spatial_dimension);
- const Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
+ const Array<Real> & quads =
+ quadrature_points_coordinates(*it, ghost_type);
Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
el.type = *it;
el.ghost_type = ghost_type;
-
+
for (UInt e = 0; e < nb_element; ++e) {
- /// global number of element
- el.element = elem_filter(e);
- if(std::find(el_begin, el_end, el) != el_end) {
- new_elements.push_back(el);
- for (UInt q = 0; q < nb_quads; ++q) {
- added_quads.push_back(*quad);
- ++quad;
- }
- }
- else
- quad += nb_quads;
+ /// global number of element
+ el.element = elem_filter(e);
+ if (std::find(el_begin, el_end, el) != el_end) {
+ new_elements.push_back(el);
+ for (UInt q = 0; q < nb_quads; ++q) {
+ added_quads.push_back(*quad);
+ ++quad;
+ }
+ } else
+ quad += nb_quads;
}
-
- /// get the extrapolated values
+ /// get the extrapolated values
for (UInt i = 0; i < this->internals_to_transfer.size(); ++i) {
- if (!new_elements.size()) continue;
- const ID name = this->getID() + ":" + this->internals_to_transfer[i];
- Array<Real> & internal = (*(this->internal_vectors_real[name]))(*it, ghost_type);
- UInt nb_component = internal.getNbComponent();
- /// Array<Real>::vector_iterator internal_it = internal.begin(nb_component);
- Array<Real> extrapolated_internal_values(new_elements.size() * nb_quads, nb_component);
- this->model->transferInternalValues(this->internals_to_transfer[i], new_elements, added_quads, extrapolated_internal_values);
-
- UInt * sub_mat_ptr = this->sub_material(*it, ghost_type).storage();
- Array<Real>::const_vector_iterator extrapolated_it = extrapolated_internal_values.begin(nb_component);
- Array<Real>::vector_iterator internal_it = internal.begin(nb_component);
- /// copy back the results
- for (UInt j = 0; j < new_elements.size(); ++j) {
- Element element_local = this->convertToLocalElement(new_elements[j]);
- for (UInt q = 0; q < nb_quads; ++q, ++extrapolated_it) {
- if (sub_mat_ptr[element_local.element * nb_quads + q])
- internal_it[element_local.element * nb_quads + q] = *extrapolated_it;
- }
- }
- }
-
+ if (!new_elements.size())
+ continue;
+ const ID name = this->getID() + ":" + this->internals_to_transfer[i];
+ Array<Real> & internal =
+ (*(this->internal_vectors_real[name]))(*it, ghost_type);
+ UInt nb_component = internal.getNbComponent();
+ /// Array<Real>::vector_iterator internal_it =
+ /// internal.begin(nb_component);
+ Array<Real> extrapolated_internal_values(new_elements.size() * nb_quads,
+ nb_component);
+ this->model->transferInternalValues(this->internals_to_transfer[i],
+ new_elements, added_quads,
+ extrapolated_internal_values);
+
+ UInt * sub_mat_ptr = this->sub_material(*it, ghost_type).storage();
+ Array<Real>::const_vector_iterator extrapolated_it =
+ extrapolated_internal_values.begin(nb_component);
+ Array<Real>::vector_iterator internal_it = internal.begin(nb_component);
+ /// copy back the results
+ for (UInt j = 0; j < new_elements.size(); ++j) {
+ Element element_local = this->convertToLocalElement(new_elements[j]);
+ for (UInt q = 0; q < nb_quads; ++q, ++extrapolated_it) {
+ if (sub_mat_ptr[element_local.element * nb_quads + q])
+ internal_it[element_local.element * nb_quads + q] =
+ *extrapolated_it;
+ }
+ }
+ }
}
}
}
/* -------------------------------------------------------------------------- */
// template<UInt spatial_dimension>
-// void MaterialIGFEMSawToothDamage<spatial_dimension>::transferInternals(Material & old_mat,
-// std::vector<ElementPair> & element_pairs) {
-
- // Element new_el_global;
- // Element new_el_local;
- // Element old_el_global;
- // Element old_el_local;
-
- // /// get the fe-engine of the old material
- // FEEngine & fem_old_mat = old_mat.getFEEngine();
- // for (UInt e = 0; e < element_pairs.size(); ++e) {
- // new_el_global = element_pairs[e].first;
- // old_el_global = element_pairs[e].second;
- // /// get the number of the elements in their materials
- // old_el_local = old_el_global;
- // Array<UInt> & mat_local_numbering = this->model->getMaterialLocalNumbering(old_el_global.type, old_el_global.ghost_type);
- // old_el_local.element = mat_local_numbering(old_el_global.element);
- // new_el_local = this->convertToLocalElement(new_el_global);
- // UInt nb_old_quads = fem_old_mat.getNbIntegrationPoints(old_el_global.type, old_el_global.ghost_type);
- // UInt nb_new_quads = this->fem->getNbIntegrationPoints(new_el_global.type, new_el_global.ghost_type);
-
- // if (old_mat.isInternal("damage", Mesh::getKind(old_el_global.type))
- // && old_mat.isInternal("Sc", Mesh::getKind(old_el_global.type)) ) {
-
- // UInt quad;
- // Vector<Real> el_old_damage(nb_old_quads);
- // Vector<Real> el_old_Sc(nb_old_quads);
- // Vector<Real> el_new_damage(nb_new_quads);
- // Vector<Real> el_new_Sc(nb_new_quads);
- // const Array<Real> & old_Sc = old_mat.getArray("Sc", old_el_global.type, old_el_global.ghost_type);
- // const Array<Real> & old_damage = old_mat.getArray("damage", old_el_global.type, old_el_global.ghost_type);
- // Array<Real> & new_Sc = this->Sc(new_el_global.type, new_el_global.ghost_type);
- // Array<Real> & new_damage = this->damage(new_el_global.type, new_el_global.ghost_type);
-
- // for (UInt q = 0; q < nb_old_quads; ++q) {
- // quad = old_el_local.element * nb_old_quads + q;
- // el_old_damage(q) = old_damage(quad);
- // el_old_Sc(q) = old_Sc(quad);
- // }
-
- // this->interpolateInternal(new_el_global, old_el_global, el_new_damage, el_old_damage, nb_new_quads, nb_old_quads);
- // this->interpolateInternal(new_el_global, old_el_global, el_new_Sc, el_old_Sc, nb_new_quads, nb_old_quads);
-
- // for (UInt q = 0; q < nb_new_quads; ++q) {
- // quad = new_el_local.element * nb_new_quads + q;
- // if (this->sub_material(new_el_global.type,new_el_global.ghost_type)(quad)) {
- // new_damage(quad) = el_new_damage(q);
- // new_Sc(quad) = el_new_damage(q);
- // }
- // }
- // }
-
- // else
- // AKANTU_DEBUG_ASSERT((!old_mat.isInternal("damage", Mesh::getKind(old_el_global.type))
- // && !old_mat.isInternal("Sc", Mesh::getKind(old_el_global.type)) ),
- // "old material has damage or Sc but not both!!!!");
- // }
+// void
+// MaterialIGFEMSawToothDamage<spatial_dimension>::transferInternals(Material &
+// old_mat,
+// std::vector<ElementPair> & element_pairs)
+// {
+
+// Element new_el_global;
+// Element new_el_local;
+// Element old_el_global;
+// Element old_el_local;
+
+// /// get the fe-engine of the old material
+// FEEngine & fem_old_mat = old_mat.getFEEngine();
+// for (UInt e = 0; e < element_pairs.size(); ++e) {
+// new_el_global = element_pairs[e].first;
+// old_el_global = element_pairs[e].second;
+// /// get the number of the elements in their materials
+// old_el_local = old_el_global;
+// Array<UInt> & mat_local_numbering =
+// this->model->getMaterialLocalNumbering(old_el_global.type,
+// old_el_global.ghost_type);
+// old_el_local.element = mat_local_numbering(old_el_global.element);
+// new_el_local = this->convertToLocalElement(new_el_global);
+// UInt nb_old_quads = fem_old_mat.getNbIntegrationPoints(old_el_global.type,
+// old_el_global.ghost_type);
+// UInt nb_new_quads = this->fem->getNbIntegrationPoints(new_el_global.type,
+// new_el_global.ghost_type);
+
+// if (old_mat.isInternal("damage", Mesh::getKind(old_el_global.type))
+// && old_mat.isInternal("Sc", Mesh::getKind(old_el_global.type)) ) {
+
+// UInt quad;
+// Vector<Real> el_old_damage(nb_old_quads);
+// Vector<Real> el_old_Sc(nb_old_quads);
+// Vector<Real> el_new_damage(nb_new_quads);
+// Vector<Real> el_new_Sc(nb_new_quads);
+// const Array<Real> & old_Sc = old_mat.getArray("Sc", old_el_global.type,
+// old_el_global.ghost_type);
+// const Array<Real> & old_damage = old_mat.getArray("damage",
+// old_el_global.type, old_el_global.ghost_type);
+// Array<Real> & new_Sc = this->Sc(new_el_global.type,
+// new_el_global.ghost_type);
+// Array<Real> & new_damage = this->damage(new_el_global.type,
+// new_el_global.ghost_type);
+
+// for (UInt q = 0; q < nb_old_quads; ++q) {
+// quad = old_el_local.element * nb_old_quads + q;
+// el_old_damage(q) = old_damage(quad);
+// el_old_Sc(q) = old_Sc(quad);
+// }
+
+// this->interpolateInternal(new_el_global, old_el_global, el_new_damage,
+// el_old_damage, nb_new_quads, nb_old_quads);
+// this->interpolateInternal(new_el_global, old_el_global, el_new_Sc,
+// el_old_Sc, nb_new_quads, nb_old_quads);
+
+// for (UInt q = 0; q < nb_new_quads; ++q) {
+// quad = new_el_local.element * nb_new_quads + q;
+// if (this->sub_material(new_el_global.type,new_el_global.ghost_type)(quad)) {
+// new_damage(quad) = el_new_damage(q);
+// new_Sc(quad) = el_new_damage(q);
+// }
+// }
+// }
+
+// else
+// AKANTU_DEBUG_ASSERT((!old_mat.isInternal("damage",
+// Mesh::getKind(old_el_global.type))
+// && !old_mat.isInternal("Sc", Mesh::getKind(old_el_global.type))
+// ),
+// "old material has damage or Sc but not both!!!!");
+// }
// }
/* -------------------------------------------------------------------------- */
-
INSTANTIATE_MATERIAL(MaterialIGFEMSawToothDamage);
__END_AKANTU__
/* /// get the material index in the model from this current material
UInt this_mat_idx = this->model->getMaterialIndex(this->name);
/// number of elements in this event
UInt nb_new_elements = element_list.getSize();
// const Array<Element> & old_elements = igfem_event->getOldElementsList();
-
+
// std::map<UInt, std::vector<ElementPair> > elements_by_old_mat;
/// store the old elements sorted by their material
for (UInt e = 0; e < nb_new_elements; ++e) {
const Element new_el = element_list(e);
- const Array<UInt> & mat_idx = this->model->getMaterialByElement(new_el.type, new_el.ghost_type);
+ const Array<UInt> & mat_idx =
+ this->model->getMaterialByElement(new_el.type, new_el.ghost_type);
if ( mat_idx(new_el.element) != this_mat_idx )
- continue; /// new element is not part of this material: nothing to be done
+ continue; /// new element is not part of this material: nothing to be done
/// get the corresponding old element and store new and old one as pair
const Element old_el = old_elements(e);
ElementPair el_pair(new_el, old_el);
- const Array<UInt> & old_mat_idx = this->model->getMaterialByElement(old_el.type, old_el.ghost_type);
+ const Array<UInt> & old_mat_idx =
+ this->model->getMaterialByElement(old_el.type, old_el.ghost_type);
UInt mat_old_idx = old_mat_idx(old_el.element);
elements_by_old_mat[mat_old_idx].push_back(el_pair);
}
/// loop over all the element pairs in the map
- for (std::map<UInt, std::vector<ElementPair> >::iterator map_it = elements_by_old_mat.begin();
- map_it != elements_by_old_mat.end(); ++map_it) {
+ for (std::map<UInt, std::vector<ElementPair> >::iterator map_it =
+ elements_by_old_mat.begin();
+ map_it != elements_by_old_mat.end(); ++map_it) {
/// get the vector of old and new element pairs
std::vector<ElementPair > & element_pairs = map_it->second;
Material & old_mat = this->model->getMaterial(map_it->first);
this->transferInternals(old_mat, element_pairs);
}
-*/
+*/
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh
index 2c714890c..f5a4d25ba 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh
@@ -1,137 +1,139 @@
/**
* @file material_igfem_saw_tooth_damage.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Linear saw-tooth softening material model for IGFEM elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage.hh"
#include "material_igfem_elastic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_IGFEM_SAW_TOOTH_DAMAGE_HH__
#define __AKANTU_MATERIAL_IGFEM_SAW_TOOTH_DAMAGE_HH__
__BEGIN_AKANTU__
-template<UInt spatial_dimension>
-class MaterialIGFEMSawToothDamage : public MaterialDamage<spatial_dimension, MaterialIGFEMElastic> {
+template <UInt spatial_dimension>
+class MaterialIGFEMSawToothDamage
+ : public MaterialDamage<spatial_dimension, MaterialIGFEMElastic> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
private:
typedef MaterialDamage<spatial_dimension, MaterialIGFEMElastic> Parent;
+
public:
typedef std::pair<Element, Element> ElementPair;
MaterialIGFEMSawToothDamage(SolidMechanicsModel & model, const ID & id = "");
- MaterialIGFEMSawToothDamage(SolidMechanicsModel & model,
- UInt dim,
- const Mesh & mesh,
- FEEngine & fe_engine,
- const ID & id = "");
+ MaterialIGFEMSawToothDamage(SolidMechanicsModel & model, UInt dim,
+ const Mesh & mesh, FEEngine & fe_engine,
+ const ID & id = "");
virtual ~MaterialIGFEMSawToothDamage() {}
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
virtual void initMaterial();
-
+
/// virtual void updateInternalParameters();
virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
/// update internal field damage
virtual UInt updateDamage();
- UInt updateDamage(UInt quad_index, const Real eq_stress, const ElementType & el_type, const GhostType & ghost_type);
+ UInt updateDamage(UInt quad_index, const Real eq_stress,
+ const ElementType & el_type, const GhostType & ghost_type);
/// update energies after damage has been updated
- // virtual void updateEnergiesAfterDamage(ElementType el_type, GhostType ghost_typ);
-
- virtual void onBeginningSolveStep(const AnalysisMethod & method) { };
+ // virtual void updateEnergiesAfterDamage(ElementType el_type, GhostType
+ // ghost_typ);
+
+ virtual void onBeginningSolveStep(const AnalysisMethod & method){};
+
+ virtual void onEndSolveStep(const AnalysisMethod & method){};
- virtual void onEndSolveStep(const AnalysisMethod & method) { };
protected:
/// constitutive law for all element of a type
- virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
+ virtual void computeStress(ElementType el_type,
+ GhostType ghost_type = _not_ghost);
- ///compute the equivalent stress on each Gauss point (i.e. the max prinicpal stress) and normalize it by the tensile strength
- virtual void computeNormalizedEquivalentStress(const Array<Real> & grad_u,
- ElementType el_type, GhostType ghost_type = _not_ghost);
+ /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
+ /// stress) and normalize it by the tensile strength
+ virtual void
+ computeNormalizedEquivalentStress(const Array<Real> & grad_u,
+ ElementType el_type,
+ GhostType ghost_type = _not_ghost);
/// find max normalized equivalent stress
- void findMaxNormalizedEquivalentStress(ElementType el_type, GhostType ghost_type = _not_ghost);
+ void findMaxNormalizedEquivalentStress(ElementType el_type,
+ GhostType ghost_type = _not_ghost);
-
- inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma,
- Real & dam);
+ inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam);
protected:
-
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
virtual void onElementsAdded(const Array<Element> & element_list,
- const NewElementsEvent & event);
+ const NewElementsEvent & event);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get max normalized equivalent stress
AKANTU_GET_MACRO(NormMaxEquivalentStress, norm_max_equivalent_stress, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// resistance to damage
IGFEMInternalField<Real> Sc;
/// internal field to store equivalent stress on each Gauss point
IGFEMInternalField<Real> equivalent_stress;
/// damage increment
Real prescribed_dam;
/// maximum equivalent stress
Real norm_max_equivalent_stress;
- /// deviation from max stress at which Gauss point will still get damaged
+ /// deviation from max stress at which Gauss point will still get damaged
Real dam_tolerance;
- /// define damage threshold at which damage will be set to 1
- Real dam_threshold;
+ /// define damage threshold at which damage will be set to 1
+ Real dam_threshold;
/// maximum damage value
Real max_damage;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_igfem_saw_tooth_damage_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_IGFEM_SAW_TOOTH_DAMAGE_HH__ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.cc b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.cc
index 9451c0062..b3994e27a 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.cc
@@ -1,64 +1,67 @@
/**
* @file material_igfem_saw_tooth_damage_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief Implementation of inline functions of the squentially linear
* saw-tooth damage model for IGFEM elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
inline void
-MaterialIGFEMSawToothDamage<spatial_dimension>::computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam) {
- sigma *= 1-dam;
+MaterialIGFEMSawToothDamage<spatial_dimension>::computeDamageAndStressOnQuad(
+ Matrix<Real> & sigma, Real & dam) {
+ sigma *= 1 - dam;
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-UInt MaterialIGFEMSawToothDamage<spatial_dimension>::updateDamage(UInt quad_index, const Real eq_stress, const ElementType & el_type, const GhostType & ghost_type) {
+template <UInt spatial_dimension>
+UInt MaterialIGFEMSawToothDamage<spatial_dimension>::updateDamage(
+ UInt quad_index, const Real eq_stress, const ElementType & el_type,
+ const GhostType & ghost_type) {
AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
- "Your prescribed damage must be greater than zero");
-
+ "Your prescribed damage must be greater than zero");
Array<Real> & dam = this->damage(el_type, ghost_type);
- Real & dam_on_quad = dam(quad_index);
+ Real & dam_on_quad = dam(quad_index);
/// check if damage occurs
- if (equivalent_stress(el_type, ghost_type)(quad_index) >= (1-dam_tolerance) * norm_max_equivalent_stress) {
+ if (equivalent_stress(el_type, ghost_type)(quad_index) >=
+ (1 - dam_tolerance) * norm_max_equivalent_stress) {
/// damage the entire sub-element -> get the element index
- UInt el_index = quad_index / this->element_filter(el_type, ghost_type).getSize();
+ UInt el_index =
+ quad_index / this->element_filter(el_type, ghost_type).getSize();
UInt nb_quads = this->fem->getNbIntegrationPoints(el_type, ghost_type);
UInt start_idx = el_index * nb_quads;
Array<UInt> & sub_mat = this->sub_material(el_type, ghost_type);
UInt damaged_quads = 0;
if (dam_on_quad < dam_threshold) {
for (UInt q = 0; q < nb_quads; ++q, ++start_idx) {
- if (sub_mat(start_idx)) {
- dam(start_idx) +=prescribed_dam;
- damaged_quads += 1;
- }
+ if (sub_mat(start_idx)) {
+ dam(start_idx) += prescribed_dam;
+ damaged_quads += 1;
+ }
}
- }
- else {
+ } else {
for (UInt q = 0; q < nb_quads; ++q, ++start_idx) {
- if (sub_mat(start_idx)) {
- dam(start_idx) += max_damage;
- damaged_quads += 1;
- }
+ if (sub_mat(start_idx)) {
+ dam(start_idx) += max_damage;
+ damaged_quads += 1;
+ }
}
- }
+ }
return damaged_quads;
}
return 0;
}
/* -------------------------------------------------------------------------- */
diff --git a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh
index cf44d2d1f..ecc0a0d36 100644
--- a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh
+++ b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh
@@ -1,208 +1,221 @@
/**
* @file mesh_igfem_spherical_growing_gel.hh
*
* @author Clement Roux-Langlois <clement.roux@epfl.ch>
*
* @date creation: Mon Jul 13 2015
*
* @brief Computation of mesh intersection with sphere(s) and growing of these
- * spheres. This class handle the intersectors templated for every element
+ * spheres. This class handle the intersectors templated for every
+ * element
* types.
*
* @section LICENSE
*
* Copyright (©) 2010-2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
//#if 0
#ifndef __AKANTU_MESH_IGFEM_SPHERICAL_GROWING_GEL_HH__
#define __AKANTU_MESH_IGFEM_SPHERICAL_GROWING_GEL_HH__
#include "aka_common.hh"
#include "mesh_sphere_intersector.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-/* classes for new igfem elements mesh events */
+/* classes for new igfem elements mesh events */
/* -------------------------------------------------------------------------- */
class NewIGFEMElementsEvent : public NewElementsEvent {
public:
AKANTU_GET_MACRO_NOT_CONST(OldElementsList, old_elements, Array<Element> &);
AKANTU_GET_MACRO(OldElementsList, old_elements, const Array<Element> &);
+
protected:
Array<Element> old_elements;
};
class NewIGFEMNodesEvent : public NewNodesEvent {
public:
void setNewNodePerElem(const Array<UInt> & new_node_per_elem) {
this->new_node_per_elem = &new_node_per_elem;
}
- void setType(ElementType new_type) {type = new_type;}
- void setGhostType(GhostType new_type) {ghost_type = new_type;}
+ void setType(ElementType new_type) { type = new_type; }
+ void setGhostType(GhostType new_type) { ghost_type = new_type; }
AKANTU_GET_MACRO(NewNodePerElem, *new_node_per_elem, const Array<UInt> &);
AKANTU_GET_MACRO(ElementType, type, ElementType);
AKANTU_GET_MACRO(GhostType, ghost_type, GhostType);
+
protected:
ElementType type;
GhostType ghost_type;
const Array<UInt> * new_node_per_elem;
};
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-class MeshIgfemSphericalGrowingGel {
- // definition of the element list
-#define ELEMENT_LIST \
- (_triangle_3) \
- (_igfem_triangle_4) \
- (_igfem_triangle_5)
-
- // Solution 1
- /* #define INTERSECTOR_DEFINITION(type) \
- MeshSphereIntersector<2, type> intersector##type(mesh);*/
+template <UInt dim> class MeshIgfemSphericalGrowingGel {
+// definition of the element list
+#define ELEMENT_LIST (_triangle_3)(_igfem_triangle_4)(_igfem_triangle_5)
- // Solution 2
-#define INSTANTIATOR(_type) \
- intersectors(_type, ghost_type) = new MeshSphereIntersector<dim, _type>(this->mesh)
+// Solution 1
+/* #define INTERSECTOR_DEFINITION(type) \
+ MeshSphereIntersector<2, type> intersector##type(mesh);*/
-/* -------------------------------------------------------------------------- */
-/* Constructor/Destructor */
-/* -------------------------------------------------------------------------- */
+// Solution 2
+#define INSTANTIATOR(_type) \
+ intersectors(_type, ghost_type) = \
+ new MeshSphereIntersector<dim, _type>(this->mesh)
+
+ /* --------------------------------------------------------------------------
+ */
+ /* Constructor/Destructor */
+ /* --------------------------------------------------------------------------
+ */
public:
/// Construct from mesh
MeshIgfemSphericalGrowingGel(Mesh & mesh);
/// Destructor
~MeshIgfemSphericalGrowingGel() {
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it = mesh.firstType(dim, ghost_type, _ek_not_defined);
+ Mesh::type_iterator it = mesh.firstType(dim, ghost_type, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(dim, ghost_type, _ek_not_defined);
- for(;it != end; ++it) {
- delete intersectors(*it, ghost_type);
+ for (; it != end; ++it) {
+ delete intersectors(*it, ghost_type);
}
}
}
-
- /* -------------------------------------------------------------------------- */
- /* Methods */
- /* -------------------------------------------------------------------------- */
-public:
+ /* --------------------------------------------------------------------------
+ */
+ /* Methods */
+ /* --------------------------------------------------------------------------
+ */
+public:
void init();
/// Remove the additionnal nodes
void removeAdditionalNodes();
- /// Compute the intersection points between the mesh and the query list for all element types and send the NewNodeEvent
- void computeMeshQueryListIntersectionPoint(const std::list<SK::Sphere_3> & query_list);
+ /// Compute the intersection points between the mesh and the query list for
+ /// all element types and send the NewNodeEvent
+ void computeMeshQueryListIntersectionPoint(
+ const std::list<SK::Sphere_3> & query_list);
- /// increase sphere radius and build the new intersection points between the mesh and the query list for all element types and send the NewNodeEvent
- void computeMeshQueryListIntersectionPoint(const std::list<SK::Sphere_3> & query_list, Real inf_fact) {
+ /// increase sphere radius and build the new intersection points between the
+ /// mesh and the query list for all element types and send the NewNodeEvent
+ void computeMeshQueryListIntersectionPoint(
+ const std::list<SK::Sphere_3> & query_list, Real inf_fact) {
std::list<SK::Sphere_3>::const_iterator query_it = query_list.begin(),
- query_end = query_list.end();
+ query_end = query_list.end();
std::list<SK::Sphere_3> sphere_list;
- for (; query_it != query_end ; ++query_it) {
+ for (; query_it != query_end; ++query_it) {
SK::Sphere_3 sphere(query_it->center(),
- query_it->squared_radius() * inf_fact * inf_fact );
+ query_it->squared_radius() * inf_fact * inf_fact);
sphere_list.push_back(sphere);
}
computeMeshQueryListIntersectionPoint(sphere_list);
}
/// Build the IGFEM mesh from intersection points
void buildIGFEMMesh();
/// Build the IGFEM mesh from spheres
- void buildIGFEMMeshFromSpheres(const std::list<SK::Sphere_3> & query_list){
+ void buildIGFEMMeshFromSpheres(const std::list<SK::Sphere_3> & query_list) {
computeMeshQueryListIntersectionPoint(query_list);
buildIGFEMMesh();
}
/// Build the IGFEM mesh from spheres with increase factor
- void buildIGFEMMeshFromSpheres(const std::list<SK::Sphere_3> & query_list, Real inf_fact){
+ void buildIGFEMMeshFromSpheres(const std::list<SK::Sphere_3> & query_list,
+ Real inf_fact) {
computeMeshQueryListIntersectionPoint(query_list, inf_fact);
buildIGFEMMesh();
}
/// set the distributed synchronizer
void setDistributedSynchronizer(DistributedSynchronizer * dist) {
synchronizer = dist;
buildSegmentConnectivityToNodeType();
}
/// update node type
void updateNodeType(const Array<UInt> & nodes_list,
- const Array<UInt> & new_node_per_elem,
- ElementType type,
- GhostType ghost_type);
+ const Array<UInt> & new_node_per_elem, ElementType type,
+ GhostType ghost_type);
protected:
- /// Build the unordered_map needed to assign the node type to new nodes in parallel
+ /// Build the unordered_map needed to assign the node type to new nodes in
+ /// parallel
void buildSegmentConnectivityToNodeType();
- /* -------------------------------------------------------------------------- */
- /* Accessors */
- /* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Accessors */
+ /* --------------------------------------------------------------------------
+ */
public:
AKANTU_GET_MACRO(NbStandardNodes, nb_nodes_fem, UInt);
AKANTU_GET_MACRO(NbEnrichedNodes, nb_enriched_nodes, UInt);
- /* -------------------------------------------------------------------------- */
- /* Class Members */
- /* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Class Members */
+ /* --------------------------------------------------------------------------
+ */
protected:
/// Mesh used to construct the primitives
Mesh & mesh;
/// number of fem nodes in the initial mesh
UInt nb_nodes_fem;
/// number of enriched nodes before intersection
UInt nb_enriched_nodes;
- //Solution 2
+ // Solution 2
/// map of the elements types in the mesh and the corresponding intersectors
- ElementTypeMap< MeshAbstractIntersector<SK::Sphere_3> *> intersectors;
+ ElementTypeMap<MeshAbstractIntersector<SK::Sphere_3> *> intersectors;
/// Map linking pairs of nodes to a node type. The pairs of nodes
/// contain the connectivity of the primitive segments that are
/// intersected.
- unordered_map< std::pair<UInt, UInt>, Int >::type segment_conn_to_node_type;
+ unordered_map<std::pair<UInt, UInt>, Int>::type segment_conn_to_node_type;
/// Pointer to the distributed synchronizer of the model
DistributedSynchronizer * synchronizer;
};
__END_AKANTU__
#include "mesh_igfem_spherical_growing_gel_tmpl.hh"
#endif // __AKANTU_MESH_IGFEM_SPHERICAL_GROWING_GEL_HH__
//#endif //
diff --git a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh
index 345c046fa..c01636c46 100644
--- a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh
+++ b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh
@@ -1,506 +1,532 @@
/**
* @file mesh_igfem_spherical_growing_gel.cc
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @date Mon Sep 21 12:42:11 2015
*
* @brief Implementation of the functions of MeshIgfemSphericalGrowingGel
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_utils.hh"
#include <algorithm>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <UInt dim>
-MeshIgfemSphericalGrowingGel<dim>::MeshIgfemSphericalGrowingGel(Mesh & mesh):
- mesh(mesh),
- nb_nodes_fem(mesh.getNbNodes()),
- nb_enriched_nodes(0),
- synchronizer(NULL) { }
+MeshIgfemSphericalGrowingGel<dim>::MeshIgfemSphericalGrowingGel(Mesh & mesh)
+ : mesh(mesh), nb_nodes_fem(mesh.getNbNodes()), nb_enriched_nodes(0),
+ synchronizer(NULL) {}
/* -------------------------------------------------------------------------- */
-template <UInt dim>
-void MeshIgfemSphericalGrowingGel<dim>::init() {
+template <UInt dim> void MeshIgfemSphericalGrowingGel<dim>::init() {
nb_nodes_fem = mesh.getNbNodes();
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator tit = mesh.firstType(dim, ghost_type);
Mesh::type_iterator tend = mesh.lastType(dim, ghost_type);
- for(;tit != tend; ++tit) { // loop to add corresponding IGFEM element types
- if(*tit == _triangle_3){
- mesh.addConnectivityType(_igfem_triangle_4, ghost_type);
- mesh.addConnectivityType(_igfem_triangle_5, ghost_type);
- }
- else
- AKANTU_DEBUG_ERROR("Not ready for mesh type " << *tit);
+ for (; tit != tend;
+ ++tit) { // loop to add corresponding IGFEM element types
+ if (*tit == _triangle_3) {
+ mesh.addConnectivityType(_igfem_triangle_4, ghost_type);
+ mesh.addConnectivityType(_igfem_triangle_5, ghost_type);
+ } else
+ AKANTU_DEBUG_ERROR("Not ready for mesh type " << *tit);
}
tit = mesh.firstType(dim, ghost_type, _ek_not_defined);
tend = mesh.lastType(dim, ghost_type, _ek_not_defined);
- for(;tit != tend; ++tit) {
+ for (; tit != tend; ++tit) {
AKANTU_BOOST_LIST_SWITCH(INSTANTIATOR, ELEMENT_LIST, *tit);
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
-void MeshIgfemSphericalGrowingGel<dim>::computeMeshQueryListIntersectionPoint(const std::list<SK::Sphere_3> & query_list) {
+void MeshIgfemSphericalGrowingGel<dim>::computeMeshQueryListIntersectionPoint(
+ const std::list<SK::Sphere_3> & query_list) {
/// store number of currently enriched nodes
this->nb_enriched_nodes = mesh.getNbNodes() - nb_nodes_fem;
UInt nb_old_nodes = mesh.getNbNodes();
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Mesh::type_iterator iit = mesh.firstType(dim, ghost_type, _ek_not_defined);
Mesh::type_iterator iend = mesh.lastType(dim, ghost_type, _ek_not_defined);
- for(;iit != iend; ++iit) {
- MeshAbstractIntersector<SK::Sphere_3> & intersector = *intersectors(*iit, ghost_type);
+ for (; iit != iend; ++iit) {
+ MeshAbstractIntersector<SK::Sphere_3> & intersector =
+ *intersectors(*iit, ghost_type);
intersector.constructData(ghost_type);
- intersector.computeMeshQueryListIntersectionPoint(query_list, nb_old_nodes);
- const Array<Real> intersection_points_current_type = *(intersector.getIntersectionPoints());
+ intersector.computeMeshQueryListIntersectionPoint(query_list,
+ nb_old_nodes);
+ const Array<Real> intersection_points_current_type =
+ *(intersector.getIntersectionPoints());
const Array<UInt> & new_node_per_elem = intersector.getNewNodePerElem();
/// Send the new node event
UInt new_points = intersection_points_current_type.getSize();
- StaticCommunicator::getStaticCommunicator().allReduce(&new_points, 1, _so_sum);
+ StaticCommunicator::getStaticCommunicator().allReduce(&new_points, 1,
+ _so_sum);
if (new_points > 0) {
- Array<Real> & nodes = this->mesh.getNodes();
- UInt nb_node = nodes.getSize();
-
- Array<Real>::const_vector_iterator intersec_p_it
- = intersection_points_current_type.begin(dim);
-
- NewIGFEMNodesEvent new_nodes_event;
- for(UInt in = 0; in < intersection_points_current_type.getSize();
- ++in, ++intersec_p_it) {
- nodes.push_back(*intersec_p_it);
- new_nodes_event.getList().push_back(nb_node + in);
- }
- new_nodes_event.setNewNodePerElem(new_node_per_elem);
- new_nodes_event.setType(*iit);
- new_nodes_event.setGhostType(ghost_type);
- this->mesh.sendEvent(new_nodes_event);
+ Array<Real> & nodes = this->mesh.getNodes();
+ UInt nb_node = nodes.getSize();
+
+ Array<Real>::const_vector_iterator intersec_p_it =
+ intersection_points_current_type.begin(dim);
+
+ NewIGFEMNodesEvent new_nodes_event;
+ for (UInt in = 0; in < intersection_points_current_type.getSize();
+ ++in, ++intersec_p_it) {
+ nodes.push_back(*intersec_p_it);
+ new_nodes_event.getList().push_back(nb_node + in);
+ }
+ new_nodes_event.setNewNodePerElem(new_node_per_elem);
+ new_nodes_event.setType(*iit);
+ new_nodes_event.setGhostType(ghost_type);
+ this->mesh.sendEvent(new_nodes_event);
}
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
-void MeshIgfemSphericalGrowingGel<dim>::removeAdditionalNodes(){
+void MeshIgfemSphericalGrowingGel<dim>::removeAdditionalNodes() {
AKANTU_DEBUG_IN();
UInt total_nodes = this->mesh.getNbNodes();
- UInt nb_new_enriched_nodes = total_nodes - this->nb_enriched_nodes - this->nb_nodes_fem;
+ UInt nb_new_enriched_nodes =
+ total_nodes - this->nb_enriched_nodes - this->nb_nodes_fem;
UInt old_total_nodes = this->nb_nodes_fem + this->nb_enriched_nodes;
UInt total_new_nodes = nb_new_enriched_nodes;
- StaticCommunicator::getStaticCommunicator().allReduce(&total_new_nodes, 1, _so_sum);
- if (total_new_nodes == 0) return;
+ StaticCommunicator::getStaticCommunicator().allReduce(&total_new_nodes, 1,
+ _so_sum);
+ if (total_new_nodes == 0)
+ return;
RemovedNodesEvent remove_nodes(this->mesh);
Array<UInt> & nodes_removed = remove_nodes.getList();
Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
- for(UInt nnod = 0; nnod < this->nb_nodes_fem ; ++nnod){
- new_numbering(nnod) = nnod ;
+ for (UInt nnod = 0; nnod < this->nb_nodes_fem; ++nnod) {
+ new_numbering(nnod) = nnod;
}
- for(UInt nnod = nb_nodes_fem ; nnod < old_total_nodes; ++nnod){
- new_numbering(nnod) = UInt(-1) ;
+ for (UInt nnod = nb_nodes_fem; nnod < old_total_nodes; ++nnod) {
+ new_numbering(nnod) = UInt(-1);
nodes_removed.push_back(nnod);
}
- for(UInt nnod = 0; nnod < nb_new_enriched_nodes ; ++nnod){
- new_numbering(nnod + old_total_nodes) = this->nb_nodes_fem + nnod ;
+ for (UInt nnod = 0; nnod < nb_new_enriched_nodes; ++nnod) {
+ new_numbering(nnod + old_total_nodes) = this->nb_nodes_fem + nnod;
}
if (nb_new_enriched_nodes > 0) {
for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
- GhostType ghost_type = (GhostType) gt;
-
- Mesh::type_iterator it = mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
- Mesh::type_iterator end = mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
- for(; it != end; ++it) {
- ElementType type = *it;
- Array<UInt> & connectivity_array = mesh.getConnectivity(type, ghost_type);
- UInt nb_nodes_per_element = connectivity_array.getNbComponent();
-
- Array<UInt>::vector_iterator conn_it = connectivity_array.begin(nb_nodes_per_element);
- Array<UInt>::vector_iterator conn_end = connectivity_array.end(nb_nodes_per_element);
-
- for (; conn_it != conn_end; ++conn_it) {
- for (UInt n = 0; n < nb_nodes_per_element; ++n) {
- (*conn_it)(n) = new_numbering((*conn_it)(n));
- }
- }
+ GhostType ghost_type = (GhostType)gt;
+
+ Mesh::type_iterator it =
+ mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
+ Mesh::type_iterator end =
+ mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
+ for (; it != end; ++it) {
+ ElementType type = *it;
+ Array<UInt> & connectivity_array =
+ mesh.getConnectivity(type, ghost_type);
+ UInt nb_nodes_per_element = connectivity_array.getNbComponent();
+
+ Array<UInt>::vector_iterator conn_it =
+ connectivity_array.begin(nb_nodes_per_element);
+ Array<UInt>::vector_iterator conn_end =
+ connectivity_array.end(nb_nodes_per_element);
+
+ for (; conn_it != conn_end; ++conn_it) {
+ for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+ (*conn_it)(n) = new_numbering((*conn_it)(n));
+ }
+ }
}
}
}
this->mesh.sendEvent(remove_nodes);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template <UInt dim>
-void MeshIgfemSphericalGrowingGel<dim>::buildIGFEMMesh(){
+template <UInt dim> void MeshIgfemSphericalGrowingGel<dim>::buildIGFEMMesh() {
AKANTU_DEBUG_IN();
NewIGFEMElementsEvent new_elements_event;
UInt total_new_elements = 0;
Array<Element> & new_elements_list = new_elements_event.getList();
Array<Element> & old_elements_list = new_elements_event.getOldElementsList();
RemovedElementsEvent removed_elements_event(this->mesh);
ChangedElementsEvent changed_elements_event(this->mesh);
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- mesh.initElementTypeMapArray(removed_elements_event.getNewNumbering(),
- 1, dim, ghost_type, false, _ek_not_defined);
- mesh.initElementTypeMapArray(changed_elements_event.getNewNumbering(),
- 1, dim, ghost_type, false, _ek_not_defined);
+ mesh.initElementTypeMapArray(removed_elements_event.getNewNumbering(), 1,
+ dim, ghost_type, false, _ek_not_defined);
+ mesh.initElementTypeMapArray(changed_elements_event.getNewNumbering(), 1,
+ dim, ghost_type, false, _ek_not_defined);
/// loop over all types in the mesh for a given ghost type
Mesh::type_iterator iit = mesh.firstType(dim, ghost_type, _ek_not_defined);
Mesh::type_iterator iend = mesh.lastType(dim, ghost_type, _ek_not_defined);
- for(;iit != iend; ++iit) {
+ for (; iit != iend; ++iit) {
ElementType type = *iit;
- MeshAbstractIntersector<SK::Sphere_3> & intersector = *intersectors(type, ghost_type);
+ MeshAbstractIntersector<SK::Sphere_3> & intersector =
+ *intersectors(type, ghost_type);
const Array<UInt> & new_node_per_elem = intersector.getNewNodePerElem();
UInt n_new_el = 0;
Array<UInt> & connectivity = this->mesh.getConnectivity(type, ghost_type);
-
- /// get the connectivities of all types that that may transform
- Array<UInt> & connec_igfem_tri_4 = this->mesh.getConnectivity(_igfem_triangle_4, ghost_type);
- Array<UInt> & connec_igfem_tri_5 = this->mesh.getConnectivity(_igfem_triangle_5, ghost_type);
- Array<UInt> & connec_tri_3 = this->mesh.getConnectivity(_triangle_3, ghost_type);
+ /// get the connectivities of all types that that may transform
+ Array<UInt> & connec_igfem_tri_4 =
+ this->mesh.getConnectivity(_igfem_triangle_4, ghost_type);
+ Array<UInt> & connec_igfem_tri_5 =
+ this->mesh.getConnectivity(_igfem_triangle_5, ghost_type);
+ Array<UInt> & connec_tri_3 =
+ this->mesh.getConnectivity(_triangle_3, ghost_type);
/// create elements to store the newly generated elements
Element el_tri_3(_triangle_3, 0, ghost_type, _ek_regular);
Element el_igfem_tri_4(_igfem_triangle_4, 0, ghost_type, _ek_igfem);
Element el_igfem_tri5(_igfem_triangle_5, 0, ghost_type, _ek_igfem);
- Array<UInt> & new_numbering = removed_elements_event.getNewNumbering(type, ghost_type);
+ Array<UInt> & new_numbering =
+ removed_elements_event.getNewNumbering(type, ghost_type);
new_numbering.resize(connectivity.getSize());
/// container for element to be removed
Element old_element(type, 0, ghost_type, Mesh::getKind(type));
- for (UInt nel = 0 ; nel != new_node_per_elem.getSize(); ++nel) {
- /// a former IGFEM triangle is transformed into a regular triangle
- if ( (type != _triangle_3) && (new_node_per_elem(nel,0) == 0)) {
-
- Vector<UInt> connec_new_elem(3);
- connec_new_elem(0) = connectivity(nel,0);
- connec_new_elem(1) = connectivity(nel,1);
- connec_new_elem(2) = connectivity(nel,2);
- /// add the new element in the mesh
- UInt nb_triangles_3 = connec_tri_3.getSize();
- connec_tri_3.push_back(connec_new_elem);
- el_tri_3.element = nb_triangles_3;
- new_elements_list.push_back(el_tri_3);
- /// the number of the old element in the mesh
- old_element.element = nel;
- old_elements_list.push_back(old_element);
- new_numbering(nel) = UInt(-1);
- ++n_new_el;
- }
-
- /// element is enriched
- else if (new_node_per_elem(nel,0) != 0) {
- switch(new_node_per_elem(nel,0)){
- /// new element is of type igfem_triangle_4
- case 1 :{
- Vector<UInt> connec_new_elem(4);
- switch(new_node_per_elem(nel,2)){
- case 0 :
- connec_new_elem(0) = connectivity(nel,2);
- connec_new_elem(1) = connectivity(nel,0);
- connec_new_elem(2) = connectivity(nel,1);
- break;
- case 1 :
- connec_new_elem(0) = connectivity(nel,0);
- connec_new_elem(1) = connectivity(nel,1);
- connec_new_elem(2) = connectivity(nel,2);
- break;
- case 2 :
- connec_new_elem(0) = connectivity(nel,1);
- connec_new_elem(1) = connectivity(nel,2);
- connec_new_elem(2) = connectivity(nel,0);
- break;
- default :
- AKANTU_DEBUG_ERROR("A triangle has only 3 segments not "<< new_node_per_elem(nel,2));
- break;
- }
- connec_new_elem(3) = new_node_per_elem(nel,1);
- UInt nb_igfem_triangles_4 = connec_igfem_tri_4.getSize();
- connec_igfem_tri_4.push_back(connec_new_elem);
- el_igfem_tri_4.element = nb_igfem_triangles_4;
- new_elements_list.push_back(el_igfem_tri_4);
- break;
- }
- /// new element is of type igfem_triangle_5
- case 2 :{
- Vector<UInt> connec_new_elem(5);
- if( (new_node_per_elem(nel,2)==0) && (new_node_per_elem(nel,4)==1) ){
- connec_new_elem(0) = connectivity(nel,1);
- connec_new_elem(1) = connectivity(nel,2);
- connec_new_elem(2) = connectivity(nel,0);
- connec_new_elem(3) = new_node_per_elem(nel,3);
- connec_new_elem(4) = new_node_per_elem(nel,1);
- }
- else if((new_node_per_elem(nel,2)==0) && (new_node_per_elem(nel,4)==2)){
- connec_new_elem(0) = connectivity(nel,0);
- connec_new_elem(1) = connectivity(nel,1);
- connec_new_elem(2) = connectivity(nel,2);
- connec_new_elem(3) = new_node_per_elem(nel,1);
- connec_new_elem(4) = new_node_per_elem(nel,3);
- }
- else if((new_node_per_elem(nel,2)==1) && (new_node_per_elem(nel,4)==2)){
- connec_new_elem(0) = connectivity(nel,2);
- connec_new_elem(1) = connectivity(nel,0);
- connec_new_elem(2) = connectivity(nel,1);
- connec_new_elem(3) = new_node_per_elem(nel,3);
- connec_new_elem(4) = new_node_per_elem(nel,1);
- }
- else if((new_node_per_elem(nel,2)==1) && (new_node_per_elem(nel,4)==0)){
- connec_new_elem(0) = connectivity(nel,1);
- connec_new_elem(1) = connectivity(nel,2);
- connec_new_elem(2) = connectivity(nel,0);
- connec_new_elem(3) = new_node_per_elem(nel,1);
- connec_new_elem(4) = new_node_per_elem(nel,3);
- }
- else if((new_node_per_elem(nel,2)==2) && (new_node_per_elem(nel,4)==0)){
- connec_new_elem(0) = connectivity(nel,0);
- connec_new_elem(1) = connectivity(nel,1);
- connec_new_elem(2) = connectivity(nel,2);
- connec_new_elem(3) = new_node_per_elem(nel,3);
- connec_new_elem(4) = new_node_per_elem(nel,1);
- }
- else if((new_node_per_elem(nel,2)==2) && (new_node_per_elem(nel,4)==1)){
- connec_new_elem(0) = connectivity(nel,2);
- connec_new_elem(1) = connectivity(nel,0);
- connec_new_elem(2) = connectivity(nel,1);
- connec_new_elem(3) = new_node_per_elem(nel,1);
- connec_new_elem(4) = new_node_per_elem(nel,3);
- }
- else
- AKANTU_DEBUG_ERROR("A triangle has only 3 segments (0 to 2) not "<< new_node_per_elem(nel,2) << "and" << new_node_per_elem(nel,4));
-
- UInt nb_igfem_triangles_5 = connec_igfem_tri_5.getSize();
- connec_igfem_tri_5.push_back(connec_new_elem);
- el_igfem_tri5.element = nb_igfem_triangles_5;
- new_elements_list.push_back(el_igfem_tri5);
- break;
- }
- default:
- AKANTU_DEBUG_ERROR("IGFEM cannot add "<< new_node_per_elem(nel,0) << " nodes to triangles");
- break;
- }
- old_element.element = nel;
- old_elements_list.push_back(old_element);
- new_numbering(nel) = UInt(-1);
- ++n_new_el;
- }
+ for (UInt nel = 0; nel != new_node_per_elem.getSize(); ++nel) {
+ /// a former IGFEM triangle is transformed into a regular triangle
+ if ((type != _triangle_3) && (new_node_per_elem(nel, 0) == 0)) {
+
+ Vector<UInt> connec_new_elem(3);
+ connec_new_elem(0) = connectivity(nel, 0);
+ connec_new_elem(1) = connectivity(nel, 1);
+ connec_new_elem(2) = connectivity(nel, 2);
+ /// add the new element in the mesh
+ UInt nb_triangles_3 = connec_tri_3.getSize();
+ connec_tri_3.push_back(connec_new_elem);
+ el_tri_3.element = nb_triangles_3;
+ new_elements_list.push_back(el_tri_3);
+ /// the number of the old element in the mesh
+ old_element.element = nel;
+ old_elements_list.push_back(old_element);
+ new_numbering(nel) = UInt(-1);
+ ++n_new_el;
+ }
+
+ /// element is enriched
+ else if (new_node_per_elem(nel, 0) != 0) {
+ switch (new_node_per_elem(nel, 0)) {
+ /// new element is of type igfem_triangle_4
+ case 1: {
+ Vector<UInt> connec_new_elem(4);
+ switch (new_node_per_elem(nel, 2)) {
+ case 0:
+ connec_new_elem(0) = connectivity(nel, 2);
+ connec_new_elem(1) = connectivity(nel, 0);
+ connec_new_elem(2) = connectivity(nel, 1);
+ break;
+ case 1:
+ connec_new_elem(0) = connectivity(nel, 0);
+ connec_new_elem(1) = connectivity(nel, 1);
+ connec_new_elem(2) = connectivity(nel, 2);
+ break;
+ case 2:
+ connec_new_elem(0) = connectivity(nel, 1);
+ connec_new_elem(1) = connectivity(nel, 2);
+ connec_new_elem(2) = connectivity(nel, 0);
+ break;
+ default:
+ AKANTU_DEBUG_ERROR("A triangle has only 3 segments not "
+ << new_node_per_elem(nel, 2));
+ break;
+ }
+ connec_new_elem(3) = new_node_per_elem(nel, 1);
+ UInt nb_igfem_triangles_4 = connec_igfem_tri_4.getSize();
+ connec_igfem_tri_4.push_back(connec_new_elem);
+ el_igfem_tri_4.element = nb_igfem_triangles_4;
+ new_elements_list.push_back(el_igfem_tri_4);
+ break;
+ }
+ /// new element is of type igfem_triangle_5
+ case 2: {
+ Vector<UInt> connec_new_elem(5);
+ if ((new_node_per_elem(nel, 2) == 0) &&
+ (new_node_per_elem(nel, 4) == 1)) {
+ connec_new_elem(0) = connectivity(nel, 1);
+ connec_new_elem(1) = connectivity(nel, 2);
+ connec_new_elem(2) = connectivity(nel, 0);
+ connec_new_elem(3) = new_node_per_elem(nel, 3);
+ connec_new_elem(4) = new_node_per_elem(nel, 1);
+ } else if ((new_node_per_elem(nel, 2) == 0) &&
+ (new_node_per_elem(nel, 4) == 2)) {
+ connec_new_elem(0) = connectivity(nel, 0);
+ connec_new_elem(1) = connectivity(nel, 1);
+ connec_new_elem(2) = connectivity(nel, 2);
+ connec_new_elem(3) = new_node_per_elem(nel, 1);
+ connec_new_elem(4) = new_node_per_elem(nel, 3);
+ } else if ((new_node_per_elem(nel, 2) == 1) &&
+ (new_node_per_elem(nel, 4) == 2)) {
+ connec_new_elem(0) = connectivity(nel, 2);
+ connec_new_elem(1) = connectivity(nel, 0);
+ connec_new_elem(2) = connectivity(nel, 1);
+ connec_new_elem(3) = new_node_per_elem(nel, 3);
+ connec_new_elem(4) = new_node_per_elem(nel, 1);
+ } else if ((new_node_per_elem(nel, 2) == 1) &&
+ (new_node_per_elem(nel, 4) == 0)) {
+ connec_new_elem(0) = connectivity(nel, 1);
+ connec_new_elem(1) = connectivity(nel, 2);
+ connec_new_elem(2) = connectivity(nel, 0);
+ connec_new_elem(3) = new_node_per_elem(nel, 1);
+ connec_new_elem(4) = new_node_per_elem(nel, 3);
+ } else if ((new_node_per_elem(nel, 2) == 2) &&
+ (new_node_per_elem(nel, 4) == 0)) {
+ connec_new_elem(0) = connectivity(nel, 0);
+ connec_new_elem(1) = connectivity(nel, 1);
+ connec_new_elem(2) = connectivity(nel, 2);
+ connec_new_elem(3) = new_node_per_elem(nel, 3);
+ connec_new_elem(4) = new_node_per_elem(nel, 1);
+ } else if ((new_node_per_elem(nel, 2) == 2) &&
+ (new_node_per_elem(nel, 4) == 1)) {
+ connec_new_elem(0) = connectivity(nel, 2);
+ connec_new_elem(1) = connectivity(nel, 0);
+ connec_new_elem(2) = connectivity(nel, 1);
+ connec_new_elem(3) = new_node_per_elem(nel, 1);
+ connec_new_elem(4) = new_node_per_elem(nel, 3);
+ } else
+ AKANTU_DEBUG_ERROR("A triangle has only 3 segments (0 to 2) not "
+ << new_node_per_elem(nel, 2) << "and"
+ << new_node_per_elem(nel, 4));
+
+ UInt nb_igfem_triangles_5 = connec_igfem_tri_5.getSize();
+ connec_igfem_tri_5.push_back(connec_new_elem);
+ el_igfem_tri5.element = nb_igfem_triangles_5;
+ new_elements_list.push_back(el_igfem_tri5);
+ break;
+ }
+ default:
+ AKANTU_DEBUG_ERROR("IGFEM cannot add " << new_node_per_elem(nel, 0)
+ << " nodes to triangles");
+ break;
+ }
+ old_element.element = nel;
+ old_elements_list.push_back(old_element);
+ new_numbering(nel) = UInt(-1);
+ ++n_new_el;
+ }
}
total_new_elements += n_new_el;
}
}
/// update new numbering
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
/// loop over all types in the mesh for a given ghost type
Mesh::type_iterator iit = mesh.firstType(dim, ghost_type, _ek_not_defined);
Mesh::type_iterator iend = mesh.lastType(dim, ghost_type, _ek_not_defined);
- for(;iit != iend; ++iit) {
+ for (; iit != iend; ++iit) {
ElementType type = *iit;
- Array<UInt> & new_numbering = removed_elements_event.getNewNumbering(type, ghost_type);
+ Array<UInt> & new_numbering =
+ removed_elements_event.getNewNumbering(type, ghost_type);
UInt el_index = 0;
UInt nb_element = this->mesh.getNbElement(type, ghost_type);
new_numbering.resize(nb_element);
for (UInt e = 0; e < nb_element; ++e) {
- if (new_numbering(e) != UInt(-1)) {
- new_numbering(e) = el_index;
- ++el_index;
- }
+ if (new_numbering(e) != UInt(-1)) {
+ new_numbering(e) = el_index;
+ ++el_index;
+ }
}
- changed_elements_event.getNewNumbering(type, ghost_type).copy(new_numbering);
+ changed_elements_event.getNewNumbering(type, ghost_type)
+ .copy(new_numbering);
}
}
-
- StaticCommunicator::getStaticCommunicator().allReduce(&total_new_elements, 1, _so_sum);
+ StaticCommunicator::getStaticCommunicator().allReduce(&total_new_elements, 1,
+ _so_sum);
- if(total_new_elements > 0){
- changed_elements_event.getListOld().copy(new_elements_event.getOldElementsList());
+ if (total_new_elements > 0) {
+ changed_elements_event.getListOld().copy(
+ new_elements_event.getOldElementsList());
changed_elements_event.getListNew().copy(new_elements_event.getList());
this->mesh.sendEvent(changed_elements_event);
this->mesh.sendEvent(new_elements_event);
Array<Element> & removed_list = removed_elements_event.getList();
removed_list.copy(new_elements_event.getOldElementsList());
this->mesh.sendEvent(removed_elements_event);
}
removeAdditionalNodes();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void MeshIgfemSphericalGrowingGel<dim>::buildSegmentConnectivityToNodeType() {
Mesh mesh_facets(mesh.initMeshFacets());
MeshUtils::buildSegmentToNodeType(mesh, mesh_facets, synchronizer);
// only the ghost elements are considered
- for(UInt g = _not_ghost; g <= _ghost; ++g) {
- GhostType ghost_type = (GhostType) g;
+ for (UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType ghost_type = (GhostType)g;
- Mesh::type_iterator it = mesh_facets.firstType(1, ghost_type);
+ Mesh::type_iterator it = mesh_facets.firstType(1, ghost_type);
Mesh::type_iterator end = mesh_facets.lastType(1, ghost_type);
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
ElementType type = *it;
- const Array<Int> & segment_to_nodetype
- = mesh_facets.getData<Int>("segment_to_nodetype", type, ghost_type);
+ const Array<Int> & segment_to_nodetype =
+ mesh_facets.getData<Int>("segment_to_nodetype", type, ghost_type);
- const Array<UInt> & segment_connectivity
- = mesh_facets.getConnectivity(type, ghost_type);
+ const Array<UInt> & segment_connectivity =
+ mesh_facets.getConnectivity(type, ghost_type);
// looping over all the segments
- Array<UInt>::const_vector_iterator conn_it
- = segment_connectivity.begin(segment_connectivity.getNbComponent());
- Array<UInt>::const_vector_iterator conn_end
- = segment_connectivity.end(segment_connectivity.getNbComponent());
+ Array<UInt>::const_vector_iterator conn_it =
+ segment_connectivity.begin(segment_connectivity.getNbComponent());
+ Array<UInt>::const_vector_iterator conn_end =
+ segment_connectivity.end(segment_connectivity.getNbComponent());
UInt seg_index = 0;
UInt n[2];
for (; conn_it != conn_end; ++conn_it, ++seg_index) {
- Int seg_type = segment_to_nodetype(seg_index);
- n[0] = (*conn_it)(0);
- n[1] = (*conn_it)(1);
-
- if ( (mesh.isMasterNode(n[0]) || mesh.isSlaveNode(n[0])) &&
- (mesh.isMasterNode(n[1]) || mesh.isSlaveNode(n[1]))) {
- std::sort(n, n+2);
- segment_conn_to_node_type[std::make_pair(n[0], n[1])] = seg_type;
- }
+ Int seg_type = segment_to_nodetype(seg_index);
+ n[0] = (*conn_it)(0);
+ n[1] = (*conn_it)(1);
+
+ if ((mesh.isMasterNode(n[0]) || mesh.isSlaveNode(n[0])) &&
+ (mesh.isMasterNode(n[1]) || mesh.isSlaveNode(n[1]))) {
+ std::sort(n, n + 2);
+ segment_conn_to_node_type[std::make_pair(n[0], n[1])] = seg_type;
+ }
}
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
-void MeshIgfemSphericalGrowingGel<dim>::updateNodeType(const Array<UInt> & nodes_list,
- const Array<UInt> & new_node_per_elem,
- ElementType type,
- GhostType ghost_type) {
+void MeshIgfemSphericalGrowingGel<dim>::updateNodeType(
+ const Array<UInt> & nodes_list, const Array<UInt> & new_node_per_elem,
+ ElementType type, GhostType ghost_type) {
Array<Int> & nodes_type = mesh.getNodesType();
UInt old_nodes = nodes_type.getSize();
UInt new_nodes = nodes_list.getSize();
// exit this function if the simulation in run in serial
- if (old_nodes == 0 || new_nodes == 0) return;
+ if (old_nodes == 0 || new_nodes == 0)
+ return;
nodes_type.resize(old_nodes + new_nodes);
Array<bool> checked_node(new_nodes, 1, false);
UInt nb_prim_by_el = 0;
- if( (type == _triangle_3) ||
- (type == _igfem_triangle_4) ||
- (type == _igfem_triangle_5) ){
+ if ((type == _triangle_3) || (type == _igfem_triangle_4) ||
+ (type == _igfem_triangle_5)) {
nb_prim_by_el = 3;
} else {
AKANTU_DEBUG_ERROR("Not ready for mesh type " << type);
}
// determine the node type for the local, master and slave nodes
const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
- unordered_map< std::pair<UInt, UInt>, Int >::type::iterator seg_type_it;
- unordered_map< std::pair<UInt, UInt>, Int >::type::iterator seg_type_end
- = segment_conn_to_node_type.end();
+ unordered_map<std::pair<UInt, UInt>, Int>::type::iterator seg_type_it;
+ unordered_map<std::pair<UInt, UInt>, Int>::type::iterator seg_type_end =
+ segment_conn_to_node_type.end();
for (UInt el = 0; el < new_node_per_elem.getSize(); ++el) {
UInt nb_nodes = new_node_per_elem(el, 0);
for (UInt n = 0; n < nb_nodes; ++n) {
- UInt node_index = new_node_per_elem(el, 2*n+1);
- if (node_index < old_nodes || checked_node(node_index - old_nodes)) continue;
+ UInt node_index = new_node_per_elem(el, 2 * n + 1);
+ if (node_index < old_nodes || checked_node(node_index - old_nodes))
+ continue;
// get the elemental connectivity of the segment associated to the node
- UInt segment_index = new_node_per_elem(el, 2*n+2);
+ UInt segment_index = new_node_per_elem(el, 2 * n + 2);
UInt extreme_nodes[2];
extreme_nodes[0] = segment_index;
extreme_nodes[1] = segment_index + 1;
- if (extreme_nodes[1] == nb_prim_by_el) extreme_nodes[1] = 0;
+ if (extreme_nodes[1] == nb_prim_by_el)
+ extreme_nodes[1] = 0;
// get the connectivity of the segment
extreme_nodes[0] = connectivity(el, extreme_nodes[0]);
extreme_nodes[1] = connectivity(el, extreme_nodes[1]);
-
- // if one extreme nodes is pure ghost, then also the new node is pure ghost
+ // if one extreme nodes is pure ghost, then also the new node is pure
+ // ghost
if (mesh.isPureGhostNode(extreme_nodes[0]) ||
- mesh.isPureGhostNode(extreme_nodes[1]))
- nodes_type(node_index) = -3;
- // if on of the two extreme nodes is local, then also the new node is local
+ mesh.isPureGhostNode(extreme_nodes[1]))
+ nodes_type(node_index) = -3;
+ // if on of the two extreme nodes is local, then also the new node is
+ // local
else if (mesh.isLocalNode(extreme_nodes[0]) ||
- mesh.isLocalNode(extreme_nodes[1]))
- nodes_type(node_index) = -1;
+ mesh.isLocalNode(extreme_nodes[1]))
+ nodes_type(node_index) = -1;
// otherwise use the value stored in the map
else {
- std::sort(extreme_nodes, extreme_nodes+2);
+ std::sort(extreme_nodes, extreme_nodes + 2);
- seg_type_it = segment_conn_to_node_type.find(std::make_pair(extreme_nodes[0],
- extreme_nodes[1]));
+ seg_type_it = segment_conn_to_node_type.find(
+ std::make_pair(extreme_nodes[0], extreme_nodes[1]));
- AKANTU_DEBUG_ASSERT(seg_type_it != seg_type_end, "Segment not found");
+ AKANTU_DEBUG_ASSERT(seg_type_it != seg_type_end, "Segment not found");
- nodes_type(node_index) = seg_type_it->second;
+ nodes_type(node_index) = seg_type_it->second;
}
checked_node(node_index - old_nodes) = true;
}
}
- AKANTU_DEBUG_ASSERT(std::accumulate(checked_node.begin(), checked_node.end(), 0)
- == Int(checked_node.getSize()),
- "Not all new nodes were assigned a node type");
+ AKANTU_DEBUG_ASSERT(std::accumulate(checked_node.begin(), checked_node.end(),
+ 0) == Int(checked_node.getSize()),
+ "Not all new nodes were assigned a node type");
}
__END_AKANTU__
diff --git a/extra_packages/igfem/src/non_local_manager_igfem.cc b/extra_packages/igfem/src/non_local_manager_igfem.cc
index 1062f1a5c..f52d56fd0 100644
--- a/extra_packages/igfem/src/non_local_manager_igfem.cc
+++ b/extra_packages/igfem/src/non_local_manager_igfem.cc
@@ -1,275 +1,308 @@
/**
* @file non_local_manager_igfem.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Mon Sep 21 15:32:10 2015
*
* @brief Implementation of non-local manager igfem
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_DAMAGE_NON_LOCAL
#include "non_local_manager_igfem.hh"
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-NonLocalManagerIGFEM::NonLocalManagerIGFEM(SolidMechanicsModelIGFEM & model,
- const ID & id,
- const MemoryID & memory_id) :
- NonLocalManager(model, id, memory_id) {
-
+NonLocalManagerIGFEM::NonLocalManagerIGFEM(SolidMechanicsModelIGFEM & model,
+ const ID & id,
+ const MemoryID & memory_id)
+ : NonLocalManager(model, id, memory_id) {
+
Mesh & mesh = this->model.getMesh();
-
+
/// initialize the element type map array
- /// it will be resized to nb_quad * nb_element during the computation of coords
- mesh.initElementTypeMapArray(quad_positions, spatial_dimension, spatial_dimension, false, _ek_igfem, true);
+ /// it will be resized to nb_quad * nb_element during the computation of
+ /// coords
+ mesh.initElementTypeMapArray(quad_positions, spatial_dimension,
+ spatial_dimension, false, _ek_igfem, true);
}
/* -------------------------------------------------------------------------- */
-NonLocalManagerIGFEM::~NonLocalManagerIGFEM() {
-
-}
+NonLocalManagerIGFEM::~NonLocalManagerIGFEM() {}
/* -------------------------------------------------------------------------- */
-void NonLocalManagerIGFEM::init(){
+void NonLocalManagerIGFEM::init() {
/// store the number of current ghost elements for each type in the mesh
ElementTypeMap<UInt> nb_ghost_protected;
Mesh & mesh = this->model.getMesh();
- for(UInt k = _ek_regular; k <= _ek_igfem; ++k) {
- ElementKind el_kind = (ElementKind) k;
+ for (UInt k = _ek_regular; k <= _ek_igfem; ++k) {
+ ElementKind el_kind = (ElementKind)k;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost, el_kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost, el_kind);
- for(; it != last_type; ++it)
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, _ghost, el_kind);
+ for (; it != last_type; ++it)
nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
}
/// exchange the missing ghosts for the non-local neighborhoods
this->createNeighborhoodSynchronizers();
- /// insert the ghost quadrature points of the non-local materials into the non-local neighborhoods
- for(UInt m = 0; m < this->non_local_materials.size(); ++m) {
+ /// insert the ghost quadrature points of the non-local materials into the
+ /// non-local neighborhoods
+ for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
switch (spatial_dimension) {
case 1:
- dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
- break;
+ dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m]))
+ .insertQuadsInNeighborhoods(_ghost);
+ break;
case 2:
- dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
- break;
+ dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m]))
+ .insertQuadsInNeighborhoods(_ghost);
+ break;
case 3:
- dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
- break;
+ dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m]))
+ .insertQuadsInNeighborhoods(_ghost);
+ break;
}
-
}
FEEngine & fee_regular = this->model.getFEEngine();
FEEngine & fee_igfem = this->model.getFEEngine("IGFEMFEEngine");
this->updatePairLists();
/// cleanup the unneccessary ghost elements
this->cleanupExtraGhostElements(nb_ghost_protected);
this->initElementTypeMap(1, volumes, fee_regular, _ek_regular);
this->initElementTypeMap(1, volumes, fee_igfem, _ek_igfem);
this->setJacobians(fee_regular, _ek_regular);
this->setJacobians(fee_igfem, _ek_igfem);
this->initNonLocalVariables();
this->computeWeights();
}
/* -------------------------------------------------------------------------- */
void NonLocalManagerIGFEM::computeAllNonLocalStresses() {
/// update the flattened version of the internals
- std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
- std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it =
+ non_local_variables.begin();
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_end =
+ non_local_variables.end();
- for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
+ for (; non_local_variable_it != non_local_variable_end;
+ ++non_local_variable_it) {
non_local_variable_it->second->local.clear();
non_local_variable_it->second->non_local.clear();
- for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
- GhostType ghost_type = (GhostType) gt;
- this->flattenInternal(non_local_variable_it->second->local, ghost_type, _ek_regular);
- this->flattenInternal(non_local_variable_it->second->local, ghost_type, _ek_igfem);
+ for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
+ GhostType ghost_type = (GhostType)gt;
+ this->flattenInternal(non_local_variable_it->second->local, ghost_type,
+ _ek_regular);
+ this->flattenInternal(non_local_variable_it->second->local, ghost_type,
+ _ek_igfem);
}
}
- this->volumes.clear();
+ this->volumes.clear();
/// loop over all the neighborhoods and compute intiate the
/// exchange of the non-local_variables
- std::set<ID>::const_iterator global_neighborhood_it = global_neighborhoods.begin();
+ std::set<ID>::const_iterator global_neighborhood_it =
+ global_neighborhoods.begin();
NeighborhoodMap::iterator it;
- for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
+ for (; global_neighborhood_it != global_neighborhoods.end();
+ ++global_neighborhood_it) {
it = neighborhoods.find(*global_neighborhood_it);
if (it != neighborhoods.end())
- it->second->getSynchronizerRegistry().asynchronousSynchronize(_gst_mnl_for_average);
- else
- dummy_synchronizers[*global_neighborhood_it]->asynchronousSynchronize(dummy_accessor, _gst_mnl_for_average);
+ it->second->getSynchronizerRegistry().asynchronousSynchronize(
+ _gst_mnl_for_average);
+ else
+ dummy_synchronizers[*global_neighborhood_it]->asynchronousSynchronize(
+ dummy_accessor, _gst_mnl_for_average);
}
this->averageInternals(_not_ghost);
AKANTU_DEBUG_INFO("Wait distant non local stresses");
/// loop over all the neighborhoods and block until all non-local
/// variables have been exchanged
global_neighborhood_it = global_neighborhoods.begin();
it = neighborhoods.begin();
- for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
+ for (; global_neighborhood_it != global_neighborhoods.end();
+ ++global_neighborhood_it) {
it = neighborhoods.find(*global_neighborhood_it);
if (it != neighborhoods.end())
- it->second->getSynchronizerRegistry().waitEndSynchronize(_gst_mnl_for_average);
+ it->second->getSynchronizerRegistry().waitEndSynchronize(
+ _gst_mnl_for_average);
else
- dummy_synchronizers[*global_neighborhood_it]->waitEndSynchronize(dummy_accessor, _gst_mnl_for_average);
+ dummy_synchronizers[*global_neighborhood_it]->waitEndSynchronize(
+ dummy_accessor, _gst_mnl_for_average);
}
-
this->averageInternals(_ghost);
/// copy the results in the materials
this->distributeInternals(_ek_regular);
- /// loop over all the materials and update the weights
- for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
- switch (spatial_dimension) {
- case 1:
- dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
- case 2:
- dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
- case 3:
- dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
- }
+ /// loop over all the materials and update the weights
+ for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
+ switch (spatial_dimension) {
+ case 1:
+ dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m]))
+ .computeNonLocalStresses(_not_ghost);
+ break;
+ case 2:
+ dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m]))
+ .computeNonLocalStresses(_not_ghost);
+ break;
+ case 3:
+ dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m]))
+ .computeNonLocalStresses(_not_ghost);
+ break;
}
-
- ++this->compute_stress_calls;
+ }
+
+ ++this->compute_stress_calls;
}
/* -------------------------------------------------------------------------- */
-void NonLocalManagerIGFEM::cleanupExtraGhostElements(ElementTypeMap<UInt> & nb_ghost_protected) {
+void NonLocalManagerIGFEM::cleanupExtraGhostElements(
+ ElementTypeMap<UInt> & nb_ghost_protected) {
typedef std::set<Element> ElementSet;
ElementSet relevant_ghost_elements;
ElementSet to_keep_per_neighborhood;
/// loop over all the neighborhoods and get their protected ghosts
NeighborhoodMap::iterator neighborhood_it = neighborhoods.begin();
- NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
+ NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
for (; neighborhood_it != neighborhood_end; ++neighborhood_it) {
- neighborhood_it->second->cleanupExtraGhostElements(to_keep_per_neighborhood);
+ neighborhood_it->second->cleanupExtraGhostElements(
+ to_keep_per_neighborhood);
ElementSet::const_iterator it = to_keep_per_neighborhood.begin();
- for(; it != to_keep_per_neighborhood.end(); ++it)
+ for (; it != to_keep_per_neighborhood.end(); ++it)
relevant_ghost_elements.insert(*it);
to_keep_per_neighborhood.clear();
}
/// remove all unneccessary ghosts from the mesh
/// Create list of element to remove and new numbering for element to keep
Mesh & mesh = this->model.getMesh();
ElementSet ghost_to_erase;
RemovedElementsEvent remove_elem(mesh);
- Element element;
+ Element element;
for (UInt k = _ek_regular; k < _ek_igfem; ++k) {
- ElementKind el_kind = (ElementKind) k;
+ ElementKind el_kind = (ElementKind)k;
element.kind = _ek_igfem;
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost, el_kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost, el_kind);
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost, el_kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, _ghost, el_kind);
element.ghost_type = _ghost;
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
element.type = *it;
UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
UInt nb_ghost_elem_protected = 0;
try {
- nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
- } catch (...) {}
+ nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
+ } catch (...) {
+ }
- if(!remove_elem.getNewNumbering().exists(*it, _ghost))
- remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
- else remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
+ if (!remove_elem.getNewNumbering().exists(*it, _ghost))
+ remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
+ else
+ remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
for (UInt g = 0; g < nb_ghost_elem; ++g) {
- element.element = g;
- if (element.element >= nb_ghost_elem_protected &&
- relevant_ghost_elements.find(element) == relevant_ghost_elements.end()) {
- remove_elem.getList().push_back(element);
- new_numbering(element.element) = UInt(-1);
- }
+ element.element = g;
+ if (element.element >= nb_ghost_elem_protected &&
+ relevant_ghost_elements.find(element) ==
+ relevant_ghost_elements.end()) {
+ remove_elem.getList().push_back(element);
+ new_numbering(element.element) = UInt(-1);
+ }
}
/// renumber remaining ghosts
UInt ng = 0;
for (UInt g = 0; g < nb_ghost_elem; ++g) {
- if (new_numbering(g) != UInt(-1)) {
- new_numbering(g) = ng;
- ++ng;
- }
+ if (new_numbering(g) != UInt(-1)) {
+ new_numbering(g) = ng;
+ ++ng;
+ }
}
}
}
for (UInt k = _ek_regular; k < _ek_igfem; ++k) {
- ElementKind el_kind = (ElementKind) k;
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost, el_kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost, el_kind);
- for(; it != last_type; ++it) {
+ ElementKind el_kind = (ElementKind)k;
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost, el_kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, _ghost, el_kind);
+ for (; it != last_type; ++it) {
UInt nb_elem = mesh.getNbElement(*it, _not_ghost);
- if(!remove_elem.getNewNumbering().exists(*it, _not_ghost))
- remove_elem.getNewNumbering().alloc(nb_elem, 1, *it, _not_ghost);
- Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _not_ghost);
+ if (!remove_elem.getNewNumbering().exists(*it, _not_ghost))
+ remove_elem.getNewNumbering().alloc(nb_elem, 1, *it, _not_ghost);
+ Array<UInt> & new_numbering =
+ remove_elem.getNewNumbering(*it, _not_ghost);
for (UInt e = 0; e < nb_elem; ++e) {
- new_numbering(e) = e;
+ new_numbering(e) = e;
}
}
}
mesh.sendEvent(remove_elem);
}
/* -------------------------------------------------------------------------- */
-void NonLocalManagerIGFEM::onElementsAdded(__attribute__((unused)) const Array<Element> & element_list,
- __attribute__((unused)) const NewElementsEvent & event) {
-
+void NonLocalManagerIGFEM::onElementsAdded(__attribute__((unused))
+ const Array<Element> & element_list,
+ __attribute__((unused))
+ const NewElementsEvent & event) {
+
FEEngine & fee = this->model.getFEEngine("IGFEMFEEngine");
this->resizeElementTypeMap(1, volumes, fee, _ek_igfem);
this->resizeElementTypeMap(spatial_dimension, quad_positions, fee, _ek_igfem);
NonLocalManager::onElementsAdded(element_list, event);
}
/* -------------------------------------------------------------------------- */
-void NonLocalManagerIGFEM::onElementsRemoved(const Array<Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- __attribute__((unused)) const RemovedElementsEvent & event) {
-
+void NonLocalManagerIGFEM::onElementsRemoved(
+ const Array<Element> & element_list,
+ const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedElementsEvent & event) {
+
FEEngine & fee = this->model.getFEEngine("IGFEMFEEngine");
- this->removeIntegrationPointsFromMap(event.getNewNumbering(), spatial_dimension, quad_positions, fee, _ek_igfem);
- this->removeIntegrationPointsFromMap(event.getNewNumbering(), 1, volumes, fee, _ek_igfem);
+ this->removeIntegrationPointsFromMap(event.getNewNumbering(),
+ spatial_dimension, quad_positions, fee,
+ _ek_igfem);
+ this->removeIntegrationPointsFromMap(event.getNewNumbering(), 1, volumes, fee,
+ _ek_igfem);
NonLocalManager::onElementsRemoved(element_list, new_numbering, event);
-
}
-
__END_AKANTU__
#endif /* AKANTU_DAMAGE_NON_LOCAL */
diff --git a/extra_packages/igfem/src/non_local_manager_igfem.hh b/extra_packages/igfem/src/non_local_manager_igfem.hh
index 465d333e5..b020c21aa 100644
--- a/extra_packages/igfem/src/non_local_manager_igfem.hh
+++ b/extra_packages/igfem/src/non_local_manager_igfem.hh
@@ -1,97 +1,98 @@
/**
* @file non_local_manager_igfem.hh
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Mon Sep 21 14:21:33 2015
*
* @brief Class that manages all the non-local neighborhoods for IGFEM
* simulations
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_DAMAGE_NON_LOCAL
#ifndef __AKANTU_NON_LOCAL_MANAGER_IGFEM_HH__
#define __AKANTU_NON_LOCAL_MANAGER_IGFEM_HH__
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class NonLocalManagerIGFEM : public NonLocalManager {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- NonLocalManagerIGFEM(SolidMechanicsModelIGFEM & model,
- const ID & id = "non_local_manager_igfem",
- const MemoryID & memory_id = 0);
+ NonLocalManagerIGFEM(SolidMechanicsModelIGFEM & model,
+ const ID & id = "non_local_manager_igfem",
+ const MemoryID & memory_id = 0);
virtual ~NonLocalManagerIGFEM();
-/* -------------------------------------------------------------------------- */
-/* Methods */
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Methods */
+ /* --------------------------------------------------------------------------
+ */
public:
-
- /// initialize the non-local manager: compute pair lists and weights for all neighborhoods
+ /// initialize the non-local manager: compute pair lists and weights for all
+ /// neighborhoods
virtual void init();
- /// average the internals and compute the non-local stresses
+ /// average the internals and compute the non-local stresses
virtual void computeAllNonLocalStresses();
-/* -------------------------------------------------------------------------- */
-/* MeshEventHandler inherited members */
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* MeshEventHandler inherited members */
+ /* --------------------------------------------------------------------------
+ */
+
+ virtual void
+ onElementsRemoved(const Array<Element> & element_list,
+ const ElementTypeMapArray<UInt> & new_numbering,
+ const RemovedElementsEvent & event);
- virtual void onElementsRemoved(const Array<Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- const RemovedElementsEvent & event);
-
virtual void onElementsAdded(const Array<Element> & element_list,
- const NewElementsEvent & event);
-private:
+ const NewElementsEvent & event);
+private:
/// cleanup unneccessary ghosts
- virtual void cleanupExtraGhostElements(ElementTypeMap<UInt> & nb_ghost_protected);
+ virtual void
+ cleanupExtraGhostElements(ElementTypeMap<UInt> & nb_ghost_protected);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
-
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-
-
-
#endif /* __AKANTU_NON_LOCAL_MANAGER_IGFEM_HH__ */
#endif /* AKANTU_DAMAGE_NON_LOCAL */
diff --git a/extra_packages/igfem/src/shape_igfem.cc b/extra_packages/igfem/src/shape_igfem.cc
index b27fe366b..8dc432922 100644
--- a/extra_packages/igfem/src/shape_igfem.cc
+++ b/extra_packages/igfem/src/shape_igfem.cc
@@ -1,92 +1,97 @@
/**
* @file shape_igfem_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief ShapeIGFEM inline implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
//#include "mesh.hh"
#include "shape_igfem.hh"
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-ShapeLagrange<_ek_igfem>::ShapeLagrange(const Mesh & mesh,
- const ID & id,
- const MemoryID & memory_id) :
- ShapeFunctions(mesh, id, memory_id),
- shapes("shapes_generic", id, memory_id),
- shapes_derivatives("shapes_derivatives_generic", id, memory_id),
- igfem_integration_points("igfem_integration_points", id, memory_id),
- shapes_at_enrichments("shapes_at_enrichments", id, memory_id) {
+ShapeLagrange<_ek_igfem>::ShapeLagrange(const Mesh & mesh, const ID & id,
+ const MemoryID & memory_id)
+ : ShapeFunctions(mesh, id, memory_id),
+ shapes("shapes_generic", id, memory_id),
+ shapes_derivatives("shapes_derivatives_generic", id, memory_id),
+ igfem_integration_points("igfem_integration_points", id, memory_id),
+ shapes_at_enrichments("shapes_at_enrichments", id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/*-------------------------------------------------------------------------- */
-void ShapeLagrange<_ek_igfem>::extractValuesAtStandardNodes(const Array<Real> & nodal_values,
- Array<Real> & extracted_values,
- const GhostType & ghost_type) const {
-
- AKANTU_DEBUG_ASSERT(nodal_values.getNbComponent() == extracted_values.getNbComponent(), "The arrays are not of the same size!!!!!");
+void ShapeLagrange<_ek_igfem>::extractValuesAtStandardNodes(
+ const Array<Real> & nodal_values, Array<Real> & extracted_values,
+ const GhostType & ghost_type) const {
+
+ AKANTU_DEBUG_ASSERT(nodal_values.getNbComponent() ==
+ extracted_values.getNbComponent(),
+ "The arrays are not of the same size!!!!!");
extracted_values.clear();
UInt spatial_dimension = mesh.getSpatialDimension();
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_igfem);
- Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_igfem);
- for(; it != end; ++it) {
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator end =
+ mesh.lastType(spatial_dimension, ghost_type, _ek_igfem);
+ for (; it != end; ++it) {
ElementType type = *it;
UInt nb_elements = mesh.getNbElement(type, ghost_type);
UInt nb_parent_nodes = 0;
UInt nb_nodes_per_element = 0;
-#define GET_NODES_INFO(type) \
- const ElementType parent_type = ElementClassProperty<type>::parent_element_type; \
- nb_parent_nodes = ElementClass<parent_type>::getNbNodesPerInterpolationElement(); \
- nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
+#define GET_NODES_INFO(type) \
+ const ElementType parent_type = \
+ ElementClassProperty<type>::parent_element_type; \
+ nb_parent_nodes = \
+ ElementClass<parent_type>::getNbNodesPerInterpolationElement(); \
+ nb_nodes_per_element = \
+ ElementClass<type>::getNbNodesPerInterpolationElement();
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(GET_NODES_INFO);
#undef GET_NODES_INFO
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
for (UInt e = 0; e < nb_elements; ++e) {
/// copy the value at standard nodes
UInt offset = e * nb_nodes_per_element;
for (UInt n = 0; n < nb_parent_nodes; ++n) {
- UInt node = conn_val[offset + n];
- for (UInt i = 0; i < nodal_values.getNbComponent(); ++i)
- extracted_values(node, i) = nodal_values(node, i);
+ UInt node = conn_val[offset + n];
+ for (UInt i = 0; i < nodal_values.getNbComponent(); ++i)
+ extracted_values(node, i) = nodal_values(node, i);
}
}
}
}
/* -------------------------------------------------------------------------- */
-void ShapeLagrange<_ek_igfem>::printself(std::ostream & stream, int indent) const {
+void ShapeLagrange<_ek_igfem>::printself(std::ostream & stream,
+ int indent) const {
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "Shapes Lagrange [" << std::endl;
ShapeFunctions::printself(stream, indent + 1);
shapes.printself(stream, indent + 1);
shapes_derivatives.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
__END_AKANTU__
#endif
-
-
-
diff --git a/extra_packages/igfem/src/shape_igfem.hh b/extra_packages/igfem/src/shape_igfem.hh
index 3d101296f..c6f49999b 100644
--- a/extra_packages/igfem/src/shape_igfem.hh
+++ b/extra_packages/igfem/src/shape_igfem.hh
@@ -1,210 +1,201 @@
/**
* @file shape_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief shape functions for interface-enriched generalized FEM
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "shape_functions.hh"
#ifndef __AKANTU_SHAPE_IGFEM_HH__
#define __AKANTU_SHAPE_IGFEM_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template <>
-class ShapeLagrange<_ek_igfem> : public ShapeFunctions{
+template <> class ShapeLagrange<_ek_igfem> : public ShapeFunctions {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- ShapeLagrange(const Mesh & mesh,
- const ID & id = "shape_igfem",
- const MemoryID & memory_id = 0);
-
+ ShapeLagrange(const Mesh & mesh, const ID & id = "shape_igfem",
+ const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline void initShapeFunctions(const Array<Real> & nodes,
- const Matrix<Real> & integration_points,
- const Matrix<Real> & integration_points_1,
- const Matrix<Real> & integration_points_2,
- const ElementType & type,
- const GhostType & ghost_type);
-
- inline void interpolateEnrichmentsAllTypes(const Array<Real> & src,
- Array<Real> & dst,
- const ElementType & type,
- const GhostType & ghost_type) const;
+ const Matrix<Real> & integration_points,
+ const Matrix<Real> & integration_points_1,
+ const Matrix<Real> & integration_points_2,
+ const ElementType & type,
+ const GhostType & ghost_type);
+ inline void
+ interpolateEnrichmentsAllTypes(const Array<Real> & src, Array<Real> & dst,
+ const ElementType & type,
+ const GhostType & ghost_type) const;
- template<ElementType type>
- inline void precomputeShapesOnEnrichedNodes(const Array<Real> & nodes,
- const GhostType & ghost_type);
+ template <ElementType type>
+ inline void precomputeShapesOnEnrichedNodes(const Array<Real> & nodes,
+ const GhostType & ghost_type);
template <ElementType type>
- void interpolateAtEnrichedNodes(const Array<Real> & src,
- Array<Real> & dst,
- const GhostType & ghost_type) const;
+ void interpolateAtEnrichedNodes(const Array<Real> & src, Array<Real> & dst,
+ const GhostType & ghost_type) const;
- /// pre compute all shapes on the element integration points from natural coordinates
- template<ElementType type>
+ /// pre compute all shapes on the element integration points from natural
+ /// coordinates
+ template <ElementType type>
void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
- GhostType ghost_type);
+ GhostType ghost_type);
- /// pre compute all shape derivatives on the element integration points from natural coordinates
+ /// pre compute all shape derivatives on the element integration points from
+ /// natural coordinates
template <ElementType type>
void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
- GhostType ghost_type);
+ GhostType ghost_type);
/// interpolate nodal values on the integration points
template <ElementType type>
- void interpolateOnIntegrationPoints(const Array<Real> &u,
- Array<Real> &uq,
- UInt nb_degree_of_freedom,
- GhostType ghost_type = _not_ghost,
- const Array<UInt> & filter_elements = empty_filter) const;
+ void interpolateOnIntegrationPoints(
+ const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
+ GhostType ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate on physical point
template <ElementType type>
- void interpolate(const Vector <Real> & real_coords,
- UInt elem,
- const Matrix<Real> & nodal_values,
- Vector<Real> & interpolated,
- const GhostType & ghost_type) const;
+ void interpolate(const Vector<Real> & real_coords, UInt elem,
+ const Matrix<Real> & nodal_values,
+ Vector<Real> & interpolated,
+ const GhostType & ghost_type) const;
/// compute the gradient of u on the integration points
template <ElementType type>
- void gradientOnIntegrationPoints(const Array<Real> &u,
- Array<Real> &nablauq,
- UInt nb_degree_of_freedom,
- GhostType ghost_type = _not_ghost,
- const Array<UInt> & filter_elements = empty_filter) const;
+ void gradientOnIntegrationPoints(
+ const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
+ GhostType ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const;
/// multiply a field by shape functions @f$ fts_{ij} = f_i * \varphi_j @f$
template <ElementType type>
void fieldTimesShapes(const Array<Real> & field,
- Array<Real> & field_times_shapes,
- GhostType ghost_type) const;
+ Array<Real> & field_times_shapes,
+ GhostType ghost_type) const;
/// find natural coords in parent element from real coords provided an element
template <ElementType type>
- void inverseMap(const Vector<Real> & real_coords,
- UInt element,
- Vector<Real> & natural_coords,
- const GhostType & ghost_type = _not_ghost) const;
+ void inverseMap(const Vector<Real> & real_coords, UInt element,
+ Vector<Real> & natural_coords,
+ const GhostType & ghost_type = _not_ghost) const;
/// find natural coords in sub-element from real coords provided an element
template <ElementType type>
- void inverseMap(const Vector<Real> & real_coords,
- UInt element,
- Vector<Real> & natural_coords,
- UInt sub_element,
- const GhostType & ghost_type = _not_ghost) const;
+ void inverseMap(const Vector<Real> & real_coords, UInt element,
+ Vector<Real> & natural_coords, UInt sub_element,
+ const GhostType & ghost_type = _not_ghost) const;
- /// return true if the coordinates provided are inside the element, false otherwise
+ /// return true if the coordinates provided are inside the element, false
+ /// otherwise
template <ElementType type>
- bool contains(const Vector<Real> & real_coords,
- UInt elem,
- const GhostType & ghost_type) const;
+ bool contains(const Vector<Real> & real_coords, UInt elem,
+ const GhostType & ghost_type) const;
/// compute the shape on a provided point
template <ElementType type>
- void computeShapes(const Vector<Real> & real_coords,
- UInt elem,
- Vector<Real> & shapes,
- const GhostType & ghost_type) const;
+ void computeShapes(const Vector<Real> & real_coords, UInt elem,
+ Vector<Real> & shapes, const GhostType & ghost_type) const;
/// compute the shape derivatives on a provided point
template <ElementType type>
- void computeShapeDerivatives(const Matrix<Real> & real_coords,
- UInt elem,
- Tensor3<Real> & shapes,
- const GhostType & ghost_type) const;
+ void computeShapeDerivatives(const Matrix<Real> & real_coords, UInt elem,
+ Tensor3<Real> & shapes,
+ const GhostType & ghost_type) const;
/// interpolate a field on a given physical point
template <ElementType type>
- void interpolateOnPhysicalPoint(const Vector<Real> & real_coords,
- UInt elem,
- const Array<Real> & field,
- Vector<Real> & interpolated,
- const GhostType & ghost_type) const;
+ void interpolateOnPhysicalPoint(const Vector<Real> & real_coords, UInt elem,
+ const Array<Real> & field,
+ Vector<Real> & interpolated,
+ const GhostType & ghost_type) const;
- /// function to extract values at standard nodes and zero-out enriched values of a nodal field
+ /// function to extract values at standard nodes and zero-out enriched values
+ /// of a nodal field
void extractValuesAtStandardNodes(const Array<Real> & nodal_values,
- Array<Real> & extracted_values,
- const GhostType & ghost_type) const;
+ Array<Real> & extracted_values,
+ const GhostType & ghost_type) const;
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
/// compute the shape derivatives on integration points for a given element
template <ElementType type>
- inline void computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
- const Matrix<Real> & natural_coords,
- Tensor3<Real> & shapesd) const;
+ inline void
+ computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
+ const Matrix<Real> & natural_coords,
+ Tensor3<Real> & shapesd) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get a the shapes vector
- inline const Array<Real> & getShapes(const ElementType & el_type,
- const GhostType & ghost_type = _not_ghost) const;
+ inline const Array<Real> &
+ getShapes(const ElementType & el_type,
+ const GhostType & ghost_type = _not_ghost) const;
/// get a the shapes derivatives vector
- inline const Array<Real> & getShapesDerivatives(const ElementType & el_type,
- const GhostType & ghost_type = _not_ghost) const;
+ inline const Array<Real> &
+ getShapesDerivatives(const ElementType & el_type,
+ const GhostType & ghost_type = _not_ghost) const;
/// get a the shapes vector
- inline const Array<Real> & getShapesAtEnrichedNodes(const ElementType & el_type,
- const GhostType & ghost_type = _not_ghost) const;
+ inline const Array<Real> &
+ getShapesAtEnrichedNodes(const ElementType & el_type,
+ const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// shape functions for all elements
ElementTypeMapArray<Real, InterpolationType> shapes;
/// shape functions derivatives for all elements
ElementTypeMapArray<Real, InterpolationType> shapes_derivatives;
/// additional integration points for the IGFEM formulation
ElementTypeMapArray<Real> igfem_integration_points;
/// values of shape functions for all elements on the enriched nodes
ElementTypeMapArray<Real, InterpolationType> shapes_at_enrichments;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "shape_igfem_inline_impl.cc"
/// standard output stream operator
// template <class ShapeFunction>
-// inline std::ostream & operator <<(std::ostream & stream, const ShapeIGFEM<ShapeFunction> & _this)
+// inline std::ostream & operator <<(std::ostream & stream, const
+// ShapeIGFEM<ShapeFunction> & _this)
// {
// _this.printself(stream);
// return stream;
// }
-
#endif /* __AKANTU_SHAPE_IGFEM_HH__ */
diff --git a/extra_packages/igfem/src/shape_igfem_inline_impl.cc b/extra_packages/igfem/src/shape_igfem_inline_impl.cc
index 5cedc81b1..9296c0a02 100644
--- a/extra_packages/igfem/src/shape_igfem_inline_impl.cc
+++ b/extra_packages/igfem/src/shape_igfem_inline_impl.cc
@@ -1,716 +1,734 @@
/**
* @file shape_igfem_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief ShapeIGFEM inline implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_IGFEM_INLINE_IMPL_CC__
#define __AKANTU_SHAPE_IGFEM_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-inline const Array<Real> & ShapeLagrange<_ek_igfem>::getShapes(const ElementType & el_type,
- const GhostType & ghost_type) const {
+inline const Array<Real> &
+ShapeLagrange<_ek_igfem>::getShapes(const ElementType & el_type,
+ const GhostType & ghost_type) const {
return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
-inline const Array<Real> & ShapeLagrange<_ek_igfem>::getShapesDerivatives(const ElementType & el_type,
- const GhostType & ghost_type) const {
- return shapes_derivatives(FEEngine::getInterpolationType(el_type), ghost_type);
+inline const Array<Real> & ShapeLagrange<_ek_igfem>::getShapesDerivatives(
+ const ElementType & el_type, const GhostType & ghost_type) const {
+ return shapes_derivatives(FEEngine::getInterpolationType(el_type),
+ ghost_type);
}
/* -------------------------------------------------------------------------- */
-#define INIT_SHAPE_FUNCTIONS(type) \
- setIntegrationPointsByType<type>(integration_points, ghost_type); \
- setIntegrationPointsByType<ElementClassProperty<type>::sub_element_type_1>(integration_points_1, ghost_type); \
- setIntegrationPointsByType<ElementClassProperty<type>::sub_element_type_2>(integration_points_2, ghost_type); \
- precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \
- if (ElementClass<type>::getNaturalSpaceDimension() == \
- mesh.getSpatialDimension()) \
- precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type); \
+#define INIT_SHAPE_FUNCTIONS(type) \
+ setIntegrationPointsByType<type>(integration_points, ghost_type); \
+ setIntegrationPointsByType<ElementClassProperty<type>::sub_element_type_1>( \
+ integration_points_1, ghost_type); \
+ setIntegrationPointsByType<ElementClassProperty<type>::sub_element_type_2>( \
+ integration_points_2, ghost_type); \
+ precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \
+ if (ElementClass<type>::getNaturalSpaceDimension() == \
+ mesh.getSpatialDimension()) \
+ precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type); \
precomputeShapesOnEnrichedNodes<type>(nodes, ghost_type);
+inline void ShapeLagrange<_ek_igfem>::initShapeFunctions(
+ const Array<Real> & nodes, const Matrix<Real> & integration_points,
+ const Matrix<Real> & integration_points_1,
+ const Matrix<Real> & integration_points_2, const ElementType & type,
+ const GhostType & ghost_type) {
-inline void ShapeLagrange<_ek_igfem>::initShapeFunctions(const Array<Real> & nodes,
- const Matrix<Real> & integration_points,
- const Matrix<Real> & integration_points_1,
- const Matrix<Real> & integration_points_2,
- const ElementType & type,
- const GhostType & ghost_type) {
-
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
}
#undef INIT_SHAPE_FUNCTIONS
/* -------------------------------------------------------------------------- */
template <ElementType type>
-inline void ShapeLagrange<_ek_igfem>::
-computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
- const Matrix<Real> & natural_coords,
- Tensor3<Real> & shapesd) const {
+inline void ShapeLagrange<_ek_igfem>::computeShapeDerivativesOnCPointsByElement(
+ const Matrix<Real> & node_coords, const Matrix<Real> & natural_coords,
+ Tensor3<Real> & shapesd) const {
AKANTU_DEBUG_IN();
// compute dnds
- Tensor3<Real> dnds(node_coords.rows(), node_coords.cols(), natural_coords.cols());
+ Tensor3<Real> dnds(node_coords.rows(), node_coords.cols(),
+ natural_coords.cols());
ElementClass<type>::computeDNDS(natural_coords, dnds);
// compute dxds
- Tensor3<Real> J(node_coords.rows(), natural_coords.rows(), natural_coords.cols());
+ Tensor3<Real> J(node_coords.rows(), natural_coords.rows(),
+ natural_coords.cols());
ElementClass<type>::computeJMat(dnds, node_coords, J);
// compute shape derivatives
ElementClass<type>::computeShapeDerivatives(J, dnds, shapesd);
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeLagrange<_ek_igfem>::inverseMap(const Vector<Real> & real_coords,
- UInt elem,
- Vector<Real> & natural_coords,
- UInt sub_element,
- const GhostType & ghost_type) const{
+ UInt elem,
+ Vector<Real> & natural_coords,
+ UInt sub_element,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
/// typedef for the two subelement_types and the parent element type
const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
UInt spatial_dimension = mesh.getSpatialDimension();
- UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_per_element =
+ ElementClass<type>::getNbNodesPerInterpolationElement();
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
- mesh.extractNodalValuesFromElement(mesh.getNodes(),
- nodes_coord.storage(),
- elem_val + elem*nb_nodes_per_element,
- nb_nodes_per_element,
- spatial_dimension);
+ mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.storage(),
+ elem_val + elem * nb_nodes_per_element,
+ nb_nodes_per_element, spatial_dimension);
-
if (!sub_element) {
- UInt nb_nodes_sub_el = ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_sub_el =
+ ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
Matrix<Real> sub_el_coords(spatial_dimension, nb_nodes_sub_el);
- ElementClass<type>::getSubElementCoords(nodes_coord, sub_el_coords, sub_element);
- ElementClass<sub_type_1>::inverseMap(real_coords,
- sub_el_coords,
- natural_coords);
+ ElementClass<type>::getSubElementCoords(nodes_coord, sub_el_coords,
+ sub_element);
+ ElementClass<sub_type_1>::inverseMap(real_coords, sub_el_coords,
+ natural_coords);
}
else {
- UInt nb_nodes_sub_el = ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_sub_el =
+ ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
Matrix<Real> sub_el_coords(spatial_dimension, nb_nodes_sub_el);
- ElementClass<type>::getSubElementCoords(nodes_coord, sub_el_coords, sub_element);
- ElementClass<sub_type_2>::inverseMap(real_coords,
- sub_el_coords,
- natural_coords);
+ ElementClass<type>::getSubElementCoords(nodes_coord, sub_el_coords,
+ sub_element);
+ ElementClass<sub_type_2>::inverseMap(real_coords, sub_el_coords,
+ natural_coords);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeLagrange<_ek_igfem>::inverseMap(const Vector<Real> & real_coords,
- UInt elem,
- Vector<Real> & natural_coords,
- const GhostType & ghost_type) const{
+ UInt elem,
+ Vector<Real> & natural_coords,
+ const GhostType & ghost_type) const {
/// map point into parent reference domain
AKANTU_DEBUG_IN();
- const ElementType parent_type = ElementClassProperty<type>::parent_element_type;
-
+ const ElementType parent_type =
+ ElementClassProperty<type>::parent_element_type;
UInt spatial_dimension = mesh.getSpatialDimension();
- UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_per_element =
+ ElementClass<type>::getNbNodesPerInterpolationElement();
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
- mesh.extractNodalValuesFromElement(mesh.getNodes(),
- nodes_coord.storage(),
- elem_val + elem*nb_nodes_per_element,
- nb_nodes_per_element,
- spatial_dimension);
+ mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.storage(),
+ elem_val + elem * nb_nodes_per_element,
+ nb_nodes_per_element, spatial_dimension);
-
- UInt nb_nodes_parent_el = ElementClass<parent_type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_parent_el =
+ ElementClass<parent_type>::getNbNodesPerInterpolationElement();
Matrix<Real> parent_coords(spatial_dimension, nb_nodes_parent_el);
ElementClass<type>::getParentCoords(nodes_coord, parent_coords);
- ElementClass<parent_type>::inverseMap(real_coords,
- parent_coords,
- natural_coords);
+ ElementClass<parent_type>::inverseMap(real_coords, parent_coords,
+ natural_coords);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
bool ShapeLagrange<_ek_igfem>::contains(const Vector<Real> & real_coords,
- UInt elem,
- const GhostType & ghost_type) const{
+ UInt elem,
+ const GhostType & ghost_type) const {
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> natural_coords(spatial_dimension);
inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
return ElementClass<type>::contains(natural_coords);
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::interpolate(const Vector <Real> & real_coords,
- UInt elem,
- const Matrix<Real> & nodal_values,
- Vector<Real> & interpolated,
- const GhostType & ghost_type) const {
+void ShapeLagrange<_ek_igfem>::interpolate(const Vector<Real> & real_coords,
+ UInt elem,
+ const Matrix<Real> & nodal_values,
+ Vector<Real> & interpolated,
+ const GhostType & ghost_type) const {
UInt nb_shapes = ElementClass<type>::getShapeSize();
Vector<Real> shapes(nb_shapes);
computeShapes<type>(real_coords, elem, shapes, ghost_type);
ElementClass<type>::interpolate(nodal_values, shapes, interpolated);
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::computeShapes(const Vector<Real> & real_coords,
- UInt elem,
- Vector<Real> & shapes,
- const GhostType & ghost_type) const {
+void ShapeLagrange<_ek_igfem>::computeShapes(
+ const Vector<Real> & real_coords, UInt elem, Vector<Real> & shapes,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
/// typedef for the two subelement_types and the parent element type
const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
- const ElementType parent_type = ElementClassProperty<type>::parent_element_type;
+ const ElementType parent_type =
+ ElementClassProperty<type>::parent_element_type;
UInt spatial_dimension = mesh.getSpatialDimension();
/// parent contribution
- /// get the size of the parent shapes
+ /// get the size of the parent shapes
UInt size_of_parent_shapes = ElementClass<parent_type>::getShapeSize();
Vector<Real> parent_shapes(size_of_parent_shapes);
-
+
/// compute parent shapes -> map shapes in the physical domain of the parent
Vector<Real> natural_coords(spatial_dimension);
Real tol = Math::getTolerance();
Math::setTolerance(1e-14);
inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
ElementClass<parent_type>::computeShapes(natural_coords, parent_shapes);
natural_coords.clear();
/// sub-element contribution
/// check which sub-element contains the physical point
/// check if point is in sub-element 1
inverseMap<type>(real_coords, elem, natural_coords, 0, ghost_type);
if (ElementClass<sub_type_1>::contains(natural_coords)) {
UInt size_of_sub_shapes = ElementClass<sub_type_1>::getShapeSize();
Vector<Real> sub_shapes(size_of_sub_shapes);
ElementClass<sub_type_1>::computeShapes(natural_coords, sub_shapes);
/// assemble shape functions
ElementClass<type>::assembleShapes(parent_shapes, sub_shapes, shapes, 0);
- }
- else {
+ } else {
natural_coords.clear();
inverseMap<type>(real_coords, elem, natural_coords, 1, ghost_type);
- AKANTU_DEBUG_ASSERT(ElementClass<sub_type_2>::contains(natural_coords),
- "Physical point not contained in any element");
+ AKANTU_DEBUG_ASSERT(ElementClass<sub_type_2>::contains(natural_coords),
+ "Physical point not contained in any element");
UInt size_of_sub_shapes = ElementClass<sub_type_2>::getShapeSize();
Vector<Real> sub_shapes(size_of_sub_shapes);
ElementClass<sub_type_2>::computeShapes(natural_coords, sub_shapes);
/// assemble shape functions
ElementClass<type>::assembleShapes(parent_shapes, sub_shapes, shapes, 1);
}
Math::setTolerance(tol);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::computeShapeDerivatives(const Matrix<Real> & real_coords,
- UInt elem,
- Tensor3<Real> & shapesd,
- const GhostType & ghost_type) const {
+void ShapeLagrange<_ek_igfem>::computeShapeDerivatives(
+ const Matrix<Real> & real_coords, UInt elem, Tensor3<Real> & shapesd,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
-
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::precomputeShapesOnIntegrationPoints(__attribute__((unused)) const Array<Real> & nodes,
- GhostType ghost_type) {
+void ShapeLagrange<_ek_igfem>::precomputeShapesOnIntegrationPoints(
+ __attribute__((unused)) const Array<Real> & nodes, GhostType ghost_type) {
AKANTU_DEBUG_IN();
-
+
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
/// typedef for the two subelement_types and the parent element type
const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
- const ElementType parent_type = ElementClassProperty<type>::parent_element_type;
+ const ElementType parent_type =
+ ElementClassProperty<type>::parent_element_type;
/// get the spatial dimension for the given element type
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
- /// get the integration points for the subelements
- Matrix<Real> & natural_coords_sub_1 = integration_points(sub_type_1, ghost_type);
- Matrix<Real> & natural_coords_sub_2 = integration_points(sub_type_2, ghost_type);
-
- /// store the number of quadrature points on each subelement and the toal number
+ /// get the integration points for the subelements
+ Matrix<Real> & natural_coords_sub_1 =
+ integration_points(sub_type_1, ghost_type);
+ Matrix<Real> & natural_coords_sub_2 =
+ integration_points(sub_type_2, ghost_type);
+
+ /// store the number of quadrature points on each subelement and the toal
+ /// number
UInt nb_points_sub_1 = natural_coords_sub_1.cols();
UInt nb_points_sub_2 = natural_coords_sub_2.cols();
UInt nb_total_points = nb_points_sub_1 + nb_points_sub_2;
// get the integration points for the parent element
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
- Array<Real> & natural_coords_parent = igfem_integration_points.alloc(nb_element*nb_total_points,
- spatial_dimension,
- type,
- ghost_type);
- Array<Real>::matrix_iterator natural_coords_parent_it = natural_coords_parent.begin_reinterpret(spatial_dimension, nb_total_points, nb_element);
-
- /// get the size of the shapes
+ Array<Real> & natural_coords_parent = igfem_integration_points.alloc(
+ nb_element * nb_total_points, spatial_dimension, type, ghost_type);
+ Array<Real>::matrix_iterator natural_coords_parent_it =
+ natural_coords_parent.begin_reinterpret(spatial_dimension,
+ nb_total_points, nb_element);
+
+ /// get the size of the shapes
UInt size_of_shapes = ElementClass<type>::getShapeSize();
UInt size_of_parent_shapes = ElementClass<parent_type>::getShapeSize();
UInt size_of_sub_1_shapes = ElementClass<sub_type_1>::getShapeSize();
UInt size_of_sub_2_shapes = ElementClass<sub_type_2>::getShapeSize();
- /// initialize the matrices to store the shape functions of the subelements and the parent
+ /// initialize the matrices to store the shape functions of the subelements
+ /// and the parent
Matrix<Real> sub_1_shapes(size_of_sub_1_shapes, nb_points_sub_1);
Matrix<Real> sub_2_shapes(size_of_sub_2_shapes, nb_points_sub_2);
Matrix<Real> parent_1_shapes(size_of_parent_shapes, nb_points_sub_1);
Matrix<Real> parent_2_shapes(size_of_parent_shapes, nb_points_sub_2);
/// compute the shape functions of the subelements
ElementClass<sub_type_1>::computeShapes(natural_coords_sub_1, sub_1_shapes);
ElementClass<sub_type_2>::computeShapes(natural_coords_sub_2, sub_2_shapes);
/// get the nodal coordinates per element
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
- FEEngine::extractNodalToElementField(mesh, nodes, x_el,
- type, ghost_type);
- Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
- nb_nodes_per_element);
+ FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
+ Array<Real>::matrix_iterator x_it =
+ x_el.begin(spatial_dimension, nb_nodes_per_element);
/// allocate the shapes for the given element type
- Array<Real> & shapes_tmp = shapes.alloc(nb_element*nb_total_points,
- size_of_shapes,
- itp_type,
- ghost_type);
-
- Array<Real>::matrix_iterator shapes_it =
- shapes_tmp.begin_reinterpret(ElementClass<type>::getNbNodesPerInterpolationElement(), nb_total_points, nb_element);
+ Array<Real> & shapes_tmp = shapes.alloc(nb_element * nb_total_points,
+ size_of_shapes, itp_type, ghost_type);
+ Array<Real>::matrix_iterator shapes_it = shapes_tmp.begin_reinterpret(
+ ElementClass<type>::getNbNodesPerInterpolationElement(), nb_total_points,
+ nb_element);
Matrix<Real> physical_points_1(spatial_dimension, nb_points_sub_1);
Matrix<Real> physical_points_2(spatial_dimension, nb_points_sub_2);
Matrix<Real> parent_natural_coords_1(spatial_dimension, nb_points_sub_1);
Matrix<Real> parent_natural_coords_2(spatial_dimension, nb_points_sub_2);
/// intialize the matrices for the parent and subelement coordinates
- UInt nb_nodes_parent_el = ElementClass<parent_type>::getNbNodesPerInterpolationElement();
- UInt nb_nodes_sub_el_1 = ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
- UInt nb_nodes_sub_el_2 = ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_parent_el =
+ ElementClass<parent_type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_sub_el_1 =
+ ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_sub_el_2 =
+ ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
Matrix<Real> parent_coords(spatial_dimension, nb_nodes_parent_el);
Matrix<Real> sub_el_1_coords(spatial_dimension, nb_nodes_sub_el_1);
Matrix<Real> sub_el_2_coords(spatial_dimension, nb_nodes_sub_el_2);
/// loop over all elements of the given type and compute the shape functions
Vector<Real> all_shapes(size_of_shapes);
- for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it, ++x_it, ++natural_coords_parent_it) {
+ for (UInt elem = 0; elem < nb_element;
+ ++elem, ++shapes_it, ++x_it, ++natural_coords_parent_it) {
Matrix<Real> & N = *shapes_it;
const Matrix<Real> & X = *x_it;
Matrix<Real> & nc_parent = *natural_coords_parent_it;
/// map the sub element integration points into the parent reference domain
- ElementClass<type>::mapFromSubRefToParentRef(X, sub_el_1_coords, parent_coords, sub_1_shapes, physical_points_1, parent_natural_coords_1, 0);
- ElementClass<type>::mapFromSubRefToParentRef(X, sub_el_2_coords, parent_coords, sub_2_shapes, physical_points_2, parent_natural_coords_2, 1);
+ ElementClass<type>::mapFromSubRefToParentRef(
+ X, sub_el_1_coords, parent_coords, sub_1_shapes, physical_points_1,
+ parent_natural_coords_1, 0);
+ ElementClass<type>::mapFromSubRefToParentRef(
+ X, sub_el_2_coords, parent_coords, sub_2_shapes, physical_points_2,
+ parent_natural_coords_2, 1);
/// compute the parent shape functions on all integration points
- ElementClass<sub_type_1>::computeShapes(parent_natural_coords_1, parent_1_shapes);
- ElementClass<sub_type_1>::computeShapes(parent_natural_coords_2, parent_2_shapes);
+ ElementClass<sub_type_1>::computeShapes(parent_natural_coords_1,
+ parent_1_shapes);
+ ElementClass<sub_type_1>::computeShapes(parent_natural_coords_2,
+ parent_2_shapes);
- /// copy the results into the shape functions iterator and natural coords iterator
+ /// copy the results into the shape functions iterator and natural coords
+ /// iterator
for (UInt i = 0; i < nb_points_sub_1; ++i) {
- ElementClass<type>::assembleShapes(parent_1_shapes(i), sub_1_shapes(i), all_shapes, 0);
+ ElementClass<type>::assembleShapes(parent_1_shapes(i), sub_1_shapes(i),
+ all_shapes, 0);
N(i) = all_shapes;
nc_parent(i) = parent_natural_coords_1(i);
}
for (UInt i = 0; i < nb_points_sub_2; ++i) {
- ElementClass<type>::assembleShapes(parent_2_shapes(i), sub_2_shapes(i), all_shapes, 1);
+ ElementClass<type>::assembleShapes(parent_2_shapes(i), sub_2_shapes(i),
+ all_shapes, 1);
N(i + nb_points_sub_1) = all_shapes;
-
- ///N(i + nb_points_sub_2) = all_shapes;
+
+ /// N(i + nb_points_sub_2) = all_shapes;
nc_parent(i + nb_points_sub_1) = parent_natural_coords_2(i);
}
-
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes, GhostType ghost_type) {
+void ShapeLagrange<_ek_igfem>::precomputeShapeDerivativesOnIntegrationPoints(
+ const Array<Real> & nodes, GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// typedef for the two subelement_types and the parent element type
const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
- const ElementType parent_type = ElementClassProperty<type>::parent_element_type;
+ const ElementType parent_type =
+ ElementClassProperty<type>::parent_element_type;
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
UInt spatial_dimension = mesh.getSpatialDimension();
- /// get the integration points for the subelements
- Matrix<Real> & natural_coords_sub_1 = integration_points(sub_type_1, ghost_type);
- Matrix<Real> & natural_coords_sub_2 = integration_points(sub_type_2, ghost_type);
- /// store the number of quadrature points on each subelement and the toal number
+ /// get the integration points for the subelements
+ Matrix<Real> & natural_coords_sub_1 =
+ integration_points(sub_type_1, ghost_type);
+ Matrix<Real> & natural_coords_sub_2 =
+ integration_points(sub_type_2, ghost_type);
+ /// store the number of quadrature points on each subelement and the toal
+ /// number
UInt nb_points_sub_1 = natural_coords_sub_1.cols();
UInt nb_points_sub_2 = natural_coords_sub_2.cols();
UInt nb_points_total = nb_points_sub_1 + nb_points_sub_2;
- UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
- UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
-
+ UInt nb_nodes_per_element =
+ ElementClass<type>::getNbNodesPerInterpolationElement();
+ UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
+
/// intialize the matrices for the parent and subelement coordinates
- UInt nb_nodes_parent_el = ElementClass<parent_type>::getNbNodesPerInterpolationElement();
- UInt nb_nodes_sub_el_1 = ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
- UInt nb_nodes_sub_el_2 = ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_parent_el =
+ ElementClass<parent_type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_sub_el_1 =
+ ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_sub_el_2 =
+ ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
Matrix<Real> parent_coords(spatial_dimension, nb_nodes_parent_el);
Matrix<Real> sub_el_1_coords(spatial_dimension, nb_nodes_sub_el_1);
Matrix<Real> sub_el_2_coords(spatial_dimension, nb_nodes_sub_el_2);
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
- Array<Real> & shapes_derivatives_tmp = shapes_derivatives.alloc(nb_element*nb_points_total,
- size_of_shapesd,
- itp_type,
- ghost_type);
+ Array<Real> & shapes_derivatives_tmp = shapes_derivatives.alloc(
+ nb_element * nb_points_total, size_of_shapesd, itp_type, ghost_type);
/// get an iterator to the coordiantes of the elements
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
- FEEngine::extractNodalToElementField(mesh, nodes, x_el,
- type, ghost_type);
+ FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
Real * shapesd_val = shapes_derivatives_tmp.storage();
- Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
- nb_nodes_per_element);
+ Array<Real>::matrix_iterator x_it =
+ x_el.begin(spatial_dimension, nb_nodes_per_element);
/// get an iterator to the integration points of the parent element
- Array<Real> & natural_coords_parent = igfem_integration_points(type, ghost_type);
- Array<Real>::matrix_iterator natural_coords_parent_it = natural_coords_parent.begin_reinterpret(spatial_dimension, nb_points_total, nb_element);
-
- Tensor3<Real> B_sub_1(spatial_dimension, nb_nodes_sub_el_1, nb_points_sub_1);
+ Array<Real> & natural_coords_parent =
+ igfem_integration_points(type, ghost_type);
+ Array<Real>::matrix_iterator natural_coords_parent_it =
+ natural_coords_parent.begin_reinterpret(spatial_dimension,
+ nb_points_total, nb_element);
+
+ Tensor3<Real> B_sub_1(spatial_dimension, nb_nodes_sub_el_1, nb_points_sub_1);
Tensor3<Real> B_sub_2(spatial_dimension, nb_nodes_sub_el_2, nb_points_sub_2);
- Tensor3<Real> B_parent(spatial_dimension, nb_nodes_parent_el, nb_points_total);
- /// assemble the shape derivatives
+ Tensor3<Real> B_parent(spatial_dimension, nb_nodes_parent_el,
+ nb_points_total);
+ /// assemble the shape derivatives
Matrix<Real> all_shapes(spatial_dimension, nb_nodes_per_element);
- for (UInt elem = 0; elem < nb_element; ++elem, ++x_it, ++natural_coords_parent_it) {
+ for (UInt elem = 0; elem < nb_element;
+ ++elem, ++x_it, ++natural_coords_parent_it) {
Matrix<Real> & X = *x_it;
Matrix<Real> & nc_parent = *natural_coords_parent_it;
- Tensor3<Real> B(shapesd_val,
- spatial_dimension, nb_nodes_per_element, nb_points_total);
-
+ Tensor3<Real> B(shapesd_val, spatial_dimension, nb_nodes_per_element,
+ nb_points_total);
+
/// get the coordinates of the two sub elements and the parent element
ElementClass<type>::getSubElementCoords(X, sub_el_1_coords, 0);
ElementClass<type>::getSubElementCoords(X, sub_el_2_coords, 1);
ElementClass<type>::getParentCoords(X, parent_coords);
- /// compute the subelements' shape derivatives and the parent shape derivatives
- computeShapeDerivativesOnCPointsByElement<sub_type_1>(sub_el_1_coords,
- natural_coords_sub_1,
- B_sub_1);
- computeShapeDerivativesOnCPointsByElement<sub_type_2>(sub_el_2_coords,
- natural_coords_sub_2,
- B_sub_2);
+ /// compute the subelements' shape derivatives and the parent shape
+ /// derivatives
+ computeShapeDerivativesOnCPointsByElement<sub_type_1>(
+ sub_el_1_coords, natural_coords_sub_1, B_sub_1);
+ computeShapeDerivativesOnCPointsByElement<sub_type_2>(
+ sub_el_2_coords, natural_coords_sub_2, B_sub_2);
computeShapeDerivativesOnCPointsByElement<parent_type>(parent_coords,
- nc_parent,
- B_parent);
+ nc_parent, B_parent);
for (UInt i = 0; i < nb_points_sub_1; ++i) {
- ElementClass<type>::assembleShapeDerivatives(B_parent(i), B_sub_1(i), all_shapes, 0);
+ ElementClass<type>::assembleShapeDerivatives(B_parent(i), B_sub_1(i),
+ all_shapes, 0);
B(i) = all_shapes;
}
for (UInt i = 0; i < nb_points_sub_2; ++i) {
- ElementClass<type>::assembleShapeDerivatives(B_parent(i), B_sub_2(i), all_shapes, 1);
+ ElementClass<type>::assembleShapeDerivatives(B_parent(i), B_sub_2(i),
+ all_shapes, 1);
B(i + nb_points_sub_1) = all_shapes;
}
-
- shapesd_val += size_of_shapesd*nb_points_total;
+
+ shapesd_val += size_of_shapesd * nb_points_total;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::interpolateOnIntegrationPoints(const Array<Real> &in_u,
- Array<Real> &out_uq,
- UInt nb_degree_of_freedom,
- GhostType ghost_type,
- const Array<UInt> & filter_elements) const {
+void ShapeLagrange<_ek_igfem>::interpolateOnIntegrationPoints(
+ const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
+ GhostType ghost_type, const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
AKANTU_DEBUG_ASSERT(shapes.exists(itp_type, ghost_type),
- "No shapes for the type "
- << shapes.printType(itp_type, ghost_type));
+ "No shapes for the type "
+ << shapes.printType(itp_type, ghost_type));
- UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_per_element =
+ ElementClass<type>::getNbNodesPerInterpolationElement();
Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
- FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type, filter_elements);
+ FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
+ filter_elements);
- this->interpolateElementalFieldOnIntegrationPoints<type>(u_el, out_uq, ghost_type,
- shapes(itp_type, ghost_type),
- filter_elements);
+ this->interpolateElementalFieldOnIntegrationPoints<type>(
+ u_el, out_uq, ghost_type, shapes(itp_type, ghost_type), filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::gradientOnIntegrationPoints(const Array<Real> &in_u,
- Array<Real> &out_nablauq,
- UInt nb_degree_of_freedom,
- GhostType ghost_type,
- const Array<UInt> & filter_elements) const {
+void ShapeLagrange<_ek_igfem>::gradientOnIntegrationPoints(
+ const Array<Real> & in_u, Array<Real> & out_nablauq,
+ UInt nb_degree_of_freedom, GhostType ghost_type,
+ const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
- AKANTU_DEBUG_ASSERT(shapes_derivatives.exists(itp_type, ghost_type),
- "No shapes derivatives for the type "
- << shapes_derivatives.printType(itp_type, ghost_type));
+ AKANTU_DEBUG_ASSERT(
+ shapes_derivatives.exists(itp_type, ghost_type),
+ "No shapes derivatives for the type "
+ << shapes_derivatives.printType(itp_type, ghost_type));
- UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_per_element =
+ ElementClass<type>::getNbNodesPerInterpolationElement();
Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
- FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type, filter_elements);
+ FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
+ filter_elements);
- this->gradientElementalFieldOnIntegrationPoints<type>(u_el, out_nablauq, ghost_type,
- shapes_derivatives(itp_type, ghost_type),
- filter_elements);
+ this->gradientElementalFieldOnIntegrationPoints<type>(
+ u_el, out_nablauq, ghost_type, shapes_derivatives(itp_type, ghost_type),
+ filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::fieldTimesShapes(const Array<Real> & field,
- Array<Real> & field_times_shapes,
- GhostType ghost_type) const {
+void ShapeLagrange<_ek_igfem>::fieldTimesShapes(
+ const Array<Real> & field, Array<Real> & field_times_shapes,
+ GhostType ghost_type) const {
AKANTU_DEBUG_IN();
field_times_shapes.resize(field.getSize());
UInt size_of_shapes = ElementClass<type>::getShapeSize();
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
UInt nb_degree_of_freedom = field.getNbComponent();
const Array<Real> & shape = shapes(itp_type, ghost_type);
- Array<Real>::const_matrix_iterator field_it = field.begin(nb_degree_of_freedom, 1);
+ Array<Real>::const_matrix_iterator field_it =
+ field.begin(nb_degree_of_freedom, 1);
Array<Real>::const_matrix_iterator shapes_it = shape.begin(1, size_of_shapes);
- Array<Real>::matrix_iterator it = field_times_shapes.begin(nb_degree_of_freedom, size_of_shapes);
- Array<Real>::matrix_iterator end = field_times_shapes.end (nb_degree_of_freedom, size_of_shapes);
+ Array<Real>::matrix_iterator it =
+ field_times_shapes.begin(nb_degree_of_freedom, size_of_shapes);
+ Array<Real>::matrix_iterator end =
+ field_times_shapes.end(nb_degree_of_freedom, size_of_shapes);
for (; it != end; ++it, ++field_it, ++shapes_it) {
it->mul<false, false>(*field_it, *shapes_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::interpolateOnPhysicalPoint(const Vector<Real> & real_coords,
- UInt elem,
- const Array<Real> & field,
- Vector<Real> & interpolated,
- const GhostType & ghost_type) const {
+void ShapeLagrange<_ek_igfem>::interpolateOnPhysicalPoint(
+ const Vector<Real> & real_coords, UInt elem, const Array<Real> & field,
+ Vector<Real> & interpolated, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
Vector<Real> shapes(ElementClass<type>::getShapeSize());
computeShapes<type>(real_coords, elem, shapes, ghost_type);
UInt spatial_dimension = mesh.getSpatialDimension();
- UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_per_element =
+ ElementClass<type>::getNbNodesPerInterpolationElement();
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
Matrix<Real> nodes_val(spatial_dimension, nb_nodes_per_element);
- mesh.extractNodalValuesFromElement(field,
- nodes_val.storage(),
- elem_val + elem * nb_nodes_per_element,
- nb_nodes_per_element,
- spatial_dimension);
+ mesh.extractNodalValuesFromElement(field, nodes_val.storage(),
+ elem_val + elem * nb_nodes_per_element,
+ nb_nodes_per_element, spatial_dimension);
ElementClass<type>::interpolate(nodes_val, shapes, interpolated);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::precomputeShapesOnEnrichedNodes(__attribute__((unused)) const Array<Real> & nodes,
- const GhostType & ghost_type) {
+void ShapeLagrange<_ek_igfem>::precomputeShapesOnEnrichedNodes(
+ __attribute__((unused)) const Array<Real> & nodes,
+ const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
-
+
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
- const ElementType parent_type = ElementClassProperty<type>::parent_element_type;
+ const ElementType parent_type =
+ ElementClassProperty<type>::parent_element_type;
const ElementType sub_type = ElementClassProperty<type>::sub_element_type_1;
/// get the spatial dimension for the given element type
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
-
-// get the integration points for the parent element
+
+ // get the integration points for the parent element
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
- /// get the size of the shapes
+ /// get the size of the shapes
UInt nb_enriched_nodes = ElementClass<type>::getNbEnrichments();
- UInt nb_parent_nodes = ElementClass<parent_type>::getNbNodesPerInterpolationElement();
+ UInt nb_parent_nodes =
+ ElementClass<parent_type>::getNbNodesPerInterpolationElement();
UInt size_of_shapes = ElementClass<type>::getShapeSize();
UInt size_of_parent_shapes = ElementClass<parent_type>::getShapeSize();
UInt size_of_sub_shapes = ElementClass<sub_type>::getShapeSize();
Vector<Real> parent_shapes(size_of_parent_shapes);
Vector<Real> sub_shapes(size_of_sub_shapes);
Vector<Real> shapes(size_of_shapes);
/// get the nodal coordinates per element
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
- FEEngine::extractNodalToElementField(mesh, nodes, x_el,
- type, ghost_type);
- Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
- nb_nodes_per_element);
+ FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
+ Array<Real>::matrix_iterator x_it =
+ x_el.begin(spatial_dimension, nb_nodes_per_element);
/// allocate the shapes for the given element type
- Array<Real> & shapes_tmp = shapes_at_enrichments.alloc(nb_element * nb_enriched_nodes,
- size_of_shapes,
- itp_type,
- ghost_type);
+ Array<Real> & shapes_tmp = shapes_at_enrichments.alloc(
+ nb_element * nb_enriched_nodes, size_of_shapes, itp_type, ghost_type);
- Array<Real>::matrix_iterator shapes_it =
- shapes_tmp.begin_reinterpret(ElementClass<type>::getNbNodesPerInterpolationElement(), nb_enriched_nodes, nb_element);
+ Array<Real>::matrix_iterator shapes_it = shapes_tmp.begin_reinterpret(
+ ElementClass<type>::getNbNodesPerInterpolationElement(),
+ nb_enriched_nodes, nb_element);
Vector<Real> real_coords(spatial_dimension);
Vector<Real> natural_coords(spatial_dimension);
Matrix<Real> parent_coords(spatial_dimension, nb_parent_nodes);
- UInt * sub_element_enrichments = ElementClass<type>::getSubElementEnrichments();
-
+ UInt * sub_element_enrichments =
+ ElementClass<type>::getSubElementEnrichments();
+
/// loop over all elements
for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it, ++x_it) {
Matrix<Real> & N = *shapes_it;
const Matrix<Real> & X = *x_it;
for (UInt i = 0; i < nb_enriched_nodes; ++i) {
/// get the parent element coordinates
ElementClass<type>::getParentCoords(X, parent_coords);
/// get the physical coords of the enriched node
real_coords = X(nb_parent_nodes + i);
/// map the physical point into the parent ref domain
- ElementClass<parent_type>::inverseMap(real_coords,
- parent_coords,
- natural_coords);
+ ElementClass<parent_type>::inverseMap(real_coords, parent_coords,
+ natural_coords);
/// compute the parent shape functions
ElementClass<parent_type>::computeShapes(natural_coords, parent_shapes);
- ///Sub-element contribution
+ /// Sub-element contribution
sub_shapes.clear();
- sub_shapes(sub_element_enrichments[i]) = 1.;
+ sub_shapes(sub_element_enrichments[i]) = 1.;
ElementClass<type>::assembleShapes(parent_shapes, sub_shapes, shapes, 0);
N(i) = shapes;
- }
+ }
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
-void ShapeLagrange<_ek_igfem>::interpolateAtEnrichedNodes(const Array<Real> & src,
- Array<Real> & dst,
- const GhostType & ghost_type) const {
+void ShapeLagrange<_ek_igfem>::interpolateAtEnrichedNodes(
+ const Array<Real> & src, Array<Real> & dst,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
- const ElementType parent_type = ElementClassProperty<type>::parent_element_type;
-
+ const ElementType parent_type =
+ ElementClassProperty<type>::parent_element_type;
+
UInt nb_element = mesh.getNbElement(type, ghost_type);
- UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
- UInt nb_parent_nodes = ElementClass<parent_type>::getNbNodesPerInterpolationElement();
+ UInt nb_nodes_per_element =
+ ElementClass<type>::getNbNodesPerInterpolationElement();
+ UInt nb_parent_nodes =
+ ElementClass<parent_type>::getNbNodesPerInterpolationElement();
UInt nb_enrichments = ElementClass<type>::getNbEnrichments();
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
UInt spatial_dimension = mesh.getSpatialDimension();
Matrix<Real> nodes_val(spatial_dimension, nb_nodes_per_element);
InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
const Array<Real> & shapes = shapes_at_enrichments(itp_type, ghost_type);
- Array<Real>::const_matrix_iterator shapes_it =
- shapes.begin_reinterpret(nb_nodes_per_element, nb_enrichments, nb_element);
+ Array<Real>::const_matrix_iterator shapes_it = shapes.begin_reinterpret(
+ nb_nodes_per_element, nb_enrichments, nb_element);
Array<Real>::vector_iterator dst_vect = dst.begin(spatial_dimension);
Vector<Real> interpolated(spatial_dimension);
- for(UInt e = 0; e < nb_element; ++e, ++shapes_it) {
+ for (UInt e = 0; e < nb_element; ++e, ++shapes_it) {
const Matrix<Real> & el_shapes = *shapes_it;
- mesh.extractNodalValuesFromElement(src,
- nodes_val.storage(),
- elem_val + e * nb_nodes_per_element,
- nb_nodes_per_element,
- spatial_dimension);;
+ mesh.extractNodalValuesFromElement(src, nodes_val.storage(),
+ elem_val + e * nb_nodes_per_element,
+ nb_nodes_per_element, spatial_dimension);
+ ;
for (UInt i = 0; i < nb_enrichments; ++i) {
ElementClass<type>::interpolate(nodes_val, el_shapes(i), interpolated);
- UInt enr_node_idx = elem_val[e * nb_nodes_per_element + nb_parent_nodes + i];
+ UInt enr_node_idx =
+ elem_val[e * nb_nodes_per_element + nb_parent_nodes + i];
dst_vect[enr_node_idx] = interpolated;
}
}
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-#define COMPUTE_ENRICHED_VALUES(type) \
- interpolateAtEnrichedNodes<type>(src, \
- dst, \
- ghost_type);
-
-inline void ShapeLagrange<_ek_igfem>::interpolateEnrichmentsAllTypes(const Array<Real> & src,
- Array<Real> & dst,
- const ElementType & type,
- const GhostType & ghost_type) const {
-
+#define COMPUTE_ENRICHED_VALUES(type) \
+ interpolateAtEnrichedNodes<type>(src, dst, ghost_type);
+
+inline void ShapeLagrange<_ek_igfem>::interpolateEnrichmentsAllTypes(
+ const Array<Real> & src, Array<Real> & dst, const ElementType & type,
+ const GhostType & ghost_type) const {
+
AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(COMPUTE_ENRICHED_VALUES);
}
#undef COMPUTE_ENRICHED_VALUES
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_SHAPE_IGFEM_INLINE_IMPL_CC__ */
-
-
-
-
-
diff --git a/extra_packages/igfem/src/solid_mechanics_model_igfem.cc b/extra_packages/igfem/src/solid_mechanics_model_igfem.cc
index 64220c2d0..2cc1670a5 100644
--- a/extra_packages/igfem/src/solid_mechanics_model_igfem.cc
+++ b/extra_packages/igfem/src/solid_mechanics_model_igfem.cc
@@ -1,540 +1,587 @@
/**
* @file solid_mechanics_model_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief solid mechanics model for IGFEM analysis
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_igfem.hh"
#include "dumpable_inline_impl.hh"
-#include "material_igfem.hh"
#include "group_manager_inline_impl.cc"
#include "igfem_helper.hh"
+#include "material_igfem.hh"
#ifdef AKANTU_USE_IOHELPER
-# include "dumper_paraview.hh"
-# include "dumper_igfem_material_internal_field.hh"
-# include "dumper_igfem_element_partition.hh"
-# include "dumper_igfem_elemental_field.hh"
-# include "dumper_material_padders.hh"
+#include "dumper_igfem_element_partition.hh"
+#include "dumper_igfem_elemental_field.hh"
+#include "dumper_igfem_material_internal_field.hh"
+#include "dumper_material_padders.hh"
+#include "dumper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-const SolidMechanicsModelIGFEMOptions default_solid_mechanics_model_igfem_options(_static,
- false);
+const SolidMechanicsModelIGFEMOptions
+ default_solid_mechanics_model_igfem_options(_static, false);
-SolidMechanicsModelIGFEM::SolidMechanicsModelIGFEM(Mesh & mesh,
- UInt dim,
- const ID & id,
- const MemoryID & memory_id) :
- SolidMechanicsModel(mesh, dim, id, memory_id),
- IGFEMEnrichment(mesh),
- global_ids_updater(NULL) {
+SolidMechanicsModelIGFEM::SolidMechanicsModelIGFEM(Mesh & mesh, UInt dim,
+ const ID & id,
+ const MemoryID & memory_id)
+ : SolidMechanicsModel(mesh, dim, id, memory_id), IGFEMEnrichment(mesh),
+ global_ids_updater(NULL) {
AKANTU_DEBUG_IN();
delete material_selector;
material_selector = new DefaultMaterialIGFEMSelector(*this);
this->registerEventHandler(*this);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("igfem elements", id);
- this->mesh.addDumpMeshToDumper("igfem elements",
- mesh, spatial_dimension, _not_ghost, _ek_igfem);
+ this->mesh.addDumpMeshToDumper("igfem elements", mesh, spatial_dimension,
+ _not_ghost, _ek_igfem);
#endif
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModelIGFEM::~SolidMechanicsModelIGFEM() {
AKANTU_DEBUG_IN();
- if (global_ids_updater) delete global_ids_updater;
+ if (global_ids_updater)
+ delete global_ids_updater;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelIGFEM::initFull(const ModelOptions & options) {
AKANTU_DEBUG_IN();
-
/// intialize the IGFEM enrichment
this->initialize();
SolidMechanicsModel::initFull(options);
// set the initial condition to 0
real_force->clear();
real_displacement->clear();
real_residual->clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Allocate all the needed vectors. By default their are not necessarily set to
* 0
*
*/
void SolidMechanicsModelIGFEM::initArrays() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
- std::stringstream sstr_rdisp; sstr_rdisp << id << ":real_displacement";
- std::stringstream sstr_rforc; sstr_rforc << id << ":real_force";
- std::stringstream sstr_rresi; sstr_rresi << id << ":real_residual";
-
- real_displacement = &(alloc<Real>(sstr_rdisp.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
- real_force = &(alloc<Real>(sstr_rforc.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
- real_residual = &(alloc<Real>(sstr_rresi.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
-
- SolidMechanicsModel::initArrays();
+ std::stringstream sstr_rdisp;
+ sstr_rdisp << id << ":real_displacement";
+ std::stringstream sstr_rforc;
+ sstr_rforc << id << ":real_force";
+ std::stringstream sstr_rresi;
+ sstr_rresi << id << ":real_residual";
+
+ real_displacement = &(alloc<Real>(sstr_rdisp.str(), nb_nodes,
+ spatial_dimension, REAL_INIT_VALUE));
+ real_force = &(alloc<Real>(sstr_rforc.str(), nb_nodes, spatial_dimension,
+ REAL_INIT_VALUE));
+ real_residual = &(alloc<Real>(sstr_rresi.str(), nb_nodes, spatial_dimension,
+ REAL_INIT_VALUE));
+
+ SolidMechanicsModel::initArrays();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelIGFEM::initParallel(MeshPartition * partition,
- DataAccessor * data_accessor) {
+ DataAccessor * data_accessor) {
SolidMechanicsModel::initParallel(partition, data_accessor);
this->intersector_sphere.setDistributedSynchronizer(synch_parallel);
if (mesh.isDistributed())
global_ids_updater = new GlobalIdsUpdater(mesh, synch_parallel);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelIGFEM::initMaterials() {
AKANTU_DEBUG_IN();
// make sure the material are instantiated
- if(!are_materials_instantiated) instantiateMaterials();
+ if (!are_materials_instantiated)
+ instantiateMaterials();
/// find the first igfem material
UInt igfem_index = 0;
- while ((dynamic_cast<MaterialIGFEM *>(materials[igfem_index]) == NULL)
- && igfem_index <= materials.size())
+ while ((dynamic_cast<MaterialIGFEM *>(materials[igfem_index]) == NULL) &&
+ igfem_index <= materials.size())
++igfem_index;
AKANTU_DEBUG_ASSERT(igfem_index != materials.size(),
- "No igfem materials in the material input file");
+ "No igfem materials in the material input file");
- DefaultMaterialIGFEMSelector * igfem_mat_selector = dynamic_cast<DefaultMaterialIGFEMSelector *>(material_selector);
- if (igfem_mat_selector != NULL)
+ DefaultMaterialIGFEMSelector * igfem_mat_selector =
+ dynamic_cast<DefaultMaterialIGFEMSelector *>(material_selector);
+ if (igfem_mat_selector != NULL)
igfem_mat_selector->setIGFEMFallback(igfem_index);
SolidMechanicsModel::initMaterials();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the model, basically pre-compute the shapes, shapes derivatives
* and jacobian
*
*/
void SolidMechanicsModelIGFEM::initModel() {
AKANTU_DEBUG_IN();
SolidMechanicsModel::initModel();
- registerFEEngineObject<MyFEEngineIGFEMType>("IGFEMFEEngine", mesh, spatial_dimension);
+ registerFEEngineObject<MyFEEngineIGFEMType>("IGFEMFEEngine", mesh,
+ spatial_dimension);
/// insert the two feengines associated with the model in the map
this->fe_engines_per_kind[_ek_regular] = &(this->getFEEngine());
this->fe_engines_per_kind[_ek_igfem] = &(this->getFEEngine("IGFEMFEEngine"));
/// add the igfem type connectivities
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType type_ghost = *gt;
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, type_ghost);
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, type_ghost);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, type_ghost);
for (; it != last; ++it) {
const Array<UInt> & connectivity = mesh.getConnectivity(*it, type_ghost);
if (connectivity.getSize() != 0) {
- ElementType type = *it;
- Vector<ElementType> types_igfem = FEEngine::getIGFEMElementTypes(type);
- for (UInt i = 0; i < types_igfem.size(); ++i)
- mesh.addConnectivityType(types_igfem(i), type_ghost);
+ ElementType type = *it;
+ Vector<ElementType> types_igfem = FEEngine::getIGFEMElementTypes(type);
+ for (UInt i = 0; i < types_igfem.size(); ++i)
+ mesh.addConnectivityType(types_igfem(i), type_ghost);
}
}
}
getFEEngine("IGFEMFEEngine").initShapeFunctions(_not_ghost);
getFEEngine("IGFEMFEEngine").initShapeFunctions(_ghost);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelIGFEM::onElementsAdded(const Array<Element> & elements,
- const NewElementsEvent & event) {
+ const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
- const NewIGFEMElementsEvent * igfem_event = dynamic_cast<const NewIGFEMElementsEvent *>(&event);
+ const NewIGFEMElementsEvent * igfem_event =
+ dynamic_cast<const NewIGFEMElementsEvent *>(&event);
/// insert the new and old elements in the map
- if (igfem_event != NULL) {
+ if (igfem_event != NULL) {
this->element_map.clear();
const Array<Element> & old_elements = igfem_event->getOldElementsList();
for (UInt e = 0; e < elements.getSize(); ++e) {
this->element_map[elements(e)] = old_elements(e);
}
}
/// update shape functions
getFEEngine("IGFEMFEEngine").initShapeFunctions(_not_ghost);
getFEEngine("IGFEMFEEngine").initShapeFunctions(_ghost);
SolidMechanicsModel::onElementsAdded(elements, event);
this->reassignMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelIGFEM::onElementsRemoved(const Array<Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- const RemovedElementsEvent & event) {
+void SolidMechanicsModelIGFEM::onElementsRemoved(
+ const Array<Element> & element_list,
+ const ElementTypeMapArray<UInt> & new_numbering,
+ const RemovedElementsEvent & event) {
this->getFEEngine("IGFEMFEEngine").initShapeFunctions(_not_ghost);
this->getFEEngine("IGFEMFEEngine").initShapeFunctions(_ghost);
SolidMechanicsModel::onElementsRemoved(element_list, new_numbering, event);
if (synch_parallel)
synch_parallel->computeAllBufferSizes(*this);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelIGFEM::onNodesAdded(const Array<UInt> & nodes_list,
- const NewNodesEvent & event) {
+ const NewNodesEvent & event) {
AKANTU_DEBUG_IN();
- const NewIGFEMNodesEvent * igfem_event = dynamic_cast<const NewIGFEMNodesEvent *>(&event);
+ const NewIGFEMNodesEvent * igfem_event =
+ dynamic_cast<const NewIGFEMNodesEvent *>(&event);
// update the node type
if (igfem_event != NULL) {
- intersector_sphere.updateNodeType(nodes_list,
- igfem_event->getNewNodePerElem(),
- igfem_event->getElementType(),
- igfem_event->getGhostType());
+ intersector_sphere.updateNodeType(
+ nodes_list, igfem_event->getNewNodePerElem(),
+ igfem_event->getElementType(), igfem_event->getGhostType());
}
UInt nb_nodes = mesh.getNbNodes();
- if(real_displacement) real_displacement->resize(nb_nodes);
- if(real_force) real_force->resize(nb_nodes);
- if(real_residual) real_residual->resize(nb_nodes);
+ if (real_displacement)
+ real_displacement->resize(nb_nodes);
+ if (real_force)
+ real_force->resize(nb_nodes);
+ if (real_residual)
+ real_residual->resize(nb_nodes);
if (mesh.isDistributed())
mesh.getGlobalNodesIds().resize(mesh.getNbNodes());
- if(displacement) displacement->resize(nb_nodes);
- if(mass ) mass ->resize(nb_nodes);
- if(velocity ) velocity ->resize(nb_nodes);
- if(acceleration) acceleration->resize(nb_nodes);
- if(force ) force ->resize(nb_nodes);
- if(residual ) residual ->resize(nb_nodes);
- if(blocked_dofs) blocked_dofs->resize(nb_nodes);
-
- if(previous_displacement) previous_displacement->resize(nb_nodes);
- if(increment_acceleration) increment_acceleration->resize(nb_nodes);
- if(increment) increment->resize(nb_nodes);
-
- if(current_position) current_position->resize(nb_nodes);
+ if (displacement)
+ displacement->resize(nb_nodes);
+ if (mass)
+ mass->resize(nb_nodes);
+ if (velocity)
+ velocity->resize(nb_nodes);
+ if (acceleration)
+ acceleration->resize(nb_nodes);
+ if (force)
+ force->resize(nb_nodes);
+ if (residual)
+ residual->resize(nb_nodes);
+ if (blocked_dofs)
+ blocked_dofs->resize(nb_nodes);
+
+ if (previous_displacement)
+ previous_displacement->resize(nb_nodes);
+ if (increment_acceleration)
+ increment_acceleration->resize(nb_nodes);
+ if (increment)
+ increment->resize(nb_nodes);
+
+ if (current_position)
+ current_position->resize(nb_nodes);
std::vector<Material *>::iterator mat_it;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->onNodesAdded(nodes_list, event);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelIGFEM::onNodesRemoved(const Array<UInt> & nodes_list,
- const Array<UInt> & new_numbering,
- const RemovedNodesEvent & event) {
- if(real_displacement) mesh.removeNodesFromArray(*real_displacement, new_numbering);
- if(real_force ) mesh.removeNodesFromArray(*real_force , new_numbering);
- if(real_residual ) mesh.removeNodesFromArray(*real_residual , new_numbering);
+ const Array<UInt> & new_numbering,
+ const RemovedNodesEvent & event) {
+ if (real_displacement)
+ mesh.removeNodesFromArray(*real_displacement, new_numbering);
+ if (real_force)
+ mesh.removeNodesFromArray(*real_force, new_numbering);
+ if (real_residual)
+ mesh.removeNodesFromArray(*real_residual, new_numbering);
// communicate global connectivity for slave nodes
if (global_ids_updater)
- global_ids_updater->updateGlobalIDs(mesh.getNbNodes() - intersector_sphere.getNbStandardNodes());
+ global_ids_updater->updateGlobalIDs(
+ mesh.getNbNodes() - intersector_sphere.getNbStandardNodes());
SolidMechanicsModel::onNodesRemoved(nodes_list, new_numbering, event);
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelIGFEM::addDumpGroupFieldToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind,
- bool padding_flag) {
+void SolidMechanicsModelIGFEM::addDumpGroupFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id,
+ const std::string & group_name, const ElementKind & element_kind,
+ bool padding_flag) {
AKANTU_DEBUG_IN();
ElementKind _element_kind = element_kind;
if (dumper_name == "igfem elements") {
_element_kind = _ek_igfem;
}
- SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name,
- field_id,
- group_name,
- _element_kind,
- padding_flag);
+ SolidMechanicsModel::addDumpGroupFieldToDumper(
+ dumper_name, field_id, group_name, _element_kind, padding_flag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelIGFEM::onDump(){
+void SolidMechanicsModelIGFEM::onDump() {
this->computeValuesOnEnrichedNodes();
this->flattenAllRegisteredInternals(_ek_igfem);
SolidMechanicsModel::onDump();
}
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
-dumper::Field * SolidMechanicsModelIGFEM
-::createElementalField(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag,
- const UInt & spatial_dimension,
- const ElementKind & kind) {
-
+dumper::Field * SolidMechanicsModelIGFEM::createElementalField(
+ const std::string & field_name, const std::string & group_name,
+ bool padding_flag, const UInt & spatial_dimension,
+ const ElementKind & kind) {
+
dumper::Field * field = NULL;
if (kind != _ek_igfem)
- field = SolidMechanicsModel::createElementalField(field_name, group_name, padding_flag, spatial_dimension, kind);
+ field = SolidMechanicsModel::createElementalField(
+ field_name, group_name, padding_flag, spatial_dimension, kind);
else {
-
- if(field_name == "partitions")
- field = mesh.createElementalField<UInt, dumper::IGFEMElementPartitionField>(mesh.getConnectivities(),group_name,spatial_dimension, kind);
- else if(field_name == "material_index")
- field = mesh.createElementalField<UInt, Vector, dumper::IGFEMElementalField >(material_index,group_name,spatial_dimension,kind);
+ if (field_name == "partitions")
+ field =
+ mesh.createElementalField<UInt, dumper::IGFEMElementPartitionField>(
+ mesh.getConnectivities(), group_name, spatial_dimension, kind);
+ else if (field_name == "material_index")
+ field =
+ mesh.createElementalField<UInt, Vector, dumper::IGFEMElementalField>(
+ material_index, group_name, spatial_dimension, kind);
else {
// this copy of field_name is used to compute derivated data such as
// strain and von mises stress that are based on grad_u and stress
std::string field_name_copy(field_name);
- if (field_name == "strain"
- || field_name == "Green strain"
- || field_name == "principal strain"
- || field_name == "principal Green strain")
- field_name_copy = "grad_u";
+ if (field_name == "strain" || field_name == "Green strain" ||
+ field_name == "principal strain" ||
+ field_name == "principal Green strain")
+ field_name_copy = "grad_u";
else if (field_name == "Von Mises stress")
- field_name_copy = "stress";
+ field_name_copy = "stress";
- bool is_internal = this->isInternal(field_name_copy,kind);
+ bool is_internal = this->isInternal(field_name_copy, kind);
if (is_internal) {
- ElementTypeMap<UInt> nb_data_per_elem = this->getInternalDataPerElem(field_name_copy,kind);
- ElementTypeMapArray<Real> & internal_flat = this->flattenInternal(field_name_copy,kind);
- field = mesh.createElementalField<Real, dumper::IGFEMInternalMaterialField>(internal_flat,
- group_name,
- spatial_dimension,kind,nb_data_per_elem);
- if (field_name == "strain"){
- dumper::ComputeStrain<false> * foo = new dumper::ComputeStrain<false>(*this);
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- } else if (field_name == "Von Mises stress") {
- dumper::ComputeVonMisesStress * foo = new dumper::ComputeVonMisesStress(*this);
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- } else if (field_name == "Green strain") {
- dumper::ComputeStrain<true> * foo = new dumper::ComputeStrain<true>(*this);
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- } else if (field_name == "principal strain") {
- dumper::ComputePrincipalStrain<false> * foo = new dumper::ComputePrincipalStrain<false>(*this);
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- } else if (field_name == "principal Green strain") {
- dumper::ComputePrincipalStrain<true> * foo = new dumper::ComputePrincipalStrain<true>(*this);
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- }
-
- /// treat the paddings
- if (padding_flag){
- if (field_name == "stress"){
- if (spatial_dimension == 2) {
- dumper::StressPadder<2> * foo = new dumper::StressPadder<2>(*this);
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- }
- } else if (field_name == "strain" || field_name == "Green strain"){
- if (spatial_dimension == 2) {
- dumper::StrainPadder<2> * foo = new dumper::StrainPadder<2>(*this);
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- }
- }
- }
- // homogenize the field
- dumper::ComputeFunctorInterface * foo =
- dumper::HomogenizerProxy::createHomogenizer(*field);
-
- field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
+ ElementTypeMap<UInt> nb_data_per_elem =
+ this->getInternalDataPerElem(field_name_copy, kind);
+ ElementTypeMapArray<Real> & internal_flat =
+ this->flattenInternal(field_name_copy, kind);
+ field =
+ mesh.createElementalField<Real, dumper::IGFEMInternalMaterialField>(
+ internal_flat, group_name, spatial_dimension, kind,
+ nb_data_per_elem);
+ if (field_name == "strain") {
+ dumper::ComputeStrain<false> * foo =
+ new dumper::ComputeStrain<false>(*this);
+ field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
+ } else if (field_name == "Von Mises stress") {
+ dumper::ComputeVonMisesStress * foo =
+ new dumper::ComputeVonMisesStress(*this);
+ field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
+ } else if (field_name == "Green strain") {
+ dumper::ComputeStrain<true> * foo =
+ new dumper::ComputeStrain<true>(*this);
+ field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
+ } else if (field_name == "principal strain") {
+ dumper::ComputePrincipalStrain<false> * foo =
+ new dumper::ComputePrincipalStrain<false>(*this);
+ field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
+ } else if (field_name == "principal Green strain") {
+ dumper::ComputePrincipalStrain<true> * foo =
+ new dumper::ComputePrincipalStrain<true>(*this);
+ field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
+ }
+
+ /// treat the paddings
+ if (padding_flag) {
+ if (field_name == "stress") {
+ if (spatial_dimension == 2) {
+ dumper::StressPadder<2> * foo =
+ new dumper::StressPadder<2>(*this);
+ field =
+ dumper::FieldComputeProxy::createFieldCompute(field, *foo);
+ }
+ } else if (field_name == "strain" || field_name == "Green strain") {
+ if (spatial_dimension == 2) {
+ dumper::StrainPadder<2> * foo =
+ new dumper::StrainPadder<2>(*this);
+ field =
+ dumper::FieldComputeProxy::createFieldCompute(field, *foo);
+ }
+ }
+ }
+ // homogenize the field
+ dumper::ComputeFunctorInterface * foo =
+ dumper::HomogenizerProxy::createHomogenizer(*field);
+
+ field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
}
}
}
- // }
+ // }
return field;
}
/* -------------------------------------------------------------------------- */
-dumper::Field * SolidMechanicsModelIGFEM::createNodalFieldReal(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag) {
+dumper::Field *
+SolidMechanicsModelIGFEM::createNodalFieldReal(const std::string & field_name,
+ const std::string & group_name,
+ bool padding_flag) {
- std::map<std::string,Array<Real>* > real_nodal_fields;
- real_nodal_fields["real_displacement" ] = real_displacement;
+ std::map<std::string, Array<Real> *> real_nodal_fields;
+ real_nodal_fields["real_displacement"] = real_displacement;
dumper::Field * field = NULL;
if (padding_flag)
- field = mesh.createNodalField(real_nodal_fields[field_name],group_name, 3);
+ field = mesh.createNodalField(real_nodal_fields[field_name], group_name, 3);
else
- field = mesh.createNodalField(real_nodal_fields[field_name],group_name);
-
+ field = mesh.createNodalField(real_nodal_fields[field_name], group_name);
+
if (field == NULL)
- return SolidMechanicsModel::createNodalFieldReal(field_name, group_name, padding_flag);
-
+ return SolidMechanicsModel::createNodalFieldReal(field_name, group_name,
+ padding_flag);
+
return field;
}
#else
/* -------------------------------------------------------------------------- */
-dumper::Field * SolidMechanicsModelIGFEM
-::createElementalField(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag,
- const UInt & spatial_dimension,
- const ElementKind & kind){
+dumper::Field * SolidMechanicsModelIGFEM::createElementalField(
+ const std::string & field_name, const std::string & group_name,
+ bool padding_flag, const UInt & spatial_dimension,
+ const ElementKind & kind) {
return NULL;
}
/* -------------------------------------------------------------------------- */
-dumper::Field * SolidMechanicsModelIGFEM::createNodalFieldReal(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag) {
+dumper::Field *
+SolidMechanicsModelIGFEM::createNodalFieldReal(const std::string & field_name,
+ const std::string & group_name,
+ bool padding_flag) {
return NULL;
}
#endif
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelIGFEM::computeValuesOnEnrichedNodes() {
- for (UInt n = 0; n < mesh.getNbNodes(); ++ n) {
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
for (UInt s = 0; s < spatial_dimension; ++s)
- (*real_displacement)(n,s) = (*displacement)(n,s);
+ (*real_displacement)(n, s) = (*displacement)(n, s);
}
-
Element element;
Vector<Real> real_coords(spatial_dimension);
Vector<Real> interpolated(spatial_dimension);
- Array<Real>::const_vector_iterator r_displ_it = this->real_displacement->begin(spatial_dimension);
-
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ Array<Real>::const_vector_iterator r_displ_it =
+ this->real_displacement->begin(spatial_dimension);
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
element.ghost_type = *gt;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, *gt, _ek_igfem);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_igfem);
- for(;it != last; ++it) {
+ Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_igfem);
+ for (; it != last; ++it) {
element.type = *it;
UInt nb_element = mesh.getNbElement(*it, *gt);
- if (!nb_element) continue;
+ if (!nb_element)
+ continue;
UInt * elem_val = mesh.getConnectivity(*it, *gt).storage();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
Matrix<Real> displ_val(spatial_dimension, nb_nodes_per_element);
-
+
UInt nb_enriched_nodes = IGFEMHelper::getNbEnrichedNodes(*it);
UInt nb_parent_nodes = IGFEMHelper::getNbParentNodes(*it);
for (UInt el = 0; el < nb_element; ++el) {
- element.element = el;
- /// get the node coordinates of the element
- mesh.extractNodalValuesFromElement(mesh.getNodes(),
- nodes_coord.storage(),
- elem_val + el * nb_nodes_per_element,
- nb_nodes_per_element,
- spatial_dimension);
-
- /// get the displacement values at the nodes of the element
- mesh.extractNodalValuesFromElement(*(this->displacement),
- displ_val.storage(),
- elem_val + el * nb_nodes_per_element,
- nb_nodes_per_element,
- spatial_dimension);
-
- for (UInt i = 0; i < nb_enriched_nodes; ++i) {
- /// coordinates of enriched node
- real_coords = nodes_coord(nb_parent_nodes + i);
- /// global index of the enriched node
- UInt idx = elem_val[el * nb_nodes_per_element + nb_parent_nodes + i];
- /// compute the real displacement value
- this->getFEEngine("IGFEMFEEngine").interpolate(real_coords, displ_val,
- interpolated, element);
- r_displ_it[idx] = interpolated;
- }
+ element.element = el;
+ /// get the node coordinates of the element
+ mesh.extractNodalValuesFromElement(
+ mesh.getNodes(), nodes_coord.storage(),
+ elem_val + el * nb_nodes_per_element, nb_nodes_per_element,
+ spatial_dimension);
+
+ /// get the displacement values at the nodes of the element
+ mesh.extractNodalValuesFromElement(
+ *(this->displacement), displ_val.storage(),
+ elem_val + el * nb_nodes_per_element, nb_nodes_per_element,
+ spatial_dimension);
+
+ for (UInt i = 0; i < nb_enriched_nodes; ++i) {
+ /// coordinates of enriched node
+ real_coords = nodes_coord(nb_parent_nodes + i);
+ /// global index of the enriched node
+ UInt idx = elem_val[el * nb_nodes_per_element + nb_parent_nodes + i];
+ /// compute the real displacement value
+ this->getFEEngine("IGFEMFEEngine")
+ .interpolate(real_coords, displ_val, interpolated, element);
+ r_displ_it[idx] = interpolated;
+ }
}
}
}
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelIGFEM::transferInternalValues(const ID & internal, std::vector<Element> & new_elements, Array<Real> & added_quads, Array<Real> & internal_values) {
+void SolidMechanicsModelIGFEM::transferInternalValues(
+ const ID & internal, std::vector<Element> & new_elements,
+ Array<Real> & added_quads, Array<Real> & internal_values) {
- /// @todo sort the new elements by their corresponding old element type and old material!!!
+ /// @todo sort the new elements by their corresponding old element type and
+ /// old material!!!
/// get the number of elements for which iternals need to be transfered
UInt nb_new_elements = new_elements.size();
UInt nb_new_quads = added_quads.getSize() / nb_new_elements;
- Array<Real>::const_matrix_iterator quad_coords = added_quads.begin_reinterpret(this->spatial_dimension, nb_new_quads, nb_new_elements);
+ Array<Real>::const_matrix_iterator quad_coords =
+ added_quads.begin_reinterpret(this->spatial_dimension, nb_new_quads,
+ nb_new_elements);
UInt nb_internal_component = internal_values.getNbComponent();
- Array<Real>::matrix_iterator internal_val = internal_values.begin_reinterpret(nb_internal_component, nb_new_quads, nb_new_elements);
+ Array<Real>::matrix_iterator internal_val = internal_values.begin_reinterpret(
+ nb_internal_component, nb_new_quads, nb_new_elements);
Vector<Real> default_values(nb_internal_component, 0.);
-
+
for (UInt e = 0; e < nb_new_elements; ++e, ++quad_coords, ++internal_val) {
Element new_element = new_elements[e];
Element old_element = this->element_map[new_element];
- UInt mat_idx = (this->material_index(old_element.type, old_element.ghost_type))(old_element.element);
+ UInt mat_idx = (this->material_index(
+ old_element.type, old_element.ghost_type))(old_element.element);
Material & old_material = *(this->materials[mat_idx]);
- old_material.extrapolateInternal(internal, old_element, *quad_coords, *internal_val);
-
+ old_material.extrapolateInternal(internal, old_element, *quad_coords,
+ *internal_val);
}
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelIGFEM::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name, const GhostType ghost_type) {
+void SolidMechanicsModelIGFEM::applyEigenGradU(
+ const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name,
+ const GhostType ghost_type) {
- AKANTU_DEBUG_ASSERT(prescribed_eigen_grad_u.size() == spatial_dimension * spatial_dimension,
- "The prescribed grad_u is not of the good size");
+ AKANTU_DEBUG_ASSERT(prescribed_eigen_grad_u.size() ==
+ spatial_dimension * spatial_dimension,
+ "The prescribed grad_u is not of the good size");
std::vector<Material *>::iterator mat_it;
- for(mat_it = this->materials.begin(); mat_it != this->materials.end(); ++mat_it) {
+ for (mat_it = this->materials.begin(); mat_it != this->materials.end();
+ ++mat_it) {
MaterialIGFEM * mat_igfem = dynamic_cast<MaterialIGFEM *>(*mat_it);
if (mat_igfem != NULL)
- mat_igfem->applyEigenGradU(prescribed_eigen_grad_u, material_name, ghost_type);
- else
- if ((*mat_it)->getName() == material_name)
- (*mat_it)->applyEigenGradU(prescribed_eigen_grad_u, ghost_type);
+ mat_igfem->applyEigenGradU(prescribed_eigen_grad_u, material_name,
+ ghost_type);
+ else if ((*mat_it)->getName() == material_name)
+ (*mat_it)->applyEigenGradU(prescribed_eigen_grad_u, ghost_type);
}
}
__END_AKANTU__
diff --git a/extra_packages/igfem/src/solid_mechanics_model_igfem.hh b/extra_packages/igfem/src/solid_mechanics_model_igfem.hh
index 15d2a6629..445d27ee0 100644
--- a/extra_packages/igfem/src/solid_mechanics_model_igfem.hh
+++ b/extra_packages/igfem/src/solid_mechanics_model_igfem.hh
@@ -1,194 +1,198 @@
/**
* @file solid_mechanics_model_igfem.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief solid mechanics model for IGFEM analysis
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_IGFEM_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_IGFEM_HH__
+#include "global_ids_updater.hh"
+#include "igfem_enrichment.hh"
#include "solid_mechanics_model.hh"
#include "solid_mechanics_model_event_handler.hh"
-#include "igfem_enrichment.hh"
-#include "global_ids_updater.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
struct SolidMechanicsModelIGFEMOptions : public SolidMechanicsModelOptions {
SolidMechanicsModelIGFEMOptions(AnalysisMethod analysis_method = _static,
- bool no_init_materials = false) :
- SolidMechanicsModelOptions(analysis_method, no_init_materials) { }
+ bool no_init_materials = false)
+ : SolidMechanicsModelOptions(analysis_method, no_init_materials) {}
};
-extern const SolidMechanicsModelIGFEMOptions default_solid_mechanics_model_igfem_options;
+extern const SolidMechanicsModelIGFEMOptions
+ default_solid_mechanics_model_igfem_options;
/* -------------------------------------------------------------------------- */
/* Solid Mechanics Model for IGFEM analysis */
/* -------------------------------------------------------------------------- */
class SolidMechanicsModelIGFEM : public SolidMechanicsModel,
- public SolidMechanicsModelEventHandler,
- public IGFEMEnrichment{
+ public SolidMechanicsModelEventHandler,
+ public IGFEMEnrichment {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem> MyFEEngineIGFEMType;
+ typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem>
+ MyFEEngineIGFEMType;
typedef std::map<Element, Element> ElementMap;
typedef std::map<ElementKind, FEEngine *> FEEnginesPerKindMap;
SolidMechanicsModelIGFEM(Mesh & mesh,
- UInt spatial_dimension = _all_dimensions,
- const ID & id = "solid_mechanics_model_igfem",
- const MemoryID & memory_id = 0);
+ UInt spatial_dimension = _all_dimensions,
+ const ID & id = "solid_mechanics_model_igfem",
+ const MemoryID & memory_id = 0);
virtual ~SolidMechanicsModelIGFEM();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// initialize the cohesive model
- virtual void initFull(const ModelOptions & options = default_solid_mechanics_model_igfem_options);
+ virtual void initFull(const ModelOptions & options =
+ default_solid_mechanics_model_igfem_options);
/// initialize the model
virtual void initModel();
/// initialize igfem material
virtual void initMaterials();
/// register the tags associated with the parallel synchronizer
- virtual void initParallel(MeshPartition *partition,
- DataAccessor *data_accessor = NULL);
+ virtual void initParallel(MeshPartition * partition,
+ DataAccessor * data_accessor = NULL);
- ///allocate all vectors
+ /// allocate all vectors
virtual void initArrays();
/// transfer internals from old to new elements
- void transferInternalValues(const ID & internal, std::vector<Element> & new_elements,
- Array<Real> & added_quads, Array<Real> & internal_values);
+ void transferInternalValues(const ID & internal,
+ std::vector<Element> & new_elements,
+ Array<Real> & added_quads,
+ Array<Real> & internal_values);
/// compute the barycenter for a sub-element
- inline void getSubElementBarycenter(UInt element, UInt sub_element,
- const ElementType & type, Vector<Real> & barycenter,
- GhostType ghost_type) const;
+ inline void getSubElementBarycenter(UInt element, UInt sub_element,
+ const ElementType & type,
+ Vector<Real> & barycenter,
+ GhostType ghost_type) const;
/// apply a constant eigen_grad_u on all quadrature points of a given material
- virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name,
- const GhostType ghost_type = _not_ghost);
+ virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
+ const ID & material_name,
+ const GhostType ghost_type = _not_ghost);
private:
-
/// compute the real values of displacement, force, etc. on the enriched nodes
void computeValuesOnEnrichedNodes();
/* ------------------------------------------------------------------------ */
/* Mesh Event Handler inherited members */
/* ------------------------------------------------------------------------ */
protected:
-
virtual void onNodesAdded(const Array<UInt> & nodes_list,
- const NewNodesEvent & event);
- virtual void onNodesRemoved(const Array <UInt> & element_list,
- const Array <UInt> & new_numbering,
- const RemovedNodesEvent & event);
+ const NewNodesEvent & event);
+ virtual void onNodesRemoved(const Array<UInt> & element_list,
+ const Array<UInt> & new_numbering,
+ const RemovedNodesEvent & event);
virtual void onElementsAdded(const Array<Element> & nodes_list,
- const NewElementsEvent & event);
- virtual void onElementsRemoved(const Array <Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- const RemovedElementsEvent & event);
+ const NewElementsEvent & event);
+ virtual void
+ onElementsRemoved(const Array<Element> & element_list,
+ const ElementTypeMapArray<UInt> & new_numbering,
+ const RemovedElementsEvent & event);
/* ------------------------------------------------------------------------ */
/* Dumpable interface */
/* ------------------------------------------------------------------------ */
public:
-
virtual void onDump();
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind,
- bool padding_flag);
+ const std::string & field_id,
+ const std::string & group_name,
+ const ElementKind & element_kind,
+ bool padding_flag);
virtual dumper::Field * createElementalField(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag,
- const UInt & spatial_dimension,
- const ElementKind & kind);
+ const std::string & group_name,
+ bool padding_flag,
+ const UInt & spatial_dimension,
+ const ElementKind & kind);
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag);
-
-/* -------------------------------------------------------------------------- */
-/* Accessors */
-/* -------------------------------------------------------------------------- */
+ const std::string & group_name,
+ bool padding_flag);
+
+ /* --------------------------------------------------------------------------
+ */
+ /* Accessors */
+ /* --------------------------------------------------------------------------
+ */
public:
-
/// get the fe-engines per kind
- AKANTU_GET_MACRO(FEEnginesPerKind, fe_engines_per_kind, const FEEnginesPerKindMap &);
+ AKANTU_GET_MACRO(FEEnginesPerKind, fe_engines_per_kind,
+ const FEEnginesPerKindMap &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
-
/// real displacements array
Array<Real> * real_displacement;
/// real forces array
Array<Real> * real_force;
/// real residuals array
Array<Real> * real_residual;
/// map between and new elements (needed when the interface is moving)
ElementMap element_map;
/// global connectivity ids updater
GlobalIdsUpdater * global_ids_updater;
/// map between element kind and corresponding FEEngine object
FEEnginesPerKindMap fe_engines_per_kind;
};
/* -------------------------------------------------------------------------- */
/* IGFEMMaterialSelector */
/* -------------------------------------------------------------------------- */
class DefaultMaterialIGFEMSelector : public DefaultMaterialSelector {
public:
- DefaultMaterialIGFEMSelector(const SolidMechanicsModelIGFEM & model) :
- DefaultMaterialSelector(model.getMaterialByElement()),
- fallback_value_igfem(0) { }
+ DefaultMaterialIGFEMSelector(const SolidMechanicsModelIGFEM & model)
+ : DefaultMaterialSelector(model.getMaterialByElement()),
+ fallback_value_igfem(0) {}
virtual UInt operator()(const Element & element) {
- if(Mesh::getKind(element.type) == _ek_igfem)
+ if (Mesh::getKind(element.type) == _ek_igfem)
return fallback_value_igfem;
else
return DefaultMaterialSelector::operator()(element);
}
void setIGFEMFallback(UInt f) { this->fallback_value_igfem = f; }
protected:
UInt fallback_value_igfem;
-
};
__END_AKANTU__
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "solid_mechanics_model_igfem_inline_impl.cc"
+#if defined(AKANTU_INCLUDE_INLINE_IMPL)
+#include "solid_mechanics_model_igfem_inline_impl.cc"
#endif
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_IGFEM_HH__ */
diff --git a/extra_packages/igfem/src/solid_mechanics_model_igfem_inline_impl.cc b/extra_packages/igfem/src/solid_mechanics_model_igfem_inline_impl.cc
index 870c3d5b0..0598e8ec2 100644
--- a/extra_packages/igfem/src/solid_mechanics_model_igfem_inline_impl.cc
+++ b/extra_packages/igfem/src/solid_mechanics_model_igfem_inline_impl.cc
@@ -1,58 +1,60 @@
/**
* @file solid_mechanics_model_igfem_inline_impl.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Wed Nov 4 15:53:52 2015
*
* @brief Implementation on inline functions for SMMIGFEM
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_IGFEM_INLINE_IMPL_CC__
#define __AKANTU_SOLID_MECHANICS_MODEL_IGFEM_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-inline void SolidMechanicsModelIGFEM::getSubElementBarycenter(UInt element, UInt sub_element,
- const ElementType & type,
- Vector<Real> & barycenter,
- GhostType ghost_type) const {
+inline void SolidMechanicsModelIGFEM::getSubElementBarycenter(
+ UInt element, UInt sub_element, const ElementType & type,
+ Vector<Real> & barycenter, GhostType ghost_type) const {
UInt * conn_val = this->mesh.getConnectivity(type, ghost_type).storage();
- UInt nb_sub_element_nodes = IGFEMHelper::getNbNodesPerSubElement(type, sub_element);
- UInt * sub_el_conn = IGFEMHelper::getSubElementConnectivity(type, sub_element);
+ UInt nb_sub_element_nodes =
+ IGFEMHelper::getNbNodesPerSubElement(type, sub_element);
+ UInt * sub_el_conn =
+ IGFEMHelper::getSubElementConnectivity(type, sub_element);
UInt nb_nodes_per_element = this->mesh.getNbNodesPerElement(type);
const Array<Real> & node_coords = this->mesh.getNodes();
Real local_coord[spatial_dimension * nb_sub_element_nodes];
UInt offset = element * nb_nodes_per_element;
for (UInt n = 0; n < nb_sub_element_nodes; ++n) {
- UInt index = conn_val[offset + sub_el_conn[n]];
+ UInt index = conn_val[offset + sub_el_conn[n]];
memcpy(local_coord + n * spatial_dimension,
- node_coords.storage() + index * spatial_dimension,
- spatial_dimension*sizeof(Real));
+ node_coords.storage() + index * spatial_dimension,
+ spatial_dimension * sizeof(Real));
}
- Math::barycenter(local_coord, nb_sub_element_nodes, spatial_dimension, barycenter.storage());
+ Math::barycenter(local_coord, nb_sub_element_nodes, spatial_dimension,
+ barycenter.storage());
}
__END_AKANTU__
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_IGFEM_INLINE_IMPL_CC__ */
diff --git a/extra_packages/igfem/test/patch_tests/test_igfem_triangle_4.cc b/extra_packages/igfem/test/patch_tests/test_igfem_triangle_4.cc
index 954be0741..305ec86be 100644
--- a/extra_packages/igfem/test/patch_tests/test_igfem_triangle_4.cc
+++ b/extra_packages/igfem/test/patch_tests/test_igfem_triangle_4.cc
@@ -1,240 +1,265 @@
/**
* @file test_igfem_triangle_4.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief patch tests with elements of type _igfem_triangle_4
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "dumpable_inline_impl.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-class StraightInterfaceMatSelector : public MeshDataMaterialSelector<std::string> {
+class StraightInterfaceMatSelector
+ : public MeshDataMaterialSelector<std::string> {
public:
- StraightInterfaceMatSelector(const ID & id, SolidMechanicsModelIGFEM & model) :
- MeshDataMaterialSelector<std::string>(id, model) {}
+ StraightInterfaceMatSelector(const ID & id, SolidMechanicsModelIGFEM & model)
+ : MeshDataMaterialSelector<std::string>(id, model) {}
UInt operator()(const Element & elem) {
- if(Mesh::getKind(elem.type) == _ek_igfem)
+ if (Mesh::getKind(elem.type) == _ek_igfem)
/// choose IGFEM material
return 2;
return MeshDataMaterialSelector<std::string>::operator()(elem);
}
};
Real computeL2Error(SolidMechanicsModelIGFEM & model);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
-
+
/// create a mesh and read the regular elements from the mesh file
/// mesh creation
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("test_mesh.msh");
/// model creation
SolidMechanicsModelIGFEM model(mesh);
/// creation of material selector
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new StraightInterfaceMatSelector("physical_names", model);
model.setMaterialSelector(*mat_selector);
model.initFull();
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpField("material_index");
model.addDumpFieldVector("displacement");
model.addDumpField("blocked_dofs");
model.addDumpField("stress");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldVectorToDumper("igfem elements", "displacement");
model.addDumpFieldVectorToDumper("igfem elements", "real_displacement");
- model.addDumpFieldToDumper("igfem elements","blocked_dofs");
+ model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "stress");
/// dump mesh before the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// create the interace: the bi-material interface is a straight line
- /// since the SMMIGFEM has only a sphere intersector we generate a large
- /// sphere so that the intersection points with the mesh lie almost along
- /// the straight line x = 0.25. We then move the interface nodes to correct
- /// their position and make them lie exactly along the line. This is a
- /// workaround to generate a straight line with the sphere intersector.
- /// Ideally, there should be a new type of IGFEM enrichment implemented to generate straight lines
+ /// since the SMMIGFEM has only a sphere intersector we generate a large
+ /// sphere so that the intersection points with the mesh lie almost along
+ /// the straight line x = 0.25. We then move the interface nodes to correct
+ /// their position and make them lie exactly along the line. This is a
+ /// workaround to generate a straight line with the sphere intersector.
+ /// Ideally, there should be a new type of IGFEM enrichment implemented to
+ /// generate straight lines
std::list<SK::Sphere_3> sphere_list;
- SK::Sphere_3 sphere_1(SK::Point_3(1000000000.5, 0., 0.), 1000000000. * 1000000000);
+ SK::Sphere_3 sphere_1(SK::Point_3(1000000000.5, 0., 0.),
+ 1000000000. * 1000000000);
sphere_list.push_back(sphere_1);
model.registerGeometryObject(sphere_list, "inside");
model.update();
- if ((mesh.getNbElement(_igfem_triangle_4) != 4) || (mesh.getNbElement(_igfem_triangle_5) != 0)) {
+ if ((mesh.getNbElement(_igfem_triangle_4) != 4) ||
+ (mesh.getNbElement(_igfem_triangle_5) != 0)) {
std::cout << "something went wrong in the interface creation" << std::endl;
finalize();
return EXIT_FAILURE;
- }
-
+ }
+
/// dump mesh after the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// apply the boundary conditions: left and bottom side on rollers
/// imposed displacement along right side
mesh.computeBoundingBox();
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
- Real bottom = lower_bounds(1);
+ Real bottom = lower_bounds(1);
Real left = lower_bounds(0);
Real right = upper_bounds(0);
Real eps = std::abs((right - left) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
- for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- if(std::abs(pos(i,1) - bottom) < eps){
- boun(i,1) = true;
- disp(i,1) = 0.0;
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ if (std::abs(pos(i, 1) - bottom) < eps) {
+ boun(i, 1) = true;
+ disp(i, 1) = 0.0;
}
- if(std::abs(pos(i,0) - left) < eps){
- boun(i,0) = true;
- disp(i,0) = 0.0;
+ if (std::abs(pos(i, 0) - left) < eps) {
+ boun(i, 0) = true;
+ disp(i, 0) = 0.0;
}
- if(std::abs(pos(i,0) - right) < eps){
- boun(i,0) = true;
- disp(i,0) = 1.0;
+ if (std::abs(pos(i, 0) - right) < eps) {
+ boun(i, 0) = true;
+ disp(i, 0) = 1.0;
}
}
/// compute the volume of the mesh
Real int_volume = 0.;
std::map<ElementKind, FEEngine *> fe_engines = model.getFEEnginesPerKind();
std::map<ElementKind, FEEngine *>::const_iterator fe_it = fe_engines.begin();
for (; fe_it != fe_engines.end(); ++fe_it) {
ElementKind kind = fe_it->first;
FEEngine & fe_engine = *(fe_it->second);
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, kind);
- for(; it != last_type ; ++it) {
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, _not_ghost, kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, _not_ghost, kind);
+ for (; it != last_type; ++it) {
ElementType type = *it;
- Array<Real> Volume(mesh.getNbElement(type) * fe_engine.getNbIntegrationPoints(type), 1, 1.);
+ Array<Real> Volume(mesh.getNbElement(type) *
+ fe_engine.getNbIntegrationPoints(type),
+ 1, 1.);
int_volume += fe_engine.integrate(Volume, type);
}
}
if (!Math::are_float_equal(int_volume, 4)) {
std::cout << "Error in area computation of the 2D mesh" << std::endl;
return EXIT_FAILURE;
}
-
std::cout << "the area of the mesh is: " << int_volume << std::endl;
/// solve the system
model.assembleStiffnessMatrix();
Real error = 0;
bool converged = false;
bool factorize = false;
- converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, error, 2, factorize);
+ converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(
+ 1e-12, error, 2, factorize);
if (!converged) {
- std::cout << "The solver did not converge!!! The error is: " << error << std::endl;
+ std::cout << "The solver did not converge!!! The error is: " << error
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
/// dump the deformed mesh
model.dump();
model.dump("igfem elements");
Real L2_error = computeL2Error(model);
std::cout << "Error: " << L2_error << std::endl;
if (L2_error > 1e-14) {
finalize();
std::cout << "The patch test did not pass!!!!" << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
Real computeL2Error(SolidMechanicsModelIGFEM & model) {
/// store the error on each element for visualization
ElementTypeMapReal error_per_element("error_per_element");
Real error = 0;
Real normalization = 0;
/// Young's moduli for the two materials
Real E_1 = 10.;
Real E_2 = 1.;
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
- mesh.addDumpFieldExternal("error_per_element", error_per_element, spatial_dimension, _not_ghost, _ek_regular);
- mesh.addDumpFieldExternalToDumper("igfem elements","error_per_element", error_per_element, spatial_dimension, _not_ghost, _ek_igfem);
+ mesh.addDumpFieldExternal("error_per_element", error_per_element,
+ spatial_dimension, _not_ghost, _ek_regular);
+ mesh.addDumpFieldExternalToDumper("igfem elements", "error_per_element",
+ error_per_element, spatial_dimension,
+ _not_ghost, _ek_igfem);
ElementTypeMapReal quad_coords("quad_coords");
GhostType ghost_type = _not_ghost;
- const std::map<ElementKind, FEEngine *> & fe_engines = model.getFEEnginesPerKind();
+ const std::map<ElementKind, FEEngine *> & fe_engines =
+ model.getFEEnginesPerKind();
std::map<ElementKind, FEEngine *>::const_iterator fe_it = fe_engines.begin();
for (; fe_it != fe_engines.end(); ++fe_it) {
ElementKind kind = fe_it->first;
FEEngine & fe_engine = *(fe_it->second);
- mesh.initElementTypeMapArray(quad_coords, spatial_dimension, spatial_dimension, false, kind, true);
- mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false, kind, true);
+ mesh.initElementTypeMapArray(quad_coords, spatial_dimension,
+ spatial_dimension, false, kind, true);
+ mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false,
+ kind, true);
fe_engine.computeIntegrationPointsCoordinates(quad_coords);
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type, kind);
- for(; it != last_type ; ++it) {
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, ghost_type, kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, ghost_type, kind);
+ for (; it != last_type; ++it) {
ElementType type = *it;
UInt nb_elements = mesh.getNbElement(type, ghost_type);
UInt nb_quads = fe_engine.getNbIntegrationPoints(type);
/// interpolate the displacement at the quadrature points
- Array<Real> displ_on_quads(nb_quads * nb_elements, spatial_dimension, "displ_on_quads");
- Array<Real> quad_coords(nb_quads * nb_elements, spatial_dimension, "quad_coords");
- fe_engine.interpolateOnIntegrationPoints(model.getDisplacement(), displ_on_quads, spatial_dimension, type);
- fe_engine.computeIntegrationPointsCoordinates(quad_coords, type, ghost_type);
+ Array<Real> displ_on_quads(nb_quads * nb_elements, spatial_dimension,
+ "displ_on_quads");
+ Array<Real> quad_coords(nb_quads * nb_elements, spatial_dimension,
+ "quad_coords");
+ fe_engine.interpolateOnIntegrationPoints(
+ model.getDisplacement(), displ_on_quads, spatial_dimension, type);
+ fe_engine.computeIntegrationPointsCoordinates(quad_coords, type,
+ ghost_type);
Array<Real> & el_error = error_per_element(type, ghost_type);
- Array<Real>::const_vector_iterator displ_it = displ_on_quads.begin(spatial_dimension);
- Array<Real>::const_vector_iterator coord_it = quad_coords.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator displ_it =
+ displ_on_quads.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator coord_it =
+ quad_coords.begin(spatial_dimension);
Vector<Real> error_vec(spatial_dimension);
for (UInt e = 0; e < nb_elements; ++e) {
- Vector<Real> error_per_quad(nb_quads);
- Vector<Real> normalization_per_quad(nb_quads);
- for (UInt q = 0; q < nb_quads; ++q, ++displ_it, ++coord_it) {
- Real exact = 0.;
- Real x = (*coord_it)(0);
- if (x < 0.5)
- exact = (2. * x * E_2)/(E_1 + 3. * E_2) + (2. * E_2)/(E_1 + 3. * E_2);
- else
- exact = 2. * x * E_1/(E_1 + 3. * E_2) - (E_1 - 3. * E_2)/(E_1 + 3. * E_2);
- error_vec = *displ_it;
- error_vec(0) -= exact;
- error_per_quad(q) = error_vec.dot(error_vec);
- normalization_per_quad(q) = std::abs(exact) * std::abs(exact);
- std::cout << error_vec << std::endl;
- }
- /// integrate the error in the element and the corresponding
- /// normalization
- Real int_error = fe_engine.integrate(error_per_quad, type, e, ghost_type);
- error += int_error;
- el_error(e) = std::sqrt(int_error);
- normalization += fe_engine.integrate(normalization_per_quad, type, e, ghost_type);
+ Vector<Real> error_per_quad(nb_quads);
+ Vector<Real> normalization_per_quad(nb_quads);
+ for (UInt q = 0; q < nb_quads; ++q, ++displ_it, ++coord_it) {
+ Real exact = 0.;
+ Real x = (*coord_it)(0);
+ if (x < 0.5)
+ exact = (2. * x * E_2) / (E_1 + 3. * E_2) +
+ (2. * E_2) / (E_1 + 3. * E_2);
+ else
+ exact = 2. * x * E_1 / (E_1 + 3. * E_2) -
+ (E_1 - 3. * E_2) / (E_1 + 3. * E_2);
+ error_vec = *displ_it;
+ error_vec(0) -= exact;
+ error_per_quad(q) = error_vec.dot(error_vec);
+ normalization_per_quad(q) = std::abs(exact) * std::abs(exact);
+ std::cout << error_vec << std::endl;
+ }
+ /// integrate the error in the element and the corresponding
+ /// normalization
+ Real int_error =
+ fe_engine.integrate(error_per_quad, type, e, ghost_type);
+ error += int_error;
+ el_error(e) = std::sqrt(int_error);
+ normalization +=
+ fe_engine.integrate(normalization_per_quad, type, e, ghost_type);
}
}
}
model.dump();
model.dump("igfem elements");
return (std::sqrt(error) / std::sqrt(normalization));
}
-
-
diff --git a/extra_packages/igfem/test/patch_tests/test_igfem_triangle_5.cc b/extra_packages/igfem/test/patch_tests/test_igfem_triangle_5.cc
index 9eebe498a..7cdbf6e46 100644
--- a/extra_packages/igfem/test/patch_tests/test_igfem_triangle_5.cc
+++ b/extra_packages/igfem/test/patch_tests/test_igfem_triangle_5.cc
@@ -1,251 +1,275 @@
/**
* @file test_igfem_triangle_5.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief patch tests with elements of type _igfem_triangle_5
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "dumpable_inline_impl.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-class StraightInterfaceMatSelector : public MeshDataMaterialSelector<std::string> {
+class StraightInterfaceMatSelector
+ : public MeshDataMaterialSelector<std::string> {
public:
- StraightInterfaceMatSelector(const ID & id, SolidMechanicsModelIGFEM & model) :
- MeshDataMaterialSelector<std::string>(id, model) {}
+ StraightInterfaceMatSelector(const ID & id, SolidMechanicsModelIGFEM & model)
+ : MeshDataMaterialSelector<std::string>(id, model) {}
UInt operator()(const Element & elem) {
- if(Mesh::getKind(elem.type) == _ek_igfem)
+ if (Mesh::getKind(elem.type) == _ek_igfem)
/// choose IGFEM material
return 2;
return MeshDataMaterialSelector<std::string>::operator()(elem);
}
};
Real computeL2Error(SolidMechanicsModelIGFEM & model);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
-
+
/// create a mesh and read the regular elements from the mesh file
/// mesh creation
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModelIGFEM model(mesh);
/// creation of material selector
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new StraightInterfaceMatSelector("physical_names", model);
model.setMaterialSelector(*mat_selector);
model.initFull();
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpField("material_index");
model.addDumpFieldVector("displacement");
model.addDumpField("blocked_dofs");
model.addDumpField("stress");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldVectorToDumper("igfem elements", "displacement");
model.addDumpFieldVectorToDumper("igfem elements", "real_displacement");
- model.addDumpFieldToDumper("igfem elements","blocked_dofs");
+ model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "stress");
/// dump mesh before the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// create the interace: the bi-material interface is a straight line
- /// since the SMMIGFEM has only a sphere intersector we generate a large
- /// sphere so that the intersection points with the mesh lie almost along
- /// the straight line x = 0.25. We then move the interface nodes to correct
- /// their position and make them lie exactly along the line. This is a
- /// workaround to generate a straight line with the sphere intersector.
- /// Ideally, there should be a new type of IGFEM enrichment implemented to generate straight lines
+ /// since the SMMIGFEM has only a sphere intersector we generate a large
+ /// sphere so that the intersection points with the mesh lie almost along
+ /// the straight line x = 0.25. We then move the interface nodes to correct
+ /// their position and make them lie exactly along the line. This is a
+ /// workaround to generate a straight line with the sphere intersector.
+ /// Ideally, there should be a new type of IGFEM enrichment implemented to
+ /// generate straight lines
std::list<SK::Sphere_3> sphere_list;
SK::Sphere_3 sphere_1(SK::Point_3(6.57, 0., 0.), 6.32 * 6.32);
sphere_list.push_back(sphere_1);
model.registerGeometryObject(sphere_list, "inside");
UInt nb_regular_nodes = mesh.getNbNodes();
model.update();
UInt nb_igfem_nodes = mesh.getNbNodes() - nb_regular_nodes;
/// adjust the positions of the node to have an exact straight line
Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
Array<Real>::vector_iterator nodes_it = nodes.begin(spatial_dimension);
nodes_it += nb_regular_nodes;
for (UInt i = 0; i < nb_igfem_nodes; ++i, ++nodes_it) {
Vector<Real> & node_coords = *nodes_it;
node_coords(0) = 0.25;
Int multiplier = std::round(node_coords(1) / 0.25);
node_coords(1) = 0.25 * multiplier;
}
/// reinitialize the shape functions because node coordinates have changed
model.getFEEngine("IGFEMFEEngine").initShapeFunctions(_not_ghost);
model.getFEEngine("IGFEMFEEngine").initShapeFunctions(_ghost);
/// dump mesh after the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// apply the boundary conditions: left and bottom side on rollers
/// imposed displacement along right side
mesh.computeBoundingBox();
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
- Real bottom = lower_bounds(1);
+ Real bottom = lower_bounds(1);
Real left = lower_bounds(0);
Real right = upper_bounds(0);
Real eps = std::abs((right - left) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
- for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- if(std::abs(pos(i,1) - bottom) < eps){
- boun(i,1) = true;
- disp(i,1) = 0.0;
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ if (std::abs(pos(i, 1) - bottom) < eps) {
+ boun(i, 1) = true;
+ disp(i, 1) = 0.0;
}
- if(std::abs(pos(i,0) - left) < eps){
- boun(i,0) = true;
- disp(i,0) = 0.0;
+ if (std::abs(pos(i, 0) - left) < eps) {
+ boun(i, 0) = true;
+ disp(i, 0) = 0.0;
}
- if(std::abs(pos(i,0) - right) < eps){
- boun(i,0) = true;
- disp(i,0) = 1.0;
+ if (std::abs(pos(i, 0) - right) < eps) {
+ boun(i, 0) = true;
+ disp(i, 0) = 1.0;
}
}
/// compute the volume of the mesh
Real int_volume = 0.;
std::map<ElementKind, FEEngine *> fe_engines = model.getFEEnginesPerKind();
std::map<ElementKind, FEEngine *>::const_iterator fe_it = fe_engines.begin();
for (; fe_it != fe_engines.end(); ++fe_it) {
ElementKind kind = fe_it->first;
FEEngine & fe_engine = *(fe_it->second);
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, kind);
- for(; it != last_type ; ++it) {
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, _not_ghost, kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, _not_ghost, kind);
+ for (; it != last_type; ++it) {
ElementType type = *it;
- Array<Real> Volume(mesh.getNbElement(type) * fe_engine.getNbIntegrationPoints(type), 1, 1.);
+ Array<Real> Volume(mesh.getNbElement(type) *
+ fe_engine.getNbIntegrationPoints(type),
+ 1, 1.);
int_volume += fe_engine.integrate(Volume, type);
}
}
if (!Math::are_float_equal(int_volume, 4)) {
std::cout << "Error in area computation of the 2D mesh" << std::endl;
return EXIT_FAILURE;
}
std::cout << "the area of the mesh is: " << int_volume << std::endl;
/// solve the system
model.assembleStiffnessMatrix();
Real error = 0;
bool converged = false;
bool factorize = false;
- converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, error, 2, factorize);
+ converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(
+ 1e-12, error, 2, factorize);
if (!converged) {
- std::cout << "The solver did not converge!!! The error is: " << error << std::endl;
+ std::cout << "The solver did not converge!!! The error is: " << error
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
/// dump the deformed mesh
model.dump();
model.dump("igfem elements");
Real L2_error = computeL2Error(model);
std::cout << "Error: " << L2_error << std::endl;
if (L2_error > 1e-12) {
finalize();
std::cout << "The patch test did not pass!!!!" << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
Real computeL2Error(SolidMechanicsModelIGFEM & model) {
/// store the error on each element for visualization
ElementTypeMapReal error_per_element("error_per_element");
Real error = 0;
Real normalization = 0;
/// Young's moduli for the two materials
Real E_1 = 10.;
Real E_2 = 1.;
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
- mesh.addDumpFieldExternal("error_per_element", error_per_element, spatial_dimension, _not_ghost, _ek_regular);
- mesh.addDumpFieldExternalToDumper("igfem elements","error_per_element", error_per_element, spatial_dimension, _not_ghost, _ek_igfem);
+ mesh.addDumpFieldExternal("error_per_element", error_per_element,
+ spatial_dimension, _not_ghost, _ek_regular);
+ mesh.addDumpFieldExternalToDumper("igfem elements", "error_per_element",
+ error_per_element, spatial_dimension,
+ _not_ghost, _ek_igfem);
ElementTypeMapReal quad_coords("quad_coords");
GhostType ghost_type = _not_ghost;
- const std::map<ElementKind, FEEngine *> & fe_engines = model.getFEEnginesPerKind();
+ const std::map<ElementKind, FEEngine *> & fe_engines =
+ model.getFEEnginesPerKind();
std::map<ElementKind, FEEngine *>::const_iterator fe_it = fe_engines.begin();
for (; fe_it != fe_engines.end(); ++fe_it) {
ElementKind kind = fe_it->first;
FEEngine & fe_engine = *(fe_it->second);
- mesh.initElementTypeMapArray(quad_coords, spatial_dimension, spatial_dimension, false, kind, true);
- mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false, kind, true);
+ mesh.initElementTypeMapArray(quad_coords, spatial_dimension,
+ spatial_dimension, false, kind, true);
+ mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false,
+ kind, true);
fe_engine.computeIntegrationPointsCoordinates(quad_coords);
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type, kind);
- for(; it != last_type ; ++it) {
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, ghost_type, kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, ghost_type, kind);
+ for (; it != last_type; ++it) {
ElementType type = *it;
UInt nb_elements = mesh.getNbElement(type, ghost_type);
UInt nb_quads = fe_engine.getNbIntegrationPoints(type);
/// interpolate the displacement at the quadrature points
- Array<Real> displ_on_quads(nb_quads * nb_elements, spatial_dimension, "displ_on_quads");
- Array<Real> quad_coords(nb_quads * nb_elements, spatial_dimension, "quad_coords");
- fe_engine.interpolateOnIntegrationPoints(model.getDisplacement(), displ_on_quads, spatial_dimension, type);
- fe_engine.computeIntegrationPointsCoordinates(quad_coords, type, ghost_type);
+ Array<Real> displ_on_quads(nb_quads * nb_elements, spatial_dimension,
+ "displ_on_quads");
+ Array<Real> quad_coords(nb_quads * nb_elements, spatial_dimension,
+ "quad_coords");
+ fe_engine.interpolateOnIntegrationPoints(
+ model.getDisplacement(), displ_on_quads, spatial_dimension, type);
+ fe_engine.computeIntegrationPointsCoordinates(quad_coords, type,
+ ghost_type);
Array<Real> & el_error = error_per_element(type, ghost_type);
- Array<Real>::const_vector_iterator displ_it = displ_on_quads.begin(spatial_dimension);
- Array<Real>::const_vector_iterator coord_it = quad_coords.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator displ_it =
+ displ_on_quads.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator coord_it =
+ quad_coords.begin(spatial_dimension);
Vector<Real> error_vec(spatial_dimension);
for (UInt e = 0; e < nb_elements; ++e) {
- Vector<Real> error_per_quad(nb_quads);
- Vector<Real> normalization_per_quad(nb_quads);
- for (UInt q = 0; q < nb_quads; ++q, ++displ_it, ++coord_it) {
- Real exact = 0.;
- Real x = (*coord_it)(0);
- if (x < 0.25)
- exact = (4. * x * E_2) /(3. * E_1 + 5. * E_2)+(4. * E_2)/(3. * E_1 + 5. * E_2);
- else
- exact = 4. * x *E_1 /(3. * E_1 + 5. *E_2)-(E_1-5.*E_2)/(3.*E_1+5.*E_2);
- error_vec = *displ_it;
- error_vec(0) -= exact;
- error_per_quad(q) = error_vec.dot(error_vec);
- normalization_per_quad(q) = std::abs(exact) * std::abs(exact);
- std::cout << error_vec << std::endl;
- }
- /// integrate the error in the element and the corresponding
- /// normalization
- Real int_error = fe_engine.integrate(error_per_quad, type, e, ghost_type);
- error += int_error;
- el_error(e) = std::sqrt(int_error);
- normalization += fe_engine.integrate(normalization_per_quad, type, e, ghost_type);
+ Vector<Real> error_per_quad(nb_quads);
+ Vector<Real> normalization_per_quad(nb_quads);
+ for (UInt q = 0; q < nb_quads; ++q, ++displ_it, ++coord_it) {
+ Real exact = 0.;
+ Real x = (*coord_it)(0);
+ if (x < 0.25)
+ exact = (4. * x * E_2) / (3. * E_1 + 5. * E_2) +
+ (4. * E_2) / (3. * E_1 + 5. * E_2);
+ else
+ exact = 4. * x * E_1 / (3. * E_1 + 5. * E_2) -
+ (E_1 - 5. * E_2) / (3. * E_1 + 5. * E_2);
+ error_vec = *displ_it;
+ error_vec(0) -= exact;
+ error_per_quad(q) = error_vec.dot(error_vec);
+ normalization_per_quad(q) = std::abs(exact) * std::abs(exact);
+ std::cout << error_vec << std::endl;
+ }
+ /// integrate the error in the element and the corresponding
+ /// normalization
+ Real int_error =
+ fe_engine.integrate(error_per_quad, type, e, ghost_type);
+ error += int_error;
+ el_error(e) = std::sqrt(int_error);
+ normalization +=
+ fe_engine.integrate(normalization_per_quad, type, e, ghost_type);
}
}
}
model.dump();
model.dump("igfem elements");
return (std::sqrt(error) / std::sqrt(normalization));
}
-
-
diff --git a/extra_packages/igfem/test/patch_tests/test_interface_position.cc b/extra_packages/igfem/test/patch_tests/test_interface_position.cc
index 88680f64e..0df9adff7 100644
--- a/extra_packages/igfem/test/patch_tests/test_interface_position.cc
+++ b/extra_packages/igfem/test/patch_tests/test_interface_position.cc
@@ -1,313 +1,348 @@
/**
* @file test_interface_position.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief patch test for interface close to standard nodes
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "dumpable_inline_impl.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-Real computeL2Error(SolidMechanicsModelIGFEM & model, ElementTypeMapReal & error_per_element);
+Real computeL2Error(SolidMechanicsModelIGFEM & model,
+ ElementTypeMapReal & error_per_element);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material_test_interface_position.dat", argc, argv);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// create a mesh and read the regular elements from the mesh file
/// mesh creation
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("test_interface_position.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
-
+
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
model.initFull();
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpField("material_index");
model.addDumpFieldVector("displacement");
model.addDumpField("blocked_dofs");
model.addDumpField("stress");
model.addDumpField("partitions");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldVectorToDumper("igfem elements", "displacement");
model.addDumpFieldVectorToDumper("igfem elements", "real_displacement");
- model.addDumpFieldToDumper("igfem elements","blocked_dofs");
+ model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "stress");
model.addDumpFieldToDumper("igfem elements", "partitions");
/// dump mesh before the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// create the interace:
UInt nb_standard_nodes = mesh.getNbNodes();
std::list<SK::Sphere_3> sphere_list;
SK::Sphere_3 sphere_1(SK::Point_3(0., 0., 0.), 0.25 * 0.25);
sphere_list.push_back(sphere_1);
model.registerGeometryObject(sphere_list, "inside");
model.update();
/// dump mesh after the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// apply the boundary conditions: left and bottom side on rollers
/// imposed displacement along right side
mesh.computeBoundingBox();
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
- Real bottom = lower_bounds(1);
+ Real bottom = lower_bounds(1);
Real left = lower_bounds(0);
Real right = upper_bounds(0);
Real eps = std::abs((right - left) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
- for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- if(std::abs(pos(i,1) - bottom) < eps){
- boun(i,1) = true;
- disp(i,1) = 0.0;
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ if (std::abs(pos(i, 1) - bottom) < eps) {
+ boun(i, 1) = true;
+ disp(i, 1) = 0.0;
}
- if(std::abs(pos(i,0) - left) < eps){
- boun(i,0) = true;
- disp(i,0) = 0.0;
+ if (std::abs(pos(i, 0) - left) < eps) {
+ boun(i, 0) = true;
+ disp(i, 0) = 0.0;
}
- if(std::abs(pos(i,0) - right) < eps){
- boun(i,0) = true;
- disp(i,0) = 1.0;
+ if (std::abs(pos(i, 0) - right) < eps) {
+ boun(i, 0) = true;
+ disp(i, 0) = 1.0;
}
}
/// compute the volume of the mesh
Real int_volume = 0.;
std::map<ElementKind, FEEngine *> fe_engines = model.getFEEnginesPerKind();
std::map<ElementKind, FEEngine *>::const_iterator fe_it = fe_engines.begin();
for (; fe_it != fe_engines.end(); ++fe_it) {
ElementKind kind = fe_it->first;
FEEngine & fe_engine = *(fe_it->second);
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, kind);
- for(; it != last_type ; ++it) {
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, _not_ghost, kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, _not_ghost, kind);
+ for (; it != last_type; ++it) {
ElementType type = *it;
- Array<Real> Volume(mesh.getNbElement(type) * fe_engine.getNbIntegrationPoints(type), 1, 1.);
+ Array<Real> Volume(mesh.getNbElement(type) *
+ fe_engine.getNbIntegrationPoints(type),
+ 1, 1.);
int_volume += fe_engine.integrate(Volume, type);
}
}
comm.allReduce(&int_volume, 1, _so_sum);
if (prank == 0)
if (!Math::are_float_equal(int_volume, 4)) {
finalize();
std::cout << "Error in area computation of the 2D mesh" << std::endl;
return EXIT_FAILURE;
}
-
+
/// solve the system
model.assembleStiffnessMatrix();
Real error = 0;
bool converged = false;
bool factorize = false;
- converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, error, 2, factorize);
+ converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(
+ 1e-12, error, 2, factorize);
if (!converged) {
- std::cout << "The solver did not converge!!! The error is: " << error << std::endl;
+ std::cout << "The solver did not converge!!! The error is: " << error
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
- /// store the error on each element for visualization
+ /// store the error on each element for visualization
ElementTypeMapReal error_per_element("error_per_element");
- mesh.addDumpFieldExternal("error_per_element", error_per_element, spatial_dimension, _not_ghost, _ek_regular);
- mesh.addDumpFieldExternalToDumper("igfem elements","error_per_element", error_per_element, spatial_dimension, _not_ghost, _ek_igfem);
- mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false, _ek_regular, true);
- mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false, _ek_igfem, true);
+ mesh.addDumpFieldExternal("error_per_element", error_per_element,
+ spatial_dimension, _not_ghost, _ek_regular);
+ mesh.addDumpFieldExternalToDumper("igfem elements", "error_per_element",
+ error_per_element, spatial_dimension,
+ _not_ghost, _ek_igfem);
+ mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false,
+ _ek_regular, true);
+ mesh.initElementTypeMapArray(error_per_element, 1, spatial_dimension, false,
+ _ek_igfem, true);
Real L2_error = computeL2Error(model, error_per_element);
comm.allReduce(&L2_error, 1, _so_sum);
if (prank == 0) {
std::cout << "Error: " << L2_error << std::endl;
if (L2_error > 1e-13) {
finalize();
std::cout << "The patch test did not pass!!!!" << std::endl;
return EXIT_FAILURE;
}
}
/// dump the deformed mesh
model.dump();
model.dump("igfem elements");
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
/// move the interface very close the standard nodes, but far enough
/// to not cut trough the standard nodes
model.moveInterface(0.5 * (1 - 1e-9));
model.dump();
model.dump("igfem elements");
UInt nb_igfem_triangle_4 = mesh.getNbElement(_igfem_triangle_4, _not_ghost);
UInt nb_igfem_triangle_5 = mesh.getNbElement(_igfem_triangle_5, _not_ghost);
comm.allReduce(&nb_igfem_triangle_4, 1, _so_sum);
comm.allReduce(&nb_igfem_triangle_5, 1, _so_sum);
-
+
if (prank == 0) {
- if ( (nb_igfem_triangle_4 != 0) || (nb_igfem_triangle_5 != 8)) {
- std::cout << "something went wrong in the interface creation" << std::endl;
+ if ((nb_igfem_triangle_4 != 0) || (nb_igfem_triangle_5 != 8)) {
+ std::cout << "something went wrong in the interface creation"
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
}
- if ( (psize == 0) && (mesh.getNbNodes() - nb_standard_nodes != 8) ) {
- std::cout << "something went wrong in the interface node creation" << std::endl;
+ if ((psize == 0) && (mesh.getNbNodes() - nb_standard_nodes != 8)) {
+ std::cout << "something went wrong in the interface node creation"
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
- converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, error, 2, factorize);
+ converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(
+ 1e-12, error, 2, factorize);
if (!converged) {
- std::cout << "The solver did not converge!!! The error is: " << error << std::endl;
+ std::cout << "The solver did not converge!!! The error is: " << error
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
L2_error = computeL2Error(model, error_per_element);
comm.allReduce(&L2_error, 1, _so_sum);
if (prank == 0) {
std::cout << "Error: " << L2_error << std::endl;
if (L2_error > 1e-13) {
finalize();
std::cout << "The patch test did not pass!!!!" << std::endl;
return EXIT_FAILURE;
}
}
/// dump the new interface
model.dump();
model.dump("igfem elements");
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
/// move the interface so that it cuts through the standard nodes
model.moveInterface((0.5 * (1 - 1e-10)));
nb_igfem_triangle_4 = mesh.getNbElement(_igfem_triangle_4, _not_ghost);
nb_igfem_triangle_5 = mesh.getNbElement(_igfem_triangle_5, _not_ghost);
comm.allReduce(&nb_igfem_triangle_4, 1, _so_sum);
comm.allReduce(&nb_igfem_triangle_5, 1, _so_sum);
if (prank == 0) {
- if ((nb_igfem_triangle_4 != 8) || (nb_igfem_triangle_5 != 0) ) {
- std::cout << "something went wrong in the interface creation" << std::endl;
- finalize();
- return EXIT_FAILURE;
+ if ((nb_igfem_triangle_4 != 8) || (nb_igfem_triangle_5 != 0)) {
+ std::cout << "something went wrong in the interface creation"
+ << std::endl;
+ finalize();
+ return EXIT_FAILURE;
}
}
- if ( (psize == 0) && (mesh.getNbNodes() - nb_standard_nodes != 4) ) {
- std::cout << "something went wrong in the interface node creation" << std::endl;
+ if ((psize == 0) && (mesh.getNbNodes() - nb_standard_nodes != 4)) {
+ std::cout << "something went wrong in the interface node creation"
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
- converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, error, 2, factorize);
+ converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(
+ 1e-12, error, 2, factorize);
if (!converged) {
- std::cout << "The solver did not converge!!! The error is: " << error << std::endl;
+ std::cout << "The solver did not converge!!! The error is: " << error
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
L2_error = computeL2Error(model, error_per_element);
comm.allReduce(&L2_error, 1, _so_sum);
if (prank == 0) {
std::cout << "Error: " << L2_error << std::endl;
if (L2_error > 1e-13) {
finalize();
std::cout << "The patch test did not pass!!!!" << std::endl;
return EXIT_FAILURE;
}
}
/// dump the new interface
model.dump();
model.dump("igfem elements");
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
-Real computeL2Error(SolidMechanicsModelIGFEM & model, ElementTypeMapReal & error_per_element) {
+Real computeL2Error(SolidMechanicsModelIGFEM & model,
+ ElementTypeMapReal & error_per_element) {
Real error = 0;
Real normalization = 0;
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
ElementTypeMapReal quad_coords("quad_coords");
GhostType ghost_type = _not_ghost;
- const std::map<ElementKind, FEEngine *> & fe_engines = model.getFEEnginesPerKind();
+ const std::map<ElementKind, FEEngine *> & fe_engines =
+ model.getFEEnginesPerKind();
std::map<ElementKind, FEEngine *>::const_iterator fe_it = fe_engines.begin();
for (; fe_it != fe_engines.end(); ++fe_it) {
ElementKind kind = fe_it->first;
FEEngine & fe_engine = *(fe_it->second);
- mesh.initElementTypeMapArray(quad_coords, spatial_dimension, spatial_dimension, false, kind, true);
+ mesh.initElementTypeMapArray(quad_coords, spatial_dimension,
+ spatial_dimension, false, kind, true);
fe_engine.computeIntegrationPointsCoordinates(quad_coords);
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, kind);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type, kind);
- for(; it != last_type ; ++it) {
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, ghost_type, kind);
+ Mesh::type_iterator last_type =
+ mesh.lastType(spatial_dimension, ghost_type, kind);
+ for (; it != last_type; ++it) {
ElementType type = *it;
UInt nb_elements = mesh.getNbElement(type, ghost_type);
UInt nb_quads = fe_engine.getNbIntegrationPoints(type);
/// interpolate the displacement at the quadrature points
- Array<Real> displ_on_quads(nb_quads * nb_elements, spatial_dimension, "displ_on_quads");
- Array<Real> quad_coords(nb_quads * nb_elements, spatial_dimension, "quad_coords");
- fe_engine.interpolateOnIntegrationPoints(model.getDisplacement(), displ_on_quads, spatial_dimension, type);
- fe_engine.computeIntegrationPointsCoordinates(quad_coords, type, ghost_type);
+ Array<Real> displ_on_quads(nb_quads * nb_elements, spatial_dimension,
+ "displ_on_quads");
+ Array<Real> quad_coords(nb_quads * nb_elements, spatial_dimension,
+ "quad_coords");
+ fe_engine.interpolateOnIntegrationPoints(
+ model.getDisplacement(), displ_on_quads, spatial_dimension, type);
+ fe_engine.computeIntegrationPointsCoordinates(quad_coords, type,
+ ghost_type);
Array<Real> & el_error = error_per_element(type, ghost_type);
el_error.resize(nb_elements);
- Array<Real>::const_vector_iterator displ_it = displ_on_quads.begin(spatial_dimension);
- Array<Real>::const_vector_iterator coord_it = quad_coords.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator displ_it =
+ displ_on_quads.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator coord_it =
+ quad_coords.begin(spatial_dimension);
Vector<Real> error_vec(spatial_dimension);
for (UInt e = 0; e < nb_elements; ++e) {
- Vector<Real> error_per_quad(nb_quads);
- Vector<Real> normalization_per_quad(nb_quads);
- for (UInt q = 0; q < nb_quads; ++q, ++displ_it, ++coord_it) {
- Real exact = 0.5 * (*coord_it)(0) + 0.5;
- error_vec = *displ_it;
- error_vec(0) -= exact;
- error_per_quad(q) = error_vec.dot(error_vec);
- normalization_per_quad(q) = std::abs(exact) * std::abs(exact);
- /// std::cout << error_vec << std::endl;
- }
- /// integrate the error in the element and the corresponding
- /// normalization
- Real int_error = fe_engine.integrate(error_per_quad, type, e, ghost_type);
- error += int_error;
- el_error(e) = std::sqrt(int_error);
- normalization += fe_engine.integrate(normalization_per_quad, type, e, ghost_type);
+ Vector<Real> error_per_quad(nb_quads);
+ Vector<Real> normalization_per_quad(nb_quads);
+ for (UInt q = 0; q < nb_quads; ++q, ++displ_it, ++coord_it) {
+ Real exact = 0.5 * (*coord_it)(0) + 0.5;
+ error_vec = *displ_it;
+ error_vec(0) -= exact;
+ error_per_quad(q) = error_vec.dot(error_vec);
+ normalization_per_quad(q) = std::abs(exact) * std::abs(exact);
+ /// std::cout << error_vec << std::endl;
+ }
+ /// integrate the error in the element and the corresponding
+ /// normalization
+ Real int_error =
+ fe_engine.integrate(error_per_quad, type, e, ghost_type);
+ error += int_error;
+ el_error(e) = std::sqrt(int_error);
+ normalization +=
+ fe_engine.integrate(normalization_per_quad, type, e, ghost_type);
}
}
}
return (std::sqrt(error) / std::sqrt(normalization));
}
diff --git a/extra_packages/igfem/test/test_fe_engine/igfem_mesh_generation.cc b/extra_packages/igfem/test/test_fe_engine/igfem_mesh_generation.cc
index d00a10e1d..d5e1b3a6c 100644
--- a/extra_packages/igfem/test/test_fe_engine/igfem_mesh_generation.cc
+++ b/extra_packages/igfem/test/test_fe_engine/igfem_mesh_generation.cc
@@ -1,112 +1,115 @@
/**
* @file igfem_mesh_generation.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Fri Oct 30 14:55:51 2015
*
* @brief function to generate a IGFEM mesh for fe_engine tests
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include <fstream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
-void generateIGFEMMesh(const ElementType type, Mesh & mesh, const std::string & filename) {
+void generateIGFEMMesh(const ElementType type, Mesh & mesh,
+ const std::string & filename) {
std::ifstream infile;
infile.open(filename.c_str());
- if(!infile.good()) {
+ if (!infile.good()) {
AKANTU_DEBUG_ERROR("Cannot open file " << filename);
}
UInt current_line = 0;
std::string line;
UInt first_node_number = std::numeric_limits<UInt>::max();
UInt last_node_number = 0;
- while(infile.good()) {
+ while (infile.good()) {
std::getline(infile, line);
current_line++;
/// read all nodes
- if(line == "$Nodes" || line == "$NOD") {
+ if (line == "$Nodes" || line == "$NOD") {
UInt nb_nodes;
std::getline(infile, line);
std::stringstream sstr(line);
sstr >> nb_nodes;
current_line++;
Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
nodes.resize(nb_nodes);
UInt index;
Real coord[3];
UInt spatial_dimension = nodes.getNbComponent();
/// for each node, read the coordinates
- for(UInt i = 0; i < nb_nodes; ++i) {
+ for (UInt i = 0; i < nb_nodes; ++i) {
UInt offset = i * spatial_dimension;
std::getline(infile, line);
std::stringstream sstr_node(line);
sstr_node >> index >> coord[0] >> coord[1] >> coord[2];
current_line++;
- first_node_number = std::min(first_node_number,index);
- last_node_number = std::max(last_node_number, index);
+ first_node_number = std::min(first_node_number, index);
+ last_node_number = std::max(last_node_number, index);
/// read the coordinates
- for(UInt j = 0; j < spatial_dimension; ++j)
+ for (UInt j = 0; j < spatial_dimension; ++j)
nodes.storage()[offset + j] = coord[j];
}
std::getline(infile, line); /// the end of block line
}
/// read all elements
- if(line == "$Elements" || line == "$ELM") {
+ if (line == "$Elements" || line == "$ELM") {
mesh.addConnectivityType(type);
- Array<UInt> & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type));
+ Array<UInt> & connectivity =
+ const_cast<Array<UInt> &>(mesh.getConnectivity(type));
UInt node_per_element = connectivity.getNbComponent();
UInt nb_elements = 0;
std::getline(infile, line);
std::stringstream sstr(line);
sstr >> nb_elements;
current_line++;
-
- for(UInt i = 0; i < nb_elements; ++i) {
+
+ for (UInt i = 0; i < nb_elements; ++i) {
std::getline(infile, line);
std::stringstream sstr_elem(line);
current_line++;
Vector<UInt> local_connect(node_per_element);
- for(UInt j = 0; j < node_per_element; ++j) {
+ for (UInt j = 0; j < node_per_element; ++j) {
UInt node_index;
sstr_elem >> node_index;
AKANTU_DEBUG_ASSERT(node_index <= last_node_number,
- "Node number not in range : line " << current_line);
+ "Node number not in range : line "
+ << current_line);
node_index -= first_node_number;
local_connect(j) = node_index;
}
connectivity.push_back(local_connect);
}
std::getline(infile, line); /// the end of block line
}
}
}
diff --git a/extra_packages/igfem/test/test_fe_engine/test_fe_engine_precomputation.cc b/extra_packages/igfem/test/test_fe_engine/test_fe_engine_precomputation.cc
index f7bcb6af5..b212469c0 100644
--- a/extra_packages/igfem/test/test_fe_engine/test_fe_engine_precomputation.cc
+++ b/extra_packages/igfem/test/test_fe_engine/test_fe_engine_precomputation.cc
@@ -1,76 +1,80 @@
/**
* @file test_fe_engine_percompuation.cc
*
* @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Fri Oct 30 2015
* @date last modification: Fri Oct 30 2015
*
* @brief test the fe-engine precomputations for IGFEM elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "shape_igfem.hh"
-#include "integrator_gauss_igfem.hh"
#include "fe_engine.hh"
+#include "integrator_gauss_igfem.hh"
+#include "shape_igfem.hh"
/* -------------------------------------------------------------------------- */
-#include <iostream>
#include <fstream>
+#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
void precompute(const ElementType type);
-void generateIGFEMMesh(const ElementType type, Mesh & mesh, const std::string & filename);
+void generateIGFEMMesh(const ElementType type, Mesh & mesh,
+ const std::string & filename);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
/// precompuation for _igfem_triangle_4
AKANTU_DEBUG_INFO("precomputation for _igfem_triangle_4...");
precompute(_igfem_triangle_4);
/// precompuation for _igfem_triangle_5
AKANTU_DEBUG_INFO("precomputation for _igfem_triangle_5...");
precompute(_igfem_triangle_5);
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void precompute(const ElementType type) {
UInt dim = 2;
- std::stringstream mesh_info; mesh_info << "mesh_info" << type << ".txt";
+ std::stringstream mesh_info;
+ mesh_info << "mesh_info" << type << ".txt";
Mesh my_mesh(dim);
generateIGFEMMesh(type, my_mesh, mesh_info.str());
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_igfem>(my_mesh, dim, "my_fem");
+ FEEngine * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem>(
+ my_mesh, dim, "my_fem");
fem->initShapeFunctions();
-
+
std::cout << *fem << std::endl;
delete fem;
}
diff --git a/extra_packages/igfem/test/test_fe_engine/test_gradient.cc b/extra_packages/igfem/test/test_fe_engine/test_gradient.cc
index 12cc2e0d8..520afba90 100644
--- a/extra_packages/igfem/test/test_fe_engine/test_gradient.cc
+++ b/extra_packages/igfem/test/test_fe_engine/test_gradient.cc
@@ -1,158 +1,166 @@
/**
* @file test_gradient.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief test the gradient computation for the igfem elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "shape_igfem.hh"
-#include "integrator_gauss_igfem.hh"
#include "fe_engine.hh"
+#include "integrator_gauss_igfem.hh"
+#include "shape_igfem.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
bool gradient(const ElementType type);
-void generateIGFEMMesh(const ElementType type, Mesh & mesh, const std::string & filename);
+void generateIGFEMMesh(const ElementType type, Mesh & mesh,
+ const std::string & filename);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
bool test_passed = false;
/// integrate test of _igfem_triangle_4
AKANTU_DEBUG_INFO("integrating _igfem_triangle_4...");
test_passed = gradient(_igfem_triangle_4);
- if(!test_passed) {
+ if (!test_passed) {
finalize();
- return EXIT_FAILURE;
+ return EXIT_FAILURE;
}
/// integrate test of _igfem_triangle_5
AKANTU_DEBUG_INFO("integrating _igfem_triangle_5...");
test_passed = gradient(_igfem_triangle_5);
- if(!test_passed) {
+ if (!test_passed) {
finalize();
- return EXIT_FAILURE;
+ return EXIT_FAILURE;
}
-
+
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
bool gradient(const ElementType type) {
bool correct_result = true;
UInt dim = 2;
- std::stringstream mesh_info; mesh_info << "mesh_info" << type << ".txt";
+ std::stringstream mesh_info;
+ mesh_info << "mesh_info" << type << ".txt";
Mesh my_mesh(dim);
generateIGFEMMesh(type, my_mesh, mesh_info.str());
Real eps = 3e-13;
std::cout << "Epsilon : " << eps << std::endl;
- FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem> *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange, _ek_igfem>(my_mesh, dim, "my_fem");
+ FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem> * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem>(
+ my_mesh, dim, "my_fem");
fem->initShapeFunctions();
- Real alpha[2][3] = {{13, 23, 31},
- {11, 7, 5}};
+ Real alpha[2][3] = {{13, 23, 31}, {11, 7, 5}};
/// create the 2 component field
- /// for field to be constant the enriched values need to be zero!! Therefore non-zero values
+ /// for field to be constant the enriched values need to be zero!! Therefore
+ /// non-zero values
/// are only imposed on standard nodes
UInt nb_standard_nodes = 9;
const Array<Real> & position = fem->getMesh().getNodes();
Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
UInt nb_element = my_mesh.getNbElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
Array<Real> grad_on_quad(nb_quadrature_points, 2 * dim, "grad_on_quad");
for (UInt i = 0; i < nb_standard_nodes; ++i) {
const_val(i, 0) = 0;
const_val(i, 1) = 0;
for (UInt d = 0; d < dim; ++d) {
const_val(i, 0) += alpha[0][d] * position(i, d);
const_val(i, 1) += alpha[1][d] * position(i, d);
}
}
/// impose zero at enriched nodes
for (UInt i = nb_standard_nodes; i < const_val.getSize(); ++i) {
const_val(i, 0) = 0;
const_val(i, 1) = 0;
}
/// compute the gradient
fem->gradientOnIntegrationPoints(const_val, grad_on_quad, 2, type);
std::cout << "Linear array on nodes : " << const_val << std::endl;
- std::cout << "Gradient on quad : " <<grad_on_quad << std::endl;
+ std::cout << "Gradient on quad : " << grad_on_quad << std::endl;
/// check the results
- Array<Real>::matrix_iterator it = grad_on_quad.begin(2,dim);
- Array<Real>::matrix_iterator it_end = grad_on_quad.end(2,dim);
- for (;it != it_end; ++it) {
+ Array<Real>::matrix_iterator it = grad_on_quad.begin(2, dim);
+ Array<Real>::matrix_iterator it_end = grad_on_quad.end(2, dim);
+ for (; it != it_end; ++it) {
for (UInt d = 0; d < dim; ++d) {
Matrix<Real> & grad = *it;
- if(!(std::abs(grad(0, d) - alpha[0][d]) < eps) ||
- !(std::abs(grad(1, d) - alpha[1][d]) < eps)) {
- std::cout << "Error gradient is not correct "
- << (*it)(0, d) << " " << alpha[0][d] << " (" << std::abs((*it)(0, d) - alpha[0][d]) << ")"
- << " - "
- << (*it)(1, d) << " " << alpha[1][d] << " (" << std::abs((*it)(1, d) - alpha[1][d]) << ")"
- << " - " << d << std::endl;
- std::cout << *it << std::endl;
- correct_result = false;
- return correct_result;
+ if (!(std::abs(grad(0, d) - alpha[0][d]) < eps) ||
+ !(std::abs(grad(1, d) - alpha[1][d]) < eps)) {
+ std::cout << "Error gradient is not correct " << (*it)(0, d) << " "
+ << alpha[0][d] << " (" << std::abs((*it)(0, d) - alpha[0][d])
+ << ")"
+ << " - " << (*it)(1, d) << " " << alpha[1][d] << " ("
+ << std::abs((*it)(1, d) - alpha[1][d]) << ")"
+ << " - " << d << std::endl;
+ std::cout << *it << std::endl;
+ correct_result = false;
+ return correct_result;
}
}
}
// compute gradient of coordinates
- Array<Real> grad_coord_on_quad(nb_quadrature_points, dim * dim, "grad_coord_on_quad");
+ Array<Real> grad_coord_on_quad(nb_quadrature_points, dim * dim,
+ "grad_coord_on_quad");
/// create an array with the nodal coordinates that need to be
/// interpolated. The nodal coordinates of the enriched nodes need
/// to be set to zero, because they represent the enrichment of the
/// position field, and the enrichments for this field are all zero!
/// There is no gap in the mesh!
- Array<Real> igfem_nodes(my_mesh.getNbNodes(), dim);
+ Array<Real> igfem_nodes(my_mesh.getNbNodes(), dim);
const ShapeLagrange<_ek_igfem> & shapes = fem->getShapeFunctions();
- shapes.extractValuesAtStandardNodes(my_mesh.getNodes(), igfem_nodes, _not_ghost);
+ shapes.extractValuesAtStandardNodes(my_mesh.getNodes(), igfem_nodes,
+ _not_ghost);
- fem->gradientOnIntegrationPoints(igfem_nodes, grad_coord_on_quad, my_mesh.getSpatialDimension(), type);
+ fem->gradientOnIntegrationPoints(igfem_nodes, grad_coord_on_quad,
+ my_mesh.getSpatialDimension(), type);
std::cout << "Node positions : " << my_mesh.getNodes() << std::endl;
std::cout << "Gradient of nodes : " << grad_coord_on_quad << std::endl;
Array<Real>::matrix_iterator itp = grad_coord_on_quad.begin(dim, dim);
Array<Real>::matrix_iterator itp_end = grad_coord_on_quad.end(dim, dim);
- for (;itp != itp_end; ++itp) {
+ for (; itp != itp_end; ++itp) {
for (UInt i = 0; i < dim; ++i) {
for (UInt j = 0; j < dim; ++j) {
- if(!(std::abs((*itp)(i,j) - (i == j)) < eps)) {
- std::cout << *itp << std::endl;
- correct_result = false;
- return correct_result;
- }
+ if (!(std::abs((*itp)(i, j) - (i == j)) < eps)) {
+ std::cout << *itp << std::endl;
+ correct_result = false;
+ return correct_result;
+ }
}
}
}
delete fem;
return correct_result;
}
diff --git a/extra_packages/igfem/test/test_fe_engine/test_integrate.cc b/extra_packages/igfem/test/test_fe_engine/test_integrate.cc
index 875fcd443..0680e6540 100644
--- a/extra_packages/igfem/test/test_fe_engine/test_integrate.cc
+++ b/extra_packages/igfem/test/test_fe_engine/test_integrate.cc
@@ -1,128 +1,136 @@
/**
* @file test_integrate.cc
*
* @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Fri Oct 30 2015
* @date last modification: Fri Oct 30 2015
*
* @brief test the integration of IGFEM elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "shape_igfem.hh"
-#include "integrator_gauss_igfem.hh"
#include "fe_engine.hh"
+#include "integrator_gauss_igfem.hh"
+#include "shape_igfem.hh"
///#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
bool integrate(const ElementType type);
-void generateIGFEMMesh(const ElementType type, Mesh & mesh, const std::string & filename);
+void generateIGFEMMesh(const ElementType type, Mesh & mesh,
+ const std::string & filename);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
bool test_passed = false;
/// integrate test of _igfem_triangle_4
AKANTU_DEBUG_INFO("integrating _igfem_triangle_4...");
test_passed = integrate(_igfem_triangle_4);
- if(!test_passed) {
+ if (!test_passed) {
finalize();
- return EXIT_FAILURE;
+ return EXIT_FAILURE;
}
/// integrate test of _igfem_triangle_5
AKANTU_DEBUG_INFO("integrating _igfem_triangle_5...");
test_passed = integrate(_igfem_triangle_5);
- if(!test_passed) {
+ if (!test_passed) {
finalize();
- return EXIT_FAILURE;
+ return EXIT_FAILURE;
}
-
+
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
bool integrate(const ElementType type) {
- bool correct_result = true;
+ bool correct_result = true;
UInt dim = 2;
- std::stringstream mesh_info; mesh_info << "mesh_info" << type << ".txt";
+ std::stringstream mesh_info;
+ mesh_info << "mesh_info" << type << ".txt";
Mesh my_mesh(dim);
generateIGFEMMesh(type, my_mesh, mesh_info.str());
// DumperParaview dumper_igfem("mesh_igfem");
// dumper_igfem.registerMesh(my_mesh, dim, _not_ghost, _ek_igfem);
// dumper_igfem.dump();
Real eps = 3e-13;
std::cout << "Epsilon : " << eps << std::endl;
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_igfem>(my_mesh, dim, "my_fem");
+ FEEngine * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem>(
+ my_mesh, dim, "my_fem");
fem->initShapeFunctions();
UInt nb_element = my_mesh.getNbElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
/// impose a constant field on the quadrature points with x = 1 and y = 2
Array<Real> val_on_quad(nb_quadrature_points, dim, "val_on_quad");
Array<Real>::vector_iterator val_it = val_on_quad.begin(dim);
Vector<Real> values(dim);
values(0) = 1.;
values(1) = 2;
- for (UInt i = 0; i < val_on_quad.getSize(); ++i, ++val_it)
+ for (UInt i = 0; i < val_on_quad.getSize(); ++i, ++val_it)
*val_it = values;
- //integrate function on elements
- akantu::Array<akantu::Real> int_val_on_elem(nb_element, dim, "int_val_on_elem");
+ // integrate function on elements
+ akantu::Array<akantu::Real> int_val_on_elem(nb_element, dim,
+ "int_val_on_elem");
fem->integrate(val_on_quad, int_val_on_elem, dim, type);
// get global integration value
- Real value[2] = {0,0};
+ Real value[2] = {0, 0};
std::cout << "Val on quads : " << val_on_quad << std::endl;
std::cout << "Integral on elements : " << int_val_on_elem << std::endl;
for (UInt i = 0; i < fem->getMesh().getNbElement(type); ++i) {
- value[0] += int_val_on_elem.storage()[2*i];
- value[1] += int_val_on_elem.storage()[2*i+1];
+ value[0] += int_val_on_elem.storage()[2 * i];
+ value[1] += int_val_on_elem.storage()[2 * i + 1];
}
- std::cout << "integral on the mesh of 1 is " << value[0] << " and of 2 is " << value[1] << std::endl;
+ std::cout << "integral on the mesh of 1 is " << value[0] << " and of 2 is "
+ << value[1] << std::endl;
delete fem;
- if(!(std::abs(value[0] - 1.) < eps && std::abs(value[1] - 2.) < eps)) {
- std::cout << "|1 - " << value[0] << "| = " << std::abs(value[0] - 1.) << std::endl
- << "|2 - " << value[1] << "| = " << std::abs(value[1] - 2.) << std::endl;
+ if (!(std::abs(value[0] - 1.) < eps && std::abs(value[1] - 2.) < eps)) {
+ std::cout << "|1 - " << value[0] << "| = " << std::abs(value[0] - 1.)
+ << std::endl
+ << "|2 - " << value[1] << "| = " << std::abs(value[1] - 2.)
+ << std::endl;
correct_result = false;
}
return correct_result;
}
diff --git a/extra_packages/igfem/test/test_fe_engine/test_interpolate.cc b/extra_packages/igfem/test/test_fe_engine/test_interpolate.cc
index 4af5619ed..59f60c334 100644
--- a/extra_packages/igfem/test/test_fe_engine/test_interpolate.cc
+++ b/extra_packages/igfem/test/test_fe_engine/test_interpolate.cc
@@ -1,109 +1,114 @@
/**
* @file test_interpolate.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief test the interpolation function of the igfem elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "shape_igfem.hh"
-#include "integrator_gauss_igfem.hh"
#include "fe_engine.hh"
+#include "integrator_gauss_igfem.hh"
+#include "shape_igfem.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
void interpolate(const ElementType type);
-void generateIGFEMMesh(const ElementType type, Mesh & mesh, const std::string & filename);
+void generateIGFEMMesh(const ElementType type, Mesh & mesh,
+ const std::string & filename);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
debug::setDebugLevel(dblTest);
/// interpolate test of _igfem_triangle_4
AKANTU_DEBUG_INFO("integrating _igfem_triangle_4...");
interpolate(_igfem_triangle_4);
/// interpolate test of _igfem_triangle_5
AKANTU_DEBUG_INFO("integrating _igfem_triangle_5...");
interpolate(_igfem_triangle_5);
-
+
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void interpolate(const ElementType type) {
UInt dim = 2;
- std::stringstream mesh_info; mesh_info << "mesh_info" << type << ".txt";
+ std::stringstream mesh_info;
+ mesh_info << "mesh_info" << type << ".txt";
Mesh my_mesh(dim);
generateIGFEMMesh(type, my_mesh, mesh_info.str());
Real eps = 3e-13;
std::cout << "Epsilon : " << eps << std::endl;
- FEEngineTemplate<IntegratorGauss,ShapeLagrange, _ek_igfem> * fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange, _ek_igfem>(my_mesh, dim, "my_fem");
+ FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem> * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem>(
+ my_mesh, dim, "my_fem");
fem->initShapeFunctions();
Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
UInt nb_element = my_mesh.getNbElement(type);
UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
Array<Real> val_on_quad(nb_quadrature_points, 2, "val_on_quad");
/// the number of standard nodes in the mesh, i.e. not interface nodes
UInt nb_standard_nodes = 9;
/// impose constant value at standard nodes
for (UInt i = 0; i < nb_standard_nodes; ++i) {
const_val.storage()[i * 2 + 0] = 1.;
const_val.storage()[i * 2 + 1] = 2.;
}
/// for field to be constant the enriched values need to be zero,
/// because enrichment is not needed since there is no kink in the
/// applied field
for (UInt i = nb_standard_nodes; i < const_val.getSize(); ++i) {
const_val.storage()[i * 2 + 0] = 0.;
const_val.storage()[i * 2 + 1] = 0.;
}
fem->interpolateOnIntegrationPoints(const_val, val_on_quad, 2, type);
std::cout << "Interpolation of array : " << const_val << std::endl;
std::cout << "Gives on quads : " << val_on_quad << std::endl;
/// interpolate coordinates
- Array<Real> coord_on_quad(nb_quadrature_points, my_mesh.getSpatialDimension(), "coord_on_quad");
+ Array<Real> coord_on_quad(nb_quadrature_points, my_mesh.getSpatialDimension(),
+ "coord_on_quad");
/// create an array with the nodal coordinates that need to be
/// interpolated. The nodal coordinates of the enriched nodes need
/// to be set to zero, because they represent the enrichment of the
/// position field, and the enrichments for this field are all zero!
/// There is no gap in the mesh!
- Array<Real> igfem_nodes(my_mesh.getNbNodes(), dim);
+ Array<Real> igfem_nodes(my_mesh.getNbNodes(), dim);
const ShapeLagrange<_ek_igfem> & shapes = fem->getShapeFunctions();
- shapes.extractValuesAtStandardNodes(my_mesh.getNodes(), igfem_nodes, _not_ghost);
- fem->interpolateOnIntegrationPoints(igfem_nodes,
- coord_on_quad,
- my_mesh.getSpatialDimension(),
- type);
+ shapes.extractValuesAtStandardNodes(my_mesh.getNodes(), igfem_nodes,
+ _not_ghost);
+ fem->interpolateOnIntegrationPoints(igfem_nodes, coord_on_quad,
+ my_mesh.getSpatialDimension(), type);
- std::cout << "Interpolations of node coordinates : " << my_mesh.getNodes() << std::endl;
+ std::cout << "Interpolations of node coordinates : " << my_mesh.getNodes()
+ << std::endl;
std::cout << "Gives : " << coord_on_quad << std::endl;
delete fem;
}
diff --git a/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere.cc b/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere.cc
index 4d60a9344..b453be3d6 100644
--- a/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere.cc
+++ b/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere.cc
@@ -1,142 +1,148 @@
/**
* @file test_.cc
*
* @author Clement Roux-Langlois <clement.roux@epfl.ch>
*
* @date creation: Fri Mar 13 2015
* @date last modification: Tue june 16 2015
*
* @brief Tests the interface mesh generation
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh_sphere_intersector.hh"
#include "mesh_igfem_spherical_growing_gel.hh"
+#include "mesh_sphere_intersector.hh"
-#include "dumper_paraview.hh"
#include "dumpable_inline_impl.hh"
+#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef Spherical SK;
/* -------------------------------------------------------------------------- */
-int main (int argc, char * argv[]) {
+int main(int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblError);
Math::setTolerance(1e-12);
Mesh mesh_gel2(2, "mesh_gel2");
mesh_gel2.read("test_geometry_triangle.msh");
MeshIgfemSphericalGrowingGel<2> gel_intersector2(mesh_gel2);
gel_intersector2.init();
- SK::Sphere_3 sphere_gel2(SK::Point_3(1, 0, 0), 0.4999999999/4);
+ SK::Sphere_3 sphere_gel2(SK::Point_3(1, 0, 0), 0.4999999999 / 4);
std::list<SK::Sphere_3> sphere_list_gel2;
sphere_list_gel2.push_back(sphere_gel2);
DumperParaview dumper_gel2_igfem("mesh_gel2_igfem");
dumper_gel2_igfem.registerMesh(mesh_gel2, 2, _not_ghost, _ek_igfem);
DumperParaview dumper_gel2_regular("mesh_gel2_regular");
dumper_gel2_regular.registerMesh(mesh_gel2, 2, _not_ghost, _ek_regular);
dumper_gel2_regular.dump();
gel_intersector2.buildIGFEMMeshFromSpheres(sphere_list_gel2);
- //gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2);
- //gel_intersector2.buildIgfemMesh();
+ // gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2);
+ // gel_intersector2.buildIgfemMesh();
dumper_gel2_igfem.dump();
dumper_gel2_regular.dump();
UInt nb_tri3_gel2 = mesh_gel2.getConnectivity(_triangle_3).getSize();
UInt nb_tri4_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_4).getSize();
UInt nb_tri5_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_5).getSize();
- if ( (nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 1)){
- std::cout << "interm. mesh_gel with " << nb_tri3_gel2 << " _triangle_3, and " << nb_tri4_gel2
- << " _igfem_triangle_4, and " << nb_tri5_gel2 << " _igfem_triangle_5"<< std::endl;
+ if ((nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 1)) {
+ std::cout << "interm. mesh_gel with " << nb_tri3_gel2
+ << " _triangle_3, and " << nb_tri4_gel2
+ << " _igfem_triangle_4, and " << nb_tri5_gel2
+ << " _igfem_triangle_5" << std::endl;
return EXIT_FAILURE;
}
gel_intersector2.buildIGFEMMeshFromSpheres(sphere_list_gel2, 1.5);
- //gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2, 1.5);
- //gel_intersector2.buildIgfemMesh();
+ // gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2,
+ // 1.5);
+ // gel_intersector2.buildIgfemMesh();
dumper_gel2_igfem.dump();
dumper_gel2_regular.dump();
nb_tri3_gel2 = mesh_gel2.getConnectivity(_triangle_3).getSize();
nb_tri4_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_4).getSize();
nb_tri5_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_5).getSize();
- if ( (nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 1)){
- std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and " << nb_tri4_gel2
- << " _igfem_triangle_4, and " << nb_tri5_gel2 << " _igfem_triangle_5"<< std::endl;
+ if ((nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 1)) {
+ std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and "
+ << nb_tri4_gel2 << " _igfem_triangle_4, and " << nb_tri5_gel2
+ << " _igfem_triangle_5" << std::endl;
return EXIT_FAILURE;
- }
+ }
gel_intersector2.buildIGFEMMeshFromSpheres(sphere_list_gel2, 2);
- //gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2, 2);
- //gel_intersector2.buildIgfemMesh();
+ // gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2,
+ // 2);
+ // gel_intersector2.buildIgfemMesh();
dumper_gel2_igfem.dump();
dumper_gel2_regular.dump();
nb_tri3_gel2 = mesh_gel2.getConnectivity(_triangle_3).getSize();
nb_tri4_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_4).getSize();
nb_tri5_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_5).getSize();
- if ( (nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 1) || (nb_tri5_gel2 != 0)){
- std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and " << nb_tri4_gel2
- << " _igfem_triangle_4, and " << nb_tri5_gel2 << " _igfem_triangle_5"<< std::endl;
+ if ((nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 1) || (nb_tri5_gel2 != 0)) {
+ std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and "
+ << nb_tri4_gel2 << " _igfem_triangle_4, and " << nb_tri5_gel2
+ << " _igfem_triangle_5" << std::endl;
return EXIT_FAILURE;
- }
+ }
- gel_intersector2.buildIGFEMMeshFromSpheres(sphere_list_gel2,2.1);
- //gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2,2.1);
- //gel_intersector2.buildIgfemMesh();
+ gel_intersector2.buildIGFEMMeshFromSpheres(sphere_list_gel2, 2.1);
+ // gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel2,2.1);
+ // gel_intersector2.buildIgfemMesh();
dumper_gel2_igfem.dump();
dumper_gel2_regular.dump();
nb_tri3_gel2 = mesh_gel2.getConnectivity(_triangle_3).getSize();
nb_tri4_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_4).getSize();
nb_tri5_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_5).getSize();
- if ( (nb_tri3_gel2 != 0) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 2)){
- std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and " << nb_tri4_gel2
- << " _igfem_triangle_4, and " << nb_tri5_gel2 << " _igfem_triangle_5"<< std::endl;
+ if ((nb_tri3_gel2 != 0) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 2)) {
+ std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and "
+ << nb_tri4_gel2 << " _igfem_triangle_4, and " << nb_tri5_gel2
+ << " _igfem_triangle_5" << std::endl;
return EXIT_FAILURE;
- }
-
- gel_intersector2.buildIGFEMMeshFromSpheres(sphere_list_gel2,3.5);
- //gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel,3.5);
- //gel_intersector2.buildIgfemMesh();
+ }
+
+ gel_intersector2.buildIGFEMMeshFromSpheres(sphere_list_gel2, 3.5);
+ // gel_intersector2.computeMeshQueryListIntersectionPoint(sphere_list_gel,3.5);
+ // gel_intersector2.buildIgfemMesh();
dumper_gel2_igfem.dump();
dumper_gel2_regular.dump();
nb_tri3_gel2 = mesh_gel2.getConnectivity(_triangle_3).getSize();
nb_tri4_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_4).getSize();
nb_tri5_gel2 = mesh_gel2.getConnectivity(_igfem_triangle_5).getSize();
- if ( (nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 1)){
- std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and " << nb_tri4_gel2
- << " _igfem_triangle_4, and " << nb_tri5_gel2 << " _igfem_triangle_5"<< std::endl;
+ if ((nb_tri3_gel2 != 1) || (nb_tri4_gel2 != 0) || (nb_tri5_gel2 != 1)) {
+ std::cout << "final mesh with " << nb_tri3_gel2 << " _triangle_3, and "
+ << nb_tri4_gel2 << " _igfem_triangle_4, and " << nb_tri5_gel2
+ << " _igfem_triangle_5" << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
-
-
diff --git a/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere_static.cc b/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere_static.cc
index b75b6ff72..991eaec58 100644
--- a/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere_static.cc
+++ b/extra_packages/igfem/test/test_geometry/test_generation_igfem_mesh_from_sphere_static.cc
@@ -1,93 +1,95 @@
/**
* @file test_.cc
*
* @author Clement Roux-Langlois <clement.roux@epfl.ch>
*
* @date creation: Fri Mar 13 2015
* @date last modification: Tue june 16 2015
*
* @brief Tests the IGFEM mesh generation for multiple spheres
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh_sphere_intersector.hh"
#include "mesh_igfem_spherical_growing_gel.hh"
+#include "mesh_sphere_intersector.hh"
#include "dumper_paraview.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef Spherical SK;
/* -------------------------------------------------------------------------- */
-int main (int argc, char * argv[]) {
+int main(int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblError);
Math::setTolerance(1e-10);
Mesh mesh(2);
mesh.read("test_geometry_triangle.msh");
// mesh.read("inclusion_2D_fineness_level_1.msh");
// mesh.read("mesh.msh");
// Spherical kernel testing the addition of nodes
- // SK::Sphere_3 sphere(SK::Point_3(0, 1, 0), 0.401*0.401); //"inclusion_2D_fineness_level_1.msh"
+ // SK::Sphere_3 sphere(SK::Point_3(0, 1, 0), 0.401*0.401);
+ // //"inclusion_2D_fineness_level_1.msh"
// SK::Sphere_3 sphere(SK::Point_3(0, 0, 0), 0.3*0.3); //"mesh.msh"
- SK::Sphere_3 sphere(SK::Point_3(0, 1, 0), 0.2*0.2); //"test_geometry_triangle.msh"
- SK::Sphere_3 sphere2(SK::Point_3(1, 0, 0), 0.4999999999); //"test_geometry_triangle.msh"
+ SK::Sphere_3 sphere(SK::Point_3(0, 1, 0),
+ 0.2 * 0.2); //"test_geometry_triangle.msh"
+ SK::Sphere_3 sphere2(SK::Point_3(1, 0, 0),
+ 0.4999999999); //"test_geometry_triangle.msh"
MeshIgfemSphericalGrowingGel<2> sphere_intersector(mesh);
sphere_intersector.init();
std::list<SK::Sphere_3> sphere_list;
sphere_list.push_back(sphere);
sphere_list.push_back(sphere2);
DumperParaview dumper_igfem("mesh_igfem");
dumper_igfem.registerMesh(mesh, 2, _not_ghost, _ek_igfem);
DumperParaview dumper_regular("mesh_regular");
dumper_regular.registerMesh(mesh, 2, _not_ghost, _ek_regular);
- //dumper_igfem.dump();
+ // dumper_igfem.dump();
dumper_regular.dump();
sphere_intersector.buildIGFEMMeshFromSpheres(sphere_list);
dumper_igfem.dump();
dumper_regular.dump();
-
+
UInt nb_tri3 = mesh.getConnectivity(_triangle_3).getSize();
UInt nb_tri4 = mesh.getConnectivity(_igfem_triangle_4).getSize();
UInt nb_tri5 = mesh.getConnectivity(_igfem_triangle_5).getSize();
- if ( (nb_tri3 != 0) || (nb_tri4 != 1) || (nb_tri5 != 1)){
- std::cout << "final mesh with " << nb_tri3 << " _triangle_3, and " << nb_tri4
- << " _igfem_triangle_4, and " << nb_tri5 << " _igfem_triangle_5"<< std::endl;
+ if ((nb_tri3 != 0) || (nb_tri4 != 1) || (nb_tri5 != 1)) {
+ std::cout << "final mesh with " << nb_tri3 << " _triangle_3, and "
+ << nb_tri4 << " _igfem_triangle_4, and " << nb_tri5
+ << " _igfem_triangle_5" << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
-
-
diff --git a/extra_packages/igfem/test/test_geometry/test_spherical_kernel.cc b/extra_packages/igfem/test/test_geometry/test_spherical_kernel.cc
index de25ac69b..009411bf3 100644
--- a/extra_packages/igfem/test/test_geometry/test_spherical_kernel.cc
+++ b/extra_packages/igfem/test/test_geometry/test_spherical_kernel.cc
@@ -1,86 +1,86 @@
/**
* @file test_.cc
*
* @author Clement Roux-Langlois <clement.roux@epfl.ch>
*
* @date creation: Fri Mar 13 2015
* @date last modification: Tue june 16 2015
*
* @brief Tests the interface mesh generation
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <CGAL/MP_Float.h>
-#include <CGAL/Lazy_exact_nt.h>
-#include <CGAL/Quotient.h>
+#include <CGAL/Lazy_exact_nt.h>
+#include <CGAL/MP_Float.h>
+#include <CGAL/Quotient.h>
+#include <CGAL/Algebraic_kernel_for_spheres_2_3.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Spherical_kernel_3.h>
-#include <CGAL/Algebraic_kernel_for_spheres_2_3.h>
-
+
/* -------------------------------------------------------------------------- */
int main() {
- //typedef CGAL::Lazy_exact_nt<CGAL::Quotient<CGAL::MP_Float> > NT;
+ // typedef CGAL::Lazy_exact_nt<CGAL::Quotient<CGAL::MP_Float> > NT;
typedef CGAL::Quotient<CGAL::MP_Float> NT;
// typedef double NT;
- typedef CGAL::Spherical_kernel_3<CGAL::Simple_cartesian<NT>, CGAL::Algebraic_kernel_for_spheres_2_3<NT> > Spherical;
+ typedef CGAL::Spherical_kernel_3<CGAL::Simple_cartesian<NT>,
+ CGAL::Algebraic_kernel_for_spheres_2_3<NT>>
+ Spherical;
- //CGAL::Point_3<Spherical> b(0.3070532930016993, 0.3958272423848058, 0.),
+ // CGAL::Point_3<Spherical> b(0.3070532930016993, 0.3958272423848058, 0.),
// c(0.480062080085834, -0.1988482243531368, 0.);
- double xb=0.3, yb=0.4, zb=0., xc=0.5, yc=-0.2, zc=0.;
- CGAL::Point_3<Spherical> b(xb, yb, zb),
- c(xc, yc, zc);
+ double xb = 0.3, yb = 0.4, zb = 0., xc = 0.5, yc = -0.2, zc = 0.;
+ CGAL::Point_3<Spherical> b(xb, yb, zb), c(xc, yc, zc);
CGAL::Line_3<Spherical> l2(b, c);
CGAL::Line_arc_3<Spherical> s2(l2, b, c);
- Spherical::Sphere_3 sphere(Spherical::Point_3(0.4, 0, 0), 0.3*0.3);
+ Spherical::Sphere_3 sphere(Spherical::Point_3(0.4, 0, 0), 0.3 * 0.3);
typedef std::pair<Spherical::Circular_arc_point_3, int> pair_type;
typedef boost::variant<pair_type> sk_inter_res;
std::list<sk_inter_res> s_results;
CGAL::intersection(s2, sphere, std::back_inserter(s_results));
- if(s_results.size()==1){ // just one point
- if (pair_type * pair = boost::get<pair_type>(&s_results.front())){
- if(pair->second==1){ // not a point tangent to the sphere
- Spherical::Circular_arc_point_3 arc_point = pair->first;
- std::cout << " x = " << arc_point.x() << ", y = " << arc_point.y() << std::endl ;
- double xint, yint;
+ if (s_results.size() == 1) { // just one point
+ if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
+ if (pair->second == 1) { // not a point tangent to the sphere
+ Spherical::Circular_arc_point_3 arc_point = pair->first;
+ std::cout << " x = " << arc_point.x() << ", y = " << arc_point.y()
+ << std::endl;
+ double xint, yint;
xint = to_double(arc_point.x());
- yint = to_double(arc_point.y());
- std::cout << "x = " << xint << ", y = " << yint << std::endl ;
+ yint = to_double(arc_point.y());
+ std::cout << "x = " << xint << ", y = " << yint << std::endl;
}
}
}
return EXIT_SUCCESS;
-
}
-
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_ASR_damage.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_ASR_damage.cc
index 03aad7942..edc2b2aa4 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_ASR_damage.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_ASR_damage.cc
@@ -1,205 +1,210 @@
/**
* @file test_ASR_damage.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief test the solidmechancis model for IGFEM analysis
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "aka_common.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
#include "material_damage_iterative.hh"
#include "material_igfem_saw_tooth_damage.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/// function declaration
void applyBoundaryConditions(SolidMechanicsModelIGFEM & model);
-class ASRMaterialSelector : public MaterialSelector {
+class ASRMaterialSelector : public MaterialSelector {
public:
- ASRMaterialSelector(SolidMechanicsModelIGFEM & model) :
- model(model) { }
+ ASRMaterialSelector(SolidMechanicsModelIGFEM & model) : model(model) {}
UInt operator()(const Element & elem) {
- if(Mesh::getKind(elem.type) == _ek_igfem)
+ if (Mesh::getKind(elem.type) == _ek_igfem)
/// choose IGFEM material
return 2;
-
+
const Mesh & mesh = model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
Vector<Real> barycenter(spatial_dimension);
mesh.getBarycenter(elem, barycenter);
- if(model.isInside(barycenter))
+ if (model.isInside(barycenter))
return 1;
return 0;
- }
+ }
protected:
SolidMechanicsModelIGFEM & model;
};
typedef Spherical SK;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material_ASR.dat", argc, argv);
/// problem dimension
- const UInt spatial_dimension = 2;
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ const UInt spatial_dimension = 2;
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// mesh creation
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("one_inclusion.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
-
+
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
- /// register the gel pocket list in the model
+ /// register the gel pocket list in the model
std::list<SK::Sphere_3> gel_pocket_list;
model.registerGeometryObject(gel_pocket_list, "gel");
ASRMaterialSelector * mat_selector;
mat_selector = new ASRMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
model.initFull();
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.addDumpField("material_index");
model.addDumpField("damage");
model.addDumpField("Sc");
model.addDumpField("partitions");
model.addDumpField("eigen_grad_u");
model.addDumpField("blocked_dofs");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "damage");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldToDumper("igfem elements", "eigen_grad_u");
model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
/// dump before the interface generation
model.dump();
model.dump("igfem elements");
/// weaken one element to enforce damage there
- Array<Real> & Sc = model.getMaterial(0).getInternal<Real>("Sc")(_triangle_3, _not_ghost);
+ Array<Real> & Sc =
+ model.getMaterial(0).getInternal<Real>("Sc")(_triangle_3, _not_ghost);
Sc(11) = 1;
/// create the gel pocket
Real initial_gel_radius = 0.1;
- SK::Sphere_3 sphere_1(SK::Point_3(0., 0., 0.), initial_gel_radius * initial_gel_radius);
+ SK::Sphere_3 sphere_1(SK::Point_3(0., 0., 0.),
+ initial_gel_radius * initial_gel_radius);
gel_pocket_list.push_back(sphere_1);
/// create the interface
model.update("gel");
/// apply eigenstrain the eigenstrain in the inclusions
Matrix<Real> prestrain(spatial_dimension, spatial_dimension, 0.);
for (UInt i = 0; i < spatial_dimension; ++i)
- prestrain(i,i) = 0.05;
-
+ prestrain(i, i) = 0.05;
+
model.applyEigenGradU(prestrain, "gel", _not_ghost);
applyBoundaryConditions(model);
/// dump
model.dump("igfem elements");
- model.dump();
+ model.dump();
/// Instantiate objects of class MyDamageso
- MaterialDamageIterative<spatial_dimension> & mat_aggregate = dynamic_cast<MaterialDamageIterative<spatial_dimension> & >(model.getMaterial(0));
- MaterialIGFEMSawToothDamage<spatial_dimension> & mat_igfem = dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> & >(model.getMaterial(2));
-
+ MaterialDamageIterative<spatial_dimension> & mat_aggregate =
+ dynamic_cast<MaterialDamageIterative<spatial_dimension> &>(
+ model.getMaterial(0));
+ MaterialIGFEMSawToothDamage<spatial_dimension> & mat_igfem =
+ dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> &>(
+ model.getMaterial(2));
bool factorize = false;
bool converged = false;
- Real error;
+ Real error;
UInt nb_damaged_elements = 0;
Real max_eq_stress_aggregate = 0;
Real max_igfem = 0;
- const Array<Real> & stress = model.getMaterial(2).getStress(_igfem_triangle_5, _not_ghost);
- Array<Real>::const_matrix_iterator stress_it = stress.begin(spatial_dimension, spatial_dimension);
+ const Array<Real> & stress =
+ model.getMaterial(2).getStress(_igfem_triangle_5, _not_ghost);
+ Array<Real>::const_matrix_iterator stress_it =
+ stress.begin(spatial_dimension, spatial_dimension);
do {
- converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-6, error, 2, factorize);
+ converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(
+ 1e-6, error, 2, factorize);
- /// compute damage
+ /// compute damage
max_eq_stress_aggregate = mat_aggregate.getNormMaxEquivalentStress();
max_igfem = mat_igfem.getNormMaxEquivalentStress();
if (max_eq_stress_aggregate > max_igfem)
nb_damaged_elements = mat_aggregate.updateDamage();
else
nb_damaged_elements = mat_igfem.updateDamage();
std::cout << "damaged elements: " << nb_damaged_elements << std::endl;
for (UInt i = 0; i < 5; ++i) {
std::cout << *stress_it << std::endl;
++stress_it;
- }
+ }
model.dump();
model.dump("igfem elements");
} while (nb_damaged_elements);
-
model.dump();
model.dump("igfem elements");
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void applyBoundaryConditions(SolidMechanicsModelIGFEM & model) {
/// boundary conditions
Mesh & mesh = model.getMesh();
mesh.computeBoundingBox();
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
- Real bottom = lowerBounds(1);
+ Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real left = lowerBounds(0);
// Real right = upperBounds(0);
Real eps = std::abs((top - bottom) * 1e-12);
const Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
disp.clear();
boun.clear();
/// free expansion
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
-
- if(std::abs(pos(i,1) - bottom) < eps){
- boun(i,1) = true;
- disp(i,1) = 0.0;
- }
- if(std::abs(pos(i,0) - left) < eps){
- boun(i,0) = true;
- disp(i,0) = 0.0;
+ if (std::abs(pos(i, 1) - bottom) < eps) {
+ boun(i, 1) = true;
+ disp(i, 1) = 0.0;
}
+ if (std::abs(pos(i, 0) - left) < eps) {
+ boun(i, 0) = true;
+ disp(i, 0) = 0.0;
+ }
}
}
-
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_eigenstrain.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_eigenstrain.cc
index 6b06e2cf7..d177795e3 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_eigenstrain.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_eigenstrain.cc
@@ -1,179 +1,184 @@
/**
* @file test_eigenstrain.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief test to that eigenstrain is only applied on one sub-material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "aka_common.hh"
#include "dumper_paraview.hh"
-#include "mesh_geom_common.hh"
#include "material_igfem.hh"
+#include "mesh_geom_common.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-class ASRMaterialSelector : public DefaultMaterialIGFEMSelector {
+class ASRMaterialSelector : public DefaultMaterialIGFEMSelector {
public:
- ASRMaterialSelector(SolidMechanicsModelIGFEM & model) :
- DefaultMaterialIGFEMSelector(model),
- model(model) {}
+ ASRMaterialSelector(SolidMechanicsModelIGFEM & model)
+ : DefaultMaterialIGFEMSelector(model), model(model) {}
UInt operator()(const Element & elem) {
- if(Mesh::getKind(elem.type) == _ek_igfem)
+ if (Mesh::getKind(elem.type) == _ek_igfem)
/// choose IGFEM material
return this->fallback_value_igfem;
const Mesh & mesh = model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
Vector<Real> barycenter(spatial_dimension);
mesh.getBarycenter(elem, barycenter);
- if(model.isInside(barycenter))
+ if (model.isInside(barycenter))
return 1;
return 0;
}
protected:
SolidMechanicsModelIGFEM & model;
};
-
typedef Spherical SK;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material_damage.dat", argc, argv);
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// problem dimension
- UInt spatial_dimension = 2;
+ UInt spatial_dimension = 2;
/// mesh creation and partioning
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("fine_mesh.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation and initialization
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
-
+
/// create the list to store the gel pockets
std::list<SK::Sphere_3> gel_pocket_list;
model.registerGeometryObject(gel_pocket_list, "mat_1");
/// set the material selector
ASRMaterialSelector * mat_selector = new ASRMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
model.initFull();
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.addDumpField("material_index");
model.addDumpField("damage");
model.addDumpField("Sc");
model.addDumpField("partitions");
model.addDumpField("eigen_grad_u");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldToDumper("igfem elements", "partitions");
model.addDumpFieldToDumper("igfem elements", "eigen_grad_u");
-
+
/// dump
model.dump("igfem elements");
model.dump();
/// create the inclusions
SK::Sphere_3 sphere_1(SK::Point_3(0., 0., 0.), 0.13 * 0.13);
SK::Sphere_3 sphere_2(SK::Point_3(0.5, 0.5, 0.), 0.4 * 0.4);
SK::Sphere_3 sphere_3(SK::Point_3(-0.75, -0.75, 0.), 0.12 * 0.12);
SK::Sphere_3 sphere_4(SK::Point_3(0.625, -0.625, 0.), 0.25 * 0.25);
gel_pocket_list.push_back(sphere_1);
gel_pocket_list.push_back(sphere_2);
gel_pocket_list.push_back(sphere_3);
gel_pocket_list.push_back(sphere_4);
/// create the interface
model.update("mat_1");
- if(mesh.getNbElement(_igfem_triangle_4, _not_ghost)) {
+ if (mesh.getNbElement(_igfem_triangle_4, _not_ghost)) {
/// something went wrong in the interface creation
finalize();
return EXIT_FAILURE;
}
/// apply eigenstrain the eigenstrain in the inclusions
Matrix<Real> prestrain(spatial_dimension, spatial_dimension, 0.);
for (UInt i = 0; i < spatial_dimension; ++i)
- prestrain(i,i) = 0.07;
-
+ prestrain(i, i) = 0.07;
+
model.applyEigenGradU(prestrain, "mat_1", _not_ghost);
/// check that eigenstrain has been applied correctly
/// check first the regular materials (the first two in the mat file)
Real error = 0;
Material & mat_1 = model.getMaterial(0);
- const Array<Real> & eigen_grad_u_1 = mat_1.getArray<Real>("eigen_grad_u", _triangle_3, _not_ghost);
- Array<Real>::const_matrix_iterator eigen_it = eigen_grad_u_1.begin(spatial_dimension, spatial_dimension);
- Array<Real>::const_matrix_iterator eigen_end = eigen_grad_u_1.end(spatial_dimension, spatial_dimension);
- for (; eigen_it!= eigen_end; ++eigen_it) {
+ const Array<Real> & eigen_grad_u_1 =
+ mat_1.getArray<Real>("eigen_grad_u", _triangle_3, _not_ghost);
+ Array<Real>::const_matrix_iterator eigen_it =
+ eigen_grad_u_1.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::const_matrix_iterator eigen_end =
+ eigen_grad_u_1.end(spatial_dimension, spatial_dimension);
+ for (; eigen_it != eigen_end; ++eigen_it) {
const Matrix<Real> & eigen_grad_u = *eigen_it;
error += eigen_grad_u.norm<L_2>();
}
Material & mat_2 = model.getMaterial(1);
- const Array<Real> & eigen_grad_u_2 = mat_2.getArray<Real>("eigen_grad_u", _triangle_3, _not_ghost);
+ const Array<Real> & eigen_grad_u_2 =
+ mat_2.getArray<Real>("eigen_grad_u", _triangle_3, _not_ghost);
eigen_it = eigen_grad_u_2.begin(spatial_dimension, spatial_dimension);
eigen_end = eigen_grad_u_2.end(spatial_dimension, spatial_dimension);
- for (; eigen_it!= eigen_end; ++eigen_it) {
+ for (; eigen_it != eigen_end; ++eigen_it) {
const Matrix<Real> & eigen_grad_u = *eigen_it;
Matrix<Real> diff = (prestrain - eigen_grad_u);
error += diff.norm<L_2>();
}
- MaterialIGFEM & mat_3 = dynamic_cast<MaterialIGFEM & >(model.getMaterial(2));
- const Array<Real> & eigen_grad_u_3 = mat_3.getArray<Real>("eigen_grad_u", _igfem_triangle_5, _not_ghost);
- UInt * sub_mat_ptr = mat_3.getArray<UInt>("sub_material",_igfem_triangle_5, _not_ghost).storage();
+ MaterialIGFEM & mat_3 = dynamic_cast<MaterialIGFEM &>(model.getMaterial(2));
+ const Array<Real> & eigen_grad_u_3 =
+ mat_3.getArray<Real>("eigen_grad_u", _igfem_triangle_5, _not_ghost);
+ UInt * sub_mat_ptr =
+ mat_3.getArray<UInt>("sub_material", _igfem_triangle_5, _not_ghost)
+ .storage();
eigen_it = eigen_grad_u_3.begin(spatial_dimension, spatial_dimension);
eigen_end = eigen_grad_u_3.end(spatial_dimension, spatial_dimension);
- for (; eigen_it!= eigen_end; ++eigen_it, ++sub_mat_ptr) {
+ for (; eigen_it != eigen_end; ++eigen_it, ++sub_mat_ptr) {
const Matrix<Real> & eigen_grad_u = *eigen_it;
- if(!(*sub_mat_ptr)) {
- Matrix<Real> diff = (prestrain - eigen_grad_u);
- error += diff.norm<L_2>();
- }
- else
+ if (!(*sub_mat_ptr)) {
+ Matrix<Real> diff = (prestrain - eigen_grad_u);
+ error += diff.norm<L_2>();
+ } else
error += eigen_grad_u.norm<L_2>();
}
std::cout << "The error in the prestrain is: " << error << std::endl;
- if(std::abs(error) > Math::getTolerance()) {
+ if (std::abs(error) > Math::getTolerance()) {
std::cout << "The test failed!!!" << std::endl;
finalize();
return EXIT_FAILURE;
- }
+ }
/// dump
model.dump("igfem elements");
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_igfem_element_orientation.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_igfem_element_orientation.cc
index fcf8a9ff1..26153c835 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_igfem_element_orientation.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_igfem_element_orientation.cc
@@ -1,141 +1,148 @@
/**
* @file test_interface_position.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief patch test for interface close to standard nodes
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "material_elastic.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// create a mesh and read the regular elements from the mesh file
/// mesh creation
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("test_igfem_element_orientation.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
-
+
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
model.initFull();
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpField("material_index");
model.addDumpField("partitions");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "partitions");
/// dump mesh before the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// create the interace:
std::list<SK::Sphere_3> sphere_list;
- Real radius = std::sqrt(0.2 * 0.2 + 0.2 * 0.2);
+ Real radius = std::sqrt(0.2 * 0.2 + 0.2 * 0.2);
Real tol = std::sqrt(2.) * 1e-11;
radius += tol;
- SK::Sphere_3 sphere_1(SK::Point_3(-0.2, 0.3, 0.),
- radius * radius);
+ SK::Sphere_3 sphere_1(SK::Point_3(-0.2, 0.3, 0.), radius * radius);
sphere_list.push_back(sphere_1);
model.registerGeometryObject(sphere_list, "gel");
model.update();
/// check that the igfem elements have been created correctly
UInt nb_igfem_triangle_4 = mesh.getNbElement(_igfem_triangle_4, _not_ghost);
UInt nb_igfem_triangle_5 = mesh.getNbElement(_igfem_triangle_5, _not_ghost);
comm.allReduce(&nb_igfem_triangle_4, 1, _so_sum);
comm.allReduce(&nb_igfem_triangle_5, 1, _so_sum);
if (prank == 0) {
- if ( (nb_igfem_triangle_4 != 2) || (nb_igfem_triangle_5 != 1)) {
- std::cout << "something went wrong in the interface creation" << std::endl;
+ if ((nb_igfem_triangle_4 != 2) || (nb_igfem_triangle_5 != 1)) {
+ std::cout << "something went wrong in the interface creation"
+ << std::endl;
finalize();
return EXIT_FAILURE;
}
}
-
+
/// check that the igfem nodes have been created correctly
UInt nb_global_nodes = 0;
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (mesh.isLocalOrMasterNode(n))
nb_global_nodes += 1;
}
comm.allReduce(&nb_global_nodes, 1, _so_sum);
if (prank == 0 && nb_global_nodes != 27) {
std::cout << "something went wrong in the interface creation" << std::endl;
finalize();
return EXIT_FAILURE;
}
/// in this test the sphere interface is positioned in a way that it
- /// genereates two IGFEM elements (of type _igfem_triangle_4), that are enriched for
+ /// genereates two IGFEM elements (of type _igfem_triangle_4), that are
+ /// enriched for
/// compatibilty with their neighboring elements but they don't
/// contain a material interface. Therefore, the same material has
- /// to be assigned to both sub-elements.
-
+ /// to be assigned to both sub-elements.
+
/// this is to check that both sub-elements have the same material
/// properties Note: This check works because all _igfem_triangle_4s
/// in the mesh do not contain a material interface
- MaterialElastic<spatial_dimension> & aggregate_mat = dynamic_cast<MaterialElastic<spatial_dimension> &> (model.getMaterial("aggregate"));
+ MaterialElastic<spatial_dimension> & aggregate_mat =
+ dynamic_cast<MaterialElastic<spatial_dimension> &>(
+ model.getMaterial("aggregate"));
Real lambda_1 = aggregate_mat.getLambda();
Real mu_1 = aggregate_mat.getMu();
ElementType type = _igfem_triangle_4;
GhostType ghost_type = _not_ghost;
UInt nb_element = mesh.getNbElement(type, ghost_type);
- UInt nb_quads = model.getFEEngine("IGFEMFEEngine").getNbIntegrationPoints(type);
- Real * lambda = model.getMaterial("igfem_elastic").getArray<Real>("lambda", type, ghost_type).storage();
- Real * mu = model.getMaterial("igfem_elastic").getArray<Real>("mu", type, ghost_type).storage();
+ UInt nb_quads =
+ model.getFEEngine("IGFEMFEEngine").getNbIntegrationPoints(type);
+ Real * lambda = model.getMaterial("igfem_elastic")
+ .getArray<Real>("lambda", type, ghost_type)
+ .storage();
+ Real * mu = model.getMaterial("igfem_elastic")
+ .getArray<Real>("mu", type, ghost_type)
+ .storage();
Real error = 0;
- for(UInt e = 0; e < nb_element; ++e) {
+ for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quads; ++q, ++lambda, ++mu) {
error += std::abs(lambda_1 - *lambda);
error += std::abs(mu_1 - *mu);
}
}
comm.allReduce(&error, 1, _so_sum);
if (prank == 0) {
std::cout << "The error is: " << error << std::endl;
if (error > 1e-14) {
std::cout << "The test failed!!!!" << std::endl;
finalize();
return EXIT_FAILURE;
- }
+ }
}
/// dump mesh after the IGFEM interface is created
model.dump();
model.dump("igfem elements");
finalize();
return EXIT_SUCCESS;
}
-
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc
index a9cc81841..c19fc760b 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc
@@ -1,385 +1,412 @@
/**
* @file test_material_igfem_iterative_strength_reduction.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 26 12:20:15 2015
*
* @brief test the material iterative stiffness reduction
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "material_damage_iterative.hh"
#include "material_igfem_saw_tooth_damage.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/// function declaration
-bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model, bool igfem_analysis);
+bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model,
+ bool igfem_analysis);
-class TestMaterialSelector : public MaterialSelector {
+class TestMaterialSelector : public MaterialSelector {
public:
- TestMaterialSelector(SolidMechanicsModelIGFEM & model) :
- MaterialSelector(),
- model(model),
- spatial_dimension(model.getSpatialDimension()){}
+ TestMaterialSelector(SolidMechanicsModelIGFEM & model)
+ : MaterialSelector(), model(model),
+ spatial_dimension(model.getSpatialDimension()) {}
UInt operator()(const Element & element) {
- if(Mesh::getKind(element.type) == _ek_igfem)
+ if (Mesh::getKind(element.type) == _ek_igfem)
return 2;
else {
/// regular elements
const Mesh & mesh = model.getMesh();
Vector<Real> barycenter(this->spatial_dimension);
mesh.getBarycenter(element, barycenter);
/// check if element belongs to ASR gel
- if(model.isInside(barycenter))
- return 1;
+ if (model.isInside(barycenter))
+ return 1;
}
return 0;
}
protected:
SolidMechanicsModelIGFEM & model;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
Math::setTolerance(1e-13);
debug::setDebugLevel(dblWarning);
- initialize("material_stiffness_reduction.dat" ,argc, argv);
-
+ initialize("material_stiffness_reduction.dat", argc, argv);
bool igfem_analysis;
std::string action(argv[1]);
if (action == "igfem") {
igfem_analysis = true;
} else if (action == "standard_fem") {
igfem_analysis = false;
} else {
std::cerr << "invalid option" << std::endl;
}
-
-
const UInt spatial_dimension = 2;
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partion it
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
if (igfem_analysis)
mesh.read("igfem_mesh.msh");
else
mesh.read("regular_mesh.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
Math::setTolerance(1.e-14);
/// intialize the geometry and set the material selector
std::list<SK::Sphere_3> inclusions_list;
model.registerGeometryObject(inclusions_list, "inclusion");
Real val = 1000000000;
- Real radius_squared = val*val;
+ Real radius_squared = val * val;
Vector<Real> center(spatial_dimension);
center(0) = 0;
center(1) = val;
SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0.), radius_squared);
inclusions_list.push_back(sphere);
TestMaterialSelector * mat_selector = new TestMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
/// initialization of the model
model.initFull();
/// create the interface
if (igfem_analysis)
model.update("inclusion");
/// boundary conditions
mesh.computeBoundingBox();
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
- Real bottom = lowerBounds(1);
+ Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real left = lowerBounds(0);
Real eps = std::abs((top - bottom) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<bool> & boun = model.getBlockedDOFs();
Array<Real> & disp = model.getDisplacement();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (std::abs(pos(n,1) - bottom) < eps) {
- boun(n,1) = true;
- disp(n,1) = 0.;
+ if (std::abs(pos(n, 1) - bottom) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 0.;
+ }
+ if (std::abs(pos(n, 1) - top) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 1.e-3;
}
- if (std::abs(pos(n,1) - top) < eps) {
- boun(n,1) = true;
- disp(n,1) = 1.e-3;
+ if (std::abs(pos(n, 0) - left) < eps) {
+ boun(n, 0) = true;
+ disp(n, 0) = 0.;
}
- if (std::abs(pos(n,0) - left) < eps) {
- boun(n,0) = true;
- disp(n,0) = 0.;
- }
}
/// add fields that should be dumped
model.setBaseName("regular");
model.addDumpField("material_index");
- model.addDumpFieldVector("displacement");;
+ model.addDumpFieldVector("displacement");
+ ;
model.addDumpField("stress");
model.addDumpField("blocked_dofs");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("damage");
model.addDumpField("partitions");
model.addDumpField("Sc");
model.addDumpField("force");
model.addDumpField("equivalent_stress");
model.addDumpField("ultimate_strain");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
- model.addDumpFieldVectorToDumper("igfem elements", "displacement");;
+ model.addDumpFieldVectorToDumper("igfem elements", "displacement");
+ ;
model.addDumpFieldToDumper("igfem elements", "stress");
model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "residual");
model.addDumpFieldToDumper("igfem elements", "grad_u");
model.addDumpFieldToDumper("igfem elements", "damage");
model.addDumpFieldToDumper("igfem elements", "partitions");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "force");
model.addDumpFieldToDumper("igfem elements", "equivalent_stress");
model.addDumpFieldToDumper("igfem elements", "ultimate_strain");
model.dump();
model.dump("igfem elements");
-
+
/// get a reference to the damage materials
- MaterialDamageIterative<spatial_dimension> & material = dynamic_cast<MaterialDamageIterative<spatial_dimension> & >(model.getMaterial(0));
- MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material = dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> & >(model.getMaterial(2));
-
+ MaterialDamageIterative<spatial_dimension> & material =
+ dynamic_cast<MaterialDamageIterative<spatial_dimension> &>(
+ model.getMaterial(0));
+ MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material =
+ dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> &>(
+ model.getMaterial(2));
+
Real error;
bool converged = false;
UInt nb_damaged_elements = 0;
Real max_eq_stress_regular = 0;
Real max_eq_stress_igfem = 0;
/// solve the system
// counter for the damage steps
UInt s = 0;
do {
- converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, error, 2);
-
+ converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-12, error, 2);
+
if (converged == false) {
std::cout << "The error is: " << error << std::endl;
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
}
- /// compute damage
+ /// compute damage
max_eq_stress_regular = material.getNormMaxEquivalentStress();
max_eq_stress_igfem = igfem_material.getNormMaxEquivalentStress();
if (max_eq_stress_regular > max_eq_stress_igfem)
nb_damaged_elements = material.updateDamage();
else if (max_eq_stress_regular == max_eq_stress_igfem) {
nb_damaged_elements = material.updateDamage();
nb_damaged_elements += igfem_material.updateDamage();
- }
- else
+ } else
nb_damaged_elements = igfem_material.updateDamage();
- model.dump();
+ model.dump();
model.dump("igfem elements");
/// check the current damage state
if (!checkDamageState(s, model, igfem_analysis)) {
std::cout << "error in the damage compuation" << std::endl;
finalize();
return EXIT_FAILURE;
}
- s++;
+ s++;
} while (nb_damaged_elements);
std::cout << action << " passed!!" << std::endl;
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
-bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model, bool igfem_analysis) {
+bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model,
+ bool igfem_analysis) {
bool test_result = true;
const UInt spatial_dimension = model.getSpatialDimension();
const Mesh & mesh = model.getMesh();
if (!igfem_analysis) {
- const ElementType element_type = _triangle_3;
- /// prepare output: compute barycenters for elements that can be damaged
- const Array<UInt> & element_filter = model.getMaterial(0).getElementFilter(element_type, _not_ghost);
- Array<Real> barycenters(element_filter.getSize(), spatial_dimension);
- Array<Real>::vector_iterator bary_it = barycenters.begin(spatial_dimension);
- for (UInt e = 0; e < element_filter.getSize(); ++e, ++bary_it) {
- UInt global_el_idx = element_filter(e);
- mesh.getBarycenter(global_el_idx, element_type, bary_it->storage(), _not_ghost);
- }
+ const ElementType element_type = _triangle_3;
+ /// prepare output: compute barycenters for elements that can be damaged
+ const Array<UInt> & element_filter =
+ model.getMaterial(0).getElementFilter(element_type, _not_ghost);
+ Array<Real> barycenters(element_filter.getSize(), spatial_dimension);
+ Array<Real>::vector_iterator bary_it = barycenters.begin(spatial_dimension);
+ for (UInt e = 0; e < element_filter.getSize(); ++e, ++bary_it) {
+ UInt global_el_idx = element_filter(e);
+ mesh.getBarycenter(global_el_idx, element_type, bary_it->storage(),
+ _not_ghost);
+ }
- const Array<Real> & damage = model.getMaterial(0).getInternal<Real>("damage")(element_type, _not_ghost);
- const Array<Real> & Sc = model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
+ const Array<Real> & damage = model.getMaterial(0).getInternal<Real>(
+ "damage")(element_type, _not_ghost);
+ const Array<Real> & Sc =
+ model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
- std::ostringstream file_name;
- file_name << "step_" << std::setfill('0') << std::setw(3) << step << ".txt";
+ std::ostringstream file_name;
+ file_name << "step_" << std::setfill('0') << std::setw(3) << step << ".txt";
- std::ofstream file_output;
- file_output.open(file_name.str());
- file_output << std::setprecision(14);
+ std::ofstream file_output;
+ file_output.open(file_name.str());
+ file_output << std::setprecision(14);
- for(UInt e = 0; e < barycenters.getSize(); ++e)
- file_output << barycenters(e, 0) << " "
- << barycenters(e, 1) << " "
- << damage(e) << " "
- << Sc(e) << std::endl;
+ for (UInt e = 0; e < barycenters.getSize(); ++e)
+ file_output << barycenters(e, 0) << " " << barycenters(e, 1) << " "
+ << damage(e) << " " << Sc(e) << std::endl;
}
else {
- /// read data
+ /// read data
Real default_tolerance = Math::getTolerance();
Math::setTolerance(1.e-10);
std::stringstream results_file;
- results_file << "step_"
- << std::setfill('0') << std::setw(3)
- << step << ".txt";
+ results_file << "step_" << std::setfill('0') << std::setw(3) << step
+ << ".txt";
std::ifstream damage_input;
damage_input.open(results_file.str().c_str());
Array<Real> damage_result(0, 1);
Array<Real> Sc_result(0, 1);
Array<Real> bary_regular(0, spatial_dimension);
Vector<Real> bary(spatial_dimension);
Real dam = 0.;
Real strength = 0;
while (damage_input.good()) {
- damage_input >> bary(0) >> bary(1)
- >> dam >> strength;
+ damage_input >> bary(0) >> bary(1) >> dam >> strength;
bary_regular.push_back(bary);
damage_result.push_back(dam);
Sc_result.push_back(strength);
}
/// compare the results
Array<Real>::const_vector_iterator bary_it;
- Array<Real>::const_vector_iterator bary_begin = bary_regular.begin(spatial_dimension);
- Array<Real>::const_vector_iterator bary_end = bary_regular.end(spatial_dimension);
+ Array<Real>::const_vector_iterator bary_begin =
+ bary_regular.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator bary_end =
+ bary_regular.end(spatial_dimension);
/// compare the regular elements
ElementType element_type = _triangle_3;
- const Array<UInt> & element_filter = model.getMaterial(0).getElementFilter(element_type, _not_ghost);
- const Array<Real> & damage_regular_el = model.getMaterial(0).getInternal<Real>("damage")(element_type, _not_ghost);
- const Array<Real> & Sc_regular_el = model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
+ const Array<UInt> & element_filter =
+ model.getMaterial(0).getElementFilter(element_type, _not_ghost);
+ const Array<Real> & damage_regular_el =
+ model.getMaterial(0).getInternal<Real>("damage")(element_type,
+ _not_ghost);
+ const Array<Real> & Sc_regular_el =
+ model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
for (UInt e = 0; e < element_filter.getSize(); ++e) {
UInt global_el_idx = element_filter(e);
- mesh.getBarycenter(global_el_idx, element_type, bary.storage(), _not_ghost);
+ mesh.getBarycenter(global_el_idx, element_type, bary.storage(),
+ _not_ghost);
/// find element
for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
- UInt matched_dim = 0;
- while (matched_dim < spatial_dimension &&
- Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
- ++matched_dim;
- if (matched_dim == spatial_dimension) break;
+ UInt matched_dim = 0;
+ while (
+ matched_dim < spatial_dimension &&
+ Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
+ ++matched_dim;
+ if (matched_dim == spatial_dimension)
+ break;
}
if (bary_it == bary_end) {
- std::cout << "Element barycenter not found!" << std::endl;
- return false;
+ std::cout << "Element barycenter not found!" << std::endl;
+ return false;
}
UInt matched_el = bary_it - bary_begin;
-
- if (std::abs(damage_result(matched_el)-damage_regular_el(e)) > 1.e-12 ||
- std::abs(Sc_result(matched_el)-Sc_regular_el(e)) > 1.e-4) {
- test_result = false;
- break;
+
+ if (std::abs(damage_result(matched_el) - damage_regular_el(e)) > 1.e-12 ||
+ std::abs(Sc_result(matched_el) - Sc_regular_el(e)) > 1.e-4) {
+ test_result = false;
+ break;
}
}
/// compare the IGFEM elements
UInt nb_sub_elements = 2;
element_type = _igfem_triangle_4;
- const Array<UInt> & element_filter_igfem = model.getMaterial(2).getElementFilter(element_type, _not_ghost);
- const Array<Real> & damage_regular_el_igfem = model.getMaterial(2).getInternal<Real>("damage")(element_type, _not_ghost);
- const Array<Real> & Sc_regular_el_igfem = model.getMaterial(2).getInternal<Real>("Sc")(element_type, _not_ghost);
- UInt * sub_el_ptr = model.getMaterial(2).getInternal<UInt>("sub_material")(element_type, _not_ghost).storage();
-
+ const Array<UInt> & element_filter_igfem =
+ model.getMaterial(2).getElementFilter(element_type, _not_ghost);
+ const Array<Real> & damage_regular_el_igfem =
+ model.getMaterial(2).getInternal<Real>("damage")(element_type,
+ _not_ghost);
+ const Array<Real> & Sc_regular_el_igfem =
+ model.getMaterial(2).getInternal<Real>("Sc")(element_type, _not_ghost);
+ UInt * sub_el_ptr =
+ model.getMaterial(2)
+ .getInternal<UInt>("sub_material")(element_type, _not_ghost)
+ .storage();
+
for (UInt e = 0; e < element_filter_igfem.getSize(); ++e) {
UInt global_el_idx = element_filter_igfem(e);
for (UInt s = 0; s < nb_sub_elements; ++s, ++sub_el_ptr) {
- if (*sub_el_ptr)
- model.getSubElementBarycenter(global_el_idx, s, element_type, bary, _not_ghost);
- else
- continue;
- /// find element
- for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
- UInt matched_dim = 0;
- while (matched_dim < spatial_dimension &&
- Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
- ++matched_dim;
- if (matched_dim == spatial_dimension) break;
- }
- if (bary_it == bary_end) {
- std::cout << "Element barycenter not found!" << std::endl;
- return false;
- }
-
- UInt matched_el = bary_it - bary_begin;
-
- if (std::abs(damage_result(matched_el)-damage_regular_el_igfem(e*nb_sub_elements+s)) > 1.e-12 ||
- std::abs(Sc_result(matched_el)-Sc_regular_el_igfem(e*nb_sub_elements+s)) > 1.e-4) {
- test_result = false;
- break;
- }
+ if (*sub_el_ptr)
+ model.getSubElementBarycenter(global_el_idx, s, element_type, bary,
+ _not_ghost);
+ else
+ continue;
+ /// find element
+ for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
+ UInt matched_dim = 0;
+ while (
+ matched_dim < spatial_dimension &&
+ Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
+ ++matched_dim;
+ if (matched_dim == spatial_dimension)
+ break;
+ }
+ if (bary_it == bary_end) {
+ std::cout << "Element barycenter not found!" << std::endl;
+ return false;
+ }
+
+ UInt matched_el = bary_it - bary_begin;
+
+ if (std::abs(damage_result(matched_el) -
+ damage_regular_el_igfem(e * nb_sub_elements + s)) >
+ 1.e-12 ||
+ std::abs(Sc_result(matched_el) -
+ Sc_regular_el_igfem(e * nb_sub_elements + s)) > 1.e-4) {
+ test_result = false;
+ break;
+ }
}
}
Math::setTolerance(default_tolerance);
}
return test_result;
}
-
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_damage_step_transfer.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_damage_step_transfer.cc
index 6ebc58856..1a329a8fd 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_damage_step_transfer.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_damage_step_transfer.cc
@@ -1,350 +1,364 @@
/**
- * @file test_material_igfem_iterative_stiffness_reduction_damage_step_transfer.cc
+ * @file
+ * test_material_igfem_iterative_stiffness_reduction_damage_step_transfer.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 26 12:20:15 2015
*
* @brief test the damage step transfer for the material iterative
* stiffness reduction
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
-#include "material_iterative_stiffness_reduction.hh"
#include "material_igfem_saw_tooth_damage.hh"
+#include "material_iterative_stiffness_reduction.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-class TestMaterialSelector : public MaterialSelector {
+class TestMaterialSelector : public MaterialSelector {
public:
- TestMaterialSelector(SolidMechanicsModelIGFEM & model) :
- MaterialSelector(),
- model(model),
- spatial_dimension(model.getSpatialDimension()){}
+ TestMaterialSelector(SolidMechanicsModelIGFEM & model)
+ : MaterialSelector(), model(model),
+ spatial_dimension(model.getSpatialDimension()) {}
UInt operator()(const Element & element) {
- if(Mesh::getKind(element.type) == _ek_igfem)
+ if (Mesh::getKind(element.type) == _ek_igfem)
return 2;
else {
/// regular elements
const Mesh & mesh = model.getMesh();
Vector<Real> barycenter(this->spatial_dimension);
mesh.getBarycenter(element, barycenter);
/// check if element belongs to ASR gel
- if(model.isInside(barycenter))
- return 1;
+ if (model.isInside(barycenter))
+ return 1;
}
return 0;
}
protected:
SolidMechanicsModelIGFEM & model;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
Math::setTolerance(1e-13);
debug::setDebugLevel(dblWarning);
- initialize("material_stiffness_reduction_2.dat" ,argc, argv);
+ initialize("material_stiffness_reduction_2.dat", argc, argv);
const UInt spatial_dimension = 2;
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partion it
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("test_damage_transfer.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
Math::setTolerance(1.e-14);
/// intialize the geometry and set the material selector
std::list<SK::Sphere_3> inclusions_list;
model.registerGeometryObject(inclusions_list, "inclusion");
Real val = 1000000000;
- Real radius_squared = (val-0.6)*(val-0.6);
+ Real radius_squared = (val - 0.6) * (val - 0.6);
Vector<Real> center(spatial_dimension);
center(0) = 0;
center(1) = val;
SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0.), radius_squared);
inclusions_list.push_back(sphere);
TestMaterialSelector * mat_selector = new TestMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
/// initialization of the model
model.initFull();
/// boundary conditions
mesh.computeBoundingBox();
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
- Real bottom = lowerBounds(1);
+ Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real left = lowerBounds(0);
Real eps = std::abs((top - bottom) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<bool> & boun = model.getBlockedDOFs();
Array<Real> & disp = model.getDisplacement();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (std::abs(pos(n,1) - bottom) < eps) {
- boun(n,1) = true;
- disp(n,1) = 0.;
+ if (std::abs(pos(n, 1) - bottom) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 0.;
+ }
+ if (std::abs(pos(n, 1) - top) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 1.e-3;
}
- if (std::abs(pos(n,1) - top) < eps) {
- boun(n,1) = true;
- disp(n,1) = 1.e-3;
+ if (std::abs(pos(n, 0) - left) < eps) {
+ boun(n, 0) = true;
+ disp(n, 0) = 0.;
}
- if (std::abs(pos(n,0) - left) < eps) {
- boun(n,0) = true;
- disp(n,0) = 0.;
- }
}
/// add fields that should be dumped
model.setBaseName("regular");
model.addDumpField("material_index");
- model.addDumpFieldVector("displacement");;
+ model.addDumpFieldVector("displacement");
+ ;
model.addDumpField("stress");
model.addDumpField("blocked_dofs");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("damage");
model.addDumpField("partitions");
model.addDumpField("Sc");
model.addDumpField("force");
model.addDumpField("equivalent_stress");
model.addDumpField("ultimate_strain");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
- model.addDumpFieldVectorToDumper("igfem elements", "displacement");;
+ model.addDumpFieldVectorToDumper("igfem elements", "displacement");
+ ;
model.addDumpFieldToDumper("igfem elements", "stress");
model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "residual");
model.addDumpFieldToDumper("igfem elements", "grad_u");
model.addDumpFieldToDumper("igfem elements", "damage");
model.addDumpFieldToDumper("igfem elements", "partitions");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "force");
model.addDumpFieldToDumper("igfem elements", "equivalent_stress");
model.addDumpFieldToDumper("igfem elements", "ultimate_strain");
model.dump();
model.dump("igfem elements");
-
+
/// get a reference to the damage materials
- MaterialIterativeStiffnessReduction<spatial_dimension> & material = dynamic_cast<MaterialIterativeStiffnessReduction<spatial_dimension> & >(model.getMaterial(0));
- MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material = dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> & >(model.getMaterial(2));
-
+ MaterialIterativeStiffnessReduction<spatial_dimension> & material =
+ dynamic_cast<MaterialIterativeStiffnessReduction<spatial_dimension> &>(
+ model.getMaterial(0));
+ MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material =
+ dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> &>(
+ model.getMaterial(2));
+
Real error;
bool converged = false;
UInt nb_damaged_elements = 0;
Real max_eq_stress_regular = 0;
Real max_eq_stress_igfem = 0;
/// solve the system
// counter for the damage steps
UInt regular_steps = 15;
- for(UInt s = 0; s < regular_steps; ++s) {
- converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, error, 2);
-
+ for (UInt s = 0; s < regular_steps; ++s) {
+ converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-12, error, 2);
+
if (converged == false) {
std::cout << "The error is: " << error << std::endl;
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
}
- /// compute damage
+ /// compute damage
max_eq_stress_regular = material.getNormMaxEquivalentStress();
max_eq_stress_igfem = igfem_material.getNormMaxEquivalentStress();
if (max_eq_stress_regular > max_eq_stress_igfem)
nb_damaged_elements = material.updateDamage();
else if (max_eq_stress_regular == max_eq_stress_igfem) {
nb_damaged_elements = material.updateDamage();
nb_damaged_elements += igfem_material.updateDamage();
- }
- else
+ } else
nb_damaged_elements = igfem_material.updateDamage();
if (!nb_damaged_elements)
break;
- model.dump();
+ model.dump();
model.dump("igfem elements");
}
-
- const Array<UInt> & reduction_step_regular = material.getInternal<UInt>("damage_step")(_triangle_3, _not_ghost);
+ const Array<UInt> & reduction_step_regular =
+ material.getInternal<UInt>("damage_step")(_triangle_3, _not_ghost);
UInt reduction_step_el_27 = reduction_step_regular(27);
UInt reduction_step_el_19 = reduction_step_regular(19);
/// create the interface
- Real new_radius = (val-0.1);
+ Real new_radius = (val - 0.1);
model.moveInterface(new_radius);
- model.dump();
+ model.dump();
model.dump("igfem elements");
/// check that the damage reduction step has been correctly computed
/// regular element id -> igfem element id
- /// 27 -> 7; 19 -> 5
- const Array<UInt> & reduction_step_igfem = igfem_material.getInternal<UInt>("damage_step")(_igfem_triangle_5, _not_ghost);
- Array<UInt>::const_scalar_iterator step_it = reduction_step_igfem.begin();
+ /// 27 -> 7; 19 -> 5
+ const Array<UInt> & reduction_step_igfem = igfem_material.getInternal<UInt>(
+ "damage_step")(_igfem_triangle_5, _not_ghost);
+ Array<UInt>::const_scalar_iterator step_it = reduction_step_igfem.begin();
/// check the igfem elements
UInt nb_igfem_elements = mesh.getNbElement(_igfem_triangle_5, _not_ghost);
- UInt nb_quads = model.getFEEngine("IGFEMFEEngine").getNbIntegrationPoints(_igfem_triangle_5, _not_ghost);
- const Array<UInt> & sub_material = igfem_material.getInternal<UInt>("sub_material")(_igfem_triangle_5, _not_ghost);
+ UInt nb_quads = model.getFEEngine("IGFEMFEEngine")
+ .getNbIntegrationPoints(_igfem_triangle_5, _not_ghost);
+ const Array<UInt> & sub_material = igfem_material.getInternal<UInt>(
+ "sub_material")(_igfem_triangle_5, _not_ghost);
Array<UInt>::const_scalar_iterator sub_it = sub_material.begin();
for (UInt e = 0; e < nb_igfem_elements; ++e) {
for (UInt q = 0; q < nb_quads; ++q, ++sub_it, ++step_it) {
if (!*sub_it) {
- if(!Math::are_float_equal(*step_it, 0.)) {
- std::cout << "the reduction step for an elastic sub-element must be zero!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else {
- if (e == 7){
- if(!Math::are_float_equal(*step_it, reduction_step_el_27)) {
- std::cout << "error in computation of damage step!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else if (e == 5){
- if(!Math::are_float_equal(*step_it, reduction_step_el_19)) {
- std::cout << "error in computation of damage step!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else {
- if(!Math::are_float_equal(*step_it, 0.)) {
- std::cout << "error in computation of damage step!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
+ if (!Math::are_float_equal(*step_it, 0.)) {
+ std::cout
+ << "the reduction step for an elastic sub-element must be zero!!"
+ << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else {
+ if (e == 7) {
+ if (!Math::are_float_equal(*step_it, reduction_step_el_27)) {
+ std::cout << "error in computation of damage step!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else if (e == 5) {
+ if (!Math::are_float_equal(*step_it, reduction_step_el_19)) {
+ std::cout << "error in computation of damage step!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else {
+ if (!Math::are_float_equal(*step_it, 0.)) {
+ std::cout << "error in computation of damage step!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ }
}
}
}
//// force the next damage event
- const Array<Real> & dam_igfem = igfem_material.getInternal<Real>("damage")(_igfem_triangle_5, _not_ghost);
+ const Array<Real> & dam_igfem =
+ igfem_material.getInternal<Real>("damage")(_igfem_triangle_5, _not_ghost);
Array<Real> old_damage(dam_igfem);
- for(UInt s = 0; s < 1; ++s) {
- converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, error, 2);
-
+ for (UInt s = 0; s < 1; ++s) {
+ converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-12, error, 2);
+
if (converged == false) {
std::cout << "The error is: " << error << std::endl;
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
}
- /// compute damage
+ /// compute damage
max_eq_stress_regular = material.getNormMaxEquivalentStress();
max_eq_stress_igfem = igfem_material.getNormMaxEquivalentStress();
if (max_eq_stress_regular > max_eq_stress_igfem)
nb_damaged_elements = material.updateDamage();
else if (max_eq_stress_regular == max_eq_stress_igfem) {
nb_damaged_elements = material.updateDamage();
nb_damaged_elements += igfem_material.updateDamage();
- }
- else
+ } else
nb_damaged_elements = igfem_material.updateDamage();
if (!nb_damaged_elements)
break;
- model.dump();
+ model.dump();
model.dump("igfem elements");
}
/// check that damage has been simultanously been updated on all the
/// the integration points of one sub-element
- const Array<Real> & new_dam_igfem = igfem_material.getInternal<Real>("damage")(_igfem_triangle_5, _not_ghost);
+ const Array<Real> & new_dam_igfem =
+ igfem_material.getInternal<Real>("damage")(_igfem_triangle_5, _not_ghost);
sub_it = sub_material.begin();
Array<Real>::const_scalar_iterator new_dam_it = new_dam_igfem.begin();
Array<Real>::const_scalar_iterator old_dam_it = old_damage.begin();
step_it = reduction_step_igfem.begin();
UInt reduction_constant = material.getParam<Real>("reduction_constant");
for (UInt e = 0; e < nb_igfem_elements; ++e) {
- for (UInt q = 0; q < nb_quads; ++q, ++sub_it, ++step_it, ++new_dam_it, ++old_dam_it) {
+ for (UInt q = 0; q < nb_quads;
+ ++q, ++sub_it, ++step_it, ++new_dam_it, ++old_dam_it) {
if (!*sub_it) {
- if(!Math::are_float_equal(*step_it, 0.) || !Math::are_float_equal(*new_dam_it, 0.)) {
- std::cout << "the reduction step and damagefor an elastic sub-element must be zero!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else {
- if (e == 7){
- if(!Math::are_float_equal(*step_it, reduction_step_el_27 + 1) ||
- !Math::are_float_equal(*new_dam_it, 1 -
- (1./std::pow(reduction_constant, reduction_step_el_27+1)))) {
- std::cout << "error in computation of damage step!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else if (e == 5){
- if(!Math::are_float_equal(*step_it, reduction_step_el_19) ||
- !Math::are_float_equal(*new_dam_it, *old_dam_it)) {
- std::cout << "error in computation of damage step!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else {
- if(!Math::are_float_equal(*step_it, 0.) ||
- !Math::are_float_equal(*new_dam_it,0.)) {
- std::cout << "error in computation of damage step!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
+ if (!Math::are_float_equal(*step_it, 0.) ||
+ !Math::are_float_equal(*new_dam_it, 0.)) {
+ std::cout << "the reduction step and damagefor an elastic "
+ "sub-element must be zero!!"
+ << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else {
+ if (e == 7) {
+ if (!Math::are_float_equal(*step_it, reduction_step_el_27 + 1) ||
+ !Math::are_float_equal(
+ *new_dam_it,
+ 1 - (1. / std::pow(reduction_constant,
+ reduction_step_el_27 + 1)))) {
+ std::cout << "error in computation of damage step!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else if (e == 5) {
+ if (!Math::are_float_equal(*step_it, reduction_step_el_19) ||
+ !Math::are_float_equal(*new_dam_it, *old_dam_it)) {
+ std::cout << "error in computation of damage step!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else {
+ if (!Math::are_float_equal(*step_it, 0.) ||
+ !Math::are_float_equal(*new_dam_it, 0.)) {
+ std::cout << "error in computation of damage step!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ }
}
}
- }
-
-
+ }
finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc
index 269266a3c..b96232c95 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc
@@ -1,407 +1,437 @@
/**
* @file test_material_igfem_iterative_stiffness_reduction_parallel.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 26 12:20:15 2015
*
* @brief test the material iterative stiffness reduction in parallel
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
-#include "material_iterative_stiffness_reduction.hh"
#include "material_igfem_saw_tooth_damage.hh"
+#include "material_iterative_stiffness_reduction.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/// function declaration
bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model);
-class TestMaterialSelector : public MaterialSelector {
+class TestMaterialSelector : public MaterialSelector {
public:
- TestMaterialSelector(SolidMechanicsModelIGFEM & model) :
- MaterialSelector(),
- model(model),
- spatial_dimension(model.getSpatialDimension()){}
+ TestMaterialSelector(SolidMechanicsModelIGFEM & model)
+ : MaterialSelector(), model(model),
+ spatial_dimension(model.getSpatialDimension()) {}
UInt operator()(const Element & element) {
- if(Mesh::getKind(element.type) == _ek_igfem)
+ if (Mesh::getKind(element.type) == _ek_igfem)
return 2;
else {
/// regular elements
const Mesh & mesh = model.getMesh();
Vector<Real> barycenter(this->spatial_dimension);
mesh.getBarycenter(element, barycenter);
/// check if element belongs to ASR gel
- if(model.isInside(barycenter))
- return 1;
+ if (model.isInside(barycenter))
+ return 1;
}
return 0;
}
protected:
SolidMechanicsModelIGFEM & model;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
Math::setTolerance(1e-13);
debug::setDebugLevel(dblWarning);
- initialize("material_stiffness_reduction_2.dat" ,argc, argv);
+ initialize("material_stiffness_reduction_2.dat", argc, argv);
const UInt spatial_dimension = 2;
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partion it
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("test_damage_transfer.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
Math::setTolerance(1.e-14);
/// intialize the geometry and set the material selector
std::list<SK::Sphere_3> inclusions_list;
model.registerGeometryObject(inclusions_list, "inclusion");
- Real radius = 0.125;;
+ Real radius = 0.125;
+ ;
Vector<Real> center(spatial_dimension);
center(0) = 0.;
center(1) = 0.;
SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0.), radius * radius);
inclusions_list.push_back(sphere);
TestMaterialSelector * mat_selector = new TestMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
/// initialization of the model
model.initFull();
/// boundary conditions
mesh.computeBoundingBox();
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
- Real bottom = lowerBounds(1);
+ Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real left = lowerBounds(0);
Real eps = std::abs((top - bottom) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<bool> & boun = model.getBlockedDOFs();
Array<Real> & disp = model.getDisplacement();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (std::abs(pos(n,1) - bottom) < eps) {
- boun(n,1) = true;
- disp(n,1) = 0.;
+ if (std::abs(pos(n, 1) - bottom) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 0.;
+ }
+ if (std::abs(pos(n, 1) - top) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 1.e-3;
}
- if (std::abs(pos(n,1) - top) < eps) {
- boun(n,1) = true;
- disp(n,1) = 1.e-3;
+ if (std::abs(pos(n, 0) - left) < eps) {
+ boun(n, 0) = true;
+ disp(n, 0) = 0.;
}
- if (std::abs(pos(n,0) - left) < eps) {
- boun(n,0) = true;
- disp(n,0) = 0.;
- }
}
/// add fields that should be dumped
model.setBaseName("regular");
model.addDumpField("material_index");
- model.addDumpFieldVector("displacement");;
+ model.addDumpFieldVector("displacement");
+ ;
model.addDumpField("stress");
model.addDumpField("blocked_dofs");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("damage");
model.addDumpField("partitions");
model.addDumpField("Sc");
model.addDumpField("force");
model.addDumpField("equivalent_stress");
model.addDumpField("ultimate_strain");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
- model.addDumpFieldVectorToDumper("igfem elements", "displacement");;
+ model.addDumpFieldVectorToDumper("igfem elements", "displacement");
+ ;
model.addDumpFieldToDumper("igfem elements", "stress");
model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "residual");
model.addDumpFieldToDumper("igfem elements", "grad_u");
model.addDumpFieldToDumper("igfem elements", "damage");
model.addDumpFieldToDumper("igfem elements", "partitions");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "force");
model.addDumpFieldToDumper("igfem elements", "equivalent_stress");
model.addDumpFieldToDumper("igfem elements", "ultimate_strain");
model.dump();
model.dump("igfem elements");
/// create the interface
model.update("inclusion");
/// get a reference to the damage materials
- MaterialIterativeStiffnessReduction<spatial_dimension> & material = dynamic_cast<MaterialIterativeStiffnessReduction<spatial_dimension> & >(model.getMaterial(0));
- MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material = dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> & >(model.getMaterial(2));
-
+ MaterialIterativeStiffnessReduction<spatial_dimension> & material =
+ dynamic_cast<MaterialIterativeStiffnessReduction<spatial_dimension> &>(
+ model.getMaterial(0));
+ MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material =
+ dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> &>(
+ model.getMaterial(2));
+
Real error;
bool converged = false;
UInt nb_damaged_elements = 0;
Real max_eq_stress_regular = 0;
Real max_eq_stress_igfem = 0;
/// solve the system
UInt s = 0;
do {
- converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-12, error, 2);
-
+ converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-12, error, 2);
+
if (converged == false) {
std::cout << "The error is: " << error << std::endl;
AKANTU_DEBUG_ASSERT(converged, "Did not converge");
}
- /// compute damage
+ /// compute damage
max_eq_stress_regular = material.getNormMaxEquivalentStress();
max_eq_stress_igfem = igfem_material.getNormMaxEquivalentStress();
if (max_eq_stress_regular > max_eq_stress_igfem)
nb_damaged_elements = material.updateDamage();
else if (max_eq_stress_regular == max_eq_stress_igfem) {
nb_damaged_elements = material.updateDamage();
nb_damaged_elements += igfem_material.updateDamage();
- }
- else
+ } else
nb_damaged_elements = igfem_material.updateDamage();
- model.dump();
+ model.dump();
model.dump("igfem elements");
/// check the current damage state
if (!checkDamageState(s, model)) {
std::cout << "error in the damage compuation" << std::endl;
finalize();
return EXIT_FAILURE;
}
s++;
- } while(nb_damaged_elements);
+ } while (nb_damaged_elements);
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model) {
bool test_result = true;
const UInt spatial_dimension = model.getSpatialDimension();
const Mesh & mesh = model.getMesh();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
if (psize == 1) {
const ElementType element_type = _triangle_3;
/// prepare output: compute barycenters for elements that can be damaged
- const Array<UInt> & element_filter = model.getMaterial(0).getElementFilter(element_type, _not_ghost);
+ const Array<UInt> & element_filter =
+ model.getMaterial(0).getElementFilter(element_type, _not_ghost);
Array<Real> barycenters(element_filter.getSize(), spatial_dimension);
Array<Real>::vector_iterator bary_it = barycenters.begin(spatial_dimension);
for (UInt e = 0; e < element_filter.getSize(); ++e, ++bary_it) {
UInt global_el_idx = element_filter(e);
- mesh.getBarycenter(global_el_idx, element_type, bary_it->storage(), _not_ghost);
+ mesh.getBarycenter(global_el_idx, element_type, bary_it->storage(),
+ _not_ghost);
}
- const Array<Real> & damage = model.getMaterial(0).getInternal<Real>("damage")(element_type, _not_ghost);
- const Array<Real> & Sc = model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
+ const Array<Real> & damage = model.getMaterial(0).getInternal<Real>(
+ "damage")(element_type, _not_ghost);
+ const Array<Real> & Sc =
+ model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
std::ostringstream file_name;
file_name << "step_" << std::setfill('0') << std::setw(3) << step << ".txt";
std::ofstream file_output;
file_output.open(file_name.str());
file_output << std::setprecision(14);
- for(UInt e = 0; e < barycenters.getSize(); ++e)
- file_output << barycenters(e, 0) << " "
- << barycenters(e, 1) << " "
- << damage(e) << " "
- << Sc(e) << std::endl;
+ for (UInt e = 0; e < barycenters.getSize(); ++e)
+ file_output << barycenters(e, 0) << " " << barycenters(e, 1) << " "
+ << damage(e) << " " << Sc(e) << std::endl;
/// igfem elements
const ElementType element_type_igfem = _igfem_triangle_5;
/// prepare output: compute barycenters for elements that can be damaged
UInt nb_igfem_elements = mesh.getNbElement(_igfem_triangle_5, _not_ghost);
UInt nb_sub_elements = 2;
- Array<Real> barycenters_igfem(nb_sub_elements * nb_igfem_elements, spatial_dimension);
+ Array<Real> barycenters_igfem(nb_sub_elements * nb_igfem_elements,
+ spatial_dimension);
bary_it = barycenters_igfem.begin(spatial_dimension);
for (UInt e = 0; e < nb_igfem_elements; ++e) {
- /// note global index is local index because there is only one igfem material
+ /// note global index is local index because there is only one igfem
+ /// material
for (UInt s = 0; s < nb_sub_elements; ++s, ++bary_it)
- model.getSubElementBarycenter(e, s, element_type_igfem, *bary_it, _not_ghost);
+ model.getSubElementBarycenter(e, s, element_type_igfem, *bary_it,
+ _not_ghost);
}
- const Array<Real> & damage_igfem = model.getMaterial(2).getInternal<Real>("damage")(element_type_igfem, _not_ghost);
+ const Array<Real> & damage_igfem = model.getMaterial(2).getInternal<Real>(
+ "damage")(element_type_igfem, _not_ghost);
Array<Real>::const_scalar_iterator dam_it = damage_igfem.begin();
- const Array<Real> & Sc_igfem = model.getMaterial(2).getInternal<Real>("Sc")(element_type_igfem, _not_ghost);
+ const Array<Real> & Sc_igfem = model.getMaterial(2).getInternal<Real>("Sc")(
+ element_type_igfem, _not_ghost);
Array<Real>::const_scalar_iterator Sc_it = Sc_igfem.begin();
- for(UInt e = 0; e < nb_igfem_elements; ++e) {
- for(UInt s = 0; s < nb_sub_elements; ++s)
- if (IGFEMHelper::getSubElementType(element_type_igfem, s) == _triangle_3) {
- file_output << barycenters_igfem(e*nb_sub_elements + s, 0) << " "
- << barycenters_igfem(e*nb_sub_elements + s, 1) << " "
- << *dam_it << " "
- << *Sc_it << std::endl;
- ++dam_it;
- ++Sc_it;
- }
- else if (IGFEMHelper::getSubElementType(element_type_igfem, s) == _quadrangle_4) {
- file_output << barycenters_igfem(e*nb_sub_elements + s, 0) << " "
- << barycenters_igfem(e*nb_sub_elements + s, 1) << " "
- << *dam_it << " "
- << *Sc_it << std::endl;
- dam_it += 4;
- Sc_it += 4;
- }
+ for (UInt e = 0; e < nb_igfem_elements; ++e) {
+ for (UInt s = 0; s < nb_sub_elements; ++s)
+ if (IGFEMHelper::getSubElementType(element_type_igfem, s) ==
+ _triangle_3) {
+ file_output << barycenters_igfem(e * nb_sub_elements + s, 0) << " "
+ << barycenters_igfem(e * nb_sub_elements + s, 1) << " "
+ << *dam_it << " " << *Sc_it << std::endl;
+ ++dam_it;
+ ++Sc_it;
+ } else if (IGFEMHelper::getSubElementType(element_type_igfem, s) ==
+ _quadrangle_4) {
+ file_output << barycenters_igfem(e * nb_sub_elements + s, 0) << " "
+ << barycenters_igfem(e * nb_sub_elements + s, 1) << " "
+ << *dam_it << " " << *Sc_it << std::endl;
+ dam_it += 4;
+ Sc_it += 4;
+ }
}
}
else {
- /// read data
+ /// read data
Real default_tolerance = Math::getTolerance();
Math::setTolerance(1.e-10);
std::stringstream results_file;
- results_file << "step_"
- << std::setfill('0') << std::setw(3)
- << step << ".txt";
+ results_file << "step_" << std::setfill('0') << std::setw(3) << step
+ << ".txt";
std::ifstream damage_input;
damage_input.open(results_file.str().c_str());
Array<Real> damage_result(0, 1);
Array<Real> Sc_result(0, 1);
Array<Real> bary_regular(0, spatial_dimension);
Vector<Real> bary(spatial_dimension);
Real dam = 0.;
Real strength = 0;
while (damage_input.good()) {
- damage_input >> bary(0) >> bary(1)
- >> dam >> strength;
+ damage_input >> bary(0) >> bary(1) >> dam >> strength;
bary_regular.push_back(bary);
damage_result.push_back(dam);
Sc_result.push_back(strength);
}
/// compare the results
Array<Real>::const_vector_iterator bary_it;
- Array<Real>::const_vector_iterator bary_begin = bary_regular.begin(spatial_dimension);
- Array<Real>::const_vector_iterator bary_end = bary_regular.end(spatial_dimension);
+ Array<Real>::const_vector_iterator bary_begin =
+ bary_regular.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator bary_end =
+ bary_regular.end(spatial_dimension);
/// compare the regular elements
ElementType element_type = _triangle_3;
- const Array<UInt> & element_filter = model.getMaterial(0).getElementFilter(element_type, _not_ghost);
- const Array<Real> & damage_regular_el = model.getMaterial(0).getInternal<Real>("damage")(element_type, _not_ghost);
- const Array<Real> & Sc_regular_el = model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
+ const Array<UInt> & element_filter =
+ model.getMaterial(0).getElementFilter(element_type, _not_ghost);
+ const Array<Real> & damage_regular_el =
+ model.getMaterial(0).getInternal<Real>("damage")(element_type,
+ _not_ghost);
+ const Array<Real> & Sc_regular_el =
+ model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
for (UInt e = 0; e < element_filter.getSize(); ++e) {
UInt global_el_idx = element_filter(e);
- mesh.getBarycenter(global_el_idx, element_type, bary.storage(), _not_ghost);
+ mesh.getBarycenter(global_el_idx, element_type, bary.storage(),
+ _not_ghost);
/// find element
for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
- UInt matched_dim = 0;
- while (matched_dim < spatial_dimension &&
- Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
- ++matched_dim;
- if (matched_dim == spatial_dimension) break;
+ UInt matched_dim = 0;
+ while (
+ matched_dim < spatial_dimension &&
+ Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
+ ++matched_dim;
+ if (matched_dim == spatial_dimension)
+ break;
}
if (bary_it == bary_end) {
- std::cout << "Element barycenter not found!" << std::endl;
- return false;
+ std::cout << "Element barycenter not found!" << std::endl;
+ return false;
}
UInt matched_el = bary_it - bary_begin;
-
- if (std::abs(damage_result(matched_el)-damage_regular_el(e)) > 1.e-12 ||
- std::abs(Sc_result(matched_el)-Sc_regular_el(e)) > 1.e-4) {
- test_result = false;
- break;
+
+ if (std::abs(damage_result(matched_el) - damage_regular_el(e)) > 1.e-12 ||
+ std::abs(Sc_result(matched_el) - Sc_regular_el(e)) > 1.e-4) {
+ test_result = false;
+ break;
}
}
/// compare the IGFEM elements
UInt nb_sub_elements = 2;
element_type = _igfem_triangle_5;
- const Array<UInt> & element_filter_igfem = model.getMaterial(2).getElementFilter(element_type, _not_ghost);
- const Array<Real> & damage_regular_el_igfem = model.getMaterial(2).getInternal<Real>("damage")(element_type, _not_ghost);
- Array<Real>::const_scalar_iterator dam_igfem_it = damage_regular_el_igfem.begin();
- const Array<Real> & Sc_regular_el_igfem = model.getMaterial(2).getInternal<Real>("Sc")(element_type, _not_ghost);
- Array<Real>::const_scalar_iterator Sc_igfem_it = Sc_regular_el_igfem.begin();
-
+ const Array<UInt> & element_filter_igfem =
+ model.getMaterial(2).getElementFilter(element_type, _not_ghost);
+ const Array<Real> & damage_regular_el_igfem =
+ model.getMaterial(2).getInternal<Real>("damage")(element_type,
+ _not_ghost);
+ Array<Real>::const_scalar_iterator dam_igfem_it =
+ damage_regular_el_igfem.begin();
+ const Array<Real> & Sc_regular_el_igfem =
+ model.getMaterial(2).getInternal<Real>("Sc")(element_type, _not_ghost);
+ Array<Real>::const_scalar_iterator Sc_igfem_it =
+ Sc_regular_el_igfem.begin();
+
for (UInt e = 0; e < element_filter_igfem.getSize(); ++e) {
UInt global_el_idx = element_filter_igfem(e);
for (UInt s = 0; s < nb_sub_elements; ++s) {
- model.getSubElementBarycenter(global_el_idx, s, element_type, bary, _not_ghost);
- /// find element
- for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
- UInt matched_dim = 0;
- while (matched_dim < spatial_dimension &&
- Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
- ++matched_dim;
- if (matched_dim == spatial_dimension) break;
- }
- if (bary_it == bary_end) {
- std::cout << "Sub-element barycenter not found!" << std::endl;
- return false;
- }
-
- UInt matched_el = bary_it - bary_begin;
-
- if (std::abs(damage_result(matched_el)- *dam_igfem_it) > 1.e-12 ||
- std::abs(Sc_result(matched_el)- *Sc_igfem_it) > 1.e-4) {
- test_result = false;
- break;
- }
- if (IGFEMHelper::getSubElementType(element_type, s) == _triangle_3) {
- ++Sc_igfem_it;
- ++dam_igfem_it;
- }
- else if (IGFEMHelper::getSubElementType(element_type, s) == _quadrangle_4) {
- Sc_igfem_it += 4;
- dam_igfem_it += 4;
- }
+ model.getSubElementBarycenter(global_el_idx, s, element_type, bary,
+ _not_ghost);
+ /// find element
+ for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
+ UInt matched_dim = 0;
+ while (
+ matched_dim < spatial_dimension &&
+ Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
+ ++matched_dim;
+ if (matched_dim == spatial_dimension)
+ break;
+ }
+ if (bary_it == bary_end) {
+ std::cout << "Sub-element barycenter not found!" << std::endl;
+ return false;
+ }
+
+ UInt matched_el = bary_it - bary_begin;
+
+ if (std::abs(damage_result(matched_el) - *dam_igfem_it) > 1.e-12 ||
+ std::abs(Sc_result(matched_el) - *Sc_igfem_it) > 1.e-4) {
+ test_result = false;
+ break;
+ }
+ if (IGFEMHelper::getSubElementType(element_type, s) == _triangle_3) {
+ ++Sc_igfem_it;
+ ++dam_igfem_it;
+ } else if (IGFEMHelper::getSubElementType(element_type, s) ==
+ _quadrangle_4) {
+ Sc_igfem_it += 4;
+ dam_igfem_it += 4;
+ }
}
}
Math::setTolerance(default_tolerance);
}
return test_result;
}
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_tangent_transfer.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_tangent_transfer.cc
index 26b524879..ae364cddb 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_tangent_transfer.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_tangent_transfer.cc
@@ -1,259 +1,273 @@
/**
* @file test_material_igfem_iterative_stiffness_reduction_tangent_transfer.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 26 12:20:15 2015
*
* @brief test the tangent transfer for the material iterative
* stiffness reduction
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
-#include "material_iterative_stiffness_reduction.hh"
#include "material_igfem_saw_tooth_damage.hh"
+#include "material_iterative_stiffness_reduction.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-class TestMaterialSelector : public MaterialSelector {
+class TestMaterialSelector : public MaterialSelector {
public:
- TestMaterialSelector(SolidMechanicsModelIGFEM & model) :
- MaterialSelector(),
- model(model),
- spatial_dimension(model.getSpatialDimension()){}
+ TestMaterialSelector(SolidMechanicsModelIGFEM & model)
+ : MaterialSelector(), model(model),
+ spatial_dimension(model.getSpatialDimension()) {}
UInt operator()(const Element & element) {
- if(Mesh::getKind(element.type) == _ek_igfem)
+ if (Mesh::getKind(element.type) == _ek_igfem)
return 2;
else {
/// regular elements
const Mesh & mesh = model.getMesh();
Vector<Real> barycenter(this->spatial_dimension);
mesh.getBarycenter(element, barycenter);
/// check if element belongs to ASR gel
- if(model.isInside(barycenter))
- return 1;
+ if (model.isInside(barycenter))
+ return 1;
}
return 0;
}
protected:
SolidMechanicsModelIGFEM & model;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
Math::setTolerance(1e-13);
debug::setDebugLevel(dblWarning);
- initialize("material_stiffness_reduction_2.dat" ,argc, argv);
+ initialize("material_stiffness_reduction_2.dat", argc, argv);
const UInt spatial_dimension = 2;
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partion it
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("test_damage_transfer.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
Math::setTolerance(1.e-14);
/// intialize the geometry and set the material selector
std::list<SK::Sphere_3> inclusions_list;
model.registerGeometryObject(inclusions_list, "inclusion");
Real val = 1000000000;
- Real radius_squared = (val-0.6)*(val-0.6);
+ Real radius_squared = (val - 0.6) * (val - 0.6);
Vector<Real> center(spatial_dimension);
center(0) = 0;
center(1) = val;
SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0.), radius_squared);
inclusions_list.push_back(sphere);
TestMaterialSelector * mat_selector = new TestMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
/// initialization of the model
model.initFull();
/// boundary conditions
mesh.computeBoundingBox();
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
- Real bottom = lowerBounds(1);
+ Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real left = lowerBounds(0);
Real eps = std::abs((top - bottom) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<bool> & boun = model.getBlockedDOFs();
Array<Real> & disp = model.getDisplacement();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (std::abs(pos(n,1) - bottom) < eps) {
- boun(n,1) = true;
- disp(n,1) = 0.;
+ if (std::abs(pos(n, 1) - bottom) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 0.;
+ }
+ if (std::abs(pos(n, 1) - top) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 1.e-3;
}
- if (std::abs(pos(n,1) - top) < eps) {
- boun(n,1) = true;
- disp(n,1) = 1.e-3;
+ if (std::abs(pos(n, 0) - left) < eps) {
+ boun(n, 0) = true;
+ disp(n, 0) = 0.;
}
- if (std::abs(pos(n,0) - left) < eps) {
- boun(n,0) = true;
- disp(n,0) = 0.;
- }
}
/// add fields that should be dumped
model.setBaseName("regular");
model.addDumpField("material_index");
- model.addDumpFieldVector("displacement");;
+ model.addDumpFieldVector("displacement");
+ ;
model.addDumpField("stress");
model.addDumpField("blocked_dofs");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("damage");
model.addDumpField("partitions");
model.addDumpField("Sc");
model.addDumpField("force");
model.addDumpField("equivalent_stress");
model.addDumpField("ultimate_strain");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
- model.addDumpFieldVectorToDumper("igfem elements", "displacement");;
+ model.addDumpFieldVectorToDumper("igfem elements", "displacement");
+ ;
model.addDumpFieldToDumper("igfem elements", "stress");
model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "residual");
model.addDumpFieldToDumper("igfem elements", "grad_u");
model.addDumpFieldToDumper("igfem elements", "damage");
model.addDumpFieldToDumper("igfem elements", "partitions");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "force");
model.addDumpFieldToDumper("igfem elements", "equivalent_stress");
model.addDumpFieldToDumper("igfem elements", "ultimate_strain");
model.dump();
model.dump("igfem elements");
-
+
/// get a reference to the damage materials
- MaterialIterativeStiffnessReduction<spatial_dimension> & material = dynamic_cast<MaterialIterativeStiffnessReduction<spatial_dimension> & >(model.getMaterial(0));
- MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material = dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> & >(model.getMaterial(2));
-
+ MaterialIterativeStiffnessReduction<spatial_dimension> & material =
+ dynamic_cast<MaterialIterativeStiffnessReduction<spatial_dimension> &>(
+ model.getMaterial(0));
+ MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material =
+ dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> &>(
+ model.getMaterial(2));
+
/// check that the tangent of the softening law has been computed correctly
- const Array<Real> & Sc = material.getInternal<Real>("Sc")(_triangle_3, _not_ghost);
+ const Array<Real> & Sc =
+ material.getInternal<Real>("Sc")(_triangle_3, _not_ghost);
Array<Real>::const_scalar_iterator Sc_it = Sc.begin();
- const Array<Real> & D = material.getInternal<Real>("tangent")(_triangle_3, _not_ghost);
+ const Array<Real> & D =
+ material.getInternal<Real>("tangent")(_triangle_3, _not_ghost);
Array<Real>::const_scalar_iterator D_it = D.begin();
Real E = material.getParam<Real>("E");
Real Gf = 20.;
Real ultimate_strain = 0;
Real crack_band_width = 0.25;
Real D_exact = 0.;
Math::setTolerance(1.e-13);
for (UInt i = 0; i < Sc.getSize(); ++i, ++Sc_it, ++D_it) {
ultimate_strain = 2. * Gf / (*Sc_it * crack_band_width);
- D_exact = *Sc_it / (ultimate_strain - (*Sc_it/E));
+ D_exact = *Sc_it / (ultimate_strain - (*Sc_it / E));
if (!Math::are_float_equal(*D_it, D_exact)) {
std::cout << "error in the tangent or ultimate strain" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
+ /// regular elements are linear triganle elements -> only one integration
+ /// point
- /// regular elements are linear triganle elements -> only one integration point
-
- const Array<Real> & eps_u = material.getInternal<Real>("ultimate_strain")(_triangle_3, _not_ghost);
+ const Array<Real> & eps_u =
+ material.getInternal<Real>("ultimate_strain")(_triangle_3, _not_ghost);
Real D_el_27 = D(27);
Real D_el_19 = D(19);
Real epsu_el_27 = eps_u(27);
Real epsu_el_19 = eps_u(19);
-
+
/// create the interface
- Real new_radius = (val-0.1);
+ Real new_radius = (val - 0.1);
model.moveInterface(new_radius);
- model.dump();
+ model.dump();
model.dump("igfem elements");
/// check that the damage reduction step has been correctly computed
/// regular element id -> igfem element id
- /// 27 -> 7; 19 -> 5
- const Array<Real> & epsu_igfem = igfem_material.getInternal<Real>("ultimate_strain")(_igfem_triangle_5, _not_ghost);
+ /// 27 -> 7; 19 -> 5
+ const Array<Real> & epsu_igfem = igfem_material.getInternal<Real>(
+ "ultimate_strain")(_igfem_triangle_5, _not_ghost);
Array<Real>::const_scalar_iterator epsu_igfem_it = epsu_igfem.begin();
- const Array<Real> & D_igfem = igfem_material.getInternal<Real>("tangent")(_igfem_triangle_5, _not_ghost);
+ const Array<Real> & D_igfem = igfem_material.getInternal<Real>("tangent")(
+ _igfem_triangle_5, _not_ghost);
Array<Real>::const_scalar_iterator D_igfem_it = D_igfem.begin();
/// check the igfem elements
UInt nb_igfem_elements = mesh.getNbElement(_igfem_triangle_5, _not_ghost);
- UInt nb_quads = model.getFEEngine("IGFEMFEEngine").getNbIntegrationPoints(_igfem_triangle_5, _not_ghost);
- const Array<UInt> & sub_material = igfem_material.getInternal<UInt>("sub_material")(_igfem_triangle_5, _not_ghost);
+ UInt nb_quads = model.getFEEngine("IGFEMFEEngine")
+ .getNbIntegrationPoints(_igfem_triangle_5, _not_ghost);
+ const Array<UInt> & sub_material = igfem_material.getInternal<UInt>(
+ "sub_material")(_igfem_triangle_5, _not_ghost);
Array<UInt>::const_scalar_iterator sub_it = sub_material.begin();
for (UInt e = 0; e < nb_igfem_elements; ++e) {
- for (UInt q = 0; q < nb_quads; ++q, ++sub_it, ++D_igfem_it, ++epsu_igfem_it) {
+ for (UInt q = 0; q < nb_quads;
+ ++q, ++sub_it, ++D_igfem_it, ++epsu_igfem_it) {
if (!*sub_it) {
- if(!Math::are_float_equal(*epsu_igfem_it, 0.) ||
- !Math::are_float_equal(*D_igfem_it, 0.)) {
- std::cout << "the tangent and ultimate strain of a sub-element must be zero!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else {
- if (e == 7){
- if(!Math::are_float_equal(*epsu_igfem_it, epsu_el_27) ||
- !Math::are_float_equal(*D_igfem_it, D_el_27)) {
- std::cout << "error in tangent or ultimate strain!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- else if (e == 5){
- if(!Math::are_float_equal(*epsu_igfem_it, epsu_el_19) ||
- !Math::are_float_equal(*D_igfem_it, D_el_19)) {
- std::cout << "error in tangent or ultimate strain!!" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
+ if (!Math::are_float_equal(*epsu_igfem_it, 0.) ||
+ !Math::are_float_equal(*D_igfem_it, 0.)) {
+ std::cout << "the tangent and ultimate strain of a sub-element must "
+ "be zero!!"
+ << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else {
+ if (e == 7) {
+ if (!Math::are_float_equal(*epsu_igfem_it, epsu_el_27) ||
+ !Math::are_float_equal(*D_igfem_it, D_el_27)) {
+ std::cout << "error in tangent or ultimate strain!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ } else if (e == 5) {
+ if (!Math::are_float_equal(*epsu_igfem_it, epsu_el_19) ||
+ !Math::are_float_equal(*D_igfem_it, D_el_19)) {
+ std::cout << "error in tangent or ultimate strain!!" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ }
}
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_solid_mechanics_model_igfem.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_solid_mechanics_model_igfem.cc
index 5ab972938..1da527ef0 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_solid_mechanics_model_igfem.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_solid_mechanics_model_igfem.cc
@@ -1,327 +1,337 @@
/**
* @file test_solid_mechanics_model_igfem.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief test the solidmechancis model for IGFEM analysis
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
-#include "material_elastic.hh"
#include "aka_common.hh"
+#include "dumper_paraview.hh"
+#include "material_elastic.hh"
+#include "mesh_geom_common.hh"
+#include "solid_mechanics_model_igfem.hh"
+#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iostream>
-#include <cmath>
-#include <math.h>
-#include "dumper_paraview.hh"
-#include "mesh_geom_common.hh"
+#include <math.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
void outputArray(const Mesh & mesh, const Array<Real> & array) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_global_nodes = mesh.getNbGlobalNodes();
Array<Real> solution(nb_global_nodes, spatial_dimension, 0.);
- Array<Real>::vector_iterator solution_begin = solution.begin(spatial_dimension);
+ Array<Real>::vector_iterator solution_begin =
+ solution.begin(spatial_dimension);
Array<Real>::const_vector_iterator array_it = array.begin(spatial_dimension);
-
+
for (UInt n = 0; n < mesh.getNbNodes(); ++n, ++array_it) {
if (mesh.isLocalOrMasterNode(n))
solution_begin[mesh.getNodeGlobalId(n)] = *array_it;
}
- comm.allReduce(solution.storage(), solution.getSize() * solution.getNbComponent(), _so_sum);
+ comm.allReduce(solution.storage(),
+ solution.getSize() * solution.getNbComponent(), _so_sum);
std::cout << std::fixed;
std::cout << std::setprecision(6);
if (prank == 0) {
- Array<Real>::const_vector_iterator sol_it = solution.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator sol_it =
+ solution.begin(spatial_dimension);
for (UInt n = 0; n < nb_global_nodes; ++n, ++sol_it)
- // Print absolute values to avoid parasite negative sign in machine precision zeros
- std::cout << std::abs((*sol_it)(0)) << "," << std::abs((*sol_it)(1)) << std::endl;
+ // Print absolute values to avoid parasite negative sign in machine
+ // precision zeros
+ std::cout << std::abs((*sol_it)(0)) << "," << std::abs((*sol_it)(1))
+ << std::endl;
}
}
/* -------------------------------------------------------------------------- */
class Sphere {
public:
- Sphere(const Vector<Real> & center, Real radius, Real tolerance = 0.) : center(center), radius(radius), tolerance(tolerance) {
- }
+ Sphere(const Vector<Real> & center, Real radius, Real tolerance = 0.)
+ : center(center), radius(radius), tolerance(tolerance) {}
bool isInside(const Vector<Real> & point) const {
return (point.distance(center) < radius + tolerance);
}
const Vector<Real> & getCenter() const { return center; }
Real & getRadius() { return radius; }
protected:
Vector<Real> center;
Real radius, tolerance;
};
void growGel(std::list<SK::Sphere_3> & query_list, Real new_radius) {
std::list<SK::Sphere_3>::const_iterator query_it = query_list.begin(),
- query_end = query_list.end();
+ query_end = query_list.end();
std::list<SK::Sphere_3> sphere_list;
- for (; query_it != query_end ; ++query_it) {
- SK::Sphere_3 sphere(query_it->center(),
- new_radius * new_radius);
+ for (; query_it != query_end; ++query_it) {
+ SK::Sphere_3 sphere(query_it->center(), new_radius * new_radius);
sphere_list.push_back(sphere);
}
query_list.clear();
query_list = sphere_list;
}
-Real computeAlpha(Real inner_radius, Real outer_radius, const Vector<Real> & lambda, const Vector<Real> & mu) {
+Real computeAlpha(Real inner_radius, Real outer_radius,
+ const Vector<Real> & lambda, const Vector<Real> & mu) {
- Real alpha = (lambda(1) + mu(1) + mu(0)) * outer_radius * outer_radius / ((lambda(0) + mu(0)) * inner_radius * inner_radius
- + (lambda(1) + mu(1)) * (outer_radius * outer_radius - inner_radius * inner_radius)+(mu(0) * outer_radius * outer_radius));
+ Real alpha = (lambda(1) + mu(1) + mu(0)) * outer_radius * outer_radius /
+ ((lambda(0) + mu(0)) * inner_radius * inner_radius +
+ (lambda(1) + mu(1)) * (outer_radius * outer_radius -
+ inner_radius * inner_radius) +
+ (mu(0) * outer_radius * outer_radius));
return alpha;
}
-void applyBoundaryConditions(SolidMechanicsModelIGFEM & model, Real inner_radius, Real outer_radius, const Vector<Real> & lambda, const Vector<Real> & mu) {
+void applyBoundaryConditions(SolidMechanicsModelIGFEM & model,
+ Real inner_radius, Real outer_radius,
+ const Vector<Real> & lambda,
+ const Vector<Real> & mu) {
/// boundary conditions for circular inclusion:
Real alpha = computeAlpha(inner_radius, outer_radius, lambda, mu);
Mesh & mesh = model.getMesh();
mesh.computeBoundingBox();
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
- Real bottom = lowerBounds(1);
+ Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real left = lowerBounds(0);
Real right = upperBounds(0);
Real eps = std::abs((top - bottom) * 1e-12);
const Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
Real radius = 0;
Real phi = 0;
disp.clear();
boun.clear();
/// absolute confinement
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
-
- if(std::abs(pos(i,0) - left) < eps) {
- radius = std::sqrt(pos(i,0)*pos(i,0) + pos(i,1)*pos(i,1));
- phi = std::atan2(pos(i,1), pos(i,0));
- boun(i,0) = true;
- disp(i,0) = cos(phi) * ( (radius - 4./radius) * alpha + 4./radius );
- boun(i,1) = true;
- disp(i,1) = sin(phi) * ( (radius - 4./radius) * alpha + 4./radius );
- }
- if(std::abs(pos(i,0) - right) < eps) {
- radius = std::sqrt(pos(i,0)*pos(i,0) + pos(i,1)*pos(i,1));
- phi = std::atan2(pos(i,1), pos(i,0));
- boun(i,0) = true;
- disp(i,0) = cos(phi) * ( (radius - 4./radius) * alpha + 4./radius );
- boun(i,1) = true;
- disp(i,1) = sin(phi) * ( (radius - 4./radius) * alpha + 4./radius );
+ if (std::abs(pos(i, 0) - left) < eps) {
+ radius = std::sqrt(pos(i, 0) * pos(i, 0) + pos(i, 1) * pos(i, 1));
+ phi = std::atan2(pos(i, 1), pos(i, 0));
+ boun(i, 0) = true;
+ disp(i, 0) = cos(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
+ boun(i, 1) = true;
+ disp(i, 1) = sin(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
}
- if(std::abs(pos(i,1) - top) < eps) {
- radius = std::sqrt(pos(i,0)*pos(i,0) + pos(i,1)*pos(i,1));
- phi = std::atan2(pos(i,1), pos(i,0));
- boun(i,0) = true;
- disp(i,0) = cos(phi) * ( (radius - 4./radius) * alpha + 4./radius );
- boun(i,1) = true;
- disp(i,1) = sin(phi) * ( (radius - 4./radius) * alpha + 4./radius );
+ if (std::abs(pos(i, 0) - right) < eps) {
+ radius = std::sqrt(pos(i, 0) * pos(i, 0) + pos(i, 1) * pos(i, 1));
+ phi = std::atan2(pos(i, 1), pos(i, 0));
+ boun(i, 0) = true;
+ disp(i, 0) = cos(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
+ boun(i, 1) = true;
+ disp(i, 1) = sin(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
}
- if(std::abs(pos(i,1) - bottom) < eps) {
- radius = std::sqrt(pos(i,0)*pos(i,0) + pos(i,1)*pos(i,1));
- phi = std::atan2(pos(i,1), pos(i,0));
- boun(i,0) = true;
- disp(i,0) = cos(phi) * ( (radius - 4./radius) * alpha + 4./radius );
- boun(i,1) = true;
- disp(i,1) = sin(phi) * ( (radius - 4./radius) * alpha + 4./radius );
+ if (std::abs(pos(i, 1) - top) < eps) {
+ radius = std::sqrt(pos(i, 0) * pos(i, 0) + pos(i, 1) * pos(i, 1));
+ phi = std::atan2(pos(i, 1), pos(i, 0));
+ boun(i, 0) = true;
+ disp(i, 0) = cos(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
+ boun(i, 1) = true;
+ disp(i, 1) = sin(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
}
+ if (std::abs(pos(i, 1) - bottom) < eps) {
+ radius = std::sqrt(pos(i, 0) * pos(i, 0) + pos(i, 1) * pos(i, 1));
+ phi = std::atan2(pos(i, 1), pos(i, 0));
+ boun(i, 0) = true;
+ disp(i, 0) = cos(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
+ boun(i, 1) = true;
+ disp(i, 1) = sin(phi) * ((radius - 4. / radius) * alpha + 4. / radius);
+ }
}
}
-class SphereMaterialSelector : public DefaultMaterialIGFEMSelector {
+class SphereMaterialSelector : public DefaultMaterialIGFEMSelector {
public:
- SphereMaterialSelector(std::vector<Sphere> & sphere_list, SolidMechanicsModelIGFEM & model) :
- DefaultMaterialIGFEMSelector(model),
- model(model),
- spheres(sphere_list) {
- }
+ SphereMaterialSelector(std::vector<Sphere> & sphere_list,
+ SolidMechanicsModelIGFEM & model)
+ : DefaultMaterialIGFEMSelector(model), model(model),
+ spheres(sphere_list) {}
UInt operator()(const Element & elem) {
- if(Mesh::getKind(elem.type) == _ek_igfem)
+ if (Mesh::getKind(elem.type) == _ek_igfem)
return this->fallback_value_igfem;
// return 2;//2model.getMaterialIndex(2);
const Mesh & mesh = model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
Vector<Real> barycenter(spatial_dimension);
mesh.getBarycenter(elem, barycenter);
std::vector<Sphere>::const_iterator iit = spheres.begin();
std::vector<Sphere>::const_iterator eit = spheres.end();
for (; iit != eit; ++iit) {
const Sphere & sp = *iit;
- if(sp.isInside(barycenter)) {
- return 1;//model.getMaterialIndex("inside");;
+ if (sp.isInside(barycenter)) {
+ return 1; // model.getMaterialIndex("inside");;
}
}
return 0;
- //return DefaultMaterialSelector::operator()(elem);
+ // return DefaultMaterialSelector::operator()(elem);
}
void update(Real new_radius) {
std::vector<Sphere>::iterator iit = spheres.begin();
std::vector<Sphere>::iterator eit = spheres.end();
for (; iit != eit; ++iit) {
Real & radius = iit->getRadius();
radius = new_radius;
- }
+ }
}
-
protected:
SolidMechanicsModelIGFEM & model;
std::vector<Sphere> spheres;
};
-
typedef Spherical SK;
-
/// the following modeling problem is explained in:
-/// T.-P. Fries "A corrected XFEM approximation without problems in blending elements", 2008
-int main(int argc, char *argv[]) {
+/// T.-P. Fries "A corrected XFEM approximation without problems in blending
+/// elements", 2008
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
/// problem dimension
- const UInt spatial_dimension = 2;
+ const UInt spatial_dimension = 2;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// mesh creation
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("plate.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
Math::setTolerance(1e-14);
/// geometry of IGFEM interface: circular inclusion
Real radius_inclusion = 0.401;
Vector<Real> center(spatial_dimension, 0.);
/// @todo: Simplify this: need to create two type of spheres:
/// one for the geometry and one for the material selector
- SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0), radius_inclusion * radius_inclusion);
+ SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0),
+ radius_inclusion * radius_inclusion);
std::list<SK::Sphere_3> sphere_list;
sphere_list.push_back(sphere);
ID domain_name = "gel";
SphereMaterialSelector * mat_selector;
-
+
/// set material selector and initialize the model completely
std::vector<Sphere> spheres;
spheres.push_back(Sphere(center, radius_inclusion, 1.e-12));
mat_selector = new SphereMaterialSelector(spheres, model);
model.setMaterialSelector(*mat_selector);
model.initFull();
/// register the sphere list in the model
model.registerGeometryObject(sphere_list, domain_name);
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpField("material_index");
model.addDumpField("partitions");
model.addDumpFieldVector("displacement");
model.addDumpField("blocked_dofs");
model.addDumpField("stress");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldVectorToDumper("igfem elements", "real_displacement");
model.addDumpFieldVectorToDumper("igfem elements", "displacement");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "stress");
model.addDumpFieldToDumper("igfem elements", "partitions");
-
/// dump mesh before the IGFEM interface is created
model.dump();
model.dump("igfem elements");
/// create the interface
model.update(domain_name);
-/* -------------------------------------------------------------------------- */
- /// apply exact solution for the displacement along the outer boundary
+ /* --------------------------------------------------------------------------
+ */
+ /// apply exact solution for the displacement along the outer boundary
Real outer_radius = 2.0;
- /// get the Lame constants for the two non-igfem materials (frist two materials in the material file):
+ /// get the Lame constants for the two non-igfem materials (frist two
+ /// materials in the material file):
/// Needed for compuation of boundary conditions
Vector<Real> lambda(2);
Vector<Real> mu(2);
for (UInt m = 0; m < 2; ++m) {
- MaterialElastic<spatial_dimension> & mat = dynamic_cast<MaterialElastic<spatial_dimension> & >(model.getMaterial(m));
+ MaterialElastic<spatial_dimension> & mat =
+ dynamic_cast<MaterialElastic<spatial_dimension> &>(
+ model.getMaterial(m));
lambda(m) = mat.getLambda();
mu(m) = mat.getMu();
}
applyBoundaryConditions(model, radius_inclusion, outer_radius, lambda, mu);
/// dump the mesh after the IGFEM interface has been created
model.dump();
model.dump("igfem elements");
/// solve the system
bool factorize = false;
bool converged = false;
- Real error;
- converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, error, 2, factorize);
+ Real error;
+ converged = model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(
+ 1e-12, error, 2, factorize);
if (!converged) {
- std::cout << "Solving step did not yield a converged solution, error: " << error << std::endl;
+ std::cout << "Solving step did not yield a converged solution, error: "
+ << error << std::endl;
return EXIT_FAILURE;
}
-
+
/// dump the solution
model.dump();
model.dump("igfem elements");
-
/// output the displacement in parallel
outputArray(mesh, model.getDisplacement());
finalize();
return EXIT_SUCCESS;
}
-
-
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_transfer_internals.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_transfer_internals.cc
index 3c692485e..fdc3182e3 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_transfer_internals.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_transfer_internals.cc
@@ -1,281 +1,299 @@
/**
* @file test_transfer_internals.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
*
* @brief test to test the transfer of internals such as damage
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
#include "aka_common.hh"
- #include "dumper_paraview.hh"
+#include "dumper_paraview.hh"
#include "mesh_geom_common.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-bool checkResults(Real & error, UInt & counter, SolidMechanicsModel & model, Real diagonal);
+bool checkResults(Real & error, UInt & counter, SolidMechanicsModel & model,
+ Real diagonal);
-class ASRMaterialSelector : public DefaultMaterialIGFEMSelector {
+class ASRMaterialSelector : public DefaultMaterialIGFEMSelector {
public:
- ASRMaterialSelector(SolidMechanicsModelIGFEM & model) :
- DefaultMaterialIGFEMSelector(model),
- model(model) {}
+ ASRMaterialSelector(SolidMechanicsModelIGFEM & model)
+ : DefaultMaterialIGFEMSelector(model), model(model) {}
UInt operator()(const Element & elem) {
- if(Mesh::getKind(elem.type) == _ek_igfem)
+ if (Mesh::getKind(elem.type) == _ek_igfem)
/// choose IGFEM material
return this->fallback_value_igfem;
const Mesh & mesh = model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
Vector<Real> barycenter(spatial_dimension);
mesh.getBarycenter(elem, barycenter);
- if(model.isInside(barycenter))
+ if (model.isInside(barycenter))
return 1;
return 0;
}
protected:
SolidMechanicsModelIGFEM & model;
};
-
typedef Spherical SK;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material_damage.dat", argc, argv);
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// problem dimension
- UInt spatial_dimension = 2;
+ UInt spatial_dimension = 2;
/// mesh creation and partioning
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("fine_mesh.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation and initialization
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
-
+
/// create the list to store the gel pockets
std::list<SK::Sphere_3> gel_pocket_list;
model.registerGeometryObject(gel_pocket_list, "mat_1");
/// set the material selector
ASRMaterialSelector * mat_selector = new ASRMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
model.initFull();
/// add fields that should be dumped
model.setBaseName("regular_elements");
model.addDumpField("material_index");
model.addDumpField("damage");
model.addDumpField("Sc");
model.addDumpField("partitions");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "damage");
model.addDumpFieldToDumper("igfem elements", "lambda");
model.addDumpFieldToDumper("igfem elements", "partitions");
/// set damage state as a function of the position of the quadrature
/// point the damage state is the absolute value of bary center
- /// position normalized by the half of the diagonal of the mesh (which is a square)
-
+ /// position normalized by the half of the diagonal of the mesh (which is a
+ /// square)
+
/// compute the mesh diagonal
mesh.computeBoundingBox();
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
Real diagonal = upper_bounds.distance(lower_bounds);
/// compute barycenters and set damage state
GhostType ghost_type = _not_ghost;
ElementType el_type = _triangle_3;
UInt nb_element = mesh.getNbElement(el_type, ghost_type);
Array<Real> barycenter(nb_element, spatial_dimension);
- Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> bary_it =
+ barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem) {
mesh.getBarycenter(elem, el_type, bary_it->storage(), ghost_type);
- UInt mat_index = model.getMaterialByElement(el_type, ghost_type).begin()[elem];
- UInt local_index = model.getMaterialLocalNumbering(el_type, ghost_type).begin()[elem];
+ UInt mat_index =
+ model.getMaterialByElement(el_type, ghost_type).begin()[elem];
+ UInt local_index =
+ model.getMaterialLocalNumbering(el_type, ghost_type).begin()[elem];
Material & mat = model.getMaterial(mat_index);
- Array<Real> & damage = mat.getArray<Real>("damage", el_type, ghost_type);
+ Array<Real> & damage = mat.getArray<Real>("damage", el_type, ghost_type);
Array<Real>::scalar_iterator damage_it = damage.begin();
- damage_it[local_index] = (*bary_it).norm()/(0.5 * diagonal);
+ damage_it[local_index] = (*bary_it).norm() / (0.5 * diagonal);
++bary_it;
}
-
-
+
/// dump
model.dump("igfem elements");
model.dump();
-
/// create the inclusions
SK::Sphere_3 sphere_1(SK::Point_3(0., 0., 0.), 0.13 * 0.13);
SK::Sphere_3 sphere_2(SK::Point_3(0.5, 0.5, 0.), 0.4 * 0.4);
SK::Sphere_3 sphere_3(SK::Point_3(-0.75, -0.75, 0.), 0.12 * 0.12);
SK::Sphere_3 sphere_4(SK::Point_3(0.625, -0.625, 0.), 0.25 * 0.25);
gel_pocket_list.push_back(sphere_1);
gel_pocket_list.push_back(sphere_2);
gel_pocket_list.push_back(sphere_3);
gel_pocket_list.push_back(sphere_4);
/// create the interface
model.update("mat_1");
/// dump
model.dump("igfem elements");
model.dump();
/// check that internals have been transferred correctly
Real error = 0.;
UInt counter = 0;
bool check_passed = checkResults(error, counter, model, diagonal);
if (!check_passed) {
finalize();
return EXIT_FAILURE;
}
comm.allReduce(&error, 1, _so_sum);
comm.allReduce(&counter, 1, _so_sum);
if (prank == 0) {
std::cout << "The error is: " << error << std::endl;
- std::cout << "There are " << counter << " igfem quads with damage material in the mesh" << std::endl;
- std::cout << "There should be 156 igfem quads with damage material in the mesh" << std::endl;
+ std::cout << "There are " << counter
+ << " igfem quads with damage material in the mesh" << std::endl;
+ std::cout
+ << "There should be 156 igfem quads with damage material in the mesh"
+ << std::endl;
}
if (error > 1e-14 || counter != 156) {
finalize();
return EXIT_FAILURE;
}
- // /// grow two of the gel pockets (gel pocket 1 and 3) and repeat the test
- std::list<SK::Sphere_3> new_gel_pocket_list;
+ // /// grow two of the gel pockets (gel pocket 1 and 3) and repeat the test
+ std::list<SK::Sphere_3> new_gel_pocket_list;
/// grow sphere 2
SK::Sphere_3 sphere_5(SK::Point_3(0., 0., 0.), 0.15 * 0.15);
/// grow sphere 3
SK::Sphere_3 sphere_6(SK::Point_3(-0.75, -0.75, 0.), 0.5 * 0.5);
new_gel_pocket_list.push_back(sphere_5);
new_gel_pocket_list.push_back(sphere_2);
new_gel_pocket_list.push_back(sphere_6);
new_gel_pocket_list.push_back(sphere_4);
gel_pocket_list.clear();
gel_pocket_list = new_gel_pocket_list;
model.update("mat_1");
/// check again that internals have been transferred correctly
error = 0.;
counter = 0;
check_passed = checkResults(error, counter, model, diagonal);
if (!check_passed) {
finalize();
return EXIT_FAILURE;
}
comm.allReduce(&error, 1, _so_sum);
comm.allReduce(&counter, 1, _so_sum);
if (prank == 0) {
std::cout << "The error is: " << error << std::endl;
- std::cout << "There are " << counter << " igfem quads with damage material in the mesh" << std::endl;
- std::cout << "There should be 150 igfem quads with damage material in the mesh" << std::endl;
+ std::cout << "There are " << counter
+ << " igfem quads with damage material in the mesh" << std::endl;
+ std::cout
+ << "There should be 150 igfem quads with damage material in the mesh"
+ << std::endl;
}
if (error > 1e-14 || counter != 150) {
finalize();
return EXIT_FAILURE;
}
/// dump
model.dump("igfem elements");
model.dump();
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
-bool checkResults(Real & error, UInt & counter, SolidMechanicsModel & model, Real diagonal) {
- /// check that damage values have been correctly transferred
+bool checkResults(Real & error, UInt & counter, SolidMechanicsModel & model,
+ Real diagonal) {
+ /// check that damage values have been correctly transferred
FEEngine & fee = model.getFEEngine("IGFEMFEEngine");
GhostType ghost_type = _not_ghost;
Mesh & mesh = model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
bool check_passed = true;
/// loop over all IGFEM elements of type _not_ghost
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_igfem);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, ghost_type, _ek_igfem);
+ Mesh::type_iterator last =
+ mesh.lastType(spatial_dimension, ghost_type, _ek_igfem);
for (; it != last; ++it) {
ElementType igfem_el_type = *it;
UInt nb_igfem_element = mesh.getNbElement(igfem_el_type);
UInt nb_quads = fee.getNbIntegrationPoints(igfem_el_type, ghost_type);
Array<Real> barycenter_igfem(nb_igfem_element, spatial_dimension);
- Array<Real>::vector_iterator bary_it = barycenter_igfem.begin(spatial_dimension);
+ Array<Real>::vector_iterator bary_it =
+ barycenter_igfem.begin(spatial_dimension);
UInt * conn_val = mesh.getConnectivity(igfem_el_type, ghost_type).storage();
Array<Real> & nodes = mesh.getNodes();
- UInt nb_parent_nodes = IGFEMHelper::getNbParentNodes(igfem_el_type);
+ UInt nb_parent_nodes = IGFEMHelper::getNbParentNodes(igfem_el_type);
/// compute the bary center of the underlying parent element
UInt nb_el_nodes = mesh.getNbNodesPerElement(igfem_el_type);
for (UInt elem = 0; elem < nb_igfem_element; ++elem) {
Real local_coord[spatial_dimension * nb_parent_nodes];
UInt offset = elem * nb_el_nodes;
for (UInt n = 0; n < nb_parent_nodes; ++n) {
- memcpy(local_coord + n * spatial_dimension,
- nodes.storage() + conn_val[offset + n] * spatial_dimension,
- spatial_dimension*sizeof(Real));
+ memcpy(local_coord + n * spatial_dimension,
+ nodes.storage() + conn_val[offset + n] * spatial_dimension,
+ spatial_dimension * sizeof(Real));
}
- Math::barycenter(local_coord, nb_parent_nodes, spatial_dimension, bary_it->storage());
- UInt mat_index = model.getMaterialByElement(igfem_el_type, ghost_type).begin()[elem];
+ Math::barycenter(local_coord, nb_parent_nodes, spatial_dimension,
+ bary_it->storage());
+ UInt mat_index =
+ model.getMaterialByElement(igfem_el_type, ghost_type).begin()[elem];
Material & mat = model.getMaterial(mat_index);
- UInt local_index = model.getMaterialLocalNumbering(igfem_el_type, ghost_type).begin()[elem];
- Array<Real> & damage = mat.getArray<Real>("damage", igfem_el_type, ghost_type);
- Array<UInt> & sub_mat = mat.getArray<UInt>("sub_material", igfem_el_type, ghost_type);
- Array<Real> & strength = mat.getArray<Real>("Sc", igfem_el_type, ghost_type);
+ UInt local_index =
+ model.getMaterialLocalNumbering(igfem_el_type, ghost_type)
+ .begin()[elem];
+ Array<Real> & damage =
+ mat.getArray<Real>("damage", igfem_el_type, ghost_type);
+ Array<UInt> & sub_mat =
+ mat.getArray<UInt>("sub_material", igfem_el_type, ghost_type);
+ Array<Real> & strength =
+ mat.getArray<Real>("Sc", igfem_el_type, ghost_type);
Array<Real>::scalar_iterator damage_it = damage.begin();
Array<UInt>::scalar_iterator sub_mat_it = sub_mat.begin();
Array<Real>::scalar_iterator Sc_it = strength.begin();
for (UInt q = 0; q < nb_quads; ++q) {
- UInt q_global = local_index * nb_quads + q;
- if (sub_mat_it[q_global] == 1) {
- if (std::abs(Sc_it[q_global] - 100) > 1e-15) {
- check_passed = false;
- return check_passed;
- }
- error += std::abs((damage_it[q_global] -(*bary_it).norm()/(0.5 * diagonal)));
- ++counter;
- }
- else if ( (std::abs(Sc_it[q_global]) > Math::getTolerance()) ||
- (std::abs(damage_it[q_global]) > Math::getTolerance()) ) {
- check_passed = false;
- return check_passed;
- }
- }
+ UInt q_global = local_index * nb_quads + q;
+ if (sub_mat_it[q_global] == 1) {
+ if (std::abs(Sc_it[q_global] - 100) > 1e-15) {
+ check_passed = false;
+ return check_passed;
+ }
+ error += std::abs(
+ (damage_it[q_global] - (*bary_it).norm() / (0.5 * diagonal)));
+ ++counter;
+ } else if ((std::abs(Sc_it[q_global]) > Math::getTolerance()) ||
+ (std::abs(damage_it[q_global]) > Math::getTolerance())) {
+ check_passed = false;
+ return check_passed;
+ }
+ }
++bary_it;
}
}
return check_passed;
}
-
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_volume_computation.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_volume_computation.cc
index d9ea26d52..3ed5b1631 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_volume_computation.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_volume_computation.cc
@@ -1,221 +1,240 @@
/**
* @file test_volume_computation.cc
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 26 12:20:15 2015
*
* @brief test the volume computation for the different sub-materials
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_igfem.hh"
-#include "material_iterative_stiffness_reduction.hh"
#include "material_igfem_saw_tooth_damage.hh"
+#include "material_iterative_stiffness_reduction.hh"
+#include "solid_mechanics_model_igfem.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-class TestMaterialSelector : public MaterialSelector {
+class TestMaterialSelector : public MaterialSelector {
public:
- TestMaterialSelector(SolidMechanicsModelIGFEM & model) :
- MaterialSelector(),
- model(model),
- spatial_dimension(model.getSpatialDimension()){}
+ TestMaterialSelector(SolidMechanicsModelIGFEM & model)
+ : MaterialSelector(), model(model),
+ spatial_dimension(model.getSpatialDimension()) {}
UInt operator()(const Element & element) {
- if(Mesh::getKind(element.type) == _ek_igfem)
+ if (Mesh::getKind(element.type) == _ek_igfem)
return 2;
else {
/// regular elements
const Mesh & mesh = model.getMesh();
Vector<Real> barycenter(this->spatial_dimension);
mesh.getBarycenter(element, barycenter);
/// check if element belongs to ASR gel
- if(model.isInside(barycenter))
- return 1;
+ if (model.isInside(barycenter))
+ return 1;
}
return 0;
}
protected:
SolidMechanicsModelIGFEM & model;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
Math::setTolerance(1e-13);
debug::setDebugLevel(dblWarning);
- initialize("material_stiffness_reduction.dat" ,argc, argv);
+ initialize("material_stiffness_reduction.dat", argc, argv);
const UInt spatial_dimension = 2;
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm =
+ akantu::StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partion it
Mesh mesh(spatial_dimension);
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("test_damage_transfer.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
/// model creation
SolidMechanicsModelIGFEM model(mesh);
model.initParallel(partition);
delete partition;
Math::setTolerance(1.e-14);
/// intialize the geometry and set the material selector
std::list<SK::Sphere_3> inclusions_list;
model.registerGeometryObject(inclusions_list, "inclusion");
Real val = 1000000000;
- Real radius_squared = (val-0.1)*(val-0.1);
+ Real radius_squared = (val - 0.1) * (val - 0.1);
Vector<Real> center(spatial_dimension);
center(0) = 0;
center(1) = val;
SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0.), radius_squared);
inclusions_list.push_back(sphere);
TestMaterialSelector * mat_selector = new TestMaterialSelector(model);
model.setMaterialSelector(*mat_selector);
/// initialization of the model
model.initFull();
/// boundary conditions
mesh.computeBoundingBox();
const Vector<Real> & lowerBounds = mesh.getLowerBounds();
const Vector<Real> & upperBounds = mesh.getUpperBounds();
- Real bottom = lowerBounds(1);
+ Real bottom = lowerBounds(1);
Real top = upperBounds(1);
Real left = lowerBounds(0);
Real eps = std::abs((top - bottom) * 1e-6);
const Array<Real> & pos = mesh.getNodes();
Array<bool> & boun = model.getBlockedDOFs();
Array<Real> & disp = model.getDisplacement();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (std::abs(pos(n,1) - bottom) < eps) {
- boun(n,1) = true;
- disp(n,1) = 0.;
+ if (std::abs(pos(n, 1) - bottom) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 0.;
}
- if (std::abs(pos(n,1) - top) < eps) {
- boun(n,1) = true;
- disp(n,1) = 1.e-3;
+ if (std::abs(pos(n, 1) - top) < eps) {
+ boun(n, 1) = true;
+ disp(n, 1) = 1.e-3;
+ }
+ if (std::abs(pos(n, 0) - left) < eps) {
+ boun(n, 0) = true;
+ disp(n, 0) = 0.;
}
- if (std::abs(pos(n,0) - left) < eps) {
- boun(n,0) = true;
- disp(n,0) = 0.;
- }
}
/// add fields that should be dumped
model.setBaseName("regular");
model.addDumpField("material_index");
- model.addDumpFieldVector("displacement");;
+ model.addDumpFieldVector("displacement");
+ ;
model.addDumpField("stress");
model.addDumpField("blocked_dofs");
model.addDumpField("residual");
model.addDumpField("grad_u");
model.addDumpField("damage");
model.addDumpField("partitions");
model.addDumpField("Sc");
model.addDumpField("force");
model.addDumpField("equivalent_stress");
model.addDumpField("ultimate_strain");
model.setBaseNameToDumper("igfem elements", "igfem elements");
model.addDumpFieldToDumper("igfem elements", "material_index");
- model.addDumpFieldVectorToDumper("igfem elements", "displacement");;
+ model.addDumpFieldVectorToDumper("igfem elements", "displacement");
+ ;
model.addDumpFieldToDumper("igfem elements", "stress");
model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
model.addDumpFieldToDumper("igfem elements", "residual");
model.addDumpFieldToDumper("igfem elements", "grad_u");
model.addDumpFieldToDumper("igfem elements", "damage");
model.addDumpFieldToDumper("igfem elements", "partitions");
model.addDumpFieldToDumper("igfem elements", "Sc");
model.addDumpFieldToDumper("igfem elements", "force");
model.addDumpFieldToDumper("igfem elements", "equivalent_stress");
model.addDumpFieldToDumper("igfem elements", "ultimate_strain");
model.dump();
model.dump("igfem elements");
- Real new_radius = (val-0.1);
+ Real new_radius = (val - 0.1);
model.moveInterface(new_radius);
model.update("inclusion");
model.dump();
model.dump("igfem elements");
/// get a reference to the all the materials
const Material & standard_material_damage = model.getMaterial(0);
const Material & standard_material_elastic = model.getMaterial(1);
const Material & igfem_material = model.getMaterial(2);
const ElementType standard_type = _triangle_3;
const ElementType igfem_type = _igfem_triangle_5;
/// compute the volume on both sides of the interface
/// regular elements
- const Array<UInt> & material_filter_0 = standard_material_damage.getElementFilter(standard_type);
- const Array<UInt> & material_filter_1 = standard_material_elastic.getElementFilter(standard_type);
- const Array<UInt> & material_filter_2 = igfem_material.getElementFilter(igfem_type);
-
- Array<Real> Volume_0(material_filter_0.getSize() * model.getFEEngine().getNbIntegrationPoints(standard_type), 1, 1.);
- Real volume_material_damage = model.getFEEngine().integrate(Volume_0, standard_type, _not_ghost, material_filter_0);
-
- Array<Real> Volume_1(material_filter_1.getSize() * model.getFEEngine().getNbIntegrationPoints(standard_type), 1, 1.);
- Real volume_material_elastic = model.getFEEngine().integrate(Volume_1, standard_type, _not_ghost, material_filter_1);
+ const Array<UInt> & material_filter_0 =
+ standard_material_damage.getElementFilter(standard_type);
+ const Array<UInt> & material_filter_1 =
+ standard_material_elastic.getElementFilter(standard_type);
+ const Array<UInt> & material_filter_2 =
+ igfem_material.getElementFilter(igfem_type);
+
+ Array<Real> Volume_0(
+ material_filter_0.getSize() *
+ model.getFEEngine().getNbIntegrationPoints(standard_type),
+ 1, 1.);
+ Real volume_material_damage = model.getFEEngine().integrate(
+ Volume_0, standard_type, _not_ghost, material_filter_0);
+
+ Array<Real> Volume_1(
+ material_filter_1.getSize() *
+ model.getFEEngine().getNbIntegrationPoints(standard_type),
+ 1, 1.);
+ Real volume_material_elastic = model.getFEEngine().integrate(
+ Volume_1, standard_type, _not_ghost, material_filter_1);
/// igfem elements
- const Array<UInt> & sub_mat = igfem_material.getInternal<UInt>("sub_material")(igfem_type, _not_ghost);
+ const Array<UInt> & sub_mat =
+ igfem_material.getInternal<UInt>("sub_material")(igfem_type, _not_ghost);
Array<Real> sub_mat_to_real(sub_mat.getSize(), 1, 1.);
- for (UInt i = 0; i < sub_mat.getSize(); ++i)
+ for (UInt i = 0; i < sub_mat.getSize(); ++i)
sub_mat_to_real(i) = Real(sub_mat(i));
- Real volume_outside = model.getFEEngine("IGFEMFEEngine").integrate(sub_mat_to_real, igfem_type, _not_ghost, material_filter_2);
+ Real volume_outside = model.getFEEngine("IGFEMFEEngine")
+ .integrate(sub_mat_to_real, igfem_type, _not_ghost,
+ material_filter_2);
Array<Real> IGFEMVolume(sub_mat.getSize(), 1, 1.);
- Real total_igfem_volume = model.getFEEngine("IGFEMFEEngine").integrate(IGFEMVolume, igfem_type, _not_ghost, material_filter_2);
+ Real total_igfem_volume =
+ model.getFEEngine("IGFEMFEEngine")
+ .integrate(IGFEMVolume, igfem_type, _not_ghost, material_filter_2);
Real volume_inside = total_igfem_volume - volume_outside;
-
Math::setTolerance(1.e-8);
- if (!Math::are_float_equal(volume_material_damage, 0.5) || !Math::are_float_equal(volume_material_elastic, 0.25)
- || !Math::are_float_equal(volume_outside, 0.1) || !Math::are_float_equal(volume_inside, (0.15))) {
+ if (!Math::are_float_equal(volume_material_damage, 0.5) ||
+ !Math::are_float_equal(volume_material_elastic, 0.25) ||
+ !Math::are_float_equal(volume_outside, 0.1) ||
+ !Math::are_float_equal(volume_inside, (0.15))) {
std::cout << "the test failed!!!" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/force_based_dirichlet.hh b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/force_based_dirichlet.hh
index eb4244521..b2b4214fa 100644
--- a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/force_based_dirichlet.hh
+++ b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/force_based_dirichlet.hh
@@ -1,122 +1,117 @@
/**
* @file force_based_dirichlet.hh
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief dirichlet boundary condition that tries
* to keep the force at a given value
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_FORCE_BASED_DIRICHLET_HH__
#define __AST_FORCE_BASED_DIRICHLET_HH__
// akantu
#include "aka_common.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class ForceBasedDirichlet : public BC::Dirichlet::IncrementValue {
protected:
typedef const Array<Real> * RealArrayPtr;
typedef const Array<Int> * IntArrayPtr;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- ForceBasedDirichlet(SolidMechanicsModel & model,
- BC::Axis ax,
- Real target_f,
- Real mass = 0.) :
- IncrementValue(0., ax),
- model(model),
- mass(mass),
- velocity(0.),
- target_force(target_f),
- total_residual(0.)
- {}
+ ForceBasedDirichlet(SolidMechanicsModel & model, BC::Axis ax, Real target_f,
+ Real mass = 0.)
+ : IncrementValue(0., ax), model(model), mass(mass), velocity(0.),
+ target_force(target_f), total_residual(0.) {}
virtual ~ForceBasedDirichlet() {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void updateTotalResidual() {
- SubBoundarySet::iterator it = this->subboundaries.begin();
+ SubBoundarySet::iterator it = this->subboundaries.begin();
SubBoundarySet::iterator end = this->subboundaries.end();
this->total_residual = 0.;
for (; it != end; ++it) {
this->total_residual += integrateResidual(*it, this->model, this->axis);
}
}
virtual Real update() {
AKANTU_DEBUG_IN();
-
+
this->updateTotalResidual();
Real total_force = this->target_force + this->total_residual;
-
+
Real a = total_force / this->mass;
- Real dt = model.getTimeStep();
- this->velocity += 0.5*dt*a;
- this->value = this->velocity*dt + 0.5*dt*dt*a; // increment position dx
- this->velocity += 0.5*dt*a;
-
+ Real dt = model.getTimeStep();
+ this->velocity += 0.5 * dt * a;
+ this->value =
+ this->velocity * dt + 0.5 * dt * dt * a; // increment position dx
+ this->velocity += 0.5 * dt * a;
+
AKANTU_DEBUG_OUT();
return this->total_residual;
}
Real applyYourself() {
AKANTU_DEBUG_IN();
Real reaction = this->update();
- SubBoundarySet::iterator it = this->subboundaries.begin();
+ SubBoundarySet::iterator it = this->subboundaries.begin();
SubBoundarySet::iterator end = this->subboundaries.end();
for (; it != end; ++it) {
- this->model.applyBC(*this,*it);
+ this->model.applyBC(*this, *it);
}
-
+
AKANTU_DEBUG_OUT();
return reaction;
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_SET_MACRO(Mass, mass, Real);
AKANTU_SET_MACRO(TargetForce, target_force, Real);
void insertSubBoundary(const std::string & sb_name) {
this->subboundaries.insert(sb_name);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
typedef std::set<std::string> SubBoundarySet;
+
protected:
SolidMechanicsModel & model;
SubBoundarySet subboundaries;
Real mass;
Real velocity;
Real target_force;
Real total_residual;
};
} // namespace akantu
#endif /* __AST_FORCE_BASED_DIRICHLET_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
index b71619eb8..cc680d96f 100644
--- a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
+++ b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
@@ -1,74 +1,66 @@
/**
* @file inclined_flat_dirichlet.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief inclined dirichlet
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_INCLINED_FLAT_DIRICHLET_HH__
#define __AST_INCLINED_FLAT_DIRICHLET_HH__
// akantu
#include "aka_common.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class InclinedFlatDirichlet : public BC::Dirichlet::DirichletFunctor {
-
+
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- InclinedFlatDirichlet(Real val,
- BC::Axis ax,
- BC::Axis incl_ax,
- Real center_coord,
- Real tang) :
- DirichletFunctor(ax),
- value(val),
- incl_ax(incl_ax),
- center_coord(center_coord),
- tang(tang) {};
+ InclinedFlatDirichlet(Real val, BC::Axis ax, BC::Axis incl_ax,
+ Real center_coord, Real tang)
+ : DirichletFunctor(ax), value(val), incl_ax(incl_ax),
+ center_coord(center_coord), tang(tang){};
virtual ~InclinedFlatDirichlet() {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- inline void operator()(UInt node,
- Vector<bool> & flags,
- Vector<Real> & primal,
- const Vector<Real> & coord) const {
+ inline void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal,
+ const Vector<Real> & coord) const {
AKANTU_DEBUG_IN();
Real dist = coord(incl_ax) - this->center_coord;
flags(axis) = true;
primal(axis) = this->value + this->tang * dist;
-
+
AKANTU_DEBUG_OUT();
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
Real value;
BC::Axis incl_ax;
Real center_coord;
Real tang;
};
} // namespace akantu
#endif /* __AST_INCLINED_FLAT_DIRICHLET_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/spring_bc.hh b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/spring_bc.hh
index 54b4b41b2..d026e1a40 100644
--- a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/spring_bc.hh
+++ b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/spring_bc.hh
@@ -1,137 +1,127 @@
/**
* @file spring_bc.hh
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief spring boundary condition
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_SPRING_BC_HH__
#define __AST_SPRING_BC_HH__
// simtools
#include "force_based_dirichlet.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class SpringBC : public ForceBasedDirichlet {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- SpringBC(SolidMechanicsModel & model,
- BC::Axis ax,
- Real stiffness,
- Real mass = 0.) :
- ForceBasedDirichlet(model, ax, 0., mass),
- stiffness(stiffness),
- elongation(0.)
- {}
+ SpringBC(SolidMechanicsModel & model, BC::Axis ax, Real stiffness,
+ Real mass = 0.)
+ : ForceBasedDirichlet(model, ax, 0., mass), stiffness(stiffness),
+ elongation(0.) {}
virtual ~SpringBC() {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual Real update() {
AKANTU_DEBUG_IN();
- this->target_force = - this->stiffness * this->elongation;
+ this->target_force = -this->stiffness * this->elongation;
Real reaction = ForceBasedDirichlet::update();
this->elongation += this->value;
AKANTU_DEBUG_OUT();
return reaction;
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Elongation, elongation, Real);
inline void setToEquilibrium() {
AKANTU_DEBUG_IN();
-
+
this->updateTotalResidual();
- this->target_force = - this->total_residual;
- this->elongation = - this->target_force / this->stiffness;
-
+ this->target_force = -this->total_residual;
+ this->elongation = -this->target_force / this->stiffness;
+
AKANTU_DEBUG_OUT();
}
/// change elongation
/// dx > 0 -> target_force < 0
inline void incrementElongation(Real dx) {
AKANTU_DEBUG_IN();
this->elongation += dx;
AKANTU_DEBUG_OUT();
}
- //friend std::ostream& operator<<(std::ostream& out, const SpringBC & spring);
+ // friend std::ostream& operator<<(std::ostream& out, const SpringBC &
+ // spring);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
Real stiffness;
Real elongation;
};
-
-
-
-
-
-
-
-
-
// class SpringBCRestricted : public SpringBC {
// public:
-// SpringBCRestricted(BC::Axis ax, Real target_force, BC::Axis surface_axis, Real min, Real max)
-// :SpringBC(ax, target_force), surface_axis(surface_axis), min(min), max(max) {}
+// SpringBCRestricted(BC::Axis ax, Real target_force, BC::Axis surface_axis,
+// Real min, Real max)
+// :SpringBC(ax, target_force), surface_axis(surface_axis), min(min),
+// max(max) {}
// virtual ~SpringBCRestricted() {}
// public:
-// inline void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal, const Vector<Real> & coord) const {
+// inline void operator()(UInt node, Vector<bool> & flags, Vector<Real> &
+// primal, const Vector<Real> & coord) const {
// if(coord(surface_axis) > min && coord(surface_axis) < max) {
// SpringBC::operator()(node, flags, primal, coord);
// }
// }
// private:
// BC::Axis surface_axis;
// Real min;
// Real max;
// };
// std::ostream& operator<<(std::ostream& out, const SpringBC & spring) {
// out << "Real total_residual: " << *spring.total_residual << std::endl;
// out << "Real mass: " << spring.mass << std::endl;
// out << "Real k: " << spring.k << std::endl;
// out << "Real delta_x: " << spring.delta_x << std::endl;
// out << "Real dt: " << spring.dt << std::endl;
// out << "Real v: " << spring.v << std::endl;
// out << "Real dx: " << spring.dx << std::endl;
// out << "Real forcing_vel: " << spring.forcing_vel << std::endl;
// return out;
// }
-
} // namespace akantu
#endif /* __AST_SPRING_BC_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/common/manual_restart.cc b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.cc
index efda2570f..8abdcd9c5 100644
--- a/extra_packages/traction-at-split-node-contact/src/common/manual_restart.cc
+++ b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.cc
@@ -1,126 +1,127 @@
/**
* @file manual_restart.cc
*
*
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/**
* @file manual_restart.cc
* @author Dana Christen <dana.christen@epfl.ch>
* @date May 15, 2013
*/
/* -------------------------------------------------------------------------- */
#include "manual_restart.hh"
//#include <iostream>
#include <fstream>
using namespace akantu;
void dumpArray(const Array<Real> & array, const std::string & fname) {
std::ofstream outFile;
outFile.open(fname.c_str());
outFile.precision(9);
outFile.setf(std::ios::scientific);
UInt size = array.getSize();
UInt nb_component = array.getNbComponent();
outFile << size << std::endl;
outFile << nb_component << std::endl;
- Array<Real>::const_iterator< Vector<Real> > tit = array.begin(nb_component);
- Array<Real>::const_iterator< Vector<Real> > tend = array.end(nb_component);
- for(; tit != tend; ++tit) {
- for (UInt c=0; c<nb_component; ++c) {
- if (c != 0)
- outFile << " ";
+ Array<Real>::const_iterator<Vector<Real>> tit = array.begin(nb_component);
+ Array<Real>::const_iterator<Vector<Real>> tend = array.end(nb_component);
+ for (; tit != tend; ++tit) {
+ for (UInt c = 0; c < nb_component; ++c) {
+ if (c != 0)
+ outFile << " ";
outFile << (*tit)(c);
}
outFile << std::endl;
}
outFile.close();
}
void loadArray(Array<Real> & array, const std::string & fname) {
std::ifstream inFile;
inFile.open(fname.c_str());
inFile.precision(9);
inFile.setf(std::ios::scientific);
UInt size(0), nb_comp(0);
inFile >> size;
inFile >> nb_comp;
- AKANTU_DEBUG_ASSERT(array.getNbComponent() == nb_comp, "BAD NUM OF COMPONENTS");
- AKANTU_DEBUG_ASSERT(array.getSize() == size, "loadArray: number of data points in file ("
- << size << ") does not correspond to array size (" << array.getSize()
- << ")!!");
- Array<Real>::iterator< Vector<Real> > tit = array.begin(nb_comp);
- Array<Real>::iterator< Vector<Real> > tend = array.end(nb_comp);
+ AKANTU_DEBUG_ASSERT(array.getNbComponent() == nb_comp,
+ "BAD NUM OF COMPONENTS");
+ AKANTU_DEBUG_ASSERT(array.getSize() == size,
+ "loadArray: number of data points in file ("
+ << size << ") does not correspond to array size ("
+ << array.getSize() << ")!!");
+ Array<Real>::iterator<Vector<Real>> tit = array.begin(nb_comp);
+ Array<Real>::iterator<Vector<Real>> tend = array.end(nb_comp);
array.resize(size);
- for(UInt i(0); i < size; ++i, ++tit) {
- for (UInt c=0; c < nb_comp; ++c) {
+ for (UInt i(0); i < size; ++i, ++tit) {
+ for (UInt c = 0; c < nb_comp; ++c) {
inFile >> (*tit)(c);
}
}
inFile.close();
}
/* -------------------------------------------------------------------------- */
-void loadRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname,
- akantu::UInt prank) {
+void loadRestart(akantu::SolidMechanicsModel & model, const std::string & fname,
+ akantu::UInt prank) {
const akantu::Mesh & mesh = model.getMesh();
const akantu::UInt spatial_dimension = model.getMesh().getSpatialDimension();
- const_cast<DOFSynchronizer &>(model.getDOFSynchronizer()).initScatterGatherCommunicationScheme();
-
- if(prank == 0) {
- akantu::Array<akantu::Real> full_reload_array(mesh.getNbGlobalNodes(),
- spatial_dimension);
+ const_cast<DOFSynchronizer &>(model.getDOFSynchronizer())
+ .initScatterGatherCommunicationScheme();
+
+ if (prank == 0) {
+ akantu::Array<akantu::Real> full_reload_array(mesh.getNbGlobalNodes(),
+ spatial_dimension);
loadArray(full_reload_array, fname);
- model.getDOFSynchronizer().scatter(model.getDisplacement(), 0, &full_reload_array);
+ model.getDOFSynchronizer().scatter(model.getDisplacement(), 0,
+ &full_reload_array);
} else {
model.getDOFSynchronizer().scatter(model.getDisplacement(), 0);
}
-
-
}
/* -------------------------------------------------------------------------- */
-void loadRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname) {
+void loadRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname) {
loadArray(model.getDisplacement(), fname);
}
/* -------------------------------------------------------------------------- */
-void dumpRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname,
- akantu::UInt prank) {
+void dumpRestart(akantu::SolidMechanicsModel & model, const std::string & fname,
+ akantu::UInt prank) {
const akantu::Mesh & mesh = model.getMesh();
const akantu::UInt spatial_dimension = model.getMesh().getSpatialDimension();
- const_cast<DOFSynchronizer &>(model.getDOFSynchronizer()).initScatterGatherCommunicationScheme();
-
- if(prank == 0) {
- akantu::Array<akantu::Real> full_array(mesh.getNbGlobalNodes(),
- spatial_dimension);
+ const_cast<DOFSynchronizer &>(model.getDOFSynchronizer())
+ .initScatterGatherCommunicationScheme();
+
+ if (prank == 0) {
+ akantu::Array<akantu::Real> full_array(mesh.getNbGlobalNodes(),
+ spatial_dimension);
model.getDOFSynchronizer().gather(model.getDisplacement(), 0, &full_array);
dumpArray(full_array, fname);
} else {
model.getDOFSynchronizer().gather(model.getDisplacement(), 0);
}
}
/* -------------------------------------------------------------------------- */
-void dumpRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname) {
+void dumpRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname) {
dumpArray(model.getDisplacement(), fname);
}
diff --git a/extra_packages/traction-at-split-node-contact/src/common/manual_restart.hh b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.hh
index 3217e140e..be9d73465 100644
--- a/extra_packages/traction-at-split-node-contact/src/common/manual_restart.hh
+++ b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.hh
@@ -1,37 +1,36 @@
/**
* @file manual_restart.hh
*
*
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/**
* @file manual_restart.hh
* @author Dana Christen <dana.christen@epfl.ch>
* @date May 15, 2013
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "solid_mechanics_model.hh"
-void dumpArray(const akantu::Array<akantu::Real> & array, const std::string & fname);
+void dumpArray(const akantu::Array<akantu::Real> & array,
+ const std::string & fname);
void loadArray(akantu::Array<akantu::Real> & array, const std::string & fname);
-void loadRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname,
- akantu::UInt prank);
-void loadRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname);
-void dumpRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname,
- akantu::UInt prank);
-void dumpRestart(akantu::SolidMechanicsModel & model,
- const std::string & fname);
+void loadRestart(akantu::SolidMechanicsModel & model, const std::string & fname,
+ akantu::UInt prank);
+void loadRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname);
+void dumpRestart(akantu::SolidMechanicsModel & model, const std::string & fname,
+ akantu::UInt prank);
+void dumpRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname);
diff --git a/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.cc b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.cc
index 86b95acc7..fc2515008 100644
--- a/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.cc
+++ b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.cc
@@ -1,447 +1,441 @@
/**
* @file parameter_reader.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of parameter reader
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// std
-#include <iostream>
+#include <algorithm>
#include <fstream>
+#include <iostream>
#include <utility>
-#include <algorithm>
// simtools
#include "parameter_reader.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-ParameterReader::ParameterReader() :
- data_types(),
- element_type_data(),
- string_data(),
- int_data(),
- uint_data(),
- real_data(),
- bool_data()
-{
+ParameterReader::ParameterReader()
+ : data_types(), element_type_data(), string_data(), int_data(), uint_data(),
+ real_data(), bool_data() {
AKANTU_DEBUG_IN();
// setup of types of element
data_types.insert("elementtype");
data_types.insert("string");
data_types.insert("uint");
data_types.insert("int");
data_types.insert("real");
data_types.insert("bool");
// data_types.insert("surface");
-
+
// define conversion maps
_input_to_akantu_element_types["_segment_2"] = akantu::_segment_2;
_input_to_akantu_element_types["_segment_3"] = akantu::_segment_3;
_input_to_akantu_element_types["_triangle_3"] = akantu::_triangle_3;
_input_to_akantu_element_types["_triangle_6"] = akantu::_triangle_6;
_input_to_akantu_element_types["_tetrahedron_4"] = akantu::_tetrahedron_4;
_input_to_akantu_element_types["_tetrahedron_10"] = akantu::_tetrahedron_10;
_input_to_akantu_element_types["_quadrangle_4"] = akantu::_quadrangle_4;
_input_to_akantu_element_types["_quadrangle_8"] = akantu::_quadrangle_8;
_input_to_akantu_element_types["_hexahedron_8"] = akantu::_hexahedron_8;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ParameterReader::readInputFile(std::string file_name) {
AKANTU_DEBUG_IN();
-
+
char comment_char = '#';
char equal_char = '=';
- // open a file called file name
+ // open a file called file name
std::ifstream infile;
infile.open(file_name.c_str());
- if(!infile.good()) {
+ if (!infile.good()) {
std::cerr << "Cannot open file " << file_name << "!!!" << std::endl;
exit(EXIT_FAILURE);
}
std::string line;
std::string clean_line;
- while(infile.good()) {
+ while (infile.good()) {
getline(infile, line);
clean_line = line;
// take out comments
size_t found_comment;
found_comment = line.find_first_of(comment_char);
if (found_comment != std::string::npos)
- clean_line = line.substr(0,found_comment);
+ clean_line = line.substr(0, found_comment);
if (clean_line.empty())
continue;
std::stringstream sstr(clean_line);
// check if data type exists
std::string type;
sstr >> type;
- std::transform(type.begin(),type.end(),type.begin(),::tolower);
+ std::transform(type.begin(), type.end(), type.begin(), ::tolower);
if (this->data_types.find(type) == this->data_types.end()) {
std::cerr << " *** WARNING *** Data type " << type << " does not exist"
- << " in this input data structure. Ignore line: ";
+ << " in this input data structure. Ignore line: ";
std::cerr << clean_line << std::endl;
continue;
}
-
+
std::string keyword;
std::string equal;
std::string value;
// get keyword
sstr >> keyword;
size_t equal_p = keyword.find_first_of(equal_char);
if (equal_p != std::string::npos) {
- equal = keyword.substr(equal_p,std::string::npos);
- keyword = keyword.substr(0,equal_p);
+ equal = keyword.substr(equal_p, std::string::npos);
+ keyword = keyword.substr(0, equal_p);
}
// get equal
if (equal.empty())
sstr >> equal;
if (equal.length() != 1) {
- value = equal.substr(1,std::string::npos);
+ value = equal.substr(1, std::string::npos);
equal = equal[0];
}
if (equal[0] != equal_char) {
std::cerr << " *** WARNING *** Unrespected convention! Ignore line: ";
std::cerr << clean_line << std::endl;
continue;
}
-
+
// get value
if (value.empty())
sstr >> value;
-
+
// no value
if (value.empty()) {
std::cerr << " *** WARNING *** No value given! Ignore line: ";
std::cerr << clean_line << std::endl;
continue;
}
-
+
// put value in map
std::stringstream convert(value);
if (type.compare("elementtype") == 0) {
std::map<std::string, akantu::ElementType>::const_iterator it;
it = this->_input_to_akantu_element_types.find(value);
if (it != this->_input_to_akantu_element_types.end())
- this->element_type_data.insert(std::make_pair(keyword,it->second));
+ this->element_type_data.insert(std::make_pair(keyword, it->second));
else {
- std::cerr << " *** WARNING *** ElementType " << value << " does not exist. Ignore line: ";
- std::cerr << clean_line << std::endl;
- continue;
+ std::cerr << " *** WARNING *** ElementType " << value
+ << " does not exist. Ignore line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
}
- }
- else if (type.compare("string") == 0) {
- this->string_data.insert(std::make_pair(keyword,value));
+ } else if (type.compare("string") == 0) {
+ this->string_data.insert(std::make_pair(keyword, value));
}
/*
else if (type.compare("surface") == 0) {
//Surface surf;
UInt surf;
convert >> surf;
//this->surface_data.insert(std::make_pair(keyword,surf));
this->uint_data.insert(std::make_pair(keyword,surf));
}
*/
else if (type.compare("int") == 0) {
Int i;
convert >> i;
- this->int_data.insert(std::make_pair(keyword,i));
- }
- else if (type.compare("uint") == 0) {
+ this->int_data.insert(std::make_pair(keyword, i));
+ } else if (type.compare("uint") == 0) {
UInt i;
convert >> i;
- this->uint_data.insert(std::make_pair(keyword,i));
- }
- else if (type.compare("real") == 0) {
+ this->uint_data.insert(std::make_pair(keyword, i));
+ } else if (type.compare("real") == 0) {
Real r;
convert >> r;
- this->real_data.insert(std::make_pair(keyword,r));
- }
- else if (type.compare("bool") == 0) {
- std::transform(value.begin(),value.end(),value.begin(),::tolower);
+ this->real_data.insert(std::make_pair(keyword, r));
+ } else if (type.compare("bool") == 0) {
+ std::transform(value.begin(), value.end(), value.begin(), ::tolower);
bool b;
if (value.compare("true") == 0)
- b = true;
+ b = true;
else if (value.compare("false") == 0)
- b = false;
+ b = false;
else {
- std::cerr << " *** WARNING *** boolean cannot be " << value << ". Ignore line: ";
- std::cerr << clean_line << std::endl;
- continue;
+ std::cerr << " *** WARNING *** boolean cannot be " << value
+ << ". Ignore line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
}
- this->bool_data.insert(std::make_pair(keyword,b));
- }
- else {
+ this->bool_data.insert(std::make_pair(keyword, b));
+ } else {
std::cerr << " *** ERROR *** Could not add data to InputData for line: ";
std::cerr << clean_line << std::endl;
continue;
exit(EXIT_FAILURE);
}
}
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ParameterReader::writeInputFile(std::string file_name) const {
AKANTU_DEBUG_IN();
-
+
// open file to write input information
std::ofstream outfile;
outfile.open(file_name.c_str());
// element type
- for (std::map<std::string, akantu::ElementType>::const_iterator it = element_type_data.begin();
+ for (std::map<std::string, akantu::ElementType>::const_iterator it =
+ element_type_data.begin();
it != element_type_data.end(); ++it) {
- for (std::map<std::string, ElementType>::const_iterator et = _input_to_akantu_element_types.begin();
- et != _input_to_akantu_element_types.end(); ++et) {
+ for (std::map<std::string, ElementType>::const_iterator et =
+ _input_to_akantu_element_types.begin();
+ et != _input_to_akantu_element_types.end(); ++et) {
if (it->second == et->second) {
- outfile << "ElementType " << it->first << " = " << et->first << std::endl;
- continue;
+ outfile << "ElementType " << it->first << " = " << et->first
+ << std::endl;
+ continue;
}
}
}
-
+
// string
- for (std::map<std::string, std::string>::const_iterator it = string_data.begin();
+ for (std::map<std::string, std::string>::const_iterator it =
+ string_data.begin();
it != string_data.end(); ++it)
outfile << "string " << it->first << " = " << it->second << std::endl;
// Surface
/*
- for (std::map<std::string, akantu::Surface>::const_iterator it = surface_data.begin();
+ for (std::map<std::string, akantu::Surface>::const_iterator it =
+ surface_data.begin();
it != surface_data.end(); ++it)
outfile << "Surface " << it->first << " = " << it->second << std::endl;
*/
// Int
for (std::map<std::string, akantu::Int>::const_iterator it = int_data.begin();
it != int_data.end(); ++it)
outfile << "Int " << it->first << " = " << it->second << std::endl;
// UInt
- for (std::map<std::string, akantu::UInt>::const_iterator it = uint_data.begin();
+ for (std::map<std::string, akantu::UInt>::const_iterator it =
+ uint_data.begin();
it != uint_data.end(); ++it)
outfile << "UInt " << it->first << " = " << it->second << std::endl;
// Real
- for (std::map<std::string, akantu::Real>::const_iterator it = real_data.begin();
+ for (std::map<std::string, akantu::Real>::const_iterator it =
+ real_data.begin();
it != real_data.end(); ++it)
outfile << "Real " << it->first << " = " << it->second << std::endl;
-
+
// Bool
for (std::map<std::string, bool>::const_iterator it = bool_data.begin();
it != bool_data.end(); ++it) {
std::string b = "false";
if (it->second)
b = "true";
outfile << "bool " << it->first << " = " << b << std::endl;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<>
+template <>
akantu::UInt ParameterReader::get<akantu::UInt>(std::string key) const {
- std::map<std::string,akantu::UInt>::const_iterator it;
+ std::map<std::string, akantu::UInt>::const_iterator it;
it = this->uint_data.find(key);
-
+
// if not in map
if (it == this->uint_data.end()) {
- std::cerr << " *** ERROR *** This data was not in input file. "
- << "You need the following line in your input file: ";
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
std::cerr << "UInt " << key << " = ???" << std::endl;
exit(EXIT_FAILURE);
}
-
- else
+
+ else
return it->second;
}
/* -------------------------------------------------------------------------- */
-template<>
-akantu::ElementType ParameterReader::get<akantu::ElementType>(std::string key) const {
- std::map<std::string,akantu::ElementType>::const_iterator it;
+template <>
+akantu::ElementType
+ParameterReader::get<akantu::ElementType>(std::string key) const {
+ std::map<std::string, akantu::ElementType>::const_iterator it;
it = this->element_type_data.find(key);
-
+
// if not in map
if (it == this->element_type_data.end()) {
- std::cerr << " *** ERROR *** This data was not in input file. "
- << "You need the following line in your input file: ";
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
std::cerr << "ElementType " << key << " = ???" << std::endl;
exit(EXIT_FAILURE);
}
-
- else
+
+ else
return it->second;
}
/* -------------------------------------------------------------------------- */
-template<>
+template <>
std::string ParameterReader::get<std::string>(std::string key) const {
- std::map<std::string,std::string>::const_iterator it;
+ std::map<std::string, std::string>::const_iterator it;
it = this->string_data.find(key);
-
+
// if not in map
if (it == this->string_data.end()) {
- std::cerr << " *** ERROR *** This data was not in input file. "
- << "You need the following line in your input file: ";
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
std::cerr << "string " << key << " = ???" << std::endl;
exit(EXIT_FAILURE);
}
-
- else
+
+ else
return it->second;
}
/* -------------------------------------------------------------------------- */
/*
template<>
akantu::Surface ParameterData::get<akantu::Surface>(std::string key) const {
std::map<std::string,akantu::Surface>::const_iterator it;
it = this->surface_data.find(key);
-
+
// if not in map
if (it == this->surface_data.end()) {
- std::cerr << " *** ERROR *** This data was not in input file. "
- << "You need the following line in your input file: ";
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
std::cerr << "Surface " << key << " = ???" << std::endl;
exit(EXIT_FAILURE);
}
-
- else
+
+ else
return it->second;
}
*/
/* -------------------------------------------------------------------------- */
-template<>
+template <>
akantu::Int ParameterReader::get<akantu::Int>(std::string key) const {
- std::map<std::string,akantu::Int>::const_iterator it;
+ std::map<std::string, akantu::Int>::const_iterator it;
it = this->int_data.find(key);
-
+
// if not in map
if (it == this->int_data.end()) {
- std::cerr << " *** ERROR *** This data was not in input file. "
- << "You need the following line in your input file: ";
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
std::cerr << "Int " << key << " = ???" << std::endl;
exit(EXIT_FAILURE);
}
-
- else
+
+ else
return it->second;
}
/* -------------------------------------------------------------------------- */
-template<>
+template <>
akantu::Real ParameterReader::get<akantu::Real>(std::string key) const {
- std::map<std::string,akantu::Real>::const_iterator it;
+ std::map<std::string, akantu::Real>::const_iterator it;
it = this->real_data.find(key);
-
+
// if not in map
if (it == this->real_data.end()) {
- std::cerr << " *** ERROR *** This data was not in input file. "
- << "You need the following line in your input file: ";
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
std::cerr << "Real " << key << " = ???" << std::endl;
exit(EXIT_FAILURE);
}
-
- else
+
+ else
return it->second;
}
/* -------------------------------------------------------------------------- */
-template<>
-bool ParameterReader::get<bool>(std::string key) const {
- std::map<std::string,bool>::const_iterator it;
+template <> bool ParameterReader::get<bool>(std::string key) const {
+ std::map<std::string, bool>::const_iterator it;
it = this->bool_data.find(key);
-
+
// if not in map
if (it == this->bool_data.end()) {
- std::cerr << " *** ERROR *** This data was not in input file. "
- << "You need the following line in your input file: ";
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
std::cerr << "bool " << key << " = ???" << std::endl;
exit(EXIT_FAILURE);
}
-
- else
+
+ else
return it->second;
}
/* -------------------------------------------------------------------------- */
-template<>
-bool ParameterReader::has<bool>(std::string key) const {
- std::map<std::string,bool>::const_iterator it;
+template <> bool ParameterReader::has<bool>(std::string key) const {
+ std::map<std::string, bool>::const_iterator it;
it = this->bool_data.find(key);
return (it != this->bool_data.end());
}
-template<>
-bool ParameterReader::has<std::string>(std::string key) const {
- std::map<std::string,std::string>::const_iterator it;
+template <> bool ParameterReader::has<std::string>(std::string key) const {
+ std::map<std::string, std::string>::const_iterator it;
it = this->string_data.find(key);
return (it != this->string_data.end());
}
-template<>
-bool ParameterReader::has<akantu::Int>(std::string key) const {
- std::map<std::string,akantu::Int>::const_iterator it;
+template <> bool ParameterReader::has<akantu::Int>(std::string key) const {
+ std::map<std::string, akantu::Int>::const_iterator it;
it = this->int_data.find(key);
return (it != this->int_data.end());
}
-template<>
-bool ParameterReader::has<akantu::UInt>(std::string key) const {
- std::map<std::string,akantu::UInt>::const_iterator it;
+template <> bool ParameterReader::has<akantu::UInt>(std::string key) const {
+ std::map<std::string, akantu::UInt>::const_iterator it;
it = this->uint_data.find(key);
return (it != this->uint_data.end());
}
-template<>
-bool ParameterReader::has<akantu::Real>(std::string key) const {
- std::map<std::string,akantu::Real>::const_iterator it;
+template <> bool ParameterReader::has<akantu::Real>(std::string key) const {
+ std::map<std::string, akantu::Real>::const_iterator it;
it = this->real_data.find(key);
return (it != this->real_data.end());
}
/* -------------------------------------------------------------------------- */
void ParameterReader::printself(std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
stream << space << "ParameterReader [" << std::endl;
/*
stream << space << this->element_type_data << std::endl;
stream << space << this->string_data << std::endl;
stream << space << this->surface_data << std::endl;
stream << space << this->int_data << std::endl;
stream << space << this->uint_data << std::endl;
stream << space << this->real_data << std::endl;
stream << space << this->bool_data << std::endl;
*/
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
index 53312ba81..f1e39a68d 100644
--- a/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
+++ b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
@@ -1,99 +1,95 @@
/**
* @file parameter_reader.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief for simulations to read parameters from an input file
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_PARAMETER_READER_HH__
#define __AST_PARAMETER_READER_HH__
/* -------------------------------------------------------------------------- */
// std
-#include <set>
#include <map>
+#include <set>
// akantu
#include "aka_common.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class ParameterReader {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
ParameterReader();
- virtual ~ParameterReader() {};
-
+ virtual ~ParameterReader(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// read input file
void readInputFile(std::string file_name);
/// write input file
void writeInputFile(std::string file_name) const;
-
+
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
- ///
- template<typename T>
- T get(std::string key) const;
+ ///
+ template <typename T> T get(std::string key) const;
+
+ template <typename T> bool has(std::string key) const;
- template<typename T>
- bool has(std::string key) const;
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// type of data available
std::set<std::string> data_types;
/// data
- std::map<std::string,akantu::ElementType> element_type_data;
- std::map<std::string,std::string> string_data;
- std::map<std::string,akantu::Int> int_data;
- std::map<std::string,akantu::UInt> uint_data;
- std::map<std::string,akantu::Real> real_data;
- std::map<std::string,bool> bool_data;
+ std::map<std::string, akantu::ElementType> element_type_data;
+ std::map<std::string, std::string> string_data;
+ std::map<std::string, akantu::Int> int_data;
+ std::map<std::string, akantu::UInt> uint_data;
+ std::map<std::string, akantu::Real> real_data;
+ std::map<std::string, bool> bool_data;
/// convert string to element type
std::map<std::string, ElementType> _input_to_akantu_element_types;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "parameter_reader_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const ParameterReader & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const ParameterReader & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_PARAMETER_READER_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.cc b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.cc
index ef44a8e64..f2d0bd016 100644
--- a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.cc
+++ b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.cc
@@ -1,222 +1,230 @@
/**
* @file synchronized_array.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of synchronized array function
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// std
-#include <iostream>
#include <fstream>
+#include <iostream>
// simtools
#include "synchronized_array.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-template<class T>
-SynchronizedArray<T>::SynchronizedArray(UInt size,
- UInt nb_component,
- SynchronizedArray<T>::const_reference value,
- const ID & id,
- SynchronizedArray<T>::const_reference default_value,
- const std::string restart_name) :
- SynchronizedArrayBase(),
- Array<T>(size, nb_component, value, id),
- default_value(default_value),
- restart_name(restart_name),
- deleted_elements(0),
- nb_added_elements(size),
- depending_arrays(0) {
+template <class T>
+SynchronizedArray<T>::SynchronizedArray(
+ UInt size, UInt nb_component, SynchronizedArray<T>::const_reference value,
+ const ID & id, SynchronizedArray<T>::const_reference default_value,
+ const std::string restart_name)
+ : SynchronizedArrayBase(), Array<T>(size, nb_component, value, id),
+ default_value(default_value), restart_name(restart_name),
+ deleted_elements(0), nb_added_elements(size), depending_arrays(0) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<class T>
+template <class T>
void SynchronizedArray<T>::syncElements(SyncChoice sync_choice) {
AKANTU_DEBUG_IN();
if (sync_choice == _deleted) {
std::vector<SynchronizedArrayBase *>::iterator it;
- for (it=depending_arrays.begin(); it != depending_arrays.end(); ++it) {
+ for (it = depending_arrays.begin(); it != depending_arrays.end(); ++it) {
UInt vec_size = (*it)->syncDeletedElements(this->deleted_elements);
AKANTU_DEBUG_ASSERT(vec_size == this->size,
- "Synchronized arrays do not have the same length" <<
- "(may be a double synchronization)");
+ "Synchronized arrays do not have the same length"
+ << "(may be a double synchronization)");
}
this->deleted_elements.clear();
}
else if (sync_choice == _added) {
std::vector<SynchronizedArrayBase *>::iterator it;
- for (it=depending_arrays.begin(); it != depending_arrays.end(); ++it) {
+ for (it = depending_arrays.begin(); it != depending_arrays.end(); ++it) {
UInt vec_size = (*it)->syncAddedElements(this->nb_added_elements);
AKANTU_DEBUG_ASSERT(vec_size == this->size,
- "Synchronized arrays do not have the same length" <<
- "(may be a double synchronization)");
+ "Synchronized arrays do not have the same length"
+ << "(may be a double synchronization)");
}
this->nb_added_elements = 0;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<class T>
-UInt SynchronizedArray<T>::syncDeletedElements(std::vector<UInt> & del_elements) {
+template <class T>
+UInt SynchronizedArray<T>::syncDeletedElements(
+ std::vector<UInt> & del_elements) {
AKANTU_DEBUG_IN();
- AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
- "Cannot sync with a SynchronizedArray if it has already been modified");
+ AKANTU_DEBUG_ASSERT(
+ nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Cannot sync with a SynchronizedArray if it has already been modified");
std::vector<UInt>::const_iterator it;
for (it = del_elements.begin(); it != del_elements.end(); ++it) {
erase(*it);
}
syncElements(_deleted);
AKANTU_DEBUG_OUT();
return this->size;
}
/* -------------------------------------------------------------------------- */
-template<class T>
+template <class T>
UInt SynchronizedArray<T>::syncAddedElements(UInt nb_add_elements) {
AKANTU_DEBUG_IN();
- AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
- "Cannot sync with a SynchronizedArray if it has already been modified");
+ AKANTU_DEBUG_ASSERT(
+ nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Cannot sync with a SynchronizedArray if it has already been modified");
- for (UInt i=0; i<nb_add_elements; ++i) {
+ for (UInt i = 0; i < nb_add_elements; ++i) {
push_back(this->default_value);
}
syncElements(_added);
AKANTU_DEBUG_OUT();
return this->size;
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-void SynchronizedArray<T>::registerDependingArray(SynchronizedArrayBase & array) {
+template <typename T>
+void SynchronizedArray<T>::registerDependingArray(
+ SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
this->depending_arrays.push_back(&array);
array.syncAddedElements(this->size);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
void SynchronizedArray<T>::printself(std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
- stream << space << "SynchronizedArray<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
- stream << space << " + default_value : " << this->default_value << std::endl;
- stream << space << " + nb_added_elements : " << this->nb_added_elements << std::endl;
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
+ stream << space << "SynchronizedArray<" << debug::demangle(typeid(T).name())
+ << "> [" << std::endl;
+ stream << space << " + default_value : " << this->default_value
+ << std::endl;
+ stream << space << " + nb_added_elements : " << this->nb_added_elements
+ << std::endl;
stream << space << " + deleted_elements : ";
- for(std::vector<UInt>::const_iterator it = this->deleted_elements.begin();
- it != this->deleted_elements.end();
- ++it)
+ for (std::vector<UInt>::const_iterator it = this->deleted_elements.begin();
+ it != this->deleted_elements.end(); ++it)
stream << *it << " ";
stream << std::endl;
stream << space << " + depending_arrays : ";
- for (std::vector<SynchronizedArrayBase *>::const_iterator it = this->depending_arrays.begin();
- it!=this->depending_arrays.end();
- ++it)
+ for (std::vector<SynchronizedArrayBase *>::const_iterator it =
+ this->depending_arrays.begin();
+ it != this->depending_arrays.end(); ++it)
stream << (*it)->getID() << " ";
stream << std::endl;
- Array<T>::printself(stream, indent+1);
+ Array<T>::printself(stream, indent + 1);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
void SynchronizedArray<T>::dumpRestartFile(std::string file_name) const {
AKANTU_DEBUG_IN();
- AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
- "Restart File for SynchronizedArray " << this->id <<
- " should not be dumped as it is not synchronized yet");
+ AKANTU_DEBUG_ASSERT(
+ nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Restart File for SynchronizedArray "
+ << this->id << " should not be dumped as it is not synchronized yet");
std::stringstream name;
name << file_name << "-" << this->restart_name << ".rs";
std::ofstream out_restart;
out_restart.open(name.str().c_str());
out_restart << this->size << " " << this->nb_component << std::endl;
Real size_comp = this->size * this->nb_component;
- for (UInt i=0; i<size_comp; ++i)
+ for (UInt i = 0; i < size_comp; ++i)
out_restart << std::setprecision(12) << this->values[i] << " ";
- // out_restart << std::hex << std::setprecision(12) << this->values[i] << " ";
- out_restart << std::endl;
+ // out_restart << std::hex << std::setprecision(12) << this->values[i] << "
+ // ";
+ out_restart << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
void SynchronizedArray<T>::readRestartFile(std::string file_name) {
AKANTU_DEBUG_IN();
- AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
- "Restart File for SynchronizedArray " << this->id <<
- " should not be read as it is not synchronized yet");
+ AKANTU_DEBUG_ASSERT(
+ nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Restart File for SynchronizedArray "
+ << this->id << " should not be read as it is not synchronized yet");
std::stringstream name;
name << file_name << "-" << this->restart_name << ".rs";
std::ifstream infile;
infile.open(name.str().c_str());
std::string line;
// get size and nb_component info
- AKANTU_DEBUG_ASSERT(infile.good(), "Could not read restart file for " <<
- "SynchronizedArray " << this->id);
+ AKANTU_DEBUG_ASSERT(infile.good(),
+ "Could not read restart file for "
+ << "SynchronizedArray " << this->id);
getline(infile, line);
std::stringstream size_comp(line);
size_comp >> this->size;
size_comp >> this->nb_component;
// get elements in array
getline(infile, line);
std::stringstream data(line);
- for (UInt i=0; i<this->size * this->nb_component; ++i) {
- AKANTU_DEBUG_ASSERT(!data.eof(), "Read SynchronizedArray " << this->id <<
- " got to the end of the file before having read all data!");
+ for (UInt i = 0; i < this->size * this->nb_component; ++i) {
+ AKANTU_DEBUG_ASSERT(
+ !data.eof(),
+ "Read SynchronizedArray "
+ << this->id
+ << " got to the end of the file before having read all data!");
data >> this->values[i];
// data >> std::hex >> this->values[i];
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template class SynchronizedArray<Real>;
template class SynchronizedArray<UInt>;
template class SynchronizedArray<Int>;
template class SynchronizedArray<bool>;
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.hh b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.hh
index cb60a8665..c3bb398db 100644
--- a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.hh
+++ b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.hh
@@ -1,189 +1,190 @@
/**
* @file synchronized_array.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
- * @brief synchronized array: a array can be registered to another (hereafter called top) array. If an element is added to or removed from the top array, the registered array removes or adds at the same position an element. The two arrays stay therefore synchronized.
+ * @brief synchronized array: a array can be registered to another (hereafter
+ * called top) array. If an element is added to or removed from the top array,
+ * the registered array removes or adds at the same position an element. The two
+ * arrays stay therefore synchronized.
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_SYNCHRONIZED_ARRAY_HH__
#define __AST_SYNCHRONIZED_ARRAY_HH__
/* -------------------------------------------------------------------------- */
// std
#include <vector>
// akantu
#include "aka_array.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-enum SyncChoice {_added, _deleted};
+enum SyncChoice { _added, _deleted };
/* -------------------------------------------------------------------------- */
class SynchronizedArrayBase {
public:
- SynchronizedArrayBase() {};
- ~SynchronizedArrayBase() {};
+ SynchronizedArrayBase(){};
+ ~SynchronizedArrayBase(){};
virtual ID getID() const { return "call should be virtual"; };
virtual UInt syncDeletedElements(std::vector<UInt> & delete_el) = 0;
virtual UInt syncAddedElements(UInt nb_added_el) = 0;
};
/* -------------------------------------------------------------------------- */
-template<class T>
+template <class T>
class SynchronizedArray : public SynchronizedArrayBase, protected Array<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef typename Array<T>::value_type value_type;
- typedef typename Array<T>::reference reference;
- typedef typename Array<T>::pointer_type pointer_type;
+ typedef typename Array<T>::value_type value_type;
+ typedef typename Array<T>::reference reference;
+ typedef typename Array<T>::pointer_type pointer_type;
typedef typename Array<T>::const_reference const_reference;
-
- SynchronizedArray(UInt size, UInt nb_component,
- const_reference value, const ID & id,
- const_reference default_value,
- const std::string restart_name);
- virtual ~SynchronizedArray() {};
-
+
+ SynchronizedArray(UInt size, UInt nb_component, const_reference value,
+ const ID & id, const_reference default_value,
+ const std::string restart_name);
+ virtual ~SynchronizedArray(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// push_back
inline void push_back(const_reference value);
inline void push_back(const value_type new_element[]);
/// erase
inline void erase(UInt i);
- //template<typename R>
- //inline void erase(const iterator<R> & it);
-
+ // template<typename R>
+ // inline void erase(const iterator<R> & it);
+
/// synchronize elements
void syncElements(SyncChoice sync_choice);
/// dump restart file
void dumpRestartFile(std::string file_name) const;
-
+
/// read restart file
void readRestartFile(std::string file_name);
/// register depending array
void registerDependingArray(SynchronizedArrayBase & array);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// find position of element
Int find(const T & elem) const { return Array<T>::find(elem); };
/// set values to zero
inline void clear() { Array<T>::clear(); };
// inline void clear() { memset(values, 0, size*nb_component*sizeof(T)); };
/// set all entries of the array to the value t
/// @param t value to fill the array with
inline void set(T t) { Array<T>::set(t); }
/// set
- template<template<typename> class C>
- inline void set(const C<T> & vm) { Array<T>::set(vm); };
+ template <template <typename> class C> inline void set(const C<T> & vm) {
+ Array<T>::set(vm);
+ };
/// set all entries of the array to value t and set default value
- inline void setAndChangeDefault(T t) {
- this->set(t);
+ inline void setAndChangeDefault(T t) {
+ this->set(t);
this->default_value = t;
}
/// copy the content of an other array
void copy(const SynchronizedArray<T> & vect) { Array<T>::copy(vect); };
-
+
/// give the address of the memory allocated for this array
T * storage() const { return Array<T>::storage(); };
// T * storage() const { return this->values; };
// get nb component
UInt getNbComponent() const { return Array<T>::getNbComponent(); };
protected:
UInt syncDeletedElements(std::vector<UInt> & del_elements);
UInt syncAddedElements(UInt nb_add_elements);
/* ------------------------------------------------------------------------ */
/* Operators */
/* ------------------------------------------------------------------------ */
public:
inline reference operator()(UInt i, UInt j = 0) {
- return Array<T>::operator()(i,j);
+ return Array<T>::operator()(i, j);
}
inline const_reference operator()(UInt i, UInt j = 0) const {
- return Array<T>::operator()(i,j);
+ return Array<T>::operator()(i, j);
}
-
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_SET_MACRO(DefaultValue, default_value, T);
- UInt getSize() const{ return this->size; };
+ UInt getSize() const { return this->size; };
ID getID() const { return Array<T>::getID(); };
const Array<T> & getArray() const {
const Array<T> & a = *(dynamic_cast<const Array<T> *>(this));
return a;
};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// init value when new elements added
T default_value;
-
+
/// restart file_name
const std::string restart_name;
/// elements that have been deleted
std::vector<UInt> deleted_elements;
/// number of elements to add
UInt nb_added_elements;
/// pointers to arrays to be updated
std::vector<SynchronizedArrayBase *> depending_arrays;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "synchronized_array_inline_impl.cc"
/// standard output stream operator
template <typename T>
-inline std::ostream & operator <<(std::ostream & stream,
- const SynchronizedArray<T> & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const SynchronizedArray<T> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_SYNCHRONIZED_ARRAY_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array_inline_impl.cc b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array_inline_impl.cc
index 2698a18c6..adbf39076 100644
--- a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array_inline_impl.cc
+++ b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array_inline_impl.cc
@@ -1,70 +1,73 @@
/**
* @file synchronized_array_inline_impl.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief inlined methods for the synchronized array
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-template <typename T> inline void SynchronizedArray<T>::push_back(const_reference value) {
+template <typename T>
+inline void SynchronizedArray<T>::push_back(const_reference value) {
AKANTU_DEBUG_IN();
-
- AKANTU_DEBUG_ASSERT(deleted_elements.size() == 0,
- "Cannot push_back element if SynchronizedArray" <<
- " is already modified without synchronization");
+
+ AKANTU_DEBUG_ASSERT(deleted_elements.size() == 0,
+ "Cannot push_back element if SynchronizedArray"
+ << " is already modified without synchronization");
Array<T>::push_back(value);
this->nb_added_elements++;
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template <typename T> inline void SynchronizedArray<T>::push_back(const value_type new_elem[]) {
+template <typename T>
+inline void SynchronizedArray<T>::push_back(const value_type new_elem[]) {
AKANTU_DEBUG_IN();
-
- AKANTU_DEBUG_ASSERT(deleted_elements.size() == 0,
- "Cannot push_back element if SynchronizedArray" <<
- " is already modified without synchronization");
+
+ AKANTU_DEBUG_ASSERT(deleted_elements.size() == 0,
+ "Cannot push_back element if SynchronizedArray"
+ << " is already modified without synchronization");
Array<T>::push_back(new_elem);
this->nb_added_elements++;
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T> inline void SynchronizedArray<T>::erase(UInt i) {
AKANTU_DEBUG_IN();
-
- AKANTU_DEBUG_ASSERT(nb_added_elements == 0,
- "Cannot erase element if SynchronizedArray" <<
- " is already modified without synchronization");
-
- for (UInt j=0; j<this->nb_component; ++j)
- this->values[i*this->nb_component+j] = this->values[(this->size-1)*this->nb_component+j];
+
+ AKANTU_DEBUG_ASSERT(nb_added_elements == 0,
+ "Cannot erase element if SynchronizedArray"
+ << " is already modified without synchronization");
+
+ for (UInt j = 0; j < this->nb_component; ++j)
+ this->values[i * this->nb_component + j] =
+ this->values[(this->size - 1) * this->nb_component + j];
this->size--;
-
+
this->deleted_elements.push_back(i);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/*
template<typename T>
template<typename R>
inline void SynchronizedArray<T>::erase(const iterator<R> & it) {
T * curr = it.getCurrentStorage();
UInt pos = (curr - values) / nb_component;
erase(pos);
}
*/
diff --git a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc
index 0594b0743..bb60d7467 100644
--- a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc
+++ b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc
@@ -1,63 +1,63 @@
/**
* @file boundary_functions.cc
*
*
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
#include "boundary_functions.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
Real integrateResidual(const std::string & sub_boundary_name,
- const SolidMechanicsModel & model,
- UInt dir) {
+ const SolidMechanicsModel & model, UInt dir) {
Real int_res = 0.;
-
+
const Mesh & mesh = model.getMesh();
const Array<Real> & residual = model.getResidual();
- // do not need try catch, as all subboundaries should be everywhere.
+ // do not need try catch, as all subboundaries should be everywhere.
// try {
const ElementGroup & boundary = mesh.getElementGroup(sub_boundary_name);
- ElementGroup::const_node_iterator nit = boundary.node_begin();
+ ElementGroup::const_node_iterator nit = boundary.node_begin();
ElementGroup::const_node_iterator nend = boundary.node_end();
for (; nit != nend; ++nit) {
bool is_local_node = mesh.isLocalOrMasterNode(*nit);
if (is_local_node) {
int_res += residual(*nit, dir);
}
}
// } catch(debug::Exception e) {
- // // AKANTU_ERROR("Error computing integrateResidual. Cannot get SubBoundary: "
+ // // AKANTU_ERROR("Error computing integrateResidual. Cannot get
+ // SubBoundary: "
// // << sub_boundary_name << " [" << e.what() << "]");
// }
StaticCommunicator::getStaticCommunicator().allReduce(&int_res, 1, _so_sum);
return int_res;
}
/* -------------------------------------------------------------------------- */
-void boundaryFix(Mesh & mesh,
- const std::vector<std::string> & sub_boundary_names) {
-
- std::vector<std::string>::const_iterator it = sub_boundary_names.begin();
+void boundaryFix(Mesh & mesh,
+ const std::vector<std::string> & sub_boundary_names) {
+
+ std::vector<std::string>::const_iterator it = sub_boundary_names.begin();
std::vector<std::string>::const_iterator end = sub_boundary_names.end();
for (; it != end; ++it) {
if (mesh.element_group_find(*it) == mesh.element_group_end()) {
- mesh.createElementGroup(*it,mesh.getSpatialDimension()-1); // empty element group
+ mesh.createElementGroup(
+ *it, mesh.getSpatialDimension() - 1); // empty element group
}
}
}
-
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
index 4873ff132..89fd859e3 100644
--- a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
+++ b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
@@ -1,31 +1,30 @@
/**
* @file boundary_functions.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief functions for boundaries
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// akantu
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
namespace akantu {
Real integrateResidual(const std::string & sub_boundary_name,
- const SolidMechanicsModel & model,
- UInt dir);
+ const SolidMechanicsModel & model, UInt dir);
/// this is a fix so that all subboundaries exist on all procs
void boundaryFix(Mesh & mesh,
- const std::vector<std::string> & sub_boundary_names);
+ const std::vector<std::string> & sub_boundary_names);
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
index ea4c64667..d910acc3c 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
@@ -1,95 +1,93 @@
/**
* @file ntn_friclaw_coulomb.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief coulomb friction with \mu_s = \mu_k (constant)
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICLAW_COULOMB_HH__
#define __AST_NTN_FRICLAW_COULOMB_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_fricreg_no_regularisation.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation = NTNFricRegNoRegularisation>
class NTNFricLawCoulomb : public Regularisation {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTNFricLawCoulomb(NTNBaseContact * contact,
- const FrictionID & id = "coulomb",
- const MemoryID & memory_id = 0);
- virtual ~NTNFricLawCoulomb() {};
-
+ NTNFricLawCoulomb(NTNBaseContact * contact, const FrictionID & id = "coulomb",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawCoulomb(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// register synchronizedarrays for sync
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
/// dump restart file
virtual void dumpRestart(const std::string & file_name) const;
/// read restart file
virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
+
protected:
/// compute frictional strength according to friction law
virtual void computeFrictionalStrength();
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
// friction coefficient
SynchronizedArray<Real> mu;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
template <class Regularisation>
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFricLawCoulomb<Regularisation> & _this)
-{
+inline std::ostream &
+operator<<(std::ostream & stream,
+ const NTNFricLawCoulomb<Regularisation> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "ntn_friclaw_coulomb_tmpl.hh"
#endif /* __AST_NTN_FRICLAW_COULOMB_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh
index 1a3ba4d04..df0841947 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh
@@ -1,147 +1,153 @@
/**
* @file ntn_friclaw_coulomb_tmpl.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of coulomb friction
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_nodal_field.hh"
-
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation>
NTNFricLawCoulomb<Regularisation>::NTNFricLawCoulomb(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- Regularisation(contact,id,memory_id),
- mu(0,1,0.,id+":mu",0.,"mu") {
+ const FrictionID & id,
+ const MemoryID & memory_id)
+ : Regularisation(contact, id, memory_id),
+ mu(0, 1, 0., id + ":mu", 0., "mu") {
AKANTU_DEBUG_IN();
Regularisation::registerSynchronizedArray(this->mu);
this->registerParam("mu", this->mu, _pat_parsmod, "friction coefficient");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
void NTNFricLawCoulomb<Regularisation>::computeFrictionalStrength() {
AKANTU_DEBUG_IN();
// get contact arrays
- const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
+ const SynchronizedArray<bool> & is_in_contact =
+ this->internalGetIsInContact();
const SynchronizedArray<Real> & pressure = this->internalGetContactPressure();
// array to fill
SynchronizedArray<Real> & strength = this->internalGetFrictionalStrength();
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// node pair is NOT in contact
if (!is_in_contact(n))
strength(n) = 0.;
// node pair is in contact
else {
// compute frictional strength
strength(n) = this->mu(n) * pressure(n);
}
}
Regularisation::computeFrictionalStrength();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(SynchronizedArrayBase & array) {
+void NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(
+ SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
this->mu.registerDependingArray(array);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawCoulomb<Regularisation>::dumpRestart(const std::string & file_name) const {
+void NTNFricLawCoulomb<Regularisation>::dumpRestart(
+ const std::string & file_name) const {
AKANTU_DEBUG_IN();
this->mu.dumpRestartFile(file_name);
Regularisation::dumpRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawCoulomb<Regularisation>::readRestart(const std::string & file_name) {
+void NTNFricLawCoulomb<Regularisation>::readRestart(
+ const std::string & file_name) {
AKANTU_DEBUG_IN();
this->mu.readRestartFile(file_name);
Regularisation::readRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawCoulomb<Regularisation>::printself(std::ostream & stream, int indent) const {
+void NTNFricLawCoulomb<Regularisation>::printself(std::ostream & stream,
+ int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "NTNFricLawCoulomb [" << std::endl;
Regularisation::printself(stream, ++indent);
stream << space << "]" << std::endl;
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawCoulomb<Regularisation>::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+void NTNFricLawCoulomb<Regularisation>::addDumpFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id) {
AKANTU_DEBUG_IN();
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+ // const SynchronizedArray<UInt> * nodal_filter =
+ // &(this->contact->getSlaves());
- if(field_id == "mu") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->mu.getArray()));
+ if (field_id == "mu") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->mu.getArray()));
}
/*
else if (field_id == "frictional_contact_pressure") {
this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new DumperIOHelper::NodalField<Real>(this->frictional_contact_pressure.getArray()));
+ field_id,
+ new
+ DumperIOHelper::NodalField<Real>(this->frictional_contact_pressure.getArray()));
}
*/
else {
Regularisation::addDumpFieldToDumper(dumper_name, field_id);
}
#endif
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
index 6ee95e260..26a84a24f 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
@@ -1,101 +1,100 @@
/**
* @file ntn_friclaw_linear_cohesive.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief linear cohesive law
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICLAW_LINEAR_COHESIVE_HH__
#define __AST_NTN_FRICLAW_LINEAR_COHESIVE_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_fricreg_no_regularisation.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation = NTNFricRegNoRegularisation>
class NTNFricLawLinearCohesive : public Regularisation {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
NTNFricLawLinearCohesive(NTNBaseContact * contact,
- const FrictionID & id = "linear_cohesive",
- const MemoryID & memory_id = 0);
- virtual ~NTNFricLawLinearCohesive() {};
-
+ const FrictionID & id = "linear_cohesive",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearCohesive(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// register synchronizedarrays for sync
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
/// dump restart file
virtual void dumpRestart(const std::string & file_name) const;
/// read restart file
virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
+
protected:
/// compute frictional strength according to friction law
virtual void computeFrictionalStrength();
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
-
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
// fracture energy
SynchronizedArray<Real> G_c;
// peak value of cohesive law
SynchronizedArray<Real> tau_c;
// residual value of cohesive law (for slip > d_c)
SynchronizedArray<Real> tau_r;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
template <class Regularisation>
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFricLawLinearCohesive<Regularisation> & _this)
-{
+inline std::ostream &
+operator<<(std::ostream & stream,
+ const NTNFricLawLinearCohesive<Regularisation> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "ntn_friclaw_linear_cohesive_tmpl.hh"
#endif /* __AST_NTN_FRICLAW_LINEAR_COHESIVE_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh
index 091ad621a..0e72a085d 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh
@@ -1,168 +1,174 @@
/**
* @file ntn_friclaw_linear_cohesive_tmpl.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of linear cohesive law
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
//#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-NTNFricLawLinearCohesive<Regularisation>::NTNFricLawLinearCohesive(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- Regularisation(contact,id,memory_id),
- G_c(0,1,0.,id+":G_c",0.,"G_c"),
- tau_c(0,1,0.,id+":tau_c",0.,"tau_c"),
- tau_r(0,1,0.,id+":tau_r",0.,"tau_r") {
+NTNFricLawLinearCohesive<Regularisation>::NTNFricLawLinearCohesive(
+ NTNBaseContact * contact, const FrictionID & id, const MemoryID & memory_id)
+ : Regularisation(contact, id, memory_id),
+ G_c(0, 1, 0., id + ":G_c", 0., "G_c"),
+ tau_c(0, 1, 0., id + ":tau_c", 0., "tau_c"),
+ tau_r(0, 1, 0., id + ":tau_r", 0., "tau_r") {
AKANTU_DEBUG_IN();
Regularisation::registerSynchronizedArray(this->G_c);
Regularisation::registerSynchronizedArray(this->tau_c);
Regularisation::registerSynchronizedArray(this->tau_r);
- this->registerParam("G_c", this->G_c, _pat_parsmod, "fracture energy");
- this->registerParam("tau_c", this->tau_c, _pat_parsmod, "peak shear strength");
- this->registerParam("tau_r", this->tau_r, _pat_parsmod, "residual shear strength");
+ this->registerParam("G_c", this->G_c, _pat_parsmod, "fracture energy");
+ this->registerParam("tau_c", this->tau_c, _pat_parsmod,
+ "peak shear strength");
+ this->registerParam("tau_r", this->tau_r, _pat_parsmod,
+ "residual shear strength");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
void NTNFricLawLinearCohesive<Regularisation>::computeFrictionalStrength() {
AKANTU_DEBUG_IN();
// get arrays
- const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
- //const SynchronizedArray<Real> & slip = this->internalGetSlip();
+ const SynchronizedArray<bool> & is_in_contact =
+ this->internalGetIsInContact();
+ // const SynchronizedArray<Real> & slip = this->internalGetSlip();
const SynchronizedArray<Real> & slip = this->internalGetCumulativeSlip();
// array to fill
SynchronizedArray<Real> & strength = this->internalGetFrictionalStrength();
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// node pair is NOT in contact
if (!is_in_contact(n))
strength(n) = 0.;
// node pair is in contact
else {
if (this->G_c(n) == 0.) {
- // strength(n) = 0.;
- strength(n) = this->tau_r(n);
- }
- else {
- Real slope = (this->tau_c(n) - this->tau_r(n)) * (this->tau_c(n) - this->tau_r(n)) / (2*this->G_c(n));
- // no strength < tau_r
- strength(n) = std::max(this->tau_c(n) - slope * slip(n), this->tau_r(n));
- // strength(n) = std::max(this->tau_c(n) - slope * slip(n), 0.); // no negative strength
+ // strength(n) = 0.;
+ strength(n) = this->tau_r(n);
+ } else {
+ Real slope = (this->tau_c(n) - this->tau_r(n)) *
+ (this->tau_c(n) - this->tau_r(n)) / (2 * this->G_c(n));
+ // no strength < tau_r
+ strength(n) =
+ std::max(this->tau_c(n) - slope * slip(n), this->tau_r(n));
+ // strength(n) = std::max(this->tau_c(n) - slope * slip(n), 0.); // no
+ // negative strength
}
}
}
Regularisation::computeFrictionalStrength();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearCohesive<Regularisation>::registerSynchronizedArray(SynchronizedArrayBase & array) {
+void NTNFricLawLinearCohesive<Regularisation>::registerSynchronizedArray(
+ SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
this->G_c.registerDependingArray(array);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearCohesive<Regularisation>::dumpRestart(const std::string & file_name) const {
+void NTNFricLawLinearCohesive<Regularisation>::dumpRestart(
+ const std::string & file_name) const {
AKANTU_DEBUG_IN();
this->G_c.dumpRestartFile(file_name);
this->tau_c.dumpRestartFile(file_name);
this->tau_r.dumpRestartFile(file_name);
Regularisation::dumpRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearCohesive<Regularisation>::readRestart(const std::string & file_name) {
+void NTNFricLawLinearCohesive<Regularisation>::readRestart(
+ const std::string & file_name) {
AKANTU_DEBUG_IN();
this->G_c.readRestartFile(file_name);
this->tau_c.readRestartFile(file_name);
this->tau_r.readRestartFile(file_name);
Regularisation::readRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
void NTNFricLawLinearCohesive<Regularisation>::printself(std::ostream & stream,
- int indent) const {
+ int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "NTNFricLawLinearCohesive [" << std::endl;
Regularisation::printself(stream, ++indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearCohesive<Regularisation>::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+void NTNFricLawLinearCohesive<Regularisation>::addDumpFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id) {
AKANTU_DEBUG_IN();
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
-
- if(field_id == "G_c") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->G_c.getArray()));
- }
- else if(field_id == "tau_c") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->tau_c.getArray()));
- }
- else if(field_id == "tau_r") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->tau_r.getArray()));
- }
- else {
+ // const SynchronizedArray<UInt> * nodal_filter =
+ // &(this->contact->getSlaves());
+
+ if (field_id == "G_c") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->G_c.getArray()));
+ } else if (field_id == "tau_c") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->tau_c.getArray()));
+ } else if (field_id == "tau_r") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->tau_r.getArray()));
+ } else {
Regularisation::addDumpFieldToDumper(dumper_name, field_id);
}
#endif
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
index e075c1300..c0cdb03e0 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
@@ -1,103 +1,102 @@
/**
* @file ntn_friclaw_linear_slip_weakening.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief linear slip weakening
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_HH__
#define __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_friclaw_coulomb.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation = NTNFricRegNoRegularisation>
class NTNFricLawLinearSlipWeakening : public NTNFricLawCoulomb<Regularisation> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
NTNFricLawLinearSlipWeakening(NTNBaseContact * contact,
- const FrictionID & id = "linear_slip_weakening",
- const MemoryID & memory_id = 0);
- virtual ~NTNFricLawLinearSlipWeakening() {};
-
+ const FrictionID & id = "linear_slip_weakening",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearSlipWeakening(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// register synchronizedarrays for sync
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
/// dump restart file
virtual void dumpRestart(const std::string & file_name) const;
/// read restart file
virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
+
protected:
/// compute frictional strength according to friction law
virtual void computeFrictionalStrength();
/// computes the friction coefficient as a function of slip
virtual void computeFrictionCoefficient();
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
-
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
// static coefficient of friction
SynchronizedArray<Real> mu_s;
// kinetic coefficient of friction
SynchronizedArray<Real> mu_k;
// Dc the length over which slip weakening happens
SynchronizedArray<Real> d_c;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
template <class Regularisation>
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFricLawLinearSlipWeakening<Regularisation> & _this)
-{
+inline std::ostream &
+operator<<(std::ostream & stream,
+ const NTNFricLawLinearSlipWeakening<Regularisation> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "ntn_friclaw_linear_slip_weakening_tmpl.hh"
#endif /* __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
index 2bb02fdb2..aa69eb866 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
@@ -1,81 +1,81 @@
/**
* @file ntn_friclaw_linear_slip_weakening_no_healing.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief linear slip weakening
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__
#define __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__
/* -------------------------------------------------------------------------- */
#include "ntn_friclaw_linear_slip_weakening.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation = NTNFricRegNoRegularisation>
-class NTNFricLawLinearSlipWeakeningNoHealing : public NTNFricLawLinearSlipWeakening<Regularisation> {
+class NTNFricLawLinearSlipWeakeningNoHealing
+ : public NTNFricLawLinearSlipWeakening<Regularisation> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTNFricLawLinearSlipWeakeningNoHealing(NTNBaseContact * contact,
- const FrictionID & id = "linear_slip_weakening_no_healing",
- const MemoryID & memory_id = 0);
- virtual ~NTNFricLawLinearSlipWeakeningNoHealing() {};
-
+ NTNFricLawLinearSlipWeakeningNoHealing(
+ NTNBaseContact * contact,
+ const FrictionID & id = "linear_slip_weakening_no_healing",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearSlipWeakeningNoHealing(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
+
protected:
/// computes the friction coefficient as a function of slip
virtual void computeFrictionCoefficient();
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
-
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
template <class Regularisation>
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFricLawLinearSlipWeakeningNoHealing<Regularisation> & _this)
-{
+inline std::ostream & operator<<(
+ std::ostream & stream,
+ const NTNFricLawLinearSlipWeakeningNoHealing<Regularisation> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh"
#endif /* __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
index 6efcabb96..bf5e2b241 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
@@ -1,69 +1,72 @@
/**
* @file ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of linear slip weakening
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation>
NTNFricLawLinearSlipWeakeningNoHealing<Regularisation>::
-NTNFricLawLinearSlipWeakeningNoHealing(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- NTNFricLawLinearSlipWeakening<Regularisation>(contact,id,memory_id) {
+ NTNFricLawLinearSlipWeakeningNoHealing(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id)
+ : NTNFricLawLinearSlipWeakening<Regularisation>(contact, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakeningNoHealing<Regularisation>::computeFrictionCoefficient() {
+void NTNFricLawLinearSlipWeakeningNoHealing<
+ Regularisation>::computeFrictionCoefficient() {
AKANTU_DEBUG_IN();
// get arrays
- const SynchronizedArray<Real> & slip = this->internalGetCumulativeSlip();
+ const SynchronizedArray<Real> & slip = this->internalGetCumulativeSlip();
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
if (slip(n) >= this->d_c(n)) {
this->mu(n) = this->mu_k(n);
- }
- else {
+ } else {
// mu = mu_k + (1 - slip / Dc) * (mu_s - mu_k)
- this->mu(n) = this->mu_k(n)
- + (1 - (slip(n) / this->d_c(n))) * (this->mu_s(n) - this->mu_k(n));
+ this->mu(n) =
+ this->mu_k(n) +
+ (1 - (slip(n) / this->d_c(n))) * (this->mu_s(n) - this->mu_k(n));
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakeningNoHealing<Regularisation>::printself(std::ostream & stream, int indent) const {
+void NTNFricLawLinearSlipWeakeningNoHealing<Regularisation>::printself(
+ std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "NTNFricLawLinearSlipWeakeningNoHealing [" << std::endl;
NTNFricLawLinearSlipWeakening<Regularisation>::printself(stream, ++indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh
index fa8ab67fc..d69db957f 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh
@@ -1,171 +1,176 @@
/**
* @file ntn_friclaw_linear_slip_weakening_tmpl.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of linear slip weakening
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-NTNFricLawLinearSlipWeakening<Regularisation>::NTNFricLawLinearSlipWeakening(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- NTNFricLawCoulomb<Regularisation>(contact,id,memory_id),
- mu_s(0,1,0.,id+":mu_s",0.,"mu_s"),
- mu_k(0,1,0.,id+":mu_k",0.,"mu_k"),
- d_c(0,1,0.,id+":d_c",0.,"d_c") {
+NTNFricLawLinearSlipWeakening<Regularisation>::NTNFricLawLinearSlipWeakening(
+ NTNBaseContact * contact, const FrictionID & id, const MemoryID & memory_id)
+ : NTNFricLawCoulomb<Regularisation>(contact, id, memory_id),
+ mu_s(0, 1, 0., id + ":mu_s", 0., "mu_s"),
+ mu_k(0, 1, 0., id + ":mu_k", 0., "mu_k"),
+ d_c(0, 1, 0., id + ":d_c", 0., "d_c") {
AKANTU_DEBUG_IN();
NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(this->mu_s);
NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(this->mu_k);
NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(this->d_c);
- this->registerParam("mu_s", this->mu_s, _pat_parsmod, "static friction coefficient");
- this->registerParam("mu_k", this->mu_k, _pat_parsmod, "kinetic friction coefficient");
- this->registerParam("d_c", this->d_c, _pat_parsmod, "slip weakening length");
+ this->registerParam("mu_s", this->mu_s, _pat_parsmod,
+ "static friction coefficient");
+ this->registerParam("mu_k", this->mu_k, _pat_parsmod,
+ "kinetic friction coefficient");
+ this->registerParam("d_c", this->d_c, _pat_parsmod, "slip weakening length");
this->setParamAccessType("mu", _pat_readable);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakening<Regularisation>::computeFrictionalStrength() {
+void NTNFricLawLinearSlipWeakening<
+ Regularisation>::computeFrictionalStrength() {
AKANTU_DEBUG_IN();
computeFrictionCoefficient();
NTNFricLawCoulomb<Regularisation>::computeFrictionalStrength();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakening<Regularisation>::computeFrictionCoefficient() {
+void NTNFricLawLinearSlipWeakening<
+ Regularisation>::computeFrictionCoefficient() {
AKANTU_DEBUG_IN();
// get arrays
const SynchronizedArray<bool> & stick = this->internalGetIsSticking();
- const SynchronizedArray<Real> & slip = this->internalGetSlip();
+ const SynchronizedArray<Real> & slip = this->internalGetSlip();
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
if (stick(n)) {
this->mu(n) = this->mu_s(n);
- }
- else {
+ } else {
if (slip(n) >= this->d_c(n)) {
- this->mu(n) = this->mu_k(n);
- }
- else {
- // mu = mu_k + (1 - slip / Dc) * (mu_s - mu_k)
- this->mu(n) = this->mu_k(n)
- + (1 - (slip(n) / this->d_c(n))) * (this->mu_s(n) - this->mu_k(n));
+ this->mu(n) = this->mu_k(n);
+ } else {
+ // mu = mu_k + (1 - slip / Dc) * (mu_s - mu_k)
+ this->mu(n) =
+ this->mu_k(n) +
+ (1 - (slip(n) / this->d_c(n))) * (this->mu_s(n) - this->mu_k(n));
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakening<Regularisation>::registerSynchronizedArray(SynchronizedArrayBase & array) {
+void NTNFricLawLinearSlipWeakening<Regularisation>::registerSynchronizedArray(
+ SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
this->mu_s.registerDependingArray(array);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakening<Regularisation>::dumpRestart(const std::string & file_name) const {
+void NTNFricLawLinearSlipWeakening<Regularisation>::dumpRestart(
+ const std::string & file_name) const {
AKANTU_DEBUG_IN();
this->mu_s.dumpRestartFile(file_name);
this->mu_k.dumpRestartFile(file_name);
this->d_c.dumpRestartFile(file_name);
NTNFricLawCoulomb<Regularisation>::dumpRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakening<Regularisation>::readRestart(const std::string & file_name) {
+void NTNFricLawLinearSlipWeakening<Regularisation>::readRestart(
+ const std::string & file_name) {
AKANTU_DEBUG_IN();
this->mu_s.readRestartFile(file_name);
this->mu_k.readRestartFile(file_name);
this->d_c.readRestartFile(file_name);
NTNFricLawCoulomb<Regularisation>::readRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakening<Regularisation>::printself(std::ostream & stream, int indent) const {
+void NTNFricLawLinearSlipWeakening<Regularisation>::printself(
+ std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "NTNFricLawLinearSlipWeakening [" << std::endl;
NTNFricLawCoulomb<Regularisation>::printself(stream, ++indent);
stream << space << "]" << std::endl;
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Regularisation>
-void NTNFricLawLinearSlipWeakening<Regularisation>::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+void NTNFricLawLinearSlipWeakening<Regularisation>::addDumpFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id) {
AKANTU_DEBUG_IN();
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
-
- if(field_id == "mu_s") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->mu_s.getArray()));
- }
- else if(field_id == "mu_k") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->mu_k.getArray()));
- }
- else if(field_id == "d_c") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->d_c.getArray()));
- }
- else {
- NTNFricLawCoulomb<Regularisation>::addDumpFieldToDumper(dumper_name, field_id);
+ // const SynchronizedArray<UInt> * nodal_filter =
+ // &(this->contact->getSlaves());
+
+ if (field_id == "mu_s") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->mu_s.getArray()));
+ } else if (field_id == "mu_k") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->mu_k.getArray()));
+ } else if (field_id == "d_c") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->d_c.getArray()));
+ } else {
+ NTNFricLawCoulomb<Regularisation>::addDumpFieldToDumper(dumper_name,
+ field_id);
}
#endif
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc
index 7cf5606e8..099b31d4d 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc
@@ -1,147 +1,153 @@
/**
* @file ntn_fricreg_no_regularisation.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of no regularisation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_fricreg_no_regularisation.hh"
-#include "dumper_text.hh"
#include "dumper_nodal_field.hh"
+#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-NTNFricRegNoRegularisation::NTNFricRegNoRegularisation(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- NTNBaseFriction(contact, id, memory_id),
- frictional_contact_pressure(0,1,0.,id+":frictional_contact_pressure",0.,
- "frictional_contact_pressure") {
+NTNFricRegNoRegularisation::NTNFricRegNoRegularisation(
+ NTNBaseContact * contact, const FrictionID & id, const MemoryID & memory_id)
+ : NTNBaseFriction(contact, id, memory_id),
+ frictional_contact_pressure(0, 1, 0., id + ":frictional_contact_pressure",
+ 0., "frictional_contact_pressure") {
AKANTU_DEBUG_IN();
-
+
NTNBaseFriction::registerSynchronizedArray(this->frictional_contact_pressure);
- this->registerParam("frictional_contact_pressure", this->frictional_contact_pressure,
- _pat_internal , "contact pressure used for friction law");
+ this->registerParam("frictional_contact_pressure",
+ this->frictional_contact_pressure, _pat_internal,
+ "contact pressure used for friction law");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-const SynchronizedArray<Real> & NTNFricRegNoRegularisation::internalGetContactPressure() {
+const SynchronizedArray<Real> &
+NTNFricRegNoRegularisation::internalGetContactPressure() {
AKANTU_DEBUG_IN();
this->computeFrictionalContactPressure();
AKANTU_DEBUG_OUT();
return this->frictional_contact_pressure;
}
/* -------------------------------------------------------------------------- */
void NTNFricRegNoRegularisation::computeFrictionalContactPressure() {
AKANTU_DEBUG_IN();
-
+
SolidMechanicsModel & model = this->contact->getModel();
UInt dim = model.getSpatialDimension();
// get contact arrays
- const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
+ const SynchronizedArray<bool> & is_in_contact =
+ this->internalGetIsInContact();
const Array<Real> & pressure = this->contact->getContactPressure().getArray();
- Array<Real>::const_iterator< Vector<Real> > it = pressure.begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it = pressure.begin(dim);
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// node pair is NOT in contact
if (!is_in_contact(n))
this->frictional_contact_pressure(n) = 0.;
// node pair is in contact
else {
// compute frictional contact pressure
const Vector<Real> & pres = it[n];
this->frictional_contact_pressure(n) = pres.norm();
}
}
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegNoRegularisation::registerSynchronizedArray(SynchronizedArrayBase & array) {
+void NTNFricRegNoRegularisation::registerSynchronizedArray(
+ SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
-
+
this->frictional_contact_pressure.registerDependingArray(array);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegNoRegularisation::dumpRestart(const std::string & file_name) const {
+void NTNFricRegNoRegularisation::dumpRestart(
+ const std::string & file_name) const {
AKANTU_DEBUG_IN();
-
+
this->frictional_contact_pressure.dumpRestartFile(file_name);
NTNBaseFriction::dumpRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNFricRegNoRegularisation::readRestart(const std::string & file_name) {
AKANTU_DEBUG_IN();
-
+
this->frictional_contact_pressure.readRestartFile(file_name);
NTNBaseFriction::readRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegNoRegularisation::printself(std::ostream & stream,
- int indent) const {
+void NTNFricRegNoRegularisation::printself(std::ostream & stream,
+ int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
stream << space << "NTNFricRegNoRegularisation [" << std::endl;
NTNBaseFriction::printself(stream, ++indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegNoRegularisation::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+void NTNFricRegNoRegularisation::addDumpFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id) {
AKANTU_DEBUG_IN();
-
+
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
-
+ // const SynchronizedArray<UInt> * nodal_filter =
+ // &(this->contact->getSlaves());
+
if (field_id == "frictional_contact_pressure") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->frictional_contact_pressure.getArray()));
- }
- else {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(
+ this->frictional_contact_pressure.getArray()));
+ } else {
NTNBaseFriction::addDumpFieldToDumper(dumper_name, field_id);
}
-
+
#endif
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
index 120ebdcc0..3e1d66e0f 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
@@ -1,125 +1,119 @@
/**
* @file ntn_fricreg_no_regularisation.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief regularisation that does nothing
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICREG_NO_REGULARISATION_HH__
#define __AST_NTN_FRICREG_NO_REGULARISATION_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_base_friction.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class NTNFricRegNoRegularisation : public NTNBaseFriction {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
NTNFricRegNoRegularisation(NTNBaseContact * contact,
- const FrictionID & id = "no_regularisation",
- const MemoryID & memory_id = 0);
- virtual ~NTNFricRegNoRegularisation() {};
-
+ const FrictionID & id = "no_regularisation",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegNoRegularisation(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// set to steady state for no regularisation -> do nothing
- virtual void setToSteadyState() {};
+ virtual void setToSteadyState(){};
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
virtual void dumpRestart(const std::string & file_name) const;
virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
virtual void computeFrictionalContactPressure();
/// compute frictional strength according to friction law
- virtual void computeFrictionalStrength() {};
+ virtual void computeFrictionalStrength(){};
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
-
+ const std::string & field_id);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
protected:
/// get the is_in_contact array
virtual const SynchronizedArray<bool> & internalGetIsInContact() {
return this->contact->getIsInContact();
};
/// get the contact pressure (the norm: scalar value)
virtual const SynchronizedArray<Real> & internalGetContactPressure();
/// get the frictional strength array
virtual SynchronizedArray<Real> & internalGetFrictionalStrength() {
return this->frictional_strength;
};
/// get the is_sticking array
virtual SynchronizedArray<bool> & internalGetIsSticking() {
return this->is_sticking;
}
-
+
/// get the slip array
- virtual SynchronizedArray<Real> & internalGetSlip() {
- return this->slip;
- }
+ virtual SynchronizedArray<Real> & internalGetSlip() { return this->slip; }
/// get the slip array
virtual SynchronizedArray<Real> & internalGetCumulativeSlip() {
return this->cumulative_slip;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
// contact pressure (absolut value) for computation of friction
SynchronizedArray<Real> frictional_contact_pressure;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "ntn_fricreg_no_regularisation_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFricRegNoRegularisation & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const NTNFricRegNoRegularisation & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_NTN_FRICREG_NO_REGULARISATION_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc
index 968d46581..10496dd03 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc
@@ -1,154 +1,161 @@
/**
* @file ntn_fricreg_rubin_ampuero.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of no regularisation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_fricreg_rubin_ampuero.hh"
-#include "dumper_text.hh"
#include "dumper_nodal_field.hh"
+#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
NTNFricRegRubinAmpuero::NTNFricRegRubinAmpuero(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- NTNFricRegNoRegularisation(contact, id, memory_id),
- t_star(0,1,0.,id+":t_star",0.,"t_star") {
+ const FrictionID & id,
+ const MemoryID & memory_id)
+ : NTNFricRegNoRegularisation(contact, id, memory_id),
+ t_star(0, 1, 0., id + ":t_star", 0., "t_star") {
AKANTU_DEBUG_IN();
-
+
NTNFricRegNoRegularisation::registerSynchronizedArray(this->t_star);
- this->registerParam("t_star", this->t_star, _pat_parsmod, "time scale of regularization");
+ this->registerParam("t_star", this->t_star, _pat_parsmod,
+ "time scale of regularization");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-const SynchronizedArray<Real> & NTNFricRegRubinAmpuero::internalGetContactPressure() {
+const SynchronizedArray<Real> &
+NTNFricRegRubinAmpuero::internalGetContactPressure() {
AKANTU_DEBUG_IN();
-
+
SolidMechanicsModel & model = this->contact->getModel();
UInt dim = model.getSpatialDimension();
Real delta_t = model.getTimeStep();
-
+
// get contact arrays
- const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
+ const SynchronizedArray<bool> & is_in_contact =
+ this->internalGetIsInContact();
const Array<Real> & pressure = this->contact->getContactPressure().getArray();
- Array<Real>::const_iterator< Vector<Real> > it = pressure.begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it = pressure.begin(dim);
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// node pair is NOT in contact
if (!is_in_contact(n))
this->frictional_contact_pressure(n) = 0.;
- // if t_star is too small compute like Coulomb friction (without regularization)
+ // if t_star is too small compute like Coulomb friction (without
+ // regularization)
else if (Math::are_float_equal(this->t_star(n), 0.)) {
const Vector<Real> & pres = it[n];
this->frictional_contact_pressure(n) = pres.norm();
}
-
+
else {
// compute frictional contact pressure
- // backward euler method: first order implicit numerical integration method
+ // backward euler method: first order implicit numerical integration
+ // method
// \reg_pres_n+1 = (\reg_pres_n + \delta_t / \t_star * \cur_pres)
// / (1 + \delta_t / \t_star)
Real alpha = delta_t / this->t_star(n);
const Vector<Real> & pres = it[n];
this->frictional_contact_pressure(n) += alpha * pres.norm();
this->frictional_contact_pressure(n) /= 1 + alpha;
}
}
AKANTU_DEBUG_OUT();
return this->frictional_contact_pressure;
}
/* -------------------------------------------------------------------------- */
void NTNFricRegRubinAmpuero::setToSteadyState() {
AKANTU_DEBUG_IN();
NTNFricRegNoRegularisation::computeFrictionalContactPressure();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegRubinAmpuero::registerSynchronizedArray(SynchronizedArrayBase & array) {
+void NTNFricRegRubinAmpuero::registerSynchronizedArray(
+ SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
-
+
this->t_star.registerDependingArray(array);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNFricRegRubinAmpuero::dumpRestart(const std::string & file_name) const {
AKANTU_DEBUG_IN();
-
+
this->t_star.dumpRestartFile(file_name);
NTNFricRegNoRegularisation::dumpRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNFricRegRubinAmpuero::readRestart(const std::string & file_name) {
AKANTU_DEBUG_IN();
-
+
this->t_star.readRestartFile(file_name);
NTNFricRegNoRegularisation::readRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegRubinAmpuero::printself(std::ostream & stream,
- int indent) const {
+void NTNFricRegRubinAmpuero::printself(std::ostream & stream,
+ int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
stream << space << "NTNFricRegRubinAmpuero [" << std::endl;
NTNFricRegNoRegularisation::printself(stream, ++indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegRubinAmpuero::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+void NTNFricRegRubinAmpuero::addDumpFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id) {
AKANTU_DEBUG_IN();
-
+
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
-
+ // const SynchronizedArray<UInt> * nodal_filter =
+ // &(this->contact->getSlaves());
+
if (field_id == "t_star") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->t_star.getArray()));
- }
- else {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->t_star.getArray()));
+ } else {
NTNFricRegNoRegularisation::addDumpFieldToDumper(dumper_name, field_id);
}
-
+
#endif
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
index 62d062675..1ec87e1b6 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
@@ -1,91 +1,87 @@
/**
* @file ntn_fricreg_rubin_ampuero.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief regularisation that regularizes the contact pressure
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICREG_RUBIN_AMPUERO_HH__
#define __AST_NTN_FRICREG_RUBIN_AMPUERO_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_fricreg_no_regularisation.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class NTNFricRegRubinAmpuero : public NTNFricRegNoRegularisation {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
NTNFricRegRubinAmpuero(NTNBaseContact * contact,
- const FrictionID & id = "rubin_ampuero",
- const MemoryID & memory_id = 0);
- virtual ~NTNFricRegRubinAmpuero() {};
-
+ const FrictionID & id = "rubin_ampuero",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegRubinAmpuero(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
virtual void dumpRestart(const std::string & file_name) const;
virtual void readRestart(const std::string & file_name);
virtual void setToSteadyState();
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
-
+ const std::string & field_id);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
protected:
/// get the contact pressure (the norm: scalar value)
virtual const SynchronizedArray<Real> & internalGetContactPressure();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
SynchronizedArray<Real> t_star;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "ntn_fricreg_rubin_ampuero_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFricRegRubinAmpuero & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const NTNFricRegRubinAmpuero & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_NTN_FRICREG_RUBIN_AMPUERO_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc
index 465b7a5fb..c81b72309 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc
@@ -1,144 +1,148 @@
/**
* @file ntn_fricreg_simplified_prakash_clifton.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of simplified prakash clifton with one parameter
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_fricreg_simplified_prakash_clifton.hh"
-#include "dumper_text.hh"
#include "dumper_nodal_field.hh"
+#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-NTNFricRegSimplifiedPrakashClifton::NTNFricRegSimplifiedPrakashClifton(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- NTNFricRegNoRegularisation(contact, id, memory_id),
- t_star(0,1,0.,id+":t_star",0.,"t_star"),
- spc_internal(0,1,0.,id+":spc_internal",0.,"spc_internal") {
+NTNFricRegSimplifiedPrakashClifton::NTNFricRegSimplifiedPrakashClifton(
+ NTNBaseContact * contact, const FrictionID & id, const MemoryID & memory_id)
+ : NTNFricRegNoRegularisation(contact, id, memory_id),
+ t_star(0, 1, 0., id + ":t_star", 0., "t_star"),
+ spc_internal(0, 1, 0., id + ":spc_internal", 0., "spc_internal") {
AKANTU_DEBUG_IN();
-
+
NTNFricRegNoRegularisation::registerSynchronizedArray(this->t_star);
NTNFricRegNoRegularisation::registerSynchronizedArray(this->spc_internal);
- this->registerParam("t_star", this->t_star, _pat_parsmod, "time scale of regularisation");
+ this->registerParam("t_star", this->t_star, _pat_parsmod,
+ "time scale of regularisation");
this->registerParam("spc_internal", this->spc_internal, _pat_internal, "");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNFricRegSimplifiedPrakashClifton::computeFrictionalStrength() {
AKANTU_DEBUG_IN();
-
+
SolidMechanicsModel & model = this->contact->getModel();
Real delta_t = model.getTimeStep();
-
+
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
Real alpha = delta_t / this->t_star(n);
this->frictional_strength(n) += alpha * this->spc_internal(n);
this->frictional_strength(n) /= 1 + alpha;
- }
+ }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNFricRegSimplifiedPrakashClifton::setToSteadyState() {
AKANTU_DEBUG_IN();
/// fill the spc_internal array
computeFrictionalStrength();
/// set strength without regularisation
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
this->frictional_strength(n) = this->spc_internal(n);
- }
+ }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegSimplifiedPrakashClifton::registerSynchronizedArray(SynchronizedArrayBase & array) {
+void NTNFricRegSimplifiedPrakashClifton::registerSynchronizedArray(
+ SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
-
+
this->t_star.registerDependingArray(array);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegSimplifiedPrakashClifton::dumpRestart(const std::string & file_name) const {
+void NTNFricRegSimplifiedPrakashClifton::dumpRestart(
+ const std::string & file_name) const {
AKANTU_DEBUG_IN();
-
+
this->t_star.dumpRestartFile(file_name);
this->spc_internal.dumpRestartFile(file_name);
NTNFricRegNoRegularisation::dumpRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegSimplifiedPrakashClifton::readRestart(const std::string & file_name) {
+void NTNFricRegSimplifiedPrakashClifton::readRestart(
+ const std::string & file_name) {
AKANTU_DEBUG_IN();
-
+
this->t_star.readRestartFile(file_name);
this->spc_internal.readRestartFile(file_name);
NTNFricRegNoRegularisation::readRestart(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegSimplifiedPrakashClifton::printself(std::ostream & stream,
- int indent) const {
+void NTNFricRegSimplifiedPrakashClifton::printself(std::ostream & stream,
+ int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
stream << space << "NTNFricRegSimplifiedPrakashClifton [" << std::endl;
NTNFricRegNoRegularisation::printself(stream, ++indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNFricRegSimplifiedPrakashClifton::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+void NTNFricRegSimplifiedPrakashClifton::addDumpFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id) {
AKANTU_DEBUG_IN();
-
+
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
-
+ // const SynchronizedArray<UInt> * nodal_filter =
+ // &(this->contact->getSlaves());
+
if (field_id == "t_star") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->t_star.getArray()));
- }
- else {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->t_star.getArray()));
+ } else {
NTNFricRegNoRegularisation::addDumpFieldToDumper(dumper_name, field_id);
}
-
+
#endif
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
index 8460d6290..211fd1980 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
@@ -1,100 +1,99 @@
/**
* @file ntn_fricreg_simplified_prakash_clifton.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
- * @brief regularisation that regularizes the frictional strength with one parameter
+ * @brief regularisation that regularizes the frictional strength with one
+ * parameter
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICREG_SIMPLIFIED_PRAKASH_CLIFTON_HH__
#define __AST_NTN_FRICREG_SIMPLIFIED_PRAKASH_CLIFTON_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_fricreg_no_regularisation.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class NTNFricRegSimplifiedPrakashClifton : public NTNFricRegNoRegularisation {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTNFricRegSimplifiedPrakashClifton(NTNBaseContact * contact,
- const FrictionID & id = "simplified_prakash_clifton",
- const MemoryID & memory_id = 0);
- virtual ~NTNFricRegSimplifiedPrakashClifton() {};
-
+ NTNFricRegSimplifiedPrakashClifton(
+ NTNBaseContact * contact,
+ const FrictionID & id = "simplified_prakash_clifton",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegSimplifiedPrakashClifton(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
virtual void dumpRestart(const std::string & file_name) const;
virtual void readRestart(const std::string & file_name);
virtual void setToSteadyState();
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
/// compute frictional strength according to friction law
virtual void computeFrictionalStrength();
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
-
+ const std::string & field_id);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
protected:
/// get the frictional strength array
virtual SynchronizedArray<Real> & internalGetFrictionalStrength() {
return this->spc_internal;
};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
SynchronizedArray<Real> t_star;
// to get the incremental frictional strength
SynchronizedArray<Real> spc_internal;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "ntn_fricreg_simplified_prakash_clifton_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFricRegSimplifiedPrakashClifton & _this)
-{
+inline std::ostream &
+operator<<(std::ostream & stream,
+ const NTNFricRegSimplifiedPrakashClifton & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_NTN_FRICREG_SIMPLIFIED_PRAKASH_CLIFTON_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
index bebc0675e..87cb89244 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
@@ -1,108 +1,105 @@
/**
* @file mIIasym_contact.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "mIIasym_contact.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
MIIASYMContact::MIIASYMContact(SolidMechanicsModel & model,
- const ContactID & id,
- const MemoryID & memory_id) :
- NTRFContact(model,id,memory_id)
-{
+ const ContactID & id, const MemoryID & memory_id)
+ : NTRFContact(model, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MIIASYMContact::updateImpedance() {
AKANTU_DEBUG_IN();
NTRFContact::updateImpedance();
- for (UInt i=0; i<this->impedance.getSize(); ++i) {
+ for (UInt i = 0; i < this->impedance.getSize(); ++i) {
this->impedance(i) *= 0.5;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/// WARNING: this is only valid for the acceleration in equilibrium
-void MIIASYMContact::computeRelativeNormalField(const Array<Real> & field,
- Array<Real> & rel_normal_field) const {
+void MIIASYMContact::computeRelativeNormalField(
+ const Array<Real> & field, Array<Real> & rel_normal_field) const {
AKANTU_DEBUG_IN();
NTRFContact::computeRelativeNormalField(field, rel_normal_field);
- for (auto it_rtfield = rel_normal_field.begin();
- it_rtfield != rel_normal_field.end();
- ++it_rtfield) {
+ for (auto it_rtfield = rel_normal_field.begin();
+ it_rtfield != rel_normal_field.end(); ++it_rtfield) {
// in the anti-symmetric case
*it_rtfield *= 2.;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void MIIASYMContact::computeRelativeTangentialField(const Array<Real> & field,
- Array<Real> & rel_tang_field) const {
+void MIIASYMContact::computeRelativeTangentialField(
+ const Array<Real> & field, Array<Real> & rel_tang_field) const {
AKANTU_DEBUG_IN();
NTRFContact::computeRelativeTangentialField(field, rel_tang_field);
UInt dim = this->model.getSpatialDimension();
-
- for (Array<Real>::iterator< Vector<Real> > it_rtfield = rel_tang_field.begin(dim);
- it_rtfield != rel_tang_field.end(dim);
- ++it_rtfield) {
+
+ for (Array<Real>::iterator<Vector<Real>> it_rtfield =
+ rel_tang_field.begin(dim);
+ it_rtfield != rel_tang_field.end(dim); ++it_rtfield) {
// in the anti-symmetric case, the tangential fields become twice as large
*it_rtfield *= 2.;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MIIASYMContact::computeContactPressureInEquilibrium() {
AKANTU_DEBUG_IN();
NTRFContact::computeContactPressure();
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
void MIIASYMContact::printself(std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "MIIASYMContact [" << std::endl;
- NTRFContact::printself(stream,indent);
+ NTRFContact::printself(stream, indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.hh
index 387539a22..94b55bd91 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.hh
@@ -1,76 +1,76 @@
/**
* @file mIIasym_contact.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief contact for mode II anti-symmetric simulations
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_MIIASYM_CONTACT_HH__
#define __AST_MIIASYM_CONTACT_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntrf_contact.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class MIIASYMContact : public NTRFContact {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- MIIASYMContact(SolidMechanicsModel & model,
- const ContactID & id = "contact",
- const MemoryID & memory_id = 0);
- virtual ~MIIASYMContact() {};
+ MIIASYMContact(SolidMechanicsModel & model, const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~MIIASYMContact(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// update the impedance matrix
virtual void updateImpedance();
- /// compute contact pressure -> do nothing because can only compute it in equilibrium
- virtual void computeContactPressure() {};
+ /// compute contact pressure -> do nothing because can only compute it in
+ /// equilibrium
+ virtual void computeContactPressure(){};
- /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// compute relative normal field (only value that has to be multiplied with
+ /// the normal)
/// WARNING: this is only valid for the acceleration in equilibrium
virtual void computeRelativeNormalField(const Array<Real> & field,
- Array<Real> & rel_normal_field) const;
+ Array<Real> & rel_normal_field) const;
/// compute relative tangential field (complet array)
/// relative to master nodes
- virtual void computeRelativeTangentialField(const Array<Real> & field,
- Array<Real> & rel_tang_field) const;
+ virtual void
+ computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const;
/// compute contact pressure that is used over the entire time
virtual void computeContactPressureInEquilibrium();
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
};
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const MIIASYMContact & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const MIIASYMContact & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_MIIASYM_CONTACT_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.cc
index d4e0629c5..840597b5b 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.cc
@@ -1,556 +1,544 @@
/**
* @file ntn_base_contact.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of ntn base contact
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_base_contact.hh"
#include "dumpable_inline_impl.hh"
-#include "dumper_text.hh"
#include "dumper_nodal_field.hh"
+#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-NTNContactSynchElementFilter::NTNContactSynchElementFilter(NTNBaseContact * contact) :
- contact(contact),
- connectivity(contact->getModel().getMesh().getConnectivities()) {
+NTNContactSynchElementFilter::NTNContactSynchElementFilter(
+ NTNBaseContact * contact)
+ : contact(contact),
+ connectivity(contact->getModel().getMesh().getConnectivities()) {
AKANTU_DEBUG_IN();
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
bool NTNContactSynchElementFilter::operator()(const Element & e) {
AKANTU_DEBUG_IN();
ElementType type = e.type;
UInt element = e.element;
GhostType ghost_type = e.ghost_type;
-
+
// loop over all nodes of this element
bool need_element = false;
UInt nb_nodes = Mesh::getNbNodesPerElement(type);
- for (UInt n=0; n<nb_nodes; ++n) {
- UInt nn = this->connectivity(type, ghost_type)(element,n);
-
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ UInt nn = this->connectivity(type, ghost_type)(element, n);
+
// if one nodes is in this contact, we need this element
if (this->contact->getNodeIndex(nn) >= 0) {
need_element = true;
break;
}
}
AKANTU_DEBUG_OUT();
return need_element;
}
/* -------------------------------------------------------------------------- */
NTNBaseContact::NTNBaseContact(SolidMechanicsModel & model,
- const ContactID & id,
- const MemoryID & memory_id) :
- Memory(id,memory_id), Dumpable(), model(model),
- slaves(0,1,0,id+":slaves",std::numeric_limits<UInt>::quiet_NaN(),"slaves"),
- normals(0,model.getSpatialDimension(),0,id+":normals",
- std::numeric_limits<Real>::quiet_NaN(),"normals"),
- contact_pressure(0,model.getSpatialDimension(),0,id+":contact_pressure",
- std::numeric_limits<Real>::quiet_NaN(),"contact_pressure"),
- is_in_contact(0,1,false,id+":is_in_contact",false,"is_in_contact"),
- lumped_boundary_slaves(0,1,0,id+":lumped_boundary_slaves",
- std::numeric_limits<Real>::quiet_NaN(),"lumped_boundary_slaves"),
- impedance(0,1,0,id+":impedance",std::numeric_limits<Real>::quiet_NaN(),"impedance"),
- contact_surfaces(),
- slave_elements("slave_elements", id, memory_id),
- node_to_elements(),
- synch_registry(NULL)
-{
+ const ContactID & id, const MemoryID & memory_id)
+ : Memory(id, memory_id), Dumpable(), model(model),
+ slaves(0, 1, 0, id + ":slaves", std::numeric_limits<UInt>::quiet_NaN(),
+ "slaves"),
+ normals(0, model.getSpatialDimension(), 0, id + ":normals",
+ std::numeric_limits<Real>::quiet_NaN(), "normals"),
+ contact_pressure(
+ 0, model.getSpatialDimension(), 0, id + ":contact_pressure",
+ std::numeric_limits<Real>::quiet_NaN(), "contact_pressure"),
+ is_in_contact(0, 1, false, id + ":is_in_contact", false, "is_in_contact"),
+ lumped_boundary_slaves(0, 1, 0, id + ":lumped_boundary_slaves",
+ std::numeric_limits<Real>::quiet_NaN(),
+ "lumped_boundary_slaves"),
+ impedance(0, 1, 0, id + ":impedance",
+ std::numeric_limits<Real>::quiet_NaN(), "impedance"),
+ contact_surfaces(), slave_elements("slave_elements", id, memory_id),
+ node_to_elements(), synch_registry(NULL) {
AKANTU_DEBUG_IN();
FEEngine & boundary_fem = this->model.getFEEngineBoundary();
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
boundary_fem.initShapeFunctions(*gt);
}
Mesh & mesh = this->model.getMesh();
UInt spatial_dimension = this->model.getSpatialDimension();
- mesh.initElementTypeMapArray(this->slave_elements,
- 1,
- spatial_dimension - 1);
+ mesh.initElementTypeMapArray(this->slave_elements, 1, spatial_dimension - 1);
- MeshUtils::buildNode2Elements(mesh,
- this->node_to_elements,
- spatial_dimension - 1);
+ MeshUtils::buildNode2Elements(mesh, this->node_to_elements,
+ spatial_dimension - 1);
this->registerDumper<DumperText>("text_all", id, true);
- this->addDumpFilteredMesh(mesh,
- slave_elements,
- slaves.getArray(),
- spatial_dimension - 1,
- _not_ghost,
- _ek_regular);
+ this->addDumpFilteredMesh(mesh, slave_elements, slaves.getArray(),
+ spatial_dimension - 1, _not_ghost, _ek_regular);
// parallelisation
this->synch_registry = new SynchronizerRegistry(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
NTNBaseContact::~NTNBaseContact() {
AKANTU_DEBUG_IN();
- if(this->synch_registry) delete this->synch_registry;
+ if (this->synch_registry)
+ delete this->synch_registry;
- if(this->synchronizer) delete this->synchronizer;
+ if (this->synchronizer)
+ delete this->synchronizer;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::initParallel() {
AKANTU_DEBUG_IN();
NTNContactSynchElementFilter elem_filter(this);
- this->synchronizer = FilteredSynchronizer::
- createFilteredSynchronizer(this->model.getSynchronizer(),
- elem_filter);
+ this->synchronizer = FilteredSynchronizer::createFilteredSynchronizer(
+ this->model.getSynchronizer(), elem_filter);
- this->synch_registry->registerSynchronizer(*(this->synchronizer), _gst_cf_nodal);
- this->synch_registry->registerSynchronizer(*(this->synchronizer), _gst_cf_incr);
+ this->synch_registry->registerSynchronizer(*(this->synchronizer),
+ _gst_cf_nodal);
+ this->synch_registry->registerSynchronizer(*(this->synchronizer),
+ _gst_cf_incr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNBaseContact::findBoundaryElements(const Array<UInt> & interface_nodes,
- ElementTypeMapArray<UInt> & elements) {
+void NTNBaseContact::findBoundaryElements(
+ const Array<UInt> & interface_nodes, ElementTypeMapArray<UInt> & elements) {
AKANTU_DEBUG_IN();
UInt nb_interface_nodes = interface_nodes.getSize();
- const ElementTypeMapArray<UInt> & connectivity = this->model.getMesh().getConnectivities();
-
+ const ElementTypeMapArray<UInt> & connectivity =
+ this->model.getMesh().getConnectivities();
+
// add connected boundary elements that have all nodes on this contact
- for (UInt i=0; i<nb_interface_nodes; ++i) {
+ for (UInt i = 0; i < nb_interface_nodes; ++i) {
UInt node = interface_nodes(i);
-
- CSR<Element>::iterator it = this->node_to_elements.begin(node);
+
+ CSR<Element>::iterator it = this->node_to_elements.begin(node);
CSR<Element>::iterator it_e = this->node_to_elements.end(node);
for (; it != it_e; ++it) { // loop over all elements connected to node
ElementType type = it->type;
UInt element = it->element;
GhostType ghost_type = it->ghost_type;
UInt nb_nodes = Mesh::getNbNodesPerElement(type);
UInt nb_found_nodes = 0;
- for (UInt n=0; n<nb_nodes; ++n) {
- UInt nn = connectivity(type,ghost_type)(element,n);
- if (interface_nodes.find(nn) >= 0)
- nb_found_nodes++;
- else
- break;
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ UInt nn = connectivity(type, ghost_type)(element, n);
+ if (interface_nodes.find(nn) >= 0)
+ nb_found_nodes++;
+ else
+ break;
}
-
+
// this is an element between all contact nodes
- // and is not already in the elements
- if ((nb_found_nodes == nb_nodes)
- && (elements(type,ghost_type).find(element) < 0)) {
- elements(type, ghost_type).push_back(element);
+ // and is not already in the elements
+ if ((nb_found_nodes == nb_nodes) &&
+ (elements(type, ghost_type).find(element) < 0)) {
+ elements(type, ghost_type).push_back(element);
}
}
}
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::addSplitNode(UInt node) {
AKANTU_DEBUG_IN();
-
+
UInt dim = this->model.getSpatialDimension();
-
+
// add to node arrays
this->slaves.push_back(node);
-
+
// set contact as false
this->is_in_contact.push_back(false);
-
+
// before initializing
// set contact pressure, normal, lumped_boundary to Nan
this->contact_pressure.push_back(std::numeric_limits<Real>::quiet_NaN());
this->impedance.push_back(std::numeric_limits<Real>::quiet_NaN());
- this->lumped_boundary_slaves.push_back(std::numeric_limits<Real>::quiet_NaN());
-
+ this->lumped_boundary_slaves.push_back(
+ std::numeric_limits<Real>::quiet_NaN());
+
Real nan_normal[dim];
- for (UInt d=0; d<dim; ++d)
+ for (UInt d = 0; d < dim; ++d)
nan_normal[d] = std::numeric_limits<Real>::quiet_NaN();
this->normals.push_back(nan_normal);
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::registerSynchronizedArray(SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
-
+
this->slaves.registerDependingArray(array);
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::dumpRestart(const std::string & file_name) const {
AKANTU_DEBUG_IN();
-
+
this->slaves.dumpRestartFile(file_name);
this->normals.dumpRestartFile(file_name);
this->is_in_contact.dumpRestartFile(file_name);
this->contact_pressure.dumpRestartFile(file_name);
this->lumped_boundary_slaves.dumpRestartFile(file_name);
this->impedance.dumpRestartFile(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::readRestart(const std::string & file_name) {
AKANTU_DEBUG_IN();
-
+
this->slaves.readRestartFile(file_name);
this->normals.readRestartFile(file_name);
this->is_in_contact.readRestartFile(file_name);
this->contact_pressure.readRestartFile(file_name);
this->lumped_boundary_slaves.readRestartFile(file_name);
this->impedance.readRestartFile(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
UInt NTNBaseContact::getNbNodesInContact() const {
AKANTU_DEBUG_IN();
-
+
UInt nb_contact = 0;
-
+
UInt nb_nodes = this->getNbContactNodes();
const Mesh & mesh = this->model.getMesh();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(this->slaves(n));
bool is_pbc_slave_node = this->model.isPBCSlaveNode(this->slaves(n));
if (is_local_node && !is_pbc_slave_node && this->is_in_contact(n)) {
nb_contact++;
}
}
-
- StaticCommunicator::getStaticCommunicator().allReduce(&nb_contact, 1, _so_sum);
-
+
+ StaticCommunicator::getStaticCommunicator().allReduce(&nb_contact, 1,
+ _so_sum);
+
AKANTU_DEBUG_OUT();
return nb_contact;
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::updateInternalData() {
AKANTU_DEBUG_IN();
-
+
updateNormals();
updateLumpedBoundary();
updateImpedance();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::updateLumpedBoundary() {
AKANTU_DEBUG_IN();
-
+
this->internalUpdateLumpedBoundary(this->slaves.getArray(),
- this->slave_elements,
- this->lumped_boundary_slaves);
+ this->slave_elements,
+ this->lumped_boundary_slaves);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNBaseContact::internalUpdateLumpedBoundary(const Array<UInt> & nodes,
- const ElementTypeMapArray<UInt> & elements,
- SynchronizedArray<Real> & boundary) {
+void NTNBaseContact::internalUpdateLumpedBoundary(
+ const Array<UInt> & nodes, const ElementTypeMapArray<UInt> & elements,
+ SynchronizedArray<Real> & boundary) {
AKANTU_DEBUG_IN();
// set all values in lumped_boundary to zero
boundary.clear();
-
+
UInt dim = this->model.getSpatialDimension();
// UInt nb_contact_nodes = getNbContactNodes();
-
+
const FEEngine & boundary_fem = this->model.getFEEngineBoundary();
-
+
const Mesh & mesh = this->model.getMesh();
-
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
- Mesh::type_iterator it = mesh.firstType(dim-1, *gt);
- Mesh::type_iterator last = mesh.lastType(dim-1, *gt);
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+ Mesh::type_iterator it = mesh.firstType(dim - 1, *gt);
+ Mesh::type_iterator last = mesh.lastType(dim - 1, *gt);
for (; it != last; ++it) {
UInt nb_elements = mesh.getNbElement(*it, *gt);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
const Array<UInt> & connectivity = mesh.getConnectivity(*it, *gt);
// get shapes and compute integral
const Array<Real> & shapes = boundary_fem.getShapes(*it, *gt);
- Array<Real> area(nb_elements,nb_nodes_per_element);
- boundary_fem.integrate(shapes,area,nb_nodes_per_element,*it, *gt);
+ Array<Real> area(nb_elements, nb_nodes_per_element);
+ boundary_fem.integrate(shapes, area, nb_nodes_per_element, *it, *gt);
if (this->contact_surfaces.size() == 0) {
- AKANTU_DEBUG_WARNING("No surfaces in ntn base contact."
- << " You have to define the lumped boundary by yourself.");
+ AKANTU_DEBUG_WARNING(
+ "No surfaces in ntn base contact."
+ << " You have to define the lumped boundary by yourself.");
}
- Array<UInt>::const_iterator<UInt> elem_it = (elements)(*it, *gt).begin();
- Array<UInt>::const_iterator<UInt> elem_it_end = (elements)(*it, *gt).end();
+ Array<UInt>::const_iterator<UInt> elem_it = (elements)(*it, *gt).begin();
+ Array<UInt>::const_iterator<UInt> elem_it_end =
+ (elements)(*it, *gt).end();
// loop over contact nodes
for (; elem_it != elem_it_end; ++elem_it) {
- for (UInt q=0; q<nb_nodes_per_element; ++q) {
- UInt node = connectivity(*elem_it,q);
+ for (UInt q = 0; q < nb_nodes_per_element; ++q) {
+ UInt node = connectivity(*elem_it, q);
UInt node_index = nodes.find(node);
- AKANTU_DEBUG_ASSERT(node_index != UInt(-1),
- "Could not find node " << node
- << " in the array!");
- Real area_to_add = area(*elem_it,q);
+ AKANTU_DEBUG_ASSERT(node_index != UInt(-1),
+ "Could not find node " << node
+ << " in the array!");
+ Real area_to_add = area(*elem_it, q);
boundary(node_index) += area_to_add;
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::computeContactPressure() {
AKANTU_DEBUG_IN();
UInt dim = this->model.getSpatialDimension();
Real delta_t = this->model.getTimeStep();
UInt nb_contact_nodes = getNbContactNodes();
- AKANTU_DEBUG_ASSERT(delta_t > 0.,
- "Cannot compute contact pressure if no time step is set");
+ AKANTU_DEBUG_ASSERT(delta_t > 0.,
+ "Cannot compute contact pressure if no time step is set");
// synchronize data
this->synch_registry->synchronize(_gst_cf_nodal);
- // pre-compute the acceleration
+ // pre-compute the acceleration
// (not increment acceleration, because residual is still Kf)
Array<Real> acceleration(this->model.getMesh().getNbNodes(), dim, 0.);
- this->model.solveLumped(acceleration,
- this->model.getMass(),
- this->model.getResidual(),
- this->model.getBlockedDOFs(),
- this->model.getF_M2A());
-
- // compute relative normal fields of displacement, velocity and acceleration
- Array<Real> r_disp(0,1);
- Array<Real> r_velo(0,1);
- Array<Real> r_acce(0,1);
- Array<Real> r_old_acce(0,1);
+ this->model.solveLumped(acceleration, this->model.getMass(),
+ this->model.getResidual(),
+ this->model.getBlockedDOFs(), this->model.getF_M2A());
+
+ // compute relative normal fields of displacement, velocity and acceleration
+ Array<Real> r_disp(0, 1);
+ Array<Real> r_velo(0, 1);
+ Array<Real> r_acce(0, 1);
+ Array<Real> r_old_acce(0, 1);
computeNormalGap(r_disp);
// computeRelativeNormalField(this->model.getCurrentPosition(), r_disp);
- computeRelativeNormalField(this->model.getVelocity(), r_velo);
- computeRelativeNormalField(acceleration, r_acce);
- computeRelativeNormalField(this->model.getAcceleration(), r_old_acce);
+ computeRelativeNormalField(this->model.getVelocity(), r_velo);
+ computeRelativeNormalField(acceleration, r_acce);
+ computeRelativeNormalField(this->model.getAcceleration(), r_old_acce);
- AKANTU_DEBUG_ASSERT(r_disp.getSize() == nb_contact_nodes,
- "computeRelativeNormalField does not give back arrays "
- << "size == nb_contact_nodes. nb_contact_nodes = " << nb_contact_nodes
- << " | array size = " << r_disp.getSize());
+ AKANTU_DEBUG_ASSERT(r_disp.getSize() == nb_contact_nodes,
+ "computeRelativeNormalField does not give back arrays "
+ << "size == nb_contact_nodes. nb_contact_nodes = "
+ << nb_contact_nodes
+ << " | array size = " << r_disp.getSize());
// compute gap array for all nodes
Array<Real> gap(nb_contact_nodes, 1);
Real * gap_p = gap.storage();
Real * r_disp_p = r_disp.storage();
Real * r_velo_p = r_velo.storage();
Real * r_acce_p = r_acce.storage();
Real * r_old_acce_p = r_old_acce.storage();
- for (UInt i=0; i<nb_contact_nodes; ++i) {
- *gap_p = *r_disp_p + delta_t * *r_velo_p + delta_t * delta_t * *r_acce_p - 0.5 * delta_t * delta_t * *r_old_acce_p;
+ for (UInt i = 0; i < nb_contact_nodes; ++i) {
+ *gap_p = *r_disp_p + delta_t * *r_velo_p + delta_t * delta_t * *r_acce_p -
+ 0.5 * delta_t * delta_t * *r_old_acce_p;
// increment pointers
gap_p++;
r_disp_p++;
r_velo_p++;
r_acce_p++;
r_old_acce_p++;
}
// check if gap is negative -> is in contact
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
if (gap(n) <= 0.) {
- for (UInt d=0; d<dim; ++d) {
- this->contact_pressure(n,d) = this->impedance(n) * gap(n) / (2 * delta_t)
- * this->normals(n,d);
+ for (UInt d = 0; d < dim; ++d) {
+ this->contact_pressure(n, d) =
+ this->impedance(n) * gap(n) / (2 * delta_t) * this->normals(n, d);
}
this->is_in_contact(n) = true;
- }
- else {
- for (UInt d=0; d<dim; ++d)
- this->contact_pressure(n,d) = 0.;
+ } else {
+ for (UInt d = 0; d < dim; ++d)
+ this->contact_pressure(n, d) = 0.;
this->is_in_contact(n) = false;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::applyContactPressure() {
AKANTU_DEBUG_IN();
UInt nb_contact_nodes = getNbContactNodes();
UInt dim = this->model.getSpatialDimension();
Array<Real> & residual = this->model.getResidual();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
UInt slave = this->slaves(n);
-
- for (UInt d=0; d<dim; ++d) {
- //residual(master,d) += this->lumped_boundary(n,0) * this->contact_pressure(n,d);
- residual(slave, d) -= this->lumped_boundary_slaves(n) * this->contact_pressure(n,d);
+
+ for (UInt d = 0; d < dim; ++d) {
+ // residual(master,d) += this->lumped_boundary(n,0) *
+ // this->contact_pressure(n,d);
+ residual(slave, d) -=
+ this->lumped_boundary_slaves(n) * this->contact_pressure(n, d);
}
}
-
+
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
Int NTNBaseContact::getNodeIndex(UInt node) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
return this->slaves.find(node);
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::printself(std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
stream << space << "NTNBaseContact [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + slaves : " << std::endl;
this->slaves.printself(stream, indent + 2);
stream << space << " + normals : " << std::endl;
this->normals.printself(stream, indent + 2);
stream << space << " + contact_pressure : " << std::endl;
this->contact_pressure.printself(stream, indent + 2);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::syncArrays(SyncChoice sync_choice) {
AKANTU_DEBUG_IN();
-
+
this->slaves.syncElements(sync_choice);
this->normals.syncElements(sync_choice);
this->is_in_contact.syncElements(sync_choice);
this->contact_pressure.syncElements(sync_choice);
this->lumped_boundary_slaves.syncElements(sync_choice);
this->impedance.syncElements(sync_choice);
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseContact::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+ const std::string & field_id) {
AKANTU_DEBUG_IN();
-
+
#ifdef AKANTU_USE_IOHELPER
const Array<UInt> & nodal_filter = this->slaves.getArray();
+#define ADD_FIELD(field_id, field, type) \
+ internalAddDumpFieldToDumper( \
+ dumper_name, field_id, \
+ new dumper::NodalField<type, true, Array<type>, Array<UInt>>( \
+ field, 0, 0, &nodal_filter))
-
-
-#define ADD_FIELD(field_id, field, type) \
- internalAddDumpFieldToDumper(dumper_name, \
- field_id, \
- new dumper::NodalField< type, true, \
- Array<type>, \
- Array<UInt> >(field, 0, 0, &nodal_filter))
-
- if(field_id == "displacement") {
+ if (field_id == "displacement") {
ADD_FIELD(field_id, this->model.getDisplacement(), Real);
- }
- else if(field_id == "mass") {
+ } else if (field_id == "mass") {
ADD_FIELD(field_id, this->model.getMass(), Real);
- }
- else if(field_id == "velocity") {
+ } else if (field_id == "velocity") {
ADD_FIELD(field_id, this->model.getVelocity(), Real);
- }
- else if(field_id == "acceleration") {
+ } else if (field_id == "acceleration") {
ADD_FIELD(field_id, this->model.getAcceleration(), Real);
- }
- else if(field_id == "force") {
+ } else if (field_id == "force") {
ADD_FIELD(field_id, this->model.getForce(), Real);
- }
- else if(field_id == "residual") {
+ } else if (field_id == "residual") {
ADD_FIELD(field_id, this->model.getResidual(), Real);
- }
- else if(field_id == "blocked_dofs") {
+ } else if (field_id == "blocked_dofs") {
ADD_FIELD(field_id, this->model.getBlockedDOFs(), bool);
- }
- else if(field_id == "increment") {
+ } else if (field_id == "increment") {
ADD_FIELD(field_id, this->model.getIncrement(), Real);
- }
- else if(field_id == "normal") {
- internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->normals.getArray()));
- }
- else if(field_id == "contact_pressure") {
- internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->contact_pressure.getArray()));
- }
- else if(field_id == "is_in_contact") {
- internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<bool>(this->is_in_contact.getArray()));
- }
- else if(field_id == "lumped_boundary_slave") {
- internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->lumped_boundary_slaves.getArray()));
- }
- else if(field_id == "impedance") {
- internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->impedance.getArray()));
- }
- else {
- std::cerr << "Could not add field '" << field_id
- << "' to the dumper. Just ignored it." << std::endl;
+ } else if (field_id == "normal") {
+ internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->normals.getArray()));
+ } else if (field_id == "contact_pressure") {
+ internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->contact_pressure.getArray()));
+ } else if (field_id == "is_in_contact") {
+ internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<bool>(this->is_in_contact.getArray()));
+ } else if (field_id == "lumped_boundary_slave") {
+ internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->lumped_boundary_slaves.getArray()));
+ } else if (field_id == "impedance") {
+ internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->impedance.getArray()));
+ } else {
+ std::cerr << "Could not add field '" << field_id
+ << "' to the dumper. Just ignored it." << std::endl;
}
#undef ADD_FIELD
#endif
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.hh
index 8642c09da..527986f61 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.hh
@@ -1,229 +1,228 @@
/**
* @file ntn_base_contact.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief base contact for ntn and ntrf contact
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_BASE_CONTACT_HH__
#define __AST_NTN_BASE_CONTACT_HH__
/* -------------------------------------------------------------------------- */
// akantu
-#include "solid_mechanics_model.hh"
#include "filtered_synchronizer.hh"
+#include "solid_mechanics_model.hh"
// simtools
#include "synchronized_array.hh"
namespace akantu {
class NTNBaseContact;
/* -------------------------------------------------------------------------- */
class NTNContactSynchElementFilter : public SynchElementFilter {
public:
// constructor
NTNContactSynchElementFilter(NTNBaseContact * contact);
// answer to: do we need this element ?
virtual bool operator()(const Element & e);
private:
const NTNBaseContact * contact;
const ElementTypeMapArray<UInt> & connectivity;
};
-
-
/* -------------------------------------------------------------------------- */
-class NTNBaseContact : protected Memory,
- public DataAccessor,
- public Dumpable {
+class NTNBaseContact : protected Memory, public DataAccessor, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTNBaseContact(SolidMechanicsModel & model,
- const ContactID & id = "contact",
- const MemoryID & memory_id = 0);
+ NTNBaseContact(SolidMechanicsModel & model, const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
virtual ~NTNBaseContact();
-
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initializes ntn contact parallel
virtual void initParallel();
/// add split node
virtual void addSplitNode(UInt node);
/// update normals, lumped boundary, and impedance
virtual void updateInternalData();
/// update (compute the normals)
virtual void updateNormals() = 0;
/// update the lumped boundary B matrix
virtual void updateLumpedBoundary();
/// update the impedance matrix
virtual void updateImpedance() = 0;
/// compute the normal contact force
virtual void computeContactPressure();
/// impose the normal contact force
virtual void applyContactPressure();
/// register synchronizedarrays for sync
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
/// dump restart file
virtual void dumpRestart(const std::string & file_name) const;
/// read restart file
virtual void readRestart(const std::string & file_name);
/// compute the normal gap
virtual void computeNormalGap(Array<Real> & gap) const = 0;
- /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// compute relative normal field (only value that has to be multiplied with
+ /// the normal)
/// relative to master nodes
- virtual void computeRelativeNormalField(const Array<Real> & field,
- Array<Real> & rel_normal_field) const = 0;
-
+ virtual void
+ computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const = 0;
+
/// compute relative tangential field (complet array)
/// relative to master nodes
- virtual void computeRelativeTangentialField(const Array<Real> & field,
- Array<Real> & rel_tang_field) const = 0;
-
+ virtual void
+ computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const = 0;
+
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
+
protected:
/// updateLumpedBoundary
- virtual void internalUpdateLumpedBoundary(const Array<UInt> & nodes,
- const ElementTypeMapArray<UInt> & elements,
- SynchronizedArray<Real> & boundary);
+ virtual void
+ internalUpdateLumpedBoundary(const Array<UInt> & nodes,
+ const ElementTypeMapArray<UInt> & elements,
+ SynchronizedArray<Real> & boundary);
// to find the slave_elements or master_elements
- virtual void findBoundaryElements(const Array<UInt> & interface_nodes,
- ElementTypeMapArray<UInt> & elements);
+ virtual void findBoundaryElements(const Array<UInt> & interface_nodes,
+ ElementTypeMapArray<UInt> & elements);
/// synchronize arrays
virtual void syncArrays(SyncChoice sync_choice);
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
inline virtual UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
-
+
inline virtual void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
-
+
inline virtual void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
-
+
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Model, model, SolidMechanicsModel &)
- AKANTU_GET_MACRO(Slaves, slaves, const SynchronizedArray<UInt> &)
- AKANTU_GET_MACRO(Normals, normals, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(ContactPressure, contact_pressure, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(LumpedBoundarySlaves, lumped_boundary_slaves, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(Impedance, impedance, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(IsInContact, is_in_contact, const SynchronizedArray<bool> &)
+ AKANTU_GET_MACRO(Slaves, slaves, const SynchronizedArray<UInt> &)
+ AKANTU_GET_MACRO(Normals, normals, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(ContactPressure, contact_pressure,
+ const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(LumpedBoundarySlaves, lumped_boundary_slaves,
+ const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(Impedance, impedance, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(IsInContact, is_in_contact, const SynchronizedArray<bool> &)
- AKANTU_GET_MACRO(SlaveElements, slave_elements, const ElementTypeMapArray<UInt> &)
+ AKANTU_GET_MACRO(SlaveElements, slave_elements,
+ const ElementTypeMapArray<UInt> &)
AKANTU_GET_MACRO(SynchronizerRegistry, synch_registry, SynchronizerRegistry *)
/// get number of nodes that are in contact (globally, on all procs together)
/// is_in_contact = true
virtual UInt getNbNodesInContact() const;
/// get index of node in either slaves or masters array
/// if node is in neither of them, return -1
virtual Int getNodeIndex(UInt node) const;
/// get number of contact nodes: nodes in the system locally (on this proc)
/// is_in_contact = true and false, because just in the system
virtual UInt getNbContactNodes() const { return this->slaves.getSize(); };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
typedef std::set<const ElementGroup *> SurfacePtrSet;
SolidMechanicsModel & model;
/// array of slave nodes
SynchronizedArray<UInt> slaves;
/// array of normals
SynchronizedArray<Real> normals;
/// array indicating if nodes are in contact
SynchronizedArray<Real> contact_pressure;
/// array indicating if nodes are in contact
SynchronizedArray<bool> is_in_contact;
/// boundary matrix for slave nodes
SynchronizedArray<Real> lumped_boundary_slaves;
/// impedance matrix
SynchronizedArray<Real> impedance;
/// contact surface
SurfacePtrSet contact_surfaces;
/// element list for dump and lumped_boundary
ElementTypeMapArray<UInt> slave_elements;
CSR<Element> node_to_elements;
/// parallelisation
SynchronizerRegistry * synch_registry;
Synchronizer * synchronizer;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "ntn_base_contact_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const NTNBaseContact & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const NTNBaseContact & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_NTN_BASE_CONTACT_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact_inline_impl.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact_inline_impl.cc
index dc0ff7ed9..276c72199 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact_inline_impl.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact_inline_impl.cc
@@ -1,121 +1,105 @@
/**
* @file ntn_base_contact_inline_impl.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief ntn base contact inline functions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-inline UInt NTNBaseContact::getNbDataForElements(const Array<Element> & elements,
- SynchronizationTag tag) const {
+inline UInt
+NTNBaseContact::getNbDataForElements(const Array<Element> & elements,
+ SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
-
+
UInt size = 0;
UInt spatial_dimension = this->model.getSpatialDimension();
UInt nb_nodes = 0;
- Array<Element>::const_iterator<Element> it = elements.begin();
+ Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
nb_nodes += Mesh::getNbNodesPerElement(el.type);
}
- switch(tag) {
+ switch (tag) {
case _gst_cf_nodal: {
- size += nb_nodes * spatial_dimension * sizeof(Real) * 3; // disp, vel and cur_pos
+ size += nb_nodes * spatial_dimension * sizeof(Real) *
+ 3; // disp, vel and cur_pos
break;
}
case _gst_cf_incr: {
size += nb_nodes * spatial_dimension * sizeof(Real) * 1;
break;
}
default: {}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void NTNBaseContact::packElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) const {
+ const Array<Element> & elements,
+ SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
-
- switch(tag) {
+
+ switch (tag) {
case _gst_cf_nodal: {
- DataAccessor::packNodalDataHelper(this->model.getDisplacement(),
- buffer,
- elements,
- this->model.getMesh());
- DataAccessor::packNodalDataHelper(this->model.getCurrentPosition(),
- buffer,
- elements,
- this->model.getMesh());
- DataAccessor::packNodalDataHelper(this->model.getVelocity(),
- buffer,
- elements,
- this->model.getMesh());
+ DataAccessor::packNodalDataHelper(this->model.getDisplacement(), buffer,
+ elements, this->model.getMesh());
+ DataAccessor::packNodalDataHelper(this->model.getCurrentPosition(), buffer,
+ elements, this->model.getMesh());
+ DataAccessor::packNodalDataHelper(this->model.getVelocity(), buffer,
+ elements, this->model.getMesh());
break;
}
case _gst_cf_incr: {
- DataAccessor::packNodalDataHelper(this->model.getIncrement(),
- buffer,
- elements,
- this->model.getMesh());
+ DataAccessor::packNodalDataHelper(this->model.getIncrement(), buffer,
+ elements, this->model.getMesh());
break;
}
- default: {
- }
+ default: {}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void NTNBaseContact::unpackElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) {
+ const Array<Element> & elements,
+ SynchronizationTag tag) {
AKANTU_DEBUG_IN();
- switch(tag) {
+ switch (tag) {
case _gst_cf_nodal: {
- DataAccessor::unpackNodalDataHelper(this->model.getDisplacement(),
- buffer,
- elements,
- this->model.getMesh());
- DataAccessor::unpackNodalDataHelper(const_cast<Array<Real> & >(this->model.getCurrentPosition()),
- buffer,
- elements,
- this->model.getMesh());
- DataAccessor::unpackNodalDataHelper(this->model.getVelocity(),
- buffer,
- elements,
- this->model.getMesh());
+ DataAccessor::unpackNodalDataHelper(this->model.getDisplacement(), buffer,
+ elements, this->model.getMesh());
+ DataAccessor::unpackNodalDataHelper(
+ const_cast<Array<Real> &>(this->model.getCurrentPosition()), buffer,
+ elements, this->model.getMesh());
+ DataAccessor::unpackNodalDataHelper(this->model.getVelocity(), buffer,
+ elements, this->model.getMesh());
break;
}
case _gst_cf_incr: {
- DataAccessor::unpackNodalDataHelper(this->model.getIncrement(),
- buffer,
- elements,
- this->model.getMesh());
+ DataAccessor::unpackNodalDataHelper(this->model.getIncrement(), buffer,
+ elements, this->model.getMesh());
break;
}
- default: {
- }
+ default: {}
}
-
+
AKANTU_DEBUG_OUT();
}
-
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
index 2d7516a25..5609ea3da 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
@@ -1,374 +1,367 @@
/**
* @file ntn_base_friction.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of ntn base friction
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_base_friction.hh"
-#include "dumper_text.hh"
#include "dumper_nodal_field.hh"
+#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
NTNBaseFriction::NTNBaseFriction(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- Memory(id,memory_id),
- Parsable(_st_friction, id),
- Dumpable(),
- contact(contact),
- is_sticking(0,1,true,id+":is_sticking",true,"is_sticking"),
- frictional_strength(0,1,0.,id+":frictional_strength",0.,"frictional_strength"),
- friction_traction(0,contact->getModel().getSpatialDimension(),
- 0.,id+":friction_traction",0.,"friction_traction"),
- slip(0,1,0.,id+":slip",0.,"slip"),
- cumulative_slip(0,1,0.,id+":cumulative_slip",0.,"cumulative_slip"),
- slip_velocity(0,contact->getModel().getSpatialDimension(),
- 0.,id+":slip_velocity",0.,"slip_velocity") {
+ const FrictionID & id,
+ const MemoryID & memory_id)
+ : Memory(id, memory_id), Parsable(_st_friction, id), Dumpable(),
+ contact(contact),
+ is_sticking(0, 1, true, id + ":is_sticking", true, "is_sticking"),
+ frictional_strength(0, 1, 0., id + ":frictional_strength", 0.,
+ "frictional_strength"),
+ friction_traction(0, contact->getModel().getSpatialDimension(), 0.,
+ id + ":friction_traction", 0., "friction_traction"),
+ slip(0, 1, 0., id + ":slip", 0., "slip"),
+ cumulative_slip(0, 1, 0., id + ":cumulative_slip", 0., "cumulative_slip"),
+ slip_velocity(0, contact->getModel().getSpatialDimension(), 0.,
+ id + ":slip_velocity", 0., "slip_velocity") {
AKANTU_DEBUG_IN();
this->contact->registerSynchronizedArray(this->is_sticking);
this->contact->registerSynchronizedArray(this->frictional_strength);
this->contact->registerSynchronizedArray(this->friction_traction);
this->contact->registerSynchronizedArray(this->slip);
this->contact->registerSynchronizedArray(this->cumulative_slip);
this->contact->registerSynchronizedArray(this->slip_velocity);
contact->getModel().setIncrementFlagOn();
this->registerExternalDumper(contact->getDumper(),
- contact->getDefaultDumperName(),
- true);
+ contact->getDefaultDumperName(), true);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::updateSlip() {
AKANTU_DEBUG_IN();
SolidMechanicsModel & model = this->contact->getModel();
UInt dim = model.getSpatialDimension();
// synchronize increment
this->contact->getSynchronizerRegistry()->synchronize(_gst_cf_incr);
- Array<Real> rel_tan_incr(0,dim);
+ Array<Real> rel_tan_incr(0, dim);
this->contact->computeRelativeTangentialField(model.getIncrement(),
- rel_tan_incr);
- Array<Real>::const_iterator< Vector<Real> > it = rel_tan_incr.begin(dim);
+ rel_tan_incr);
+ Array<Real>::const_iterator<Vector<Real>> it = rel_tan_incr.begin(dim);
UInt nb_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_nodes; ++n) {
+ for (UInt n = 0; n < nb_nodes; ++n) {
if (this->is_sticking(n)) {
this->slip(n) = 0.;
- }
- else {
+ } else {
const Vector<Real> & rti = it[n];
this->slip(n) += rti.norm();
this->cumulative_slip(n) += rti.norm();
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::computeFrictionTraction() {
AKANTU_DEBUG_IN();
this->computeStickTraction();
this->computeFrictionalStrength();
SolidMechanicsModel & model = this->contact->getModel();
UInt dim = model.getSpatialDimension();
// get contact arrays
- const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
+ const SynchronizedArray<bool> & is_in_contact =
+ this->contact->getIsInContact();
- Array<Real> & traction = const_cast< Array<Real> & >(this->friction_traction.getArray());
- Array<Real>::iterator< Vector<Real> > it_fric_trac = traction.begin(dim);
+ Array<Real> & traction =
+ const_cast<Array<Real> &>(this->friction_traction.getArray());
+ Array<Real>::iterator<Vector<Real>> it_fric_trac = traction.begin(dim);
this->is_sticking.clear(); // set to not sticking
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// node pair is in contact
if (is_in_contact(n)) {
Vector<Real> fric_trac = it_fric_trac[n];
// check if it is larger than frictional strength
Real abs_fric = fric_trac.norm();
if (abs_fric != 0.) {
- Real alpha = this->frictional_strength(n) / abs_fric;
-
- // larger -> sliding
- if (alpha < 1.) {
- fric_trac *= alpha;
- }
- else
- this->is_sticking(n) = true;
- }
- else {
- // frictional traction is already zero
- this->is_sticking(n) = true;
+ Real alpha = this->frictional_strength(n) / abs_fric;
+
+ // larger -> sliding
+ if (alpha < 1.) {
+ fric_trac *= alpha;
+ } else
+ this->is_sticking(n) = true;
+ } else {
+ // frictional traction is already zero
+ this->is_sticking(n) = true;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::computeStickTraction() {
AKANTU_DEBUG_IN();
SolidMechanicsModel & model = this->contact->getModel();
UInt dim = model.getSpatialDimension();
Real delta_t = model.getTimeStep();
UInt nb_contact_nodes = this->contact->getNbContactNodes();
// get contact arrays
const SynchronizedArray<Real> & impedance = this->contact->getImpedance();
- const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
+ const SynchronizedArray<bool> & is_in_contact =
+ this->contact->getIsInContact();
// pre-compute the acceleration
// (not increment acceleration, because residual is still Kf)
Array<Real> acceleration(model.getFEEngine().getMesh().getNbNodes(), dim, 0.);
- model.solveLumped(acceleration,
- model.getMass(),
- model.getResidual(),
- model.getBlockedDOFs(),
- model.getF_M2A());
+ model.solveLumped(acceleration, model.getMass(), model.getResidual(),
+ model.getBlockedDOFs(), model.getF_M2A());
// compute relative normal fields of velocity and acceleration
- Array<Real> r_velo(0,dim);
- Array<Real> r_acce(0,dim);
- Array<Real> r_old_acce(0,dim);
- this->contact->computeRelativeTangentialField(model.getVelocity(), r_velo);
- this->contact->computeRelativeTangentialField(acceleration, r_acce);
- this->contact->computeRelativeTangentialField(model.getAcceleration(), r_old_acce);
+ Array<Real> r_velo(0, dim);
+ Array<Real> r_acce(0, dim);
+ Array<Real> r_old_acce(0, dim);
+ this->contact->computeRelativeTangentialField(model.getVelocity(), r_velo);
+ this->contact->computeRelativeTangentialField(acceleration, r_acce);
+ this->contact->computeRelativeTangentialField(model.getAcceleration(),
+ r_old_acce);
AKANTU_DEBUG_ASSERT(r_velo.getSize() == nb_contact_nodes,
- "computeRelativeNormalField does not give back arrays "
- << "size == nb_contact_nodes. nb_contact_nodes = " << nb_contact_nodes
- << " | array size = " << r_velo.getSize());
+ "computeRelativeNormalField does not give back arrays "
+ << "size == nb_contact_nodes. nb_contact_nodes = "
+ << nb_contact_nodes
+ << " | array size = " << r_velo.getSize());
// compute tangential gap_dot array for all nodes
Array<Real> gap_dot(nb_contact_nodes, dim);
Real * gap_dot_p = gap_dot.storage();
Real * r_velo_p = r_velo.storage();
Real * r_acce_p = r_acce.storage();
Real * r_old_acce_p = r_old_acce.storage();
- for (UInt i=0; i<nb_contact_nodes*dim; ++i) {
- *gap_dot_p = *r_velo_p + delta_t * *r_acce_p - 0.5 * delta_t * *r_old_acce_p;
+ for (UInt i = 0; i < nb_contact_nodes * dim; ++i) {
+ *gap_dot_p =
+ *r_velo_p + delta_t * *r_acce_p - 0.5 * delta_t * *r_old_acce_p;
// increment pointers
gap_dot_p++;
r_velo_p++;
r_acce_p++;
r_old_acce_p++;
}
// compute friction traction to stop sliding
- Array<Real> & traction = const_cast< Array<Real> & >(this->friction_traction.getArray());
+ Array<Real> & traction =
+ const_cast<Array<Real> &>(this->friction_traction.getArray());
auto it_fric_trac = traction.begin(dim);
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
Vector<Real> fric_trac = it_fric_trac[n];
// node pair is NOT in contact
if (!is_in_contact(n)) {
fric_trac.clear(); // set to zero
}
// node pair is in contact
else {
// compute friction traction
- for (UInt d=0; d<dim; ++d)
- fric_trac(d) = impedance(n) * gap_dot(n,d) / 2.;
+ for (UInt d = 0; d < dim; ++d)
+ fric_trac(d) = impedance(n) * gap_dot(n, d) / 2.;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::applyFrictionTraction() {
AKANTU_DEBUG_IN();
SolidMechanicsModel & model = this->contact->getModel();
Array<Real> & residual = model.getResidual();
UInt dim = model.getSpatialDimension();
const SynchronizedArray<UInt> & slaves = this->contact->getSlaves();
- const SynchronizedArray<Real> & lumped_boundary_slaves = this->contact->getLumpedBoundarySlaves();
+ const SynchronizedArray<Real> & lumped_boundary_slaves =
+ this->contact->getLumpedBoundarySlaves();
UInt nb_contact_nodes = this->contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
UInt slave = slaves(n);
- for (UInt d=0; d<dim; ++d) {
- residual(slave, d) -= lumped_boundary_slaves(n) * this->friction_traction(n,d);
+ for (UInt d = 0; d < dim; ++d) {
+ residual(slave, d) -=
+ lumped_boundary_slaves(n) * this->friction_traction(n, d);
}
}
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::registerSynchronizedArray(SynchronizedArrayBase & array) {
AKANTU_DEBUG_IN();
this->frictional_strength.registerDependingArray(array);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::dumpRestart(const std::string & file_name) const {
AKANTU_DEBUG_IN();
this->is_sticking.dumpRestartFile(file_name);
this->frictional_strength.dumpRestartFile(file_name);
this->friction_traction.dumpRestartFile(file_name);
this->slip.dumpRestartFile(file_name);
this->cumulative_slip.dumpRestartFile(file_name);
this->slip_velocity.dumpRestartFile(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::readRestart(const std::string & file_name) {
AKANTU_DEBUG_IN();
this->is_sticking.readRestartFile(file_name);
this->frictional_strength.readRestartFile(file_name);
this->friction_traction.readRestartFile(file_name);
this->cumulative_slip.readRestartFile(file_name);
this->slip_velocity.readRestartFile(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNBaseFriction::setParam(const std::string & name, UInt node, Real value) {
+void NTNBaseFriction::setParam(const std::string & name, UInt node,
+ Real value) {
AKANTU_DEBUG_IN();
- SynchronizedArray<Real> & array = this->get< SynchronizedArray<Real> >(name);
+ SynchronizedArray<Real> & array = this->get<SynchronizedArray<Real>>(name);
Int index = this->contact->getNodeIndex(node);
if (index < 0) {
- AKANTU_DEBUG_WARNING("Node " << node << " is not a contact node. "
- << "Therefore, cannot set interface parameter!!");
- }
- else {
+ AKANTU_DEBUG_WARNING("Node "
+ << node << " is not a contact node. "
+ << "Therefore, cannot set interface parameter!!");
+ } else {
array(index) = value; // put value
}
AKANTU_DEBUG_OUT();
};
/* -------------------------------------------------------------------------- */
UInt NTNBaseFriction::getNbStickingNodes() const {
AKANTU_DEBUG_IN();
UInt nb_stick = 0;
UInt nb_nodes = this->contact->getNbContactNodes();
const SynchronizedArray<UInt> & nodes = this->contact->getSlaves();
- const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
+ const SynchronizedArray<bool> & is_in_contact =
+ this->contact->getIsInContact();
const Mesh & mesh = this->contact->getModel().getMesh();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(nodes(n));
bool is_pbc_slave_node = this->contact->getModel().isPBCSlaveNode(nodes(n));
- if (is_local_node
- && !is_pbc_slave_node
- && is_in_contact(n)
- && this->is_sticking(n)) {
+ if (is_local_node && !is_pbc_slave_node && is_in_contact(n) &&
+ this->is_sticking(n)) {
nb_stick++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&nb_stick, 1, _so_sum);
AKANTU_DEBUG_OUT();
return nb_stick;
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::printself(std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "NTNBaseFriction [" << std::endl;
Parsable::printself(stream, indent);
stream << space << "]" << std::endl;
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNBaseFriction::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+ const std::string & field_id) {
AKANTU_DEBUG_IN();
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
-
- if(field_id == "is_sticking") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<bool>(this->is_sticking.getArray()));
- }
- else if(field_id == "frictional_strength") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->frictional_strength.getArray()));
- }
- else if(field_id == "friction_traction") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->friction_traction.getArray()));
- }
- else if(field_id == "slip") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->slip.getArray()));
- }
- else if(field_id == "cumulative_slip") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->cumulative_slip.getArray()));
- }
- else if(field_id == "slip_velocity") {
- this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->slip_velocity.getArray()));
- }
- else {
+ // const SynchronizedArray<UInt> * nodal_filter =
+ // &(this->contact->getSlaves());
+
+ if (field_id == "is_sticking") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<bool>(this->is_sticking.getArray()));
+ } else if (field_id == "frictional_strength") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->frictional_strength.getArray()));
+ } else if (field_id == "friction_traction") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->friction_traction.getArray()));
+ } else if (field_id == "slip") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->slip.getArray()));
+ } else if (field_id == "cumulative_slip") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->cumulative_slip.getArray()));
+ } else if (field_id == "slip_velocity") {
+ this->internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->slip_velocity.getArray()));
+ } else {
this->contact->addDumpFieldToDumper(dumper_name, field_id);
}
#endif
AKANTU_DEBUG_OUT();
}
-
-
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.hh
index 6452eda7a..d5a3d06e5 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.hh
@@ -1,161 +1,162 @@
/**
* @file ntn_base_friction.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief base class for ntn and ntrf friction
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_BASE_FRICTION_HH__
#define __AST_NTN_BASE_FRICTION_HH__
/* -------------------------------------------------------------------------- */
// akantu
#include "parsable.hh"
// simtools
#include "ntn_base_contact.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
-template<>
-inline void ParsableParamTyped< akantu::SynchronizedArray<Real> >::parseParam(const ParserParameter & in_param) {
+template <>
+inline void ParsableParamTyped<akantu::SynchronizedArray<Real>>::parseParam(
+ const ParserParameter & in_param) {
ParsableParam::parseParam(in_param);
Real tmp = in_param;
param.setAndChangeDefault(tmp);
}
/* -------------------------------------------------------------------------- */
-template<>
-template<>
-inline void ParsableParamTyped< akantu::SynchronizedArray<Real> >::setTyped<Real>(const Real & value) {
- param.setAndChangeDefault(value);
+template <>
+template <>
+inline void ParsableParamTyped<akantu::SynchronizedArray<Real>>::setTyped<Real>(
+ const Real & value) {
+ param.setAndChangeDefault(value);
}
/* -------------------------------------------------------------------------- */
class NTNBaseFriction : protected Memory, public Parsable, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTNBaseFriction(NTNBaseContact * contact,
- const FrictionID & id = "friction",
- const MemoryID & memory_id = 0);
- virtual ~NTNBaseFriction() {};
-
+ NTNBaseFriction(NTNBaseContact * contact, const FrictionID & id = "friction",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNBaseFriction(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// compute friction traction
virtual void computeFrictionTraction();
/// compute stick traction (friction traction needed to stick the nodes)
virtual void computeStickTraction();
/// apply the friction force
virtual void applyFrictionTraction();
/// compute slip
virtual void updateSlip();
/// register Syncronizedarrays for sync
virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
-
+
/// dump restart file
virtual void dumpRestart(const std::string & file_name) const;
/// read restart file
virtual void readRestart(const std::string & file_name);
/// set to steady state
- virtual void setToSteadyState() {
- AKANTU_TO_IMPLEMENT();
- };
+ virtual void setToSteadyState() { AKANTU_TO_IMPLEMENT(); };
/// get the number of sticking nodes (in parallel)
/// a node that is not in contact does not count as sticking
virtual UInt getNbStickingNodes() const;
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
/// compute frictional strength according to friction law
virtual void computeFrictionalStrength() = 0;
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Contact, contact, const NTNBaseContact *)
- AKANTU_GET_MACRO(IsSticking, is_sticking, const SynchronizedArray<bool> &)
- AKANTU_GET_MACRO(FrictionalStrength, frictional_strength, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(FrictionTraction, friction_traction, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(Slip, slip, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(CumulativeSlip, cumulative_slip, const SynchronizedArray<Real> &)
- AKANTU_GET_MACRO(SlipVelocity, slip_velocity, const SynchronizedArray<Real> &)
-
- /// set parameter of a given node
+ AKANTU_GET_MACRO(IsSticking, is_sticking, const SynchronizedArray<bool> &)
+ AKANTU_GET_MACRO(FrictionalStrength, frictional_strength,
+ const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(FrictionTraction, friction_traction,
+ const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(Slip, slip, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(CumulativeSlip, cumulative_slip,
+ const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(SlipVelocity, slip_velocity, const SynchronizedArray<Real> &)
+
+ /// set parameter of a given node
/// (if you need to set to all: used the setMixed function of the Parsable).
virtual void setParam(const std::string & name, UInt node, Real value);
// replaced by the setMixed of the Parsable
// virtual void setParam(const std::string & param, Real value) {
- // AKANTU_ERROR("Friction does not know the following parameter: " << param);
+ // AKANTU_ERROR("Friction does not know the following parameter: " <<
+ // param);
// };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
NTNBaseContact * contact;
// if node is sticking
SynchronizedArray<bool> is_sticking;
// frictional strength
SynchronizedArray<Real> frictional_strength;
// friction force
SynchronizedArray<Real> friction_traction;
// slip
SynchronizedArray<Real> slip;
SynchronizedArray<Real> cumulative_slip;
// slip velocity (tangential vector)
SynchronizedArray<Real> slip_velocity;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "ntn_base_friction_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const NTNBaseFriction & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const NTNBaseFriction & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_NTN_BASE_FRICTION_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
index 935b7f5fe..8af146114 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
@@ -1,564 +1,575 @@
/**
* @file ntn_contact.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of ntn_contact
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_contact.hh"
-#include "dumper_text.hh"
#include "dumper_nodal_field.hh"
+#include "dumper_text.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-NTNContact::NTNContact(SolidMechanicsModel & model,
- const ContactID & id,
- const MemoryID & memory_id) :
- NTNBaseContact(model,id,memory_id),
- masters(0,1,0,id+":masters",std::numeric_limits<UInt>::quiet_NaN(),"masters"),
- lumped_boundary_masters(0,1,0,id+":lumped_boundary_masters",
- std::numeric_limits<Real>::quiet_NaN(),"lumped_boundary_masters"),
- master_elements("master_elements", id, memory_id)
-{
+NTNContact::NTNContact(SolidMechanicsModel & model, const ContactID & id,
+ const MemoryID & memory_id)
+ : NTNBaseContact(model, id, memory_id),
+ masters(0, 1, 0, id + ":masters", std::numeric_limits<UInt>::quiet_NaN(),
+ "masters"),
+ lumped_boundary_masters(0, 1, 0, id + ":lumped_boundary_masters",
+ std::numeric_limits<Real>::quiet_NaN(),
+ "lumped_boundary_masters"),
+ master_elements("master_elements", id, memory_id) {
AKANTU_DEBUG_IN();
const Mesh & mesh = this->model.getMesh();
UInt spatial_dimension = this->model.getSpatialDimension();
- mesh.initElementTypeMapArray(this->master_elements,
- 1,
- spatial_dimension - 1);
+ mesh.initElementTypeMapArray(this->master_elements, 1, spatial_dimension - 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::pairInterfaceNodes(const ElementGroup & slave_boundary,
- const ElementGroup & master_boundary,
- UInt surface_normal_dir,
- const Mesh & mesh,
- Array<UInt> & pairs) {
+ const ElementGroup & master_boundary,
+ UInt surface_normal_dir, const Mesh & mesh,
+ Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
pairs.resize(0);
AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
- "Array of node pairs should have nb_component = 2," <<
- " but has nb_component = " << pairs.getNbComponent());
+ "Array of node pairs should have nb_component = 2,"
+ << " but has nb_component = "
+ << pairs.getNbComponent());
UInt dim = mesh.getSpatialDimension();
- AKANTU_DEBUG_ASSERT(surface_normal_dir < dim, "Mesh is of " << dim << " dimensions"
- << " and cannot have direction " << surface_normal_dir
- << " for surface normal");
+ AKANTU_DEBUG_ASSERT(surface_normal_dir < dim,
+ "Mesh is of " << dim << " dimensions"
+ << " and cannot have direction "
+ << surface_normal_dir
+ << " for surface normal");
// offset for projection computation
- UInt offset[dim-1];
- for (UInt i=0, j=0; i<dim; ++i) {
+ UInt offset[dim - 1];
+ for (UInt i = 0, j = 0; i < dim; ++i) {
if (surface_normal_dir != i) {
offset[j] = i;
++j;
}
}
// find projected node coordinates
const Array<Real> & coordinates = mesh.getNodes();
// find slave nodes
- Array<Real> proj_slave_coord(slave_boundary.getNbNodes(),dim-1,0.);
+ Array<Real> proj_slave_coord(slave_boundary.getNbNodes(), dim - 1, 0.);
Array<UInt> slave_nodes(slave_boundary.getNbNodes());
UInt n(0);
- for(ElementGroup::const_node_iterator nodes_it(slave_boundary.node_begin()); nodes_it!= slave_boundary.node_end(); ++nodes_it) {
- for (UInt d=0; d<dim-1; ++d) {
- proj_slave_coord(n,d) = coordinates(*nodes_it,offset[d]);
- slave_nodes(n)=*nodes_it;
+ for (ElementGroup::const_node_iterator nodes_it(slave_boundary.node_begin());
+ nodes_it != slave_boundary.node_end(); ++nodes_it) {
+ for (UInt d = 0; d < dim - 1; ++d) {
+ proj_slave_coord(n, d) = coordinates(*nodes_it, offset[d]);
+ slave_nodes(n) = *nodes_it;
}
++n;
}
// find master nodes
- Array<Real> proj_master_coord(master_boundary.getNbNodes(),dim-1,0.);
+ Array<Real> proj_master_coord(master_boundary.getNbNodes(), dim - 1, 0.);
Array<UInt> master_nodes(master_boundary.getNbNodes());
- n=0;
- for(ElementGroup::const_node_iterator nodes_it(master_boundary.node_begin()); nodes_it!= master_boundary.node_end(); ++nodes_it) {
- for (UInt d=0; d<dim-1; ++d) {
- proj_master_coord(n,d) = coordinates(*nodes_it,offset[d]);
- master_nodes(n)=*nodes_it;
+ n = 0;
+ for (ElementGroup::const_node_iterator nodes_it(master_boundary.node_begin());
+ nodes_it != master_boundary.node_end(); ++nodes_it) {
+ for (UInt d = 0; d < dim - 1; ++d) {
+ proj_master_coord(n, d) = coordinates(*nodes_it, offset[d]);
+ master_nodes(n) = *nodes_it;
}
++n;
}
// find minimum distance between slave nodes to define tolerance
Real min_dist = std::numeric_limits<Real>::max();
- for (UInt i=0; i<proj_slave_coord.getSize(); ++i) {
- for (UInt j=i+1; j<proj_slave_coord.getSize(); ++j) {
+ for (UInt i = 0; i < proj_slave_coord.getSize(); ++i) {
+ for (UInt j = i + 1; j < proj_slave_coord.getSize(); ++j) {
Real dist = 0.;
- for (UInt d=0; d<dim-1; ++d) {
- dist += (proj_slave_coord(i,d) - proj_slave_coord(j,d))
- * (proj_slave_coord(i,d) - proj_slave_coord(j,d));
+ for (UInt d = 0; d < dim - 1; ++d) {
+ dist += (proj_slave_coord(i, d) - proj_slave_coord(j, d)) *
+ (proj_slave_coord(i, d) - proj_slave_coord(j, d));
}
if (dist < min_dist) {
- min_dist = dist;
+ min_dist = dist;
}
}
}
min_dist = std::sqrt(min_dist);
- Real local_tol = 0.1*min_dist;
+ Real local_tol = 0.1 * min_dist;
// find master slave node pairs
- for (UInt i=0; i<proj_slave_coord.getSize(); ++i) {
- for (UInt j=0; j<proj_master_coord.getSize(); ++j) {
+ for (UInt i = 0; i < proj_slave_coord.getSize(); ++i) {
+ for (UInt j = 0; j < proj_master_coord.getSize(); ++j) {
Real dist = 0.;
- for (UInt d=0; d<dim-1; ++d) {
- dist += (proj_slave_coord(i,d) - proj_master_coord(j,d))
- * (proj_slave_coord(i,d) - proj_master_coord(j,d));
+ for (UInt d = 0; d < dim - 1; ++d) {
+ dist += (proj_slave_coord(i, d) - proj_master_coord(j, d)) *
+ (proj_slave_coord(i, d) - proj_master_coord(j, d));
}
dist = std::sqrt(dist);
if (dist < local_tol) { // it is a pair
- UInt pair[2];
- pair[0] = slave_nodes(i);
- pair[1] = master_nodes(j);
- pairs.push_back(pair);
- continue; // found master do not need to search further for this slave
+ UInt pair[2];
+ pair[0] = slave_nodes(i);
+ pair[1] = master_nodes(j);
+ pairs.push_back(pair);
+ continue; // found master do not need to search further for this slave
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNContact::addSurfacePair(const Surface & slave,
- const Surface & master,
- UInt surface_normal_dir) {
+void NTNContact::addSurfacePair(const Surface & slave, const Surface & master,
+ UInt surface_normal_dir) {
AKANTU_DEBUG_IN();
const Mesh & mesh = this->model.getMesh();
- const ElementGroup & slave_boundary = mesh.getElementGroup(slave);
+ const ElementGroup & slave_boundary = mesh.getElementGroup(slave);
const ElementGroup & master_boundary = mesh.getElementGroup(master);
this->contact_surfaces.insert(&slave_boundary);
this->contact_surfaces.insert(&master_boundary);
- Array<UInt> pairs(0,2);
- NTNContact::pairInterfaceNodes(slave_boundary,
- master_boundary,
- surface_normal_dir,
- this->model.getMesh(),
- pairs);
+ Array<UInt> pairs(0, 2);
+ NTNContact::pairInterfaceNodes(slave_boundary, master_boundary,
+ surface_normal_dir, this->model.getMesh(),
+ pairs);
// eliminate pairs which contain a pbc slave node
- Array<UInt> pairs_no_PBC_slaves(0,2);
- Array<UInt>::const_vector_iterator it = pairs.begin(2);
+ Array<UInt> pairs_no_PBC_slaves(0, 2);
+ Array<UInt>::const_vector_iterator it = pairs.begin(2);
Array<UInt>::const_vector_iterator end = pairs.end(2);
- for (; it!=end; ++it) {
+ for (; it != end; ++it) {
const Vector<UInt> & pair = *it;
- if (!this->model.isPBCSlaveNode(pair(0)) && !this->model.isPBCSlaveNode(pair(1))) {
+ if (!this->model.isPBCSlaveNode(pair(0)) &&
+ !this->model.isPBCSlaveNode(pair(1))) {
pairs_no_PBC_slaves.push_back(pair);
}
}
this->addNodePairs(pairs_no_PBC_slaves);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::addNodePairs(const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
- "Array of node pairs should have nb_component = 2," <<
- " but has nb_component = " << pairs.getNbComponent());
+ "Array of node pairs should have nb_component = 2,"
+ << " but has nb_component = "
+ << pairs.getNbComponent());
UInt nb_pairs = pairs.getSize();
- for (UInt n=0; n<nb_pairs; ++n) {
- this->addSplitNode(pairs(n,0), pairs(n,1));
+ for (UInt n = 0; n < nb_pairs; ++n) {
+ this->addSplitNode(pairs(n, 0), pairs(n, 1));
}
// synchronize with depending nodes
- findBoundaryElements(this->slaves.getArray(), this->slave_elements);
+ findBoundaryElements(this->slaves.getArray(), this->slave_elements);
findBoundaryElements(this->masters.getArray(), this->master_elements);
updateInternalData();
syncArrays(_added);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::getNodePairs(Array<UInt> & pairs) const {
AKANTU_DEBUG_IN();
pairs.resize(0);
AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
- "Array of node pairs should have nb_component = 2," <<
- " but has nb_component = " << pairs.getNbComponent());
+ "Array of node pairs should have nb_component = 2,"
+ << " but has nb_component = "
+ << pairs.getNbComponent());
UInt nb_pairs = this->getNbContactNodes();
- for (UInt n=0; n<nb_pairs; ++n) {
+ for (UInt n = 0; n < nb_pairs; ++n) {
UInt pair[2];
pair[0] = this->slaves(n);
pair[1] = this->masters(n);
pairs.push_back(pair);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::addSplitNode(UInt slave, UInt master) {
AKANTU_DEBUG_IN();
NTNBaseContact::addSplitNode(slave);
this->masters.push_back(master);
- this->lumped_boundary_masters.push_back(std::numeric_limits<Real>::quiet_NaN());
+ this->lumped_boundary_masters.push_back(
+ std::numeric_limits<Real>::quiet_NaN());
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/*
This function only works for surface elements with one quad point. For
surface elements with more quad points, it computes still, but the result
might not be what you are looking for.
*/
void NTNContact::updateNormals() {
AKANTU_DEBUG_IN();
// set normals to zero
this->normals.clear();
// contact information
UInt dim = this->model.getSpatialDimension();
UInt nb_contact_nodes = this->getNbContactNodes();
this->synch_registry->synchronize(_gst_cf_nodal); // synchronize current pos
const Array<Real> & cur_pos = this->model.getCurrentPosition();
FEEngine & boundary_fem = this->model.getFEEngineBoundary();
const Mesh & mesh = this->model.getMesh();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
- Mesh::type_iterator it = mesh.firstType(dim-1, *gt);
- Mesh::type_iterator last = mesh.lastType(dim-1, *gt);
+ gt != ghost_type_t::end(); ++gt) {
+ Mesh::type_iterator it = mesh.firstType(dim - 1, *gt);
+ Mesh::type_iterator last = mesh.lastType(dim - 1, *gt);
for (; it != last; ++it) {
// compute the normals
- Array<Real> quad_normals(0,dim);
- boundary_fem.computeNormalsOnIntegrationPoints(cur_pos, quad_normals, *it, *gt);
+ Array<Real> quad_normals(0, dim);
+ boundary_fem.computeNormalsOnIntegrationPoints(cur_pos, quad_normals, *it,
+ *gt);
UInt nb_quad_points = boundary_fem.getNbIntegrationPoints(*it, *gt);
- // new version: compute normals only based on master elements (and not all boundary elements)
+ // new version: compute normals only based on master elements (and not all
+ // boundary elements)
// -------------------------------------------------------------------------------------
- UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
+ UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
const Array<UInt> & connectivity = mesh.getConnectivity(*it, *gt);
- Array<UInt>::const_iterator<UInt> elem_it = (this->master_elements)(*it, *gt).begin();
- Array<UInt>::const_iterator<UInt> elem_it_end = (this->master_elements)(*it, *gt).end();
+ Array<UInt>::const_iterator<UInt> elem_it =
+ (this->master_elements)(*it, *gt).begin();
+ Array<UInt>::const_iterator<UInt> elem_it_end =
+ (this->master_elements)(*it, *gt).end();
// loop over contact nodes
for (; elem_it != elem_it_end; ++elem_it) {
- for (UInt q=0; q<nb_nodes_per_element; ++q) {
- UInt node = connectivity(*elem_it,q);
+ for (UInt q = 0; q < nb_nodes_per_element; ++q) {
+ UInt node = connectivity(*elem_it, q);
UInt node_index = this->masters.find(node);
- AKANTU_DEBUG_ASSERT(node_index != UInt(-1),
- "Could not find node " << node
- << " in the array!");
-
- for (UInt q=0; q<nb_quad_points; ++q) {
- // add quad normal to master normal
- for (UInt d=0; d<dim; ++d) {
- this->normals(node_index,d) += quad_normals((*elem_it)*nb_quad_points + q, d);
- }
- }
+ AKANTU_DEBUG_ASSERT(node_index != UInt(-1),
+ "Could not find node " << node
+ << " in the array!");
+
+ for (UInt q = 0; q < nb_quad_points; ++q) {
+ // add quad normal to master normal
+ for (UInt d = 0; d < dim; ++d) {
+ this->normals(node_index, d) +=
+ quad_normals((*elem_it) * nb_quad_points + q, d);
+ }
+ }
}
}
// -------------------------------------------------------------------------------------
-
+
/*
// get elements connected to each node
CSR<UInt> node_to_element;
- MeshUtils::buildNode2ElementsElementTypeMap(mesh, node_to_element, *it, *gt);
+ MeshUtils::buildNode2ElementsElementTypeMap(mesh, node_to_element, *it,
+ *gt);
// add up normals to all master nodes
for (UInt n=0; n<nb_contact_nodes; ++n) {
- UInt master = this->masters(n);
- CSR<UInt>::iterator elem = node_to_element.begin(master);
- // loop over all elements connected to this master node
- for (; elem != node_to_element.end(master); ++elem) {
- UInt e = *elem;
- // loop over all quad points of this element
- for (UInt q=0; q<nb_quad_points; ++q) {
- // add quad normal to master normal
- for (UInt d=0; d<dim; ++d) {
- this->normals(n,d) += quad_normals(e*nb_quad_points + q, d);
- }
- }
- }
+ UInt master = this->masters(n);
+ CSR<UInt>::iterator elem = node_to_element.begin(master);
+ // loop over all elements connected to this master node
+ for (; elem != node_to_element.end(master); ++elem) {
+ UInt e = *elem;
+ // loop over all quad points of this element
+ for (UInt q=0; q<nb_quad_points; ++q) {
+ // add quad normal to master normal
+ for (UInt d=0; d<dim; ++d) {
+ this->normals(n,d) += quad_normals(e*nb_quad_points + q, d);
+ }
+ }
+ }
}
*/
}
}
Real * master_normals = this->normals.storage();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
- if (dim==2)
- Math::normalize2(&(master_normals[n*dim]));
- else if (dim==3)
- Math::normalize3(&(master_normals[n*dim]));
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
+ if (dim == 2)
+ Math::normalize2(&(master_normals[n * dim]));
+ else if (dim == 3)
+ Math::normalize3(&(master_normals[n * dim]));
}
// // normalize normals
// auto nit = this->normals.begin();
// auto nend = this->normals.end();
// for (; nit != nend; ++nit) {
// nit->normalize();
// }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::dumpRestart(const std::string & file_name) const {
AKANTU_DEBUG_IN();
NTNBaseContact::dumpRestart(file_name);
this->masters.dumpRestartFile(file_name);
this->lumped_boundary_masters.dumpRestartFile(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::readRestart(const std::string & file_name) {
AKANTU_DEBUG_IN();
NTNBaseContact::readRestart(file_name);
this->masters.readRestartFile(file_name);
this->lumped_boundary_masters.readRestartFile(file_name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::updateImpedance() {
AKANTU_DEBUG_IN();
UInt nb_contact_nodes = getNbContactNodes();
Real delta_t = this->model.getTimeStep();
- AKANTU_DEBUG_ASSERT(delta_t != NAN, "Time step is NAN. Have you set it already?");
+ AKANTU_DEBUG_ASSERT(delta_t != NAN,
+ "Time step is NAN. Have you set it already?");
const Array<Real> & mass = this->model.getMass();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
UInt master = this->masters(n);
UInt slave = this->slaves(n);
- Real imp = (this->lumped_boundary_masters(n) / mass(master))
- + (this->lumped_boundary_slaves(n) / mass(slave));
+ Real imp = (this->lumped_boundary_masters(n) / mass(master)) +
+ (this->lumped_boundary_slaves(n) / mass(slave));
imp = 2 / delta_t / imp;
this->impedance(n) = imp;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::updateLumpedBoundary() {
AKANTU_DEBUG_IN();
- internalUpdateLumpedBoundary(this->slaves.getArray(),
- this->slave_elements,
- this->lumped_boundary_slaves);
+ internalUpdateLumpedBoundary(this->slaves.getArray(), this->slave_elements,
+ this->lumped_boundary_slaves);
- internalUpdateLumpedBoundary(this->masters.getArray(),
- this->master_elements,
- this->lumped_boundary_masters);
+ internalUpdateLumpedBoundary(this->masters.getArray(), this->master_elements,
+ this->lumped_boundary_masters);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::applyContactPressure() {
AKANTU_DEBUG_IN();
UInt nb_ntn_pairs = getNbContactNodes();
UInt dim = this->model.getSpatialDimension();
Array<Real> & residual = this->model.getResidual();
- for (UInt n=0; n<nb_ntn_pairs; ++n) {
+ for (UInt n = 0; n < nb_ntn_pairs; ++n) {
UInt master = this->masters(n);
UInt slave = this->slaves(n);
- for (UInt d=0; d<dim; ++d) {
- residual(master,d) += this->lumped_boundary_masters(n) * this->contact_pressure(n,d);
- residual(slave, d) -= this->lumped_boundary_slaves(n) * this->contact_pressure(n,d);
+ for (UInt d = 0; d < dim; ++d) {
+ residual(master, d) +=
+ this->lumped_boundary_masters(n) * this->contact_pressure(n, d);
+ residual(slave, d) -=
+ this->lumped_boundary_slaves(n) * this->contact_pressure(n, d);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNContact::computeRelativeTangentialField(const Array<Real> & field,
- Array<Real> & rel_tang_field) const {
+void NTNContact::computeRelativeTangentialField(
+ const Array<Real> & field, Array<Real> & rel_tang_field) const {
AKANTU_DEBUG_IN();
// resize arrays to zero
rel_tang_field.resize(0);
UInt dim = this->model.getSpatialDimension();
- auto it_field = field.begin(dim);
+ auto it_field = field.begin(dim);
auto it_normal = this->normals.getArray().begin(dim);
Vector<Real> rfv(dim);
Vector<Real> np_rfv(dim);
UInt nb_contact_nodes = this->slaves.getSize();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// nodes
- UInt slave = this->slaves(n);
+ UInt slave = this->slaves(n);
UInt master = this->masters(n);
// relative field vector (slave - master)
rfv = Vector<Real>(it_field[slave]);
rfv -= Vector<Real>(it_field[master]);
// normal projection of relative field
const Vector<Real> normal_v = it_normal[n];
np_rfv = normal_v;
np_rfv *= rfv.dot(normal_v);
- // subract normal projection from relative field to get the tangential projection
+ // subract normal projection from relative field to get the tangential
+ // projection
rfv -= np_rfv;
rel_tang_field.push_back(rfv);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTNContact::computeRelativeNormalField(const Array<Real> & field,
- Array<Real> & rel_normal_field) const {
+void NTNContact::computeRelativeNormalField(
+ const Array<Real> & field, Array<Real> & rel_normal_field) const {
AKANTU_DEBUG_IN();
// resize arrays to zero
rel_normal_field.resize(0);
UInt dim = this->model.getSpatialDimension();
// Real * field_p = field.storage();
// Real * normals_p = this->normals.storage();
- Array<Real>::const_iterator< Vector<Real> > it_field = field.begin(dim);
- Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it_field = field.begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it_normal =
+ this->normals.getArray().begin(dim);
Vector<Real> rfv(dim);
UInt nb_contact_nodes = this->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// nodes
- UInt slave = this->slaves(n);
+ UInt slave = this->slaves(n);
UInt master = this->masters(n);
// relative field vector (slave - master)
rfv = Vector<Real>(it_field[slave]);
rfv -= Vector<Real>(it_field[master]);
// length of normal projection of relative field
const Vector<Real> normal_v = it_normal[n];
rel_normal_field.push_back(rfv.dot(normal_v));
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Int NTNContact::getNodeIndex(UInt node) const {
AKANTU_DEBUG_IN();
- Int slave_i = NTNBaseContact::getNodeIndex(node);
+ Int slave_i = NTNBaseContact::getNodeIndex(node);
Int master_i = this->masters.find(node);
AKANTU_DEBUG_OUT();
- return std::max(slave_i,master_i);
+ return std::max(slave_i, master_i);
}
/* -------------------------------------------------------------------------- */
void NTNContact::printself(std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "NTNContact [" << std::endl;
NTNBaseContact::printself(stream, indent);
stream << space << " + masters : " << std::endl;
this->masters.printself(stream, indent + 2);
stream << space << " + lumped_boundary_mastres : " << std::endl;
this->lumped_boundary_masters.printself(stream, indent + 2);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::syncArrays(SyncChoice sync_choice) {
AKANTU_DEBUG_IN();
NTNBaseContact::syncArrays(sync_choice);
this->masters.syncElements(sync_choice);
this->lumped_boundary_masters.syncElements(sync_choice);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTNContact::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+ const std::string & field_id) {
AKANTU_DEBUG_IN();
/*
#ifdef AKANTU_USE_IOHELPER
const Array<UInt> & nodal_filter = this->slaves.getArray();
#define ADD_FIELD(field_id, field, type) \
internalAddDumpFieldToDumper(dumper_name, \
- field_id, \
- new DumperIOHelper::NodalField< type, true, \
- Array<type>, \
- Array<UInt> >(field, 0, 0, &nodal_filter))
+ field_id, \
+ new DumperIOHelper::NodalField< type, true, \
+ Array<type>, \
+ Array<UInt> >(field, 0, 0, &nodal_filter))
*/
- if(field_id == "lumped_boundary_master") {
- internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new dumper::NodalField<Real>(this->lumped_boundary_masters.getArray()));
- }
- else {
+ if (field_id == "lumped_boundary_master") {
+ internalAddDumpFieldToDumper(
+ dumper_name, field_id,
+ new dumper::NodalField<Real>(this->lumped_boundary_masters.getArray()));
+ } else {
NTNBaseContact::addDumpFieldToDumper(dumper_name, field_id);
}
/*
#undef ADD_FIELD
#endif
*/
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.hh
index 236c2d04d..c5754157f 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.hh
@@ -1,153 +1,151 @@
/**
* @file ntn_contact.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief contact for node to node discretization
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_CONTACT_HH__
#define __AST_NTN_CONTACT_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_base_contact.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class NTNContact : public NTNBaseContact {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTNContact(SolidMechanicsModel & model,
- const ContactID & id = "contact",
- const MemoryID & memory_id = 0);
- virtual ~NTNContact() {};
-
+ NTNContact(SolidMechanicsModel & model, const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNContact(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// add surface pair and pair nodes according to the surface normal
- void addSurfacePair(const Surface & slave,
- const Surface & master,
- UInt surface_normal_dir);
+ void addSurfacePair(const Surface & slave, const Surface & master,
+ UInt surface_normal_dir);
- /// fills the pairs vector with interface node pairs (*,0)=slaves, (*,1)=masters
- static void pairInterfaceNodes(const ElementGroup & slave_boundary,
- const ElementGroup & master_boundary,
- UInt surface_normal_dir,
- const Mesh & mesh,
- Array<UInt> & pairs);
+ /// fills the pairs vector with interface node pairs (*,0)=slaves,
+ /// (*,1)=masters
+ static void pairInterfaceNodes(const ElementGroup & slave_boundary,
+ const ElementGroup & master_boundary,
+ UInt surface_normal_dir, const Mesh & mesh,
+ Array<UInt> & pairs);
// add node pairs from a list with pairs(*,0)=slaves and pairs(*,1)=masters
void addNodePairs(const Array<UInt> & pairs);
/// add node pair
virtual void addSplitNode(UInt slave, UInt master);
/// update (compute the normals on the master nodes)
virtual void updateNormals();
/// update the lumped boundary B matrix
virtual void updateLumpedBoundary();
/// update the impedance matrix
virtual void updateImpedance();
/// impose the normal contact force
virtual void applyContactPressure();
/// dump restart file
virtual void dumpRestart(const std::string & file_name) const;
/// read restart file
virtual void readRestart(const std::string & file_name);
/// compute the normal gap
virtual void computeNormalGap(Array<Real> & gap) const {
- this->computeRelativeNormalField(this->model.getCurrentPosition(),
- gap);
+ this->computeRelativeNormalField(this->model.getCurrentPosition(), gap);
};
- /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// compute relative normal field (only value that has to be multiplied with
+ /// the normal)
/// relative to master nodes
virtual void computeRelativeNormalField(const Array<Real> & field,
- Array<Real> & rel_normal_field) const;
+ Array<Real> & rel_normal_field) const;
/// compute relative tangential field (complet array)
/// relative to master nodes
- virtual void computeRelativeTangentialField(const Array<Real> & field,
- Array<Real> & rel_tang_field) const;
-
+ virtual void
+ computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const;
+
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
/// synchronize arrays
virtual void syncArrays(SyncChoice sync_choice);
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
// virtual void addDumpFieldVector(const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
- AKANTU_GET_MACRO(Masters, masters, const SynchronizedArray<UInt> &)
- AKANTU_GET_MACRO(LumpedBoundaryMasters, lumped_boundary_masters, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(Masters, masters, const SynchronizedArray<UInt> &)
+ AKANTU_GET_MACRO(LumpedBoundaryMasters, lumped_boundary_masters,
+ const SynchronizedArray<Real> &)
/// get interface node pairs (*,0) are slaves, (*,1) are masters
void getNodePairs(Array<UInt> & pairs) const;
/// get index of node in either slaves or masters array
/// if node is in neither of them, return -1
Int getNodeIndex(UInt node) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// array of master nodes
SynchronizedArray<UInt> masters;
/// lumped boundary of master nodes
SynchronizedArray<Real> lumped_boundary_masters;
// element list for dump and lumped_boundary
ElementTypeMapArray<UInt> master_elements;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "ntn_contact_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const NTNContact & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const NTNContact & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_NTN_CONTACT_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
index c55471e59..1707dd2b3 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
@@ -1,91 +1,85 @@
/**
* @file ntn_friction.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of friction for node to node contact
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTN_FRICTION_HH__
#define __AST_NTN_FRICTION_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_base_friction.hh"
#include "ntn_friclaw_coulomb.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-template <template<class> class FrictionLaw = NTNFricLawCoulomb,
- class Regularisation = NTNFricRegNoRegularisation>
+template <template <class> class FrictionLaw = NTNFricLawCoulomb,
+ class Regularisation = NTNFricRegNoRegularisation>
class NTNFriction : public FrictionLaw<Regularisation> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- NTNFriction(NTNBaseContact * contact,
- const FrictionID & id = "friction",
- const MemoryID & memory_id = 0);
- virtual ~NTNFriction() {};
-
+ NTNFriction(NTNBaseContact * contact, const FrictionID & id = "friction",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFriction(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// apply the friction force
virtual void applyFrictionTraction();
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
-
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
// virtual void addDumpFieldToDumper(const std::string & dumper_name,
// const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
-template <template<class> class FrictionLaw, class Regularisation>
-inline std::ostream & operator <<(std::ostream & stream,
- const NTNFriction<FrictionLaw,
- Regularisation> & _this)
-{
+template <template <class> class FrictionLaw, class Regularisation>
+inline std::ostream &
+operator<<(std::ostream & stream,
+ const NTNFriction<FrictionLaw, Regularisation> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "ntn_friction_tmpl.hh"
#endif /* __AST_NTN_FRICTION_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction_tmpl.hh
index 3daff2dcd..4ec271a9b 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction_tmpl.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction_tmpl.hh
@@ -1,79 +1,81 @@
/**
* @file ntn_friction_tmpl.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_contact.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <template <class> class FrictionLaw, class Regularisation>
-NTNFriction<FrictionLaw, Regularisation>::NTNFriction(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- FrictionLaw<Regularisation>(contact, id, memory_id) {
+NTNFriction<FrictionLaw, Regularisation>::NTNFriction(
+ NTNBaseContact * contact, const FrictionID & id, const MemoryID & memory_id)
+ : FrictionLaw<Regularisation>(contact, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <template <class> class FrictionLaw, class Regularisation>
void NTNFriction<FrictionLaw, Regularisation>::applyFrictionTraction() {
AKANTU_DEBUG_IN();
- NTNContact * ntn_contact = dynamic_cast<NTNContact * >(this->contact);
+ NTNContact * ntn_contact = dynamic_cast<NTNContact *>(this->contact);
SolidMechanicsModel & model = ntn_contact->getModel();
Array<Real> & residual = model.getResidual();
UInt dim = model.getSpatialDimension();
-
+
const SynchronizedArray<UInt> & masters = ntn_contact->getMasters();
- const SynchronizedArray<UInt> & slaves = ntn_contact->getSlaves();
- const SynchronizedArray<Real> & l_boundary_slaves = ntn_contact->getLumpedBoundarySlaves();
- const SynchronizedArray<Real> & l_boundary_masters = ntn_contact->getLumpedBoundaryMasters();
+ const SynchronizedArray<UInt> & slaves = ntn_contact->getSlaves();
+ const SynchronizedArray<Real> & l_boundary_slaves =
+ ntn_contact->getLumpedBoundarySlaves();
+ const SynchronizedArray<Real> & l_boundary_masters =
+ ntn_contact->getLumpedBoundaryMasters();
UInt nb_contact_nodes = ntn_contact->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
UInt master = masters(n);
- UInt slave = slaves(n);
-
- for (UInt d=0; d<dim; ++d) {
- residual(master,d) += l_boundary_masters(n) * this->friction_traction(n,d);
- residual(slave, d) -= l_boundary_slaves(n) * this->friction_traction(n,d);
+ UInt slave = slaves(n);
+
+ for (UInt d = 0; d < dim; ++d) {
+ residual(master, d) +=
+ l_boundary_masters(n) * this->friction_traction(n, d);
+ residual(slave, d) -=
+ l_boundary_slaves(n) * this->friction_traction(n, d);
}
}
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <template <class> class FrictionLaw, class Regularisation>
-void NTNFriction<FrictionLaw, Regularisation>::printself(std::ostream & stream,
- int indent) const {
+void NTNFriction<FrictionLaw, Regularisation>::printself(std::ostream & stream,
+ int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
stream << space << "NTNFriction [" << std::endl;
FrictionLaw<Regularisation>::printself(stream, ++indent);
stream << space << "]" << std::endl;
-
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.cc
index ca6701f64..3ebe6abf1 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.cc
@@ -1,398 +1,395 @@
/**
* @file ntn_initiation_function.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of initializing ntn and ntrf friction
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
-#include "mIIasym_contact.hh"
#include "ntn_initiation_function.hh"
+#include "mIIasym_contact.hh"
#include "ntn_friction.hh"
#include "ntrf_friction.hh"
// friction regularisations
#include "ntn_fricreg_rubin_ampuero.hh"
#include "ntn_fricreg_simplified_prakash_clifton.hh"
// friction laws
#include "ntn_friclaw_linear_cohesive.hh"
#include "ntn_friclaw_linear_slip_weakening.hh"
#include "ntn_friclaw_linear_slip_weakening_no_healing.hh"
namespace akantu {
-NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
- ParameterReader & data) {
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
+ ParameterReader & data) {
AKANTU_DEBUG_IN();
-
+
const std::string & friction_law = data.get<std::string>("friction_law");
- const std::string & friction_reg = data.get<std::string>("friction_regularisation");
-
+ const std::string & friction_reg =
+ data.get<std::string>("friction_regularisation");
+
NTNBaseFriction * friction;
-
+
bool is_ntn_contact = true;
- if (dynamic_cast<NTRFContact *>(contact) != NULL ||
+ if (dynamic_cast<NTRFContact *>(contact) != NULL ||
dynamic_cast<MIIASYMContact *>(contact) != NULL) {
is_ntn_contact = false;
}
if (friction_law == "coulomb") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawCoulomb,
- NTNFricRegNoRegularisation>(contact);
+ friction =
+ new NTNFriction<NTNFricLawCoulomb, NTNFricRegNoRegularisation>(
+ contact);
else
- friction = new NTRFFriction<NTNFricLawCoulomb,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction =
+ new NTRFFriction<NTNFricLawCoulomb, NTNFricRegNoRegularisation>(
+ contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawCoulomb,
- NTNFricRegRubinAmpuero>(contact);
+ friction =
+ new NTNFriction<NTNFricLawCoulomb, NTNFricRegRubinAmpuero>(contact);
else
- friction = new NTRFFriction<NTNFricLawCoulomb,
- NTNFricRegRubinAmpuero>(contact);
-
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction = new NTRFFriction<NTNFricLawCoulomb, NTNFricRegRubinAmpuero>(
+ contact);
+
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawCoulomb,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawCoulomb,
- NTNFricRegSimplifiedPrakashClifton>(contact);
-
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
+ friction =
+ new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
}
- friction->setMixed< SynchronizedArray<Real> >("mu_s", data.get<Real>("mu_s"));
+ friction->setMixed<SynchronizedArray<Real>>("mu_s", data.get<Real>("mu_s"));
}
// Friction Law: Linear Slip Weakening
else if (friction_law == "linear_slip_weakening") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegNoRegularisation>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegRubinAmpuero>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegRubinAmpuero>(contact);
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction =
+ new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
}
- friction->setMixed< SynchronizedArray<Real> >("mu_s", data.get<Real>("mu_s"));
- friction->setMixed< SynchronizedArray<Real> >("mu_k", data.get<Real>("mu_k"));
- friction->setMixed< SynchronizedArray<Real> >("d_c", data.get<Real>("d_c"));
+ friction->setMixed<SynchronizedArray<Real>>("mu_s", data.get<Real>("mu_s"));
+ friction->setMixed<SynchronizedArray<Real>>("mu_k", data.get<Real>("mu_k"));
+ friction->setMixed<SynchronizedArray<Real>>("d_c", data.get<Real>("d_c"));
}
// Friction Law: Linear Slip Weakening No Healing
else if (friction_law == "linear_slip_weakening_no_healing") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegNoRegularisation>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegRubinAmpuero>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegRubinAmpuero>(contact);
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction =
+ new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
}
- friction->setMixed< SynchronizedArray<Real> >("mu_s", data.get<Real>("mu_s"));
- friction->setMixed< SynchronizedArray<Real> >("mu_k", data.get<Real>("mu_k"));
- friction->setMixed< SynchronizedArray<Real> >("d_c", data.get<Real>("d_c"));
+ friction->setMixed<SynchronizedArray<Real>>("mu_s", data.get<Real>("mu_s"));
+ friction->setMixed<SynchronizedArray<Real>>("mu_k", data.get<Real>("mu_k"));
+ friction->setMixed<SynchronizedArray<Real>>("d_c", data.get<Real>("d_c"));
}
// Friction Law: Linear Cohesive
else if (friction_law == "linear_cohesive") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearCohesive,
- NTNFricRegNoRegularisation>(contact);
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearCohesive,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearCohesive,
- NTNFricRegRubinAmpuero>(contact);
+ friction =
+ new NTNFriction<NTNFricLawLinearCohesive, NTNFricRegRubinAmpuero>(
+ contact);
else
- friction = new NTRFFriction<NTNFricLawLinearCohesive,
- NTNFricRegRubinAmpuero>(contact);
-
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction =
+ new NTRFFriction<NTNFricLawLinearCohesive, NTNFricRegRubinAmpuero>(
+ contact);
+
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearCohesive,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearCohesive,
- NTNFricRegSimplifiedPrakashClifton>(contact);
-
- friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
- }
-
- friction->setMixed< SynchronizedArray<Real> >("G_c", data.get<Real>("G_c"));
- friction->setMixed< SynchronizedArray<Real> >("tau_c", data.get<Real>("tau_c"));
- friction->setMixed< SynchronizedArray<Real> >("tau_r", data.get<Real>("tau_r"));
+ friction =
+ new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+
+ friction->setMixed<SynchronizedArray<Real>>("t_star",
+ data.get<Real>("t_star"));
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+
+ friction->setMixed<SynchronizedArray<Real>>("G_c", data.get<Real>("G_c"));
+ friction->setMixed<SynchronizedArray<Real>>("tau_c",
+ data.get<Real>("tau_c"));
+ friction->setMixed<SynchronizedArray<Real>>("tau_r",
+ data.get<Real>("tau_r"));
}
-
+
else {
- AKANTU_ERROR("Do not know the following friction law: "
- << friction_law);
+ AKANTU_ERROR("Do not know the following friction law: " << friction_law);
}
AKANTU_DEBUG_OUT();
return friction;
}
/* -------------------------------------------------------------------------- */
NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact) {
AKANTU_DEBUG_IN();
std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
- sub_sect = getStaticParser().getSubSections(_st_friction);
+ sub_sect = getStaticParser().getSubSections(_st_friction);
Parser::const_section_iterator it = sub_sect.first;
const ParserSection & section = *it;
std::string friction_law = section.getName();
std::string friction_reg = section.getOption();
if (friction_reg == "") {
std::string friction_reg = "no_regularisation";
}
-
- NTNBaseFriction * friction = initializeNTNFriction(contact,
- friction_law,
- friction_reg);
+
+ NTNBaseFriction * friction =
+ initializeNTNFriction(contact, friction_law, friction_reg);
friction->parseSection(section);
if (++it != sub_sect.second) {
- AKANTU_DEBUG_WARNING("There were several friction sections in input file. "
- << "Only first one was used and all others ignored.");
+ AKANTU_DEBUG_WARNING("There were several friction sections in input file. "
+ << "Only first one was used and all others ignored.");
}
-
+
AKANTU_DEBUG_OUT();
return friction;
}
-
/* -------------------------------------------------------------------------- */
NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
- const std::string & friction_law,
- const std::string & friction_reg) {
+ const std::string & friction_law,
+ const std::string & friction_reg) {
AKANTU_DEBUG_IN();
-
+
NTNBaseFriction * friction;
-
- // check whether is is node-to-rigid-flat contact or mIIasym (which is also ntrf)
+
+ // check whether is is node-to-rigid-flat contact or mIIasym (which is also
+ // ntrf)
bool is_ntn_contact = true;
if (dynamic_cast<NTRFContact *>(contact) != NULL ||
dynamic_cast<MIIASYMContact *>(contact) != NULL) {
is_ntn_contact = false;
}
if (friction_law == "coulomb") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawCoulomb,
- NTNFricRegNoRegularisation>(contact);
+ friction =
+ new NTNFriction<NTNFricLawCoulomb, NTNFricRegNoRegularisation>(
+ contact);
else
- friction = new NTRFFriction<NTNFricLawCoulomb,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction =
+ new NTRFFriction<NTNFricLawCoulomb, NTNFricRegNoRegularisation>(
+ contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawCoulomb,
- NTNFricRegRubinAmpuero>(contact);
+ friction =
+ new NTNFriction<NTNFricLawCoulomb, NTNFricRegRubinAmpuero>(contact);
else
- friction = new NTRFFriction<NTNFricLawCoulomb,
- NTNFricRegRubinAmpuero>(contact);
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction = new NTRFFriction<NTNFricLawCoulomb, NTNFricRegRubinAmpuero>(
+ contact);
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawCoulomb,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawCoulomb,
- NTNFricRegSimplifiedPrakashClifton>(contact);
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
+ friction =
+ new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
}
}
// Friction Law: Linear Slip Weakening
else if (friction_law == "linear_slip_weakening") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegNoRegularisation>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegRubinAmpuero>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegRubinAmpuero>(contact);
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
- NTNFricRegSimplifiedPrakashClifton>(contact);
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
+ friction =
+ new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
}
}
-
// Friction Law: Linear Slip Weakening No Healing
else if (friction_law == "linear_slip_weakening_no_healing") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegNoRegularisation>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegRubinAmpuero>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegRubinAmpuero>(contact);
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
- NTNFricRegSimplifiedPrakashClifton>(contact);
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
+ friction =
+ new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
}
}
// Friction Law: Linear Cohesive
else if (friction_law == "linear_cohesive") {
if (friction_reg == "no_regularisation") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearCohesive,
- NTNFricRegNoRegularisation>(contact);
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearCohesive,
- NTNFricRegNoRegularisation>(contact);
- }
- else if (friction_reg == "rubin_ampuero") {
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
+ } else if (friction_reg == "rubin_ampuero") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearCohesive,
- NTNFricRegRubinAmpuero>(contact);
+ friction =
+ new NTNFriction<NTNFricLawLinearCohesive, NTNFricRegRubinAmpuero>(
+ contact);
else
- friction = new NTRFFriction<NTNFricLawLinearCohesive,
- NTNFricRegRubinAmpuero>(contact);
- }
- else if (friction_reg == "simplified_prakash_clifton") {
+ friction =
+ new NTRFFriction<NTNFricLawLinearCohesive, NTNFricRegRubinAmpuero>(
+ contact);
+ } else if (friction_reg == "simplified_prakash_clifton") {
if (is_ntn_contact)
- friction = new NTNFriction<NTNFricLawLinearCohesive,
- NTNFricRegSimplifiedPrakashClifton>(contact);
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
else
- friction = new NTRFFriction<NTNFricLawLinearCohesive,
- NTNFricRegSimplifiedPrakashClifton>(contact);
- }
- else {
- AKANTU_ERROR("Do not know the following friction regularisation: "
- << friction_reg);
- }
- }
- else {
- AKANTU_ERROR("Do not know the following friction law: "
- << friction_law);
+ friction =
+ new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ } else {
+ AKANTU_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+ } else {
+ AKANTU_ERROR("Do not know the following friction law: " << friction_law);
}
-
+
AKANTU_DEBUG_OUT();
return friction;
}
-
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
index 849982ef5..ca6f28bd0 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
@@ -1,33 +1,33 @@
/**
* @file ntn_initiation_function.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief initiation ntn and ntrf friction
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
-#include "parameter_reader.hh"
-#include "ntrf_contact.hh"
#include "ntn_base_friction.hh"
+#include "ntrf_contact.hh"
+#include "parameter_reader.hh"
namespace akantu {
-NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
- ParameterReader & data);
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
+ ParameterReader & data);
NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact);
NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
- const std::string & friction_law,
- const std::string & friction_reg);
+ const std::string & friction_law,
+ const std::string & friction_reg);
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc
index bf8bcfbf5..eea242fc4 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc
@@ -1,299 +1,306 @@
/**
* @file ntrf_contact.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// simtools
#include "ntrf_contact.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-NTRFContact::NTRFContact(SolidMechanicsModel & model,
- const ContactID & id,
- const MemoryID & memory_id) :
- NTNBaseContact(model,id,memory_id),
- reference_point(model.getSpatialDimension()),
- normal(model.getSpatialDimension())
-{
+NTRFContact::NTRFContact(SolidMechanicsModel & model, const ContactID & id,
+ const MemoryID & memory_id)
+ : NTNBaseContact(model, id, memory_id),
+ reference_point(model.getSpatialDimension()),
+ normal(model.getSpatialDimension()) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::setReferencePoint(Real x, Real y, Real z) {
AKANTU_DEBUG_IN();
Real coord[3];
coord[0] = x;
coord[1] = y;
coord[2] = z;
UInt dim = this->model.getSpatialDimension();
- for (UInt d=0; d<dim; ++d)
+ for (UInt d = 0; d < dim; ++d)
this->reference_point(d) = coord[d];
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::setNormal(Real x, Real y, Real z) {
AKANTU_DEBUG_IN();
UInt dim = this->model.getSpatialDimension();
Real coord[3];
coord[0] = x;
coord[1] = y;
coord[2] = z;
- for (UInt d=0; d<dim; ++d)
+ for (UInt d = 0; d < dim; ++d)
this->normal(d) = coord[d];
-
+
this->normal.normalize();
-
+
this->updateNormals();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::addSurface(const Surface & surf) {
AKANTU_DEBUG_IN();
const Mesh & mesh_ref = this->model.getFEEngine().getMesh();
try {
const ElementGroup & boundary = mesh_ref.getElementGroup(surf);
this->contact_surfaces.insert(&boundary);
// find slave nodes
- for(ElementGroup::const_node_iterator nodes_it(boundary.node_begin());
- nodes_it!= boundary.node_end();
- ++nodes_it) {
+ for (ElementGroup::const_node_iterator nodes_it(boundary.node_begin());
+ nodes_it != boundary.node_end(); ++nodes_it) {
if (!this->model.isPBCSlaveNode(*nodes_it)) {
- this->addSplitNode(*nodes_it);
+ this->addSplitNode(*nodes_it);
}
}
} catch (debug::Exception e) {
- AKANTU_DEBUG_INFO("NTRFContact addSurface did not found subboundary " << surf
- << " and ignored it. Other procs might have it :)");
+ AKANTU_DEBUG_INFO("NTRFContact addSurface did not found subboundary "
+ << surf
+ << " and ignored it. Other procs might have it :)");
}
// synchronize with depending nodes
findBoundaryElements(this->slaves.getArray(), this->slave_elements);
updateInternalData();
syncArrays(_added);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::addNodes(Array<UInt> & nodes) {
AKANTU_DEBUG_IN();
UInt nb_nodes = nodes.getSize();
UInt nb_compo = nodes.getNbComponent();
- for (UInt n=0; n<nb_nodes; ++n) {
- for (UInt c=0; c<nb_compo; ++c) {
- this->addSplitNode(nodes(n,c));
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ for (UInt c = 0; c < nb_compo; ++c) {
+ this->addSplitNode(nodes(n, c));
}
}
// synchronize with depending nodes
findBoundaryElements(this->slaves.getArray(), this->slave_elements);
updateInternalData();
syncArrays(_added);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::updateNormals() {
AKANTU_DEBUG_IN();
-
+
// normal is the same for all slaves
this->normals.set(this->normal);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::updateImpedance() {
AKANTU_DEBUG_IN();
-
+
UInt nb_contact_nodes = getNbContactNodes();
Real delta_t = this->model.getTimeStep();
- AKANTU_DEBUG_ASSERT(delta_t != NAN, "Time step is NAN. Have you set it already?");
+ AKANTU_DEBUG_ASSERT(delta_t != NAN,
+ "Time step is NAN. Have you set it already?");
const Array<Real> & mass = this->model.getMass();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
UInt slave = this->slaves(n);
Real imp = this->lumped_boundary_slaves(n) / mass(slave);
imp = 2 / delta_t / imp;
this->impedance(n) = imp;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTRFContact::computeRelativeTangentialField(const Array<Real> & field,
- Array<Real> & rel_tang_field) const {
+void NTRFContact::computeRelativeTangentialField(
+ const Array<Real> & field, Array<Real> & rel_tang_field) const {
AKANTU_DEBUG_IN();
// resize arrays to zero
rel_tang_field.resize(0);
UInt dim = this->model.getSpatialDimension();
-
- Array<Real>::const_iterator< Vector<Real> > it_field = field.begin(dim);
- Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+
+ Array<Real>::const_iterator<Vector<Real>> it_field = field.begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it_normal =
+ this->normals.getArray().begin(dim);
Vector<Real> rfv(dim);
Vector<Real> np_rfv(dim);
UInt nb_contact_nodes = this->slaves.getSize();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// nodes
UInt node = this->slaves(n);
// relative field vector
- rfv = it_field[node];;
+ rfv = it_field[node];
+ ;
// normal projection of relative field
const Vector<Real> & normal_v = it_normal[n];
np_rfv = normal_v;
np_rfv *= rfv.dot(normal_v);
- // subtract normal projection from relative field to get the tangential projection
+ // subtract normal projection from relative field to get the tangential
+ // projection
rfv -= np_rfv;
rel_tang_field.push_back(rfv);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::computeNormalGap(Array<Real> & gap) const {
AKANTU_DEBUG_IN();
gap.resize(0);
UInt dim = this->model.getSpatialDimension();
- Array<Real>::const_iterator< Vector<Real> > it_cur_pos = this->model.getCurrentPosition().begin(dim);
- Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it_cur_pos =
+ this->model.getCurrentPosition().begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it_normal =
+ this->normals.getArray().begin(dim);
Vector<Real> gap_v(dim);
UInt nb_contact_nodes = this->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// nodes
UInt node = this->slaves(n);
// gap vector
gap_v = it_cur_pos[node];
gap_v -= this->reference_point;
// length of normal projection of gap vector
- const Vector<Real> & normal_v = it_normal[n];
+ const Vector<Real> & normal_v = it_normal[n];
gap.push_back(gap_v.dot(normal_v));
}
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void NTRFContact::computeRelativeNormalField(const Array<Real> & field,
- Array<Real> & rel_normal_field) const {
+void NTRFContact::computeRelativeNormalField(
+ const Array<Real> & field, Array<Real> & rel_normal_field) const {
AKANTU_DEBUG_IN();
// resize arrays to zero
rel_normal_field.resize(0);
UInt dim = this->model.getSpatialDimension();
- Array<Real>::const_iterator< Vector<Real> > it_field = field.begin(dim);
- Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it_field = field.begin(dim);
+ Array<Real>::const_iterator<Vector<Real>> it_normal =
+ this->normals.getArray().begin(dim);
UInt nb_contact_nodes = this->getNbContactNodes();
- for (UInt n=0; n<nb_contact_nodes; ++n) {
+ for (UInt n = 0; n < nb_contact_nodes; ++n) {
// nodes
UInt node = this->slaves(n);
- const Vector<Real> & field_v = it_field[node];
+ const Vector<Real> & field_v = it_field[node];
const Vector<Real> & normal_v = it_normal[n];
-
+
rel_normal_field.push_back(field_v.dot(normal_v));
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::printself(std::ostream & stream, int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "NTRFContact [" << std::endl;
- NTNBaseContact::printself(stream,indent);
+ NTNBaseContact::printself(stream, indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NTRFContact::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+ const std::string & field_id) {
AKANTU_DEBUG_IN();
/*
#ifdef AKANTU_USE_IOHELPER
const Array<UInt> & nodal_filter = this->slaves.getArray();
#define ADD_FIELD(field_id, field, type) \
internalAddDumpFieldToDumper(dumper_name, \
- field_id, \
- new DumperIOHelper::NodalField< type, true, \
- Array<type>, \
- Array<UInt> >(field, 0, 0, &nodal_filter))
+ field_id, \
+ new DumperIOHelper::NodalField< type, true, \
+ Array<type>, \
+ Array<UInt> >(field, 0, 0, &nodal_filter))
*/
/*
if(field_id == "displacement") {
ADD_FIELD(field_id, this->model.getDisplacement(), Real);
}
else if(field_id == "contact_pressure") {
internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new DumperIOHelper::NodalField<Real>(this->contact_pressure.getArray()));
+ field_id,
+ new
+ DumperIOHelper::NodalField<Real>(this->contact_pressure.getArray()));
}
else {*/
NTNBaseContact::addDumpFieldToDumper(dumper_name, field_id);
- //}
+ //}
/*
#undef ADD_FIELD
#endif
*/
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
index 41f92c8b5..28eef5a4b 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
@@ -1,113 +1,111 @@
/**
* @file ntrf_contact.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief contact for node to rigid flat interface
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTRF_CONTACT_HH__
#define __AST_NTRF_CONTACT_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_base_contact.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
class NTRFContact : public NTNBaseContact {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTRFContact(SolidMechanicsModel & model,
- const ContactID & id = "contact",
- const MemoryID & memory_id = 0);
- virtual ~NTRFContact() {};
+ NTRFContact(SolidMechanicsModel & model, const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~NTRFContact(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- void setReferencePoint(Real x=0., Real y=0., Real z=0.);
- void setNormal(Real x=1., Real y=0., Real z=0.);
+ void setReferencePoint(Real x = 0., Real y = 0., Real z = 0.);
+ void setNormal(Real x = 1., Real y = 0., Real z = 0.);
/// add surface and nodes according to the surface normal
void addSurface(const Surface & surf);
// add nodes from a list
void addNodes(Array<UInt> & nodes);
/// update (copy the normal to all normals)
virtual void updateNormals();
/// update the impedance matrix
virtual void updateImpedance();
/// compute the normal gap
virtual void computeNormalGap(Array<Real> & gap) const;
- /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// compute relative normal field (only value that has to be multiplied with
+ /// the normal)
/// relative to master nodes
virtual void computeRelativeNormalField(const Array<Real> & field,
- Array<Real> & rel_normal_field) const;
+ Array<Real> & rel_normal_field) const;
/// compute relative tangential field (complet array)
/// relative to master nodes
- virtual void computeRelativeTangentialField(const Array<Real> & field,
- Array<Real> & rel_tang_field) const;
+ virtual void
+ computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const;
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
// virtual void addDumpFieldVector(const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// reference point for rigid flat surface
Vector<Real> reference_point;
/// outpointing normal of rigid flat surface
Vector<Real> normal;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "ntrf_contact_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const NTRFContact & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const NTRFContact & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AST_NTRF_CONTACT_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
index 713ecd113..97bf1aeb7 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
@@ -1,85 +1,77 @@
/**
* @file ntrf_friction.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief friction for node to rigid flat interface
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AST_NTRF_FRICTION_HH__
#define __AST_NTRF_FRICTION_HH__
/* -------------------------------------------------------------------------- */
// simtools
#include "ntn_friclaw_coulomb.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-template <template<class> class FrictionLaw = NTNFricLawCoulomb,
- class Regularisation = NTNFricRegNoRegularisation>
+template <template <class> class FrictionLaw = NTNFricLawCoulomb,
+ class Regularisation = NTNFricRegNoRegularisation>
class NTRFFriction : public FrictionLaw<Regularisation> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NTRFFriction(NTNBaseContact * contact,
- const FrictionID & id = "friction",
- const MemoryID & memory_id = 0);
- virtual ~NTRFFriction() {};
-
+ NTRFFriction(NTNBaseContact * contact, const FrictionID & id = "friction",
+ const MemoryID & memory_id = 0);
+ virtual ~NTRFFriction(){};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Dumpable */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operato
-template <template<class> class FrictionLaw, class Regularisation>
-inline std::ostream & operator <<(std::ostream & stream,
- const NTRFFriction<FrictionLaw,
- Regularisation> & _this)
-{
+template <template <class> class FrictionLaw, class Regularisation>
+inline std::ostream &
+operator<<(std::ostream & stream,
+ const NTRFFriction<FrictionLaw, Regularisation> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "ntrf_friction_tmpl.hh"
#endif /* __AST_NTRF_FRICTION_HH__ */
-
-
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction_tmpl.hh
index 46f135672..2e0212824 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction_tmpl.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction_tmpl.hh
@@ -1,86 +1,90 @@
/**
* @file ntrf_friction_tmpl.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
*
* @brief implementation of node to rigid flat interface friction
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
//#include "ntrf_friction.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <template <class> class FrictionLaw, class Regularisation>
-NTRFFriction<FrictionLaw, Regularisation>::NTRFFriction(NTNBaseContact * contact,
- const FrictionID & id,
- const MemoryID & memory_id) :
- FrictionLaw<Regularisation>(contact,id,memory_id) {
+NTRFFriction<FrictionLaw, Regularisation>::NTRFFriction(
+ NTNBaseContact * contact, const FrictionID & id, const MemoryID & memory_id)
+ : FrictionLaw<Regularisation>(contact, id, memory_id) {
AKANTU_DEBUG_IN();
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <template <class> class FrictionLaw, class Regularisation>
-void NTRFFriction<FrictionLaw, Regularisation>::printself(std::ostream & stream,
- int indent) const {
+void NTRFFriction<FrictionLaw, Regularisation>::printself(std::ostream & stream,
+ int indent) const {
AKANTU_DEBUG_IN();
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
stream << space << "NTRFFriction [" << std::endl;
FrictionLaw<Regularisation>::printself(stream, ++indent);
stream << space << "]" << std::endl;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/*
void NTRFFriction::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+ const std::string & field_id) {
AKANTU_DEBUG_IN();
-
+
#ifdef AKANTU_USE_IOHELPER
- // const SynchronizedArray<UInt> * nodal_filter = &(this->contact.getSlaves());
-
+ // const SynchronizedArray<UInt> * nodal_filter =
+&(this->contact.getSlaves());
+
if(field_id == "is_sticking") {
this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new DumperIOHelper::NodalField<bool>(this->is_sticking.getArray()));
+ field_id,
+ new
+DumperIOHelper::NodalField<bool>(this->is_sticking.getArray()));
}
else if(field_id == "frictional_strength") {
this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new DumperIOHelper::NodalField<Real>(this->frictional_strength.getArray()));
+ field_id,
+ new
+DumperIOHelper::NodalField<Real>(this->frictional_strength.getArray()));
}
else if(field_id == "friction_traction") {
this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new DumperIOHelper::NodalField<Real>(this->friction_traction.getArray()));
+ field_id,
+ new
+DumperIOHelper::NodalField<Real>(this->friction_traction.getArray()));
}
else if(field_id == "slip") {
this->internalAddDumpFieldToDumper(dumper_name,
- field_id,
- new DumperIOHelper::NodalField<Real>(this->slip.getArray()));
+ field_id,
+ new DumperIOHelper::NodalField<Real>(this->slip.getArray()));
}
else {
this->contact.addDumpFieldToDumper(dumper_name, field_id);
}
-
+
#endif
AKANTU_DEBUG_OUT();
}
*/
} // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/tasn_contact.hh b/extra_packages/traction-at-split-node-contact/src/tasn_contact.hh
index f51ff77e3..31cabc401 100644
--- a/extra_packages/traction-at-split-node-contact/src/tasn_contact.hh
+++ b/extra_packages/traction-at-split-node-contact/src/tasn_contact.hh
@@ -1,52 +1,52 @@
/**
* @file akantu_simtools.hh
*
*
*
- * @brief
+ * @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
// ast common
-#include "synchronized_array.hh"
-#include "parameter_reader.hh"
#include "manual_restart.hh"
+#include "parameter_reader.hh"
+#include "synchronized_array.hh"
// functions
#include "boundary_functions.hh"
#include "node_filter.hh"
// boundary conditions
#include "force_based_dirichlet.hh"
-#include "spring_bc.hh"
#include "inclined_flat_dirichlet.hh"
+#include "spring_bc.hh"
// ntn/ntrf contact
+#include "mIIasym_contact.hh"
#include "ntn_base_contact.hh"
#include "ntn_contact.hh"
#include "ntrf_contact.hh"
-#include "mIIasym_contact.hh"
// ntn/ntrf friction
#include "ntn_base_friction.hh"
#include "ntn_friction.hh"
#include "ntrf_friction.hh"
// friction regularisations
#include "ntn_fricreg_no_regularisation.hh"
#include "ntn_fricreg_rubin_ampuero.hh"
#include "ntn_fricreg_simplified_prakash_clifton.hh"
// friction laws
#include "ntn_friclaw_coulomb.hh"
+#include "ntn_friclaw_linear_cohesive.hh"
#include "ntn_friclaw_linear_slip_weakening.hh"
#include "ntn_friclaw_linear_slip_weakening_no_healing.hh"
-#include "ntn_friclaw_linear_cohesive.hh"
// initiation of friction
#include "ntn_initiation_function.hh"
diff --git a/src/common/aka_array.hh b/src/common/aka_array.hh
index 609e1f3b2..518b2b062 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,371 +1,372 @@
/**
* @file aka_array.hh
*
* @author Till Junge <till.junge@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Jan 22 2016
*
* @brief Array container for Akantu
* This container differs from the std::vector from the fact it as 2 dimensions
* a main dimension and the size stored per entries
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_VECTOR_HH__
#define __AKANTU_VECTOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#include <typeinfo>
#include <vector>
/* -------------------------------------------------------------------------- */
namespace akantu {
/// class that afford to store vectors in static memory
class ArrayBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
explicit ArrayBase(ID id = "");
virtual ~ArrayBase();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get the amount of space allocated in bytes
inline UInt getMemorySize() const;
/// set the size to zero without freeing the allocated space
inline void empty();
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get the real size allocated in memory
AKANTU_GET_MACRO(AllocatedSize, allocated_size, UInt);
/// Get the Size of the Array
UInt getSize() const __attribute__((deprecated)) { return size_; }
UInt size() const { return size_; }
/// Get the number of components
AKANTU_GET_MACRO(NbComponent, nb_component, UInt);
/// Get the name of th array
AKANTU_GET_MACRO(ID, id, const ID &);
/// Set the name of th array
AKANTU_SET_MACRO(ID, id, const ID &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id of the vector
ID id;
/// the size allocated
UInt allocated_size{0};
/// the size used
UInt size_{0};
/// number of components
UInt nb_component{1};
/// size of the stored type
UInt size_of_type{0};
};
/* -------------------------------------------------------------------------- */
namespace {
template <std::size_t dim, typename T> struct IteratorHelper {};
template <typename T> struct IteratorHelper<0, T> { using type = T; };
template <typename T> struct IteratorHelper<1, T> { using type = Vector<T>; };
template <typename T> struct IteratorHelper<2, T> { using type = Matrix<T>; };
template <typename T> struct IteratorHelper<3, T> {
using type = Tensor3<T>;
};
template <std::size_t dim, typename T>
using IteratorHelper_t = typename IteratorHelper<dim, T>::type;
} // namespace
/* -------------------------------------------------------------------------- */
template <typename T, bool is_scal> class Array : public ArrayBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
using value_type = T;
using reference = value_type &;
using pointer_type = value_type *;
using const_reference = const value_type &;
/// Allocation of a new vector
explicit inline Array(UInt size = 0, UInt nb_component = 1,
const ID & id = "");
/// Allocation of a new vector with a default value
Array(UInt size, UInt nb_component, const value_type def_values[],
const ID & id = "");
/// Allocation of a new vector with a default value
Array(UInt size, UInt nb_component, const_reference value,
const ID & id = "");
/// Copy constructor (deep copy if deep=true)
Array(const Array<value_type, is_scal> & vect, bool deep = true,
const ID & id = "");
#ifndef SWIG
/// Copy constructor (deep copy)
explicit Array(const std::vector<value_type> & vect);
#endif
inline ~Array() override;
Array & operator=(const Array & a) {
/// this is to let STL allocate and copy arrays in the case of
/// std::vector::resize
AKANTU_DEBUG_ASSERT(this->size_ == 0, "Cannot copy akantu::Array");
return const_cast<Array &>(a);
}
#ifndef SWIG
/* ------------------------------------------------------------------------ */
/* Iterator */
/* ------------------------------------------------------------------------ */
/// \todo protected: does not compile with intel check why
public:
- template <class R, class it, class IR = R, bool is_tensor_ = is_tensor<R>::value>
+ template <class R, class it, class IR = R,
+ bool is_tensor_ = is_tensor<R>::value>
class iterator_internal;
public:
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
template <typename R = T> class const_iterator;
template <typename R = T> class iterator;
/* ------------------------------------------------------------------------ */
/// iterator for Array of nb_component = 1
using scalar_iterator = iterator<T>;
/// const_iterator for Array of nb_component = 1
using const_scalar_iterator = const_iterator<T>;
/// iterator returning Vectors of size n on entries of Array with
/// nb_component = n
using vector_iterator = iterator<Vector<T>>;
/// const_iterator returning Vectors of n size on entries of Array with
/// nb_component = n
using const_vector_iterator = const_iterator<Vector<T>>;
/// iterator returning Matrices of size (m, n) on entries of Array with
/// nb_component = m*n
using matrix_iterator = iterator<Matrix<T>>;
/// const iterator returning Matrices of size (m, n) on entries of Array with
/// nb_component = m*n
using const_matrix_iterator = const_iterator<Matrix<T>>;
/// iterator returning Tensor3 of size (m, n, k) on entries of Array with
/// nb_component = m*n*k
using tensor3_iterator = iterator<Tensor3<T>>;
/// const iterator returning Tensor3 of size (m, n, k) on entries of Array
/// with nb_component = m*n*k
using const_tensor3_iterator = const_iterator<Tensor3<T>>;
/* ------------------------------------------------------------------------ */
- template <typename... Ns> inline decltype(auto) begin(Ns&&... n);
- template <typename... Ns> inline decltype(auto) end(Ns&&... n);
+ template <typename... Ns> inline decltype(auto) begin(Ns &&... n);
+ template <typename... Ns> inline decltype(auto) end(Ns &&... n);
- template <typename... Ns> inline decltype(auto) begin(Ns&&... n) const;
- template <typename... Ns> inline decltype(auto) end(Ns&&... n) const;
+ template <typename... Ns> inline decltype(auto) begin(Ns &&... n) const;
+ template <typename... Ns> inline decltype(auto) end(Ns &&... n) const;
- template <typename... Ns> inline decltype(auto) begin_reinterpret(Ns&&... n);
- template <typename... Ns> inline decltype(auto) end_reinterpret(Ns&&... n);
+ template <typename... Ns> inline decltype(auto) begin_reinterpret(Ns &&... n);
+ template <typename... Ns> inline decltype(auto) end_reinterpret(Ns &&... n);
template <typename... Ns>
- inline decltype(auto) begin_reinterpret(Ns&&... n) const;
+ inline decltype(auto) begin_reinterpret(Ns &&... n) const;
template <typename... Ns>
- inline decltype(auto) end_reinterpret(Ns&&... n) const;
+ inline decltype(auto) end_reinterpret(Ns &&... n) const;
#endif // SWIG
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// append a tuple of size nb_component containing value
inline void push_back(const_reference value);
- /// append a vector
- // inline void push_back(const value_type new_elem[]);
+/// append a vector
+// inline void push_back(const value_type new_elem[]);
#ifndef SWIG
/// append a Vector or a Matrix
template <template <typename> class C,
typename = std::enable_if_t<is_tensor<C<T>>::value>>
inline void push_back(const C<T> & new_elem);
/// append the value of the iterator
template <typename Ret> inline void push_back(const iterator<Ret> & it);
/// erase the value at position i
inline void erase(UInt i);
/// ask Nico, clarify
template <typename R> inline iterator<R> erase(const iterator<R> & it);
#endif
/// changes the allocated size but not the size
virtual void reserve(UInt size);
/// change the size of the Array
virtual void resize(UInt size);
/// change the size of the Array and initialize the values
virtual void resize(UInt size, const T & val);
/// change the number of components by interlacing data
/// @param multiplicator number of interlaced components add
/// @param block_size blocks of data in the array
/// Examaple for block_size = 2, multiplicator = 2
/// array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn
void extendComponentsInterlaced(UInt multiplicator, UInt stride);
/// search elem in the vector, return the position of the first occurrence or
/// -1 if not found
UInt find(const_reference elem) const;
/// @see Array::find(const_reference elem) const
UInt find(T elem[]) const;
#ifndef SWIG
/// @see Array::find(const_reference elem) const
template <template <typename> class C,
typename = std::enable_if_t<is_tensor<C<T>>::value>>
inline UInt find(const C<T> & elem);
#endif
/// set all entries of the array to 0
inline void clear() { std::fill_n(values, size_ * nb_component, T()); }
/// set all entries of the array to the value t
/// @param t value to fill the array with
inline void set(T t) { std::fill_n(values, size_ * nb_component, t); }
#ifndef SWIG
/// set all tuples of the array to a given vector or matrix
/// @param vm Matrix or Vector to fill the array with
template <template <typename> class C,
typename = std::enable_if_t<is_tensor<C<T>>::value>>
inline void set(const C<T> & vm);
#endif
/// Append the content of the other array to the current one
void append(const Array<T> & other);
/// copy another Array in the current Array, the no_sanity_check allows you to
/// force the copy in cases where you know what you do with two non matching
/// Arrays in terms of n
void copy(const Array<T, is_scal> & other, bool no_sanity_check = false);
/// give the address of the memory allocated for this vector
T * storage() const { return values; };
/// function to print the containt of the class
void printself(std::ostream & stream, int indent = 0) const override;
protected:
/// perform the allocation for the constructors
void allocate(UInt size, UInt nb_component = 1);
/// resize initializing with uninitialized_fill if fill is set
void resizeUnitialized(UInt new_size, bool fill, const T & val = T());
/* ------------------------------------------------------------------------ */
/* Operators */
/* ------------------------------------------------------------------------ */
public:
/// substraction entry-wise
Array<T, is_scal> & operator-=(const Array<T, is_scal> & other);
/// addition entry-wise
Array<T, is_scal> & operator+=(const Array<T, is_scal> & other);
/// multiply evry entry by alpha
Array<T, is_scal> & operator*=(const T & alpha);
/// check if the array are identical entry-wise
bool operator==(const Array<T, is_scal> & other) const;
/// @see Array::operator==(const Array<T, is_scal> & other) const
bool operator!=(const Array<T, is_scal> & other) const;
/// return a reference to the j-th entry of the i-th tuple
inline reference operator()(UInt i, UInt j = 0);
/// return a const reference to the j-th entry of the i-th tuple
inline const_reference operator()(UInt i, UInt j = 0) const;
/// return a reference to the ith component of the 1D array
inline reference operator[](UInt i);
/// return a const reference to the ith component of the 1D array
inline const_reference operator[](UInt i) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// array of values
T * values; // /!\ very dangerous
};
/* -------------------------------------------------------------------------- */
/* Inline Functions Array<T, is_scal> */
/* -------------------------------------------------------------------------- */
template <typename T, bool is_scal>
inline std::ostream & operator<<(std::ostream & stream,
const Array<T, is_scal> & _this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline std::ostream & operator<<(std::ostream & stream,
const ArrayBase & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "aka_array_tmpl.hh"
#include "aka_types.hh"
#endif /* __AKANTU_VECTOR_HH__ */
diff --git a/src/common/aka_array_tmpl.hh b/src/common/aka_array_tmpl.hh
index 5f779890e..624536626 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1280 +1,1278 @@
/**
* @file aka_array_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Fri Jan 22 2016
*
* @brief Inline functions of the classes Array<T> and ArrayBase
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* Inline Functions Array<T> */
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#include <memory>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_ARRAY_TMPL_HH__
#define __AKANTU_AKA_ARRAY_TMPL_HH__
namespace akantu {
namespace debug {
struct ArrayException : public Exception {};
} // namespace debug
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline T & Array<T, is_scal>::operator()(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size_) && (j < nb_component),
"The value at position ["
<< i << "," << j << "] is out of range in array \""
<< id << "\"");
return values[i * nb_component + j];
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline const T & Array<T, is_scal>::operator()(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size_) && (j < nb_component),
"The value at position ["
<< i << "," << j << "] is out of range in array \""
<< id << "\"");
return values[i * nb_component + j];
}
template <class T, bool is_scal>
inline T & Array<T, is_scal>::operator[](UInt i) {
AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size_ * nb_component),
"The value at position ["
<< i << "] is out of range in array \"" << id
<< "\"");
return values[i];
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline const T & Array<T, is_scal>::operator[](UInt i) const {
AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size_ * nb_component),
"The value at position ["
<< i << "] is out of range in array \"" << id
<< "\"");
return values[i];
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array with the value value for all components
* @param value the new last tuple or the array will contain nb_component copies
* of value
*/
template <class T, bool is_scal>
inline void Array<T, is_scal>::push_back(const T & value) {
resizeUnitialized(size_ + 1, true, value);
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array
* @param new_elem a C-array containing the values to be copied to the end of
* the array */
// template <class T, bool is_scal>
// inline void Array<T, is_scal>::push_back(const T new_elem[]) {
// UInt pos = size_;
// resizeUnitialized(size_ + 1, false);
// T * tmp = values + nb_component * pos;
// std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
// }
/* -------------------------------------------------------------------------- */
#ifndef SWIG
/**
* append a matrix or a vector to the array
* @param new_elem a reference to a Matrix<T> or Vector<T> */
template <class T, bool is_scal>
template <template <typename> class C, typename>
inline void Array<T, is_scal>::push_back(const C<T> & new_elem) {
AKANTU_DEBUG_ASSERT(
nb_component == new_elem.size(),
"The vector("
<< new_elem.size()
<< ") as not a size compatible with the Array (nb_component="
<< nb_component << ").");
UInt pos = size_;
resizeUnitialized(size_ + 1, false);
T * tmp = values + nb_component * pos;
std::uninitialized_copy(new_elem.storage(), new_elem.storage() + nb_component,
tmp);
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array
* @param it an iterator to the tuple to be copied to the end of the array */
template <class T, bool is_scal>
template <class Ret>
inline void
Array<T, is_scal>::push_back(const Array<T, is_scal>::iterator<Ret> & it) {
UInt pos = size_;
resizeUnitialized(size_ + 1, false);
T * tmp = values + nb_component * pos;
T * new_elem = it.data();
std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
}
#endif
/* -------------------------------------------------------------------------- */
/**
* erase an element. If the erased element is not the last of the array, the
* last element is moved into the hole in order to maintain contiguity. This
* may invalidate existing iterators (For instance an iterator obtained by
* Array::end() is no longer correct) and will change the order of the
* elements.
* @param i index of element to erase
*/
template <class T, bool is_scal> inline void Array<T, is_scal>::erase(UInt i) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT((size_ > 0), "The array is empty");
AKANTU_DEBUG_ASSERT((i < size_),
"The element at position [" << i << "] is out of range ("
<< i << ">=" << size_ << ")");
if (i != (size_ - 1)) {
for (UInt j = 0; j < nb_component; ++j) {
values[i * nb_component + j] = values[(size_ - 1) * nb_component + j];
}
}
resize(size_ - 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Subtract another array entry by entry from this array in place. Both arrays
* must
* have the same size and nb_component. If the arrays have different shapes,
* code compiled in debug mode will throw an expeption and optimised code
* will behave in an unpredicted manner
* @param other array to subtract from this
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::
operator-=(const Array<T, is_scal> & vect) {
AKANTU_DEBUG_ASSERT((size_ == vect.size_) &&
(nb_component == vect.nb_component),
"The too array don't have the same sizes");
T * a = values;
T * b = vect.storage();
for (UInt i = 0; i < size_ * nb_component; ++i) {
*a -= *b;
++a;
++b;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Add another array entry by entry to this array in place. Both arrays must
* have the same size and nb_component. If the arrays have different shapes,
* code compiled in debug mode will throw an expeption and optimised code
* will behave in an unpredicted manner
* @param other array to add to this
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::
operator+=(const Array<T, is_scal> & vect) {
AKANTU_DEBUG_ASSERT((size_ == vect.size()) &&
(nb_component == vect.nb_component),
"The too array don't have the same sizes");
T * a = values;
T * b = vect.storage();
for (UInt i = 0; i < size_ * nb_component; ++i) {
*a++ += *b++;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Multiply all entries of this array by a scalar in place
* @param alpha scalar multiplicant
* @return reference to modified this
*/
#ifndef SWIG
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::operator*=(const T & alpha) {
T * a = values;
for (UInt i = 0; i < size_ * nb_component; ++i) {
*a++ *= alpha;
}
return *this;
}
#endif
/* -------------------------------------------------------------------------- */
/**
* Compare this array element by element to another.
* @param other array to compare to
* @return true it all element are equal and arrays have the same shape, else
* false
*/
template <class T, bool is_scal>
bool Array<T, is_scal>::operator==(const Array<T, is_scal> & array) const {
bool equal = nb_component == array.nb_component && size_ == array.size_ &&
id == array.id;
if (!equal)
return false;
if (values == array.storage())
return true;
else
return std::equal(values, values + size_ * nb_component, array.storage());
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
bool Array<T, is_scal>::operator!=(const Array<T, is_scal> & array) const {
return !operator==(array);
}
/* -------------------------------------------------------------------------- */
#ifndef SWIG
/**
* set all tuples of the array to a given vector or matrix
* @param vm Matrix or Vector to fill the array with
*/
template <class T, bool is_scal>
template <template <typename> class C, typename>
inline void Array<T, is_scal>::set(const C<T> & vm) {
AKANTU_DEBUG_ASSERT(
nb_component == vm.size(),
"The size of the object does not match the number of components");
for (T * it = values; it < values + nb_component * size_;
it += nb_component) {
std::copy(vm.storage(), vm.storage() + nb_component, it);
}
}
#endif
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
void Array<T, is_scal>::append(const Array<T> & other) {
AKANTU_DEBUG_ASSERT(
nb_component == other.nb_component,
"Cannot append an array with a different number of component");
UInt old_size = this->size_;
this->resizeUnitialized(this->size_ + other.size(), false);
T * tmp = values + nb_component * old_size;
std::uninitialized_copy(other.storage(),
other.storage() + other.size() * nb_component, tmp);
}
/* -------------------------------------------------------------------------- */
/* Functions Array<T, is_scal> */
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array(UInt size, UInt nb_component, const ID & id)
: ArrayBase(id), values(nullptr) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
if (!is_scal) {
T val = T();
std::uninitialized_fill(values, values + size * nb_component, val);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array(UInt size, UInt nb_component, const T def_values[],
const ID & id)
: ArrayBase(id), values(NULL) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
T * tmp = values;
for (UInt i = 0; i < size; ++i) {
tmp = values + nb_component * i;
std::uninitialized_copy(def_values, def_values + nb_component, tmp);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array(UInt size, UInt nb_component, const T & value,
const ID & id)
: ArrayBase(id), values(nullptr) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
std::uninitialized_fill_n(values, size * nb_component, value);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array(const Array<T, is_scal> & vect, bool deep,
const ID & id)
: ArrayBase(vect) {
AKANTU_DEBUG_IN();
this->id = (id == "") ? vect.id : id;
if (deep) {
allocate(vect.size_, vect.nb_component);
T * tmp = values;
std::uninitialized_copy(vect.storage(),
vect.storage() + size_ * nb_component, tmp);
} else {
this->values = vect.storage();
this->size_ = vect.size_;
this->nb_component = vect.nb_component;
this->allocated_size = vect.allocated_size;
this->size_of_type = vect.size_of_type;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#ifndef SWIG
template <class T, bool is_scal>
Array<T, is_scal>::Array(const std::vector<T> & vect) {
AKANTU_DEBUG_IN();
this->id = "";
allocate(vect.size(), 1);
T * tmp = values;
std::uninitialized_copy(&(vect[0]), &(vect[size_ - 1]), tmp);
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal> Array<T, is_scal>::~Array() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG(dblAccessory,
"Freeing " << printMemorySize<T>(allocated_size * nb_component)
<< " (" << id << ")");
if (values) {
if (!is_scal)
for (UInt i = 0; i < size_ * nb_component; ++i) {
T * obj = values + i;
obj->~T();
}
free(values);
}
size_ = allocated_size = 0;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* perform the allocation for the constructors
* @param size is the size of the array
* @param nb_component is the number of component of the array
*/
template <class T, bool is_scal>
void Array<T, is_scal>::allocate(UInt size, UInt nb_component) {
AKANTU_DEBUG_IN();
if (size == 0) {
values = nullptr;
} else {
values = static_cast<T *>(malloc(nb_component * size * sizeof(T)));
AKANTU_DEBUG_ASSERT(values != nullptr,
"Cannot allocate "
<< printMemorySize<T>(size * nb_component) << " ("
<< id << ")");
}
if (values == nullptr) {
this->size_ = this->allocated_size = 0;
} else {
AKANTU_DEBUG(dblAccessory,
"Allocated " << printMemorySize<T>(size * nb_component) << " ("
<< id << ")");
this->size_ = this->allocated_size = size;
}
this->size_of_type = sizeof(T);
this->nb_component = nb_component;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
void Array<T, is_scal>::reserve(UInt new_size) {
UInt tmp_size = this->size_;
resizeUnitialized(new_size, false);
this->size_ = tmp_size;
}
/* -------------------------------------------------------------------------- */
/**
* change the size of the array and allocate or free memory if needed. If the
* size increases, the new tuples are filled with zeros
* @param new_size new number of tuples contained in the array */
template <class T, bool is_scal> void Array<T, is_scal>::resize(UInt new_size) {
resizeUnitialized(new_size, !is_scal);
}
/* -------------------------------------------------------------------------- */
/**
* change the size of the array and allocate or free memory if needed. If the
* size increases, the new tuples are filled with zeros
* @param new_size new number of tuples contained in the array */
template <class T, bool is_scal>
void Array<T, is_scal>::resize(UInt new_size, const T & val) {
this->resizeUnitialized(new_size, true, val);
}
/* -------------------------------------------------------------------------- */
/**
* change the size of the array and allocate or free memory if needed.
* @param new_size new number of tuples contained in the array */
template <class T, bool is_scal>
void Array<T, is_scal>::resizeUnitialized(UInt new_size, bool fill,
const T & val) {
// AKANTU_DEBUG_IN();
// free some memory
if (new_size <= allocated_size) {
if (!is_scal) {
T * old_values = values;
if (new_size < size_) {
for (UInt i = new_size * nb_component; i < size_ * nb_component; ++i) {
T * obj = old_values + i;
obj->~T();
}
}
}
if (allocated_size - new_size > AKANTU_MIN_ALLOCATION) {
AKANTU_DEBUG(dblAccessory,
"Freeing " << printMemorySize<T>((allocated_size - size_) *
nb_component)
<< " (" << id << ")");
// Normally there are no allocation problem when reducing an array
if (new_size == 0) {
free(values);
values = nullptr;
} else {
auto * tmp_ptr = static_cast<T *>(
realloc(values, new_size * nb_component * sizeof(T)));
if (tmp_ptr == nullptr) {
AKANTU_EXCEPTION("Cannot free data ("
<< id << ")"
<< " [current allocated size : " << allocated_size
<< " | "
<< "requested size : " << new_size << "]");
}
values = tmp_ptr;
}
allocated_size = new_size;
}
} else {
// allocate more memory
UInt size_to_alloc = (new_size - allocated_size < AKANTU_MIN_ALLOCATION)
? allocated_size + AKANTU_MIN_ALLOCATION
: new_size;
auto * tmp_ptr = static_cast<T *>(
realloc(values, size_to_alloc * nb_component * sizeof(T)));
AKANTU_DEBUG_ASSERT(
tmp_ptr != nullptr,
"Cannot allocate " << printMemorySize<T>(size_to_alloc * nb_component));
if (tmp_ptr == nullptr) {
AKANTU_ERROR("Cannot allocate more data ("
- << id << ")"
- << " [current allocated size : " << allocated_size
- << " | "
- << "requested size : " << new_size << "]");
+ << id << ")"
+ << " [current allocated size : " << allocated_size << " | "
+ << "requested size : " << new_size << "]");
}
AKANTU_DEBUG(dblAccessory,
"Allocating " << printMemorySize<T>(
(size_to_alloc - allocated_size) * nb_component));
allocated_size = size_to_alloc;
values = tmp_ptr;
}
if (fill && this->size_ < new_size) {
std::uninitialized_fill(values + size_ * nb_component,
values + new_size * nb_component, val);
}
size_ = new_size;
// AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* change the number of components by interlacing data
* @param multiplicator number of interlaced components add
* @param block_size blocks of data in the array
* Examaple for block_size = 2, multiplicator = 2
* array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn */
template <class T, bool is_scal>
void Array<T, is_scal>::extendComponentsInterlaced(UInt multiplicator,
UInt block_size) {
AKANTU_DEBUG_IN();
if (multiplicator == 1)
return;
AKANTU_DEBUG_ASSERT(multiplicator > 1, "invalid multiplicator");
AKANTU_DEBUG_ASSERT(nb_component % block_size == 0,
"stride must divide actual number of components");
values = static_cast<T *>(
realloc(values, nb_component * multiplicator * size_ * sizeof(T)));
UInt new_component = nb_component / block_size * multiplicator;
for (UInt i = 0, k = size_ - 1; i < size_; ++i, --k) {
for (UInt j = 0; j < new_component; ++j) {
UInt m = new_component - j - 1;
UInt n = m / multiplicator;
for (UInt l = 0, p = block_size - 1; l < block_size; ++l, --p) {
values[k * nb_component * multiplicator + m * block_size + p] =
values[k * nb_component + n * block_size + p];
}
}
}
nb_component = nb_component * multiplicator;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* search elem in the array, return the position of the first occurrence or
* -1 if not found
* @param elem the element to look for
* @return index of the first occurrence of elem or -1 if elem is not present
*/
template <class T, bool is_scal>
UInt Array<T, is_scal>::find(const T & elem) const {
AKANTU_DEBUG_IN();
auto begin = this->begin();
auto end = this->end();
auto it = std::find(begin, end, elem);
AKANTU_DEBUG_OUT();
return (it != end) ? it - begin : UInt(-1);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal> UInt Array<T, is_scal>::find(T elem[]) const {
AKANTU_DEBUG_IN();
T * it = values;
UInt i = 0;
for (; i < size_; ++i) {
if (*it == elem[0]) {
T * cit = it;
UInt c = 0;
for (; (c < nb_component) && (*cit == elem[c]); ++c, ++cit)
;
if (c == nb_component) {
AKANTU_DEBUG_OUT();
return i;
}
}
it += nb_component;
}
return UInt(-1);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template <template <typename> class C, typename>
inline UInt Array<T, is_scal>::find(const C<T> & elem) {
AKANTU_DEBUG_ASSERT(elem.size() == nb_component,
"Cannot find an element with a wrong size ("
<< elem.size() << ") != " << nb_component);
return this->find(elem.storage());
}
/* -------------------------------------------------------------------------- */
/**
* copy the content of another array. This overwrites the current content.
* @param other Array to copy into this array. It has to have the same
* nb_component as this. If compiled in debug mode, an incorrect other will
* result in an exception being thrown. Optimised code may result in
* unpredicted behaviour.
*/
template <class T, bool is_scal>
void Array<T, is_scal>::copy(const Array<T, is_scal> & vect,
bool no_sanity_check) {
AKANTU_DEBUG_IN();
if (!no_sanity_check)
if (vect.nb_component != nb_component)
- AKANTU_ERROR(
- "The two arrays do not have the same number of components");
+ AKANTU_ERROR("The two arrays do not have the same number of components");
resize((vect.size_ * vect.nb_component) / nb_component);
T * tmp = values;
std::uninitialized_copy(vect.storage(), vect.storage() + size_ * nb_component,
tmp);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool is_scal> class ArrayPrintHelper {
public:
template <typename T>
static void print_content(const Array<T> & vect, std::ostream & stream,
int indent) {
if (AKANTU_DEBUG_TEST(dblDump) || AKANTU_DEBUG_LEVEL_IS_TEST()) {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << " + values : {";
for (UInt i = 0; i < vect.size(); ++i) {
stream << "{";
for (UInt j = 0; j < vect.getNbComponent(); ++j) {
stream << vect(i, j);
if (j != vect.getNbComponent() - 1)
stream << ", ";
}
stream << "}";
if (i != vect.size() - 1)
stream << ", ";
}
stream << "}" << std::endl;
}
}
};
template <> class ArrayPrintHelper<false> {
public:
template <typename T>
static void print_content(__attribute__((unused)) const Array<T> & vect,
__attribute__((unused)) std::ostream & stream,
__attribute__((unused)) int indent) {}
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
void Array<T, is_scal>::printself(std::ostream & stream, int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
std::streamsize prec = stream.precision();
std::ios_base::fmtflags ff = stream.flags();
stream.setf(std::ios_base::showbase);
stream.precision(2);
stream << space << "Array<" << debug::demangle(typeid(T).name()) << "> ["
<< std::endl;
stream << space << " + id : " << this->id << std::endl;
stream << space << " + size : " << this->size_ << std::endl;
stream << space << " + nb_component : " << this->nb_component << std::endl;
stream << space << " + allocated size : " << this->allocated_size
<< std::endl;
stream << space << " + memory size : "
<< printMemorySize<T>(allocated_size * nb_component) << std::endl;
if (!AKANTU_DEBUG_LEVEL_IS_TEST())
stream << space << " + address : " << std::hex << this->values
<< std::dec << std::endl;
stream.precision(prec);
stream.flags(ff);
ArrayPrintHelper<is_scal>::print_content(*this, stream, indent);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline UInt ArrayBase::getMemorySize() const {
return allocated_size * nb_component * size_of_type;
}
inline void ArrayBase::empty() { size_ = 0; }
#ifndef SWIG
/* -------------------------------------------------------------------------- */
/* Iterators */
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template <class R, class daughter, class IR, bool is_tensor>
class Array<T, is_scal>::iterator_internal {
public:
using value_type = R;
using pointer = R *;
using reference = R &;
using proxy = typename R::proxy;
using const_proxy = const typename R::proxy;
using const_reference = const R &;
using internal_value_type = IR;
using internal_pointer = IR *;
using difference_type = std::ptrdiff_t;
using iterator_category = std::random_access_iterator_tag;
public:
iterator_internal() = default;
iterator_internal(pointer_type data, UInt _offset)
: _offset(_offset), initial(data), ret(nullptr), ret_ptr(data) {
AKANTU_ERROR(
"The constructor should never be called it is just an ugly trick...");
}
iterator_internal(std::unique_ptr<internal_value_type> && wrapped)
: _offset(wrapped->size()), initial(wrapped->storage()),
ret(std::move(wrapped)), ret_ptr(ret->storage()) {}
iterator_internal(const iterator_internal & it) {
if (this != &it) {
this->_offset = it._offset;
this->initial = it.initial;
this->ret_ptr = it.ret_ptr;
this->ret = std::make_unique<internal_value_type>(*it.ret, false);
}
}
iterator_internal(iterator_internal && it) = default;
virtual ~iterator_internal() = default;
inline iterator_internal & operator=(const iterator_internal & it) {
if (this != &it) {
this->_offset = it._offset;
this->initial = it.initial;
this->ret_ptr = it.ret_ptr;
if (this->ret)
this->ret->shallowCopy(*it.ret);
else
this->ret = std::make_unique<internal_value_type>(*it.ret, false);
}
return *this;
}
UInt getCurrentIndex() {
return (this->ret_ptr - this->initial) / this->_offset;
};
inline reference operator*() {
ret->values = ret_ptr;
return *ret;
};
inline const_reference operator*() const {
ret->values = ret_ptr;
return *ret;
};
inline pointer operator->() {
ret->values = ret_ptr;
return ret.get();
};
inline daughter & operator++() {
ret_ptr += _offset;
return static_cast<daughter &>(*this);
};
inline daughter & operator--() {
ret_ptr -= _offset;
return static_cast<daughter &>(*this);
};
inline daughter & operator+=(const UInt n) {
ret_ptr += _offset * n;
return static_cast<daughter &>(*this);
}
inline daughter & operator-=(const UInt n) {
ret_ptr -= _offset * n;
return static_cast<daughter &>(*this);
}
inline proxy operator[](const UInt n) {
ret->values = ret_ptr + n * _offset;
return proxy(*ret);
}
inline const_proxy operator[](const UInt n) const {
ret->values = ret_ptr + n * _offset;
return const_proxy(*ret);
}
inline bool operator==(const iterator_internal & other) const {
return this->ret_ptr == other.ret_ptr;
}
inline bool operator!=(const iterator_internal & other) const {
return this->ret_ptr != other.ret_ptr;
}
inline bool operator<(const iterator_internal & other) const {
return this->ret_ptr < other.ret_ptr;
}
inline bool operator<=(const iterator_internal & other) const {
return this->ret_ptr <= other.ret_ptr;
}
inline bool operator>(const iterator_internal & other) const {
return this->ret_ptr > other.ret_ptr;
}
inline bool operator>=(const iterator_internal & other) const {
return this->ret_ptr >= other.ret_ptr;
}
inline daughter operator+(difference_type n) {
daughter tmp(static_cast<daughter &>(*this));
tmp += n;
return tmp;
}
inline daughter operator-(difference_type n) {
daughter tmp(static_cast<daughter &>(*this));
tmp -= n;
return tmp;
}
inline difference_type operator-(const iterator_internal & b) {
return (this->ret_ptr - b.ret_ptr) / _offset;
}
inline pointer_type data() const { return ret_ptr; }
inline difference_type offset() const { return _offset; }
protected:
UInt _offset{0};
pointer_type initial{nullptr};
std::unique_ptr<internal_value_type> ret{nullptr};
pointer_type ret_ptr{nullptr};
};
/* -------------------------------------------------------------------------- */
/**
* Specialization for scalar types
*/
template <class T, bool is_scal>
template <class R, class daughter, class IR>
class Array<T, is_scal>::iterator_internal<R, daughter, IR, false> {
public:
using value_type = R;
using pointer = R *;
using reference = R &;
using const_reference = const R &;
using internal_value_type = IR;
using internal_pointer = IR *;
using difference_type = std::ptrdiff_t;
using iterator_category = std::random_access_iterator_tag;
public:
iterator_internal(pointer data = nullptr) : ret(data), initial(data){};
iterator_internal(const iterator_internal & it) = default;
iterator_internal(iterator_internal && it) = default;
virtual ~iterator_internal() = default;
inline iterator_internal & operator=(const iterator_internal & it) = default;
UInt getCurrentIndex() { return (this->ret - this->initial); };
inline reference operator*() { return *ret; };
inline const_reference operator*() const { return *ret; };
inline pointer operator->() { return ret; };
inline daughter & operator++() {
++ret;
return static_cast<daughter &>(*this);
};
inline daughter & operator--() {
--ret;
return static_cast<daughter &>(*this);
};
inline daughter & operator+=(const UInt n) {
ret += n;
return static_cast<daughter &>(*this);
}
inline daughter & operator-=(const UInt n) {
ret -= n;
return static_cast<daughter &>(*this);
}
inline reference operator[](const UInt n) { return ret[n]; }
inline bool operator==(const iterator_internal & other) const {
return ret == other.ret;
}
inline bool operator!=(const iterator_internal & other) const {
return ret != other.ret;
}
inline bool operator<(const iterator_internal & other) const {
return ret < other.ret;
}
inline bool operator<=(const iterator_internal & other) const {
return ret <= other.ret;
}
inline bool operator>(const iterator_internal & other) const {
return ret > other.ret;
}
inline bool operator>=(const iterator_internal & other) const {
return ret >= other.ret;
}
inline daughter operator-(difference_type n) { return daughter(ret - n); }
inline daughter operator+(difference_type n) { return daughter(ret + n); }
inline difference_type operator-(const iterator_internal & b) {
return ret - b.ret;
}
inline pointer data() const { return ret; }
protected:
pointer ret{nullptr};
pointer initial{nullptr};
};
/* -------------------------------------------------------------------------- */
/* Begin/End functions implementation */
/* -------------------------------------------------------------------------- */
namespace detail {
template <class Tuple, size_t... Is>
constexpr auto take_front_impl(Tuple && t, std::index_sequence<Is...>) {
return std::make_tuple(std::get<Is>(std::forward<Tuple>(t))...);
}
template <size_t N, class Tuple> constexpr auto take_front(Tuple && t) {
return take_front_impl(std::forward<Tuple>(t),
std::make_index_sequence<N>{});
}
template <typename... V> constexpr auto product_all(V &&... v) {
std::common_type_t<int, V...> result = 1;
(void)std::initializer_list<int>{(result *= v, 0)...};
return result;
}
template <typename... T> std::string to_string_all(T &&... t) {
if (sizeof...(T) == 0)
return "";
std::stringstream ss;
bool noComma = true;
ss << "(";
(void)std::initializer_list<bool>{
(ss << (noComma ? "" : ", ") << t, noComma = false)...};
ss << ")";
return ss.str();
}
template <std::size_t N> struct InstantiationHelper {
template <typename type, typename T, typename... Ns>
static auto instantiate(T && data, Ns... ns) {
return std::make_unique<type>(data, ns...);
}
};
template <> struct InstantiationHelper<0> {
template <typename type, typename T> static auto instantiate(T && data) {
return data;
}
};
template <typename Arr, typename T, typename... Ns>
decltype(auto) get_iterator(Arr && array, T * data, Ns &&... ns) {
using type = IteratorHelper_t<sizeof...(Ns) - 1, T>;
using array_type = std::decay_t<Arr>;
using iterator =
std::conditional_t<std::is_const<std::remove_reference_t<Arr>>::value,
typename array_type::template const_iterator<type>,
typename array_type::template iterator<type>>;
static_assert(sizeof...(Ns), "You should provide a least one size");
if (array.getNbComponent() * array.size() !=
product_all(std::forward<Ns>(ns)...)) {
AKANTU_CUSTOM_EXCEPTION_INFO(
debug::ArrayException(),
"The iterator on "
<< debug::demangle(typeid(Arr).name())
<< to_string_all(array.size(), array.getNbComponent())
<< "is not compatible with the type "
<< debug::demangle(typeid(type).name()) << to_string_all(ns...));
}
auto && wrapped = aka::apply(
[&](auto... n) {
return InstantiationHelper<sizeof...(n)>::template instantiate<type>(
data, n...);
},
take_front<sizeof...(Ns) - 1>(std::make_tuple(ns...)));
return iterator(std::move(wrapped));
}
} // namespace detail
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) {
return detail::get_iterator(*this, values, std::forward<Ns>(ns)..., size_);
}
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) {
return detail::get_iterator(*this, values + nb_component * size_,
std::forward<Ns>(ns)..., size_);
}
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) const {
return detail::get_iterator(*this, values, std::forward<Ns>(ns)..., size_);
}
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) const {
return detail::get_iterator(*this, values + nb_component * size_,
std::forward<Ns>(ns)..., size_);
}
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::begin_reinterpret(Ns &&... ns) {
return detail::get_iterator(*this, values, std::forward<Ns>(ns)...);
}
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::end_reinterpret(Ns &&... ns) {
return detail::get_iterator(
*this, values + detail::product_all(std::forward<Ns>(ns)...),
std::forward<Ns>(ns)...);
}
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::begin_reinterpret(Ns &&... ns) const {
return detail::get_iterator(*this, values, std::forward<Ns>(ns)...);
}
template <class T, bool is_scal>
template <typename... Ns>
inline decltype(auto) Array<T, is_scal>::end_reinterpret(Ns &&... ns) const {
return detail::get_iterator(
*this, values + detail::product_all(std::forward<Ns>(ns)...),
std::forward<Ns>(ns)...);
}
/* -------------------------------------------------------------------------- */
/* Views */
/* -------------------------------------------------------------------------- */
namespace detail {
template <typename Array, typename... Ns> class ArrayView {
using tuple = std::tuple<Ns...>;
public:
ArrayView(Array && array, Ns... ns)
: array(std::forward<Array>(array)), sizes(std::move(ns)...) {}
ArrayView(ArrayView && array_view) = default;
ArrayView & operator=(const ArrayView & array_view) = default;
ArrayView & operator=(ArrayView && array_view) = default;
decltype(auto) begin() {
return aka::apply(
[&](auto &&... ns) { return array.begin_reinterpret(ns...); }, sizes);
}
decltype(auto) begin() const {
return aka::apply(
[&](auto &&... ns) { return array.begin_reinterpret(ns...); }, sizes);
}
decltype(auto) end() {
return aka::apply(
[&](auto &&... ns) { return array.end_reinterpret(ns...); }, sizes);
}
decltype(auto) end() const {
return aka::apply(
[&](auto &&... ns) { return array.end_reinterpret(ns...); }, sizes);
}
decltype(auto) size() const {
return std::get<std::tuple_size<tuple>::value - 1>(sizes);
}
decltype(auto) dims() const { return std::tuple_size<tuple>::value - 1; }
private:
Array array;
tuple sizes;
};
} // namespace detail
/* -------------------------------------------------------------------------- */
template <typename Array, typename... Ns>
decltype(auto) make_view(Array && array, Ns... ns) {
static_assert(aka::conjunction<std::is_integral<std::decay_t<Ns>>...>::value,
"Ns should be integral types");
auto size = std::forward<decltype(array)>(array).size() *
std::forward<decltype(array)>(array).getNbComponent() /
detail::product_all(ns...);
return detail::ArrayView<Array, std::common_type_t<size_t, Ns>...,
std::common_type_t<size_t, decltype(size)>>(
std::forward<Array>(array), std::move(ns)..., size);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template <typename R>
class Array<T, is_scal>::const_iterator
: public iterator_internal<const R, Array<T, is_scal>::const_iterator<R>,
R> {
public:
using parent = iterator_internal<const R, const_iterator, R>;
using value_type = typename parent::value_type;
using pointer = typename parent::pointer;
using reference = typename parent::reference;
using difference_type = typename parent::difference_type;
using iterator_category = typename parent::iterator_category;
public:
const_iterator() : parent(){};
// const_iterator(pointer_type data, UInt offset) : parent(data, offset) {}
// const_iterator(pointer warped) : parent(warped) {}
// const_iterator(const parent & it) : parent(it) {}
const_iterator(const const_iterator & it) = default;
const_iterator(const_iterator && it) = default;
template <typename P, typename = std::enable_if_t<not is_tensor<P>::value>>
const_iterator(P * data) : parent(data) {}
template <typename UP_P,
typename =
std::enable_if_t<is_tensor<typename UP_P::element_type>::value>>
const_iterator(UP_P && tensor) : parent(std::forward<UP_P>(tensor)) {}
const_iterator & operator=(const const_iterator & it) = default;
};
template <class T, class R, bool is_tensor_ = is_tensor<R>::value>
struct ConstConverterIteratorHelper {
using const_iterator = typename Array<T>::template const_iterator<R>;
using iterator = typename Array<T>::template iterator<R>;
static inline const_iterator convert(const iterator & it) {
return const_iterator(std::unique_ptr<R>(new R(*it, false)));
}
};
template <class T, class R> struct ConstConverterIteratorHelper<T, R, false> {
using const_iterator = typename Array<T>::template const_iterator<R>;
using iterator = typename Array<T>::template iterator<R>;
static inline const_iterator convert(const iterator & it) {
return const_iterator(it.data());
}
};
template <class T, bool is_scal>
template <typename R>
class Array<T, is_scal>::iterator
: public iterator_internal<R, Array<T, is_scal>::iterator<R>> {
public:
using parent = iterator_internal<R, iterator>;
using value_type = typename parent::value_type;
using pointer = typename parent::pointer;
using reference = typename parent::reference;
using difference_type = typename parent::difference_type;
using iterator_category = typename parent::iterator_category;
public:
iterator() : parent(){};
iterator(const iterator & it) = default;
iterator(iterator && it) = default;
template <typename P, typename = std::enable_if_t<not is_tensor<P>::value>>
iterator(P * data) : parent(data) {}
template <typename UP_P,
typename =
std::enable_if_t<is_tensor<typename UP_P::element_type>::value>>
iterator(UP_P && tensor) : parent(std::forward<UP_P>(tensor)) {}
iterator & operator=(const iterator & it) = default;
operator const_iterator<R>() {
return ConstConverterIteratorHelper<T, R>::convert(*this);
}
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template <typename R>
inline typename Array<T, is_scal>::template iterator<R>
Array<T, is_scal>::erase(const iterator<R> & it) {
T * curr = it.data();
UInt pos = (curr - values) / nb_component;
erase(pos);
iterator<R> rit = it;
return --rit;
}
#endif
} // namespace akantu
#endif /* __AKANTU_AKA_ARRAY_TMPL_HH__ */
diff --git a/src/common/aka_blas_lapack.hh b/src/common/aka_blas_lapack.hh
index 3da5ed016..55ba9a8c4 100644
--- a/src/common/aka_blas_lapack.hh
+++ b/src/common/aka_blas_lapack.hh
@@ -1,343 +1,343 @@
/**
* @file aka_blas_lapack.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Mar 06 2013
* @date last modification: Mon Jan 18 2016
*
* @brief Interface of the Fortran BLAS/LAPACK libraries
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_BLAS_LAPACK_HH__
#define __AKANTU_AKA_BLAS_LAPACK_HH__
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_BLAS
#include "aka_fortran_mangling.hh"
extern "C" {
- /* ------------------------------------------------------------------------ */
- /* Double precision */
- /* ------------------------------------------------------------------------ */
- // LEVEL 1
- double AKA_FC_GLOBAL(ddot, DDOT)(int *, double *, int *, double *, int *);
+/* ------------------------------------------------------------------------ */
+/* Double precision */
+/* ------------------------------------------------------------------------ */
+// LEVEL 1
+double AKA_FC_GLOBAL(ddot, DDOT)(int *, double *, int *, double *, int *);
void AKA_FC_GLOBAL(daxpy, DAXPY)(int *, double *, double *, int *, double *,
int *);
// LEVEL 2
void AKA_FC_GLOBAL(dgemv, DGEMV)(char *, int *, int *, double *, double *,
int *, double *, int *, double *, double *,
int *);
// LEVEL 3
void AKA_FC_GLOBAL(dgemm, DGEMM)(char *, char *, int *, int *, int *, double *,
double *, int *, double *, int *, double *,
double *, int *);
/* ------------------------------------------------------------------------ */
/* Simple precision */
/* ------------------------------------------------------------------------ */
// LEVEL 1
float AKA_FC_GLOBAL(sdot, SDOT)(int *, float *, int *, float *, int *);
void AKA_FC_GLOBAL(saxpy, SAXPY)(int *, float *, float *, int *, float *,
int *);
// LEVEL 2
void AKA_FC_GLOBAL(sgemv, SGEMV)(char *, int *, int *, float *, float *, int *,
float *, int *, float *, float *, int *);
// LEVEL 3
void AKA_FC_GLOBAL(sgemm, SGEMM)(char *, char *, int *, int *, int *, float *,
float *, int *, float *, int *, float *,
float *, int *);
}
#endif
namespace akantu {
#define AKANTU_WARNING_IGNORE_UNUSED_PARAMETER
#include "aka_warning.hh"
/// Wrapper around the S/DDOT BLAS function that returns the dot product of two
/// vectors
template <typename T>
inline T aka_dot(int * n, T * x, int * incx, T * y, int * incy) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "BLAS in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "BLAS in the compilation options!");
}
/// Wrapper around the S/DAXPY BLAS function that computes \f$y := \alpha x +
/// y\f$
template <typename T>
inline void aka_axpy(int * n, T * alpha, T * x, int * incx, T * y, int * incy) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "BLAS in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "BLAS in the compilation options!");
}
/// Wrapper around the S/DGEMV BLAS function that computes matrix-vector product
/// \f$y := \alpha A^{(T)}x + \beta y \f$
template <typename T>
inline void aka_gemv(char * trans, int * m, int * n, T * alpha, T * a,
int * lda, T * x, int * incx, T * beta, T * y,
int * incy) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "BLAS in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "BLAS in the compilation options!");
}
/// Wrapper around the S/DGEMM BLAS function that computes the product of two
/// matrices \f$C := \alpha A^{(T)} B^{(T)} + \beta C \f$
template <typename T>
inline void aka_gemm(char * transa, char * transb, int * m, int * n, int * k,
T * alpha, T * a, int * lda, T * b, int * ldb, T * beta,
T * c, int * ldc) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "BLAS in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "BLAS in the compilation options!");
}
#if defined(AKANTU_USE_BLAS)
template <>
inline double aka_dot<double>(int * n, double * x, int * incx, double * y,
int * incy) {
return AKA_FC_GLOBAL(ddot, DDOT)(n, x, incx, y, incy);
}
template <>
inline void aka_axpy(int * n, double * alpha, double * x, int * incx,
double * y, int * incy) {
return AKA_FC_GLOBAL(daxpy, DAXPY)(n, alpha, x, incx, y, incy);
}
template <>
inline void aka_gemv<double>(char * trans, int * m, int * n, double * alpha,
double * a, int * lda, double * x, int * incx,
double * beta, double * y, int * incy) {
return AKA_FC_GLOBAL(dgemv, DGEMV)(trans, m, n, alpha, a, lda, x, incx, beta,
y, incy);
}
template <>
inline void aka_gemm<double>(char * transa, char * transb, int * m, int * n,
int * k, double * alpha, double * a, int * lda,
double * b, int * ldb, double * beta, double * c,
int * ldc) {
AKA_FC_GLOBAL(dgemm, DGEMM)
(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <>
inline float aka_dot<float>(int * n, float * x, int * incx, float * y,
int * incy) {
return AKA_FC_GLOBAL(sdot, SDOT)(n, x, incx, y, incy);
}
template <>
inline void aka_axpy(int * n, float * alpha, float * x, int * incx, float * y,
int * incy) {
return AKA_FC_GLOBAL(daxpy, DAXPY)(n, alpha, x, incx, y, incy);
}
template <>
inline void aka_gemv<float>(char * trans, int * m, int * n, float * alpha,
float * a, int * lda, float * x, int * incx,
float * beta, float * y, int * incy) {
AKA_FC_GLOBAL(sgemv, SGEMV)
(trans, m, n, alpha, a, lda, x, incx, beta, y, incy);
}
template <>
inline void aka_gemm<float>(char * transa, char * transb, int * m, int * n,
int * k, float * alpha, float * a, int * lda,
float * b, int * ldb, float * beta, float * c,
int * ldc) {
AKA_FC_GLOBAL(sgemm, SGEMM)
(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
}
#endif
} // akantu
#ifdef AKANTU_USE_LAPACK
#include "aka_fortran_mangling.hh"
extern "C" {
/* ------------------------------------------------------------------------ */
/* Double general matrix */
/* ------------------------------------------------------------------------ */
/// compute the eigenvalues/vectors
void AKA_FC_GLOBAL(dgeev, DGEEV)(char * jobvl, char * jobvr, int * n,
double * a, int * lda, double * wr,
double * wi, double * vl, int * ldvl,
double * vr, int * ldvr, double * work,
int * lwork, int * info);
/// LU decomposition of a general matrix
void AKA_FC_GLOBAL(dgetrf, DGETRF)(int * m, int * n, double * a, int * lda,
int * ipiv, int * info);
/// generate inverse of a matrix given its LU decomposition
void AKA_FC_GLOBAL(dgetri, DGETRI)(int * n, double * a, int * lda, int * ipiv,
double * work, int * lwork, int * info);
/// solving A x = b using a LU factorization
void AKA_FC_GLOBAL(dgetrs, DGETRS)(char * trans, int * n, int * nrhs,
double * A, int * lda, int * ipiv,
double * b, int * ldb, int * info);
/* ------------------------------------------------------------------------ */
/* Simple general matrix */
/* ------------------------------------------------------------------------ */
/// compute the eigenvalues/vectors
void AKA_FC_GLOBAL(sgeev, SGEEV)(char * jobvl, char * jobvr, int * n, float * a,
int * lda, float * wr, float * wi, float * vl,
int * ldvl, float * vr, int * ldvr,
float * work, int * lwork, int * info);
/// LU decomposition of a general matrix
void AKA_FC_GLOBAL(sgetrf, SGETRF)(int * m, int * n, float * a, int * lda,
int * ipiv, int * info);
/// generate inverse of a matrix given its LU decomposition
void AKA_FC_GLOBAL(sgetri, SGETRI)(int * n, float * a, int * lda, int * ipiv,
float * work, int * lwork, int * info);
/// solving A x = b using a LU factorization
void AKA_FC_GLOBAL(sgetrs, SGETRS)(char * trans, int * n, int * nrhs, float * A,
int * lda, int * ipiv, float * b, int * ldb,
int * info);
}
#endif // AKANTU_USE_LAPACK
namespace akantu {
/// Wrapper around the S/DGEEV BLAS function that computes the eigenvalues and
/// eigenvectors of a matrix
template <typename T>
inline void aka_geev(char * jobvl, char * jobvr, int * n, T * a, int * lda,
T * wr, T * wi, T * vl, int * ldvl, T * vr, int * ldvr,
T * work, int * lwork, int * info) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "LAPACK in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "LAPACK in the compilation options!");
}
/// Wrapper around the S/DGETRF BLAS function that computes the LU decomposition
/// of a matrix
template <typename T>
inline void aka_getrf(int * m, int * n, T * a, int * lda, int * ipiv,
int * info) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "LAPACK in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "LAPACK in the compilation options!");
}
/// Wrapper around the S/DGETRI BLAS function that computes the inverse of a
/// matrix given its LU decomposition
template <typename T>
inline void aka_getri(int * n, T * a, int * lda, int * ipiv, T * work,
int * lwork, int * info) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "LAPACK in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "LAPACK in the compilation options!");
}
/// Wrapper around the S/DGETRS BLAS function that solves \f$A^{(T)}x = b\f$
/// using LU decomposition
template <typename T>
inline void aka_getrs(char * trans, int * n, int * nrhs, T * A, int * lda,
int * ipiv, T * b, int * ldb, int * info) {
AKANTU_ERROR(debug::demangle(typeid(T).name())
- << "is not a type recognized, or you didn't activated "
- "LAPACK in the compilation options!");
+ << "is not a type recognized, or you didn't activated "
+ "LAPACK in the compilation options!");
}
#include "aka_warning_restore.hh"
#ifdef AKANTU_USE_LAPACK
template <>
inline void aka_geev<double>(char * jobvl, char * jobvr, int * n, double * a,
int * lda, double * wr, double * wi, double * vl,
int * ldvl, double * vr, int * ldvr, double * work,
int * lwork, int * info) {
AKA_FC_GLOBAL(dgeev, DGEEV)
(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
}
template <>
inline void aka_getrf<double>(int * m, int * n, double * a, int * lda,
int * ipiv, int * info) {
AKA_FC_GLOBAL(dgetrf, DGETRF)(m, n, a, lda, ipiv, info);
}
template <>
inline void aka_getri<double>(int * n, double * a, int * lda, int * ipiv,
double * work, int * lwork, int * info) {
AKA_FC_GLOBAL(dgetri, DGETRI)(n, a, lda, ipiv, work, lwork, info);
}
template <>
inline void aka_getrs<double>(char * trans, int * n, int * nrhs, double * A,
int * lda, int * ipiv, double * b, int * ldb,
int * info) {
AKA_FC_GLOBAL(dgetrs, DGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <>
inline void aka_geev<float>(char * jobvl, char * jobvr, int * n, float * a,
int * lda, float * wr, float * wi, float * vl,
int * ldvl, float * vr, int * ldvr, float * work,
int * lwork, int * info) {
AKA_FC_GLOBAL(sgeev, SGEEV)
(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
}
template <>
inline void aka_getrf<float>(int * m, int * n, float * a, int * lda, int * ipiv,
int * info) {
AKA_FC_GLOBAL(sgetrf, SGETRF)(m, n, a, lda, ipiv, info);
}
template <>
inline void aka_getri<float>(int * n, float * a, int * lda, int * ipiv,
float * work, int * lwork, int * info) {
AKA_FC_GLOBAL(sgetri, SGETRI)(n, a, lda, ipiv, work, lwork, info);
}
template <>
inline void aka_getrs<float>(char * trans, int * n, int * nrhs, float * A,
int * lda, int * ipiv, float * b, int * ldb,
int * info) {
AKA_FC_GLOBAL(sgetrs, SGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
}
#endif
} // akantu
#endif /* __AKANTU_AKA_BLAS_LAPACK_HH__ */
diff --git a/src/common/aka_circular_array.hh b/src/common/aka_circular_array.hh
index f533430c0..7b9972b38 100644
--- a/src/common/aka_circular_array.hh
+++ b/src/common/aka_circular_array.hh
@@ -1,140 +1,130 @@
/**
* @file aka_circular_array.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief class of circular array
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_CIRCULAR_ARRAY_HH__
#define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
/* -------------------------------------------------------------------------- */
#include <typeinfo>
/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
#include "aka_array.hh"
+#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
-template<class T>
-class CircularArray : protected Array<T> {
+template <class T> class CircularArray : protected Array<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef typename Array<T>::value_type value_type;
- typedef typename Array<T>::reference reference;
- typedef typename Array<T>::pointer_type pointer_type;
+ typedef typename Array<T>::value_type value_type;
+ typedef typename Array<T>::reference reference;
+ typedef typename Array<T>::pointer_type pointer_type;
typedef typename Array<T>::const_reference const_reference;
/// Allocation of a new array with a default value
CircularArray(UInt size, UInt nb_component = 1,
- const_reference value = value_type(), const ID & id = "") :
- Array<T>(size, nb_component, value, id),
- start_position(0),
- end_position(size-1) {
+ const_reference value = value_type(), const ID & id = "")
+ : Array<T>(size, nb_component, value, id), start_position(0),
+ end_position(size - 1) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
};
virtual ~CircularArray() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/**
- advance start and end position by one:
+ advance start and end position by one:
the first element is now at the end of the array
**/
inline void makeStep();
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
private:
-
/* ------------------------------------------------------------------------ */
/* Operators */
/* ------------------------------------------------------------------------ */
public:
inline reference operator()(UInt i, UInt j = 0);
inline const_reference operator()(UInt i, UInt j = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
- UInt size() const{ return this->size_; };
+ UInt size() const { return this->size_; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// indice of first element in this circular array
UInt start_position;
/// indice of last element in this circular array
UInt end_position;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "aka_circular_array_inline_impl.cc"
+#if defined(AKANTU_INCLUDE_INLINE_IMPL)
+#include "aka_circular_array_inline_impl.cc"
#endif
/// standard output stream operator
template <typename T>
-inline std::ostream & operator <<(std::ostream & stream, const CircularArray<T> & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const CircularArray<T> & _this) {
_this.printself(stream);
return stream;
}
-
-
} // akantu
-
-
#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
-
-
diff --git a/src/common/aka_circular_array_inline_impl.cc b/src/common/aka_circular_array_inline_impl.cc
index 1691e5a8d..8ebf880dc 100644
--- a/src/common/aka_circular_array_inline_impl.cc
+++ b/src/common/aka_circular_array_inline_impl.cc
@@ -1,84 +1,99 @@
/**
* @file aka_circular_array_inline_impl.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Nov 11 2011
* @date last modification: Sun Oct 19 2014
*
* @brief implementation of circular array
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* Inline Functions Array<T> */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-template<class T>
-inline typename CircularArray<T>::reference CircularArray<T>::operator()(UInt i, UInt j) {
+template <class T>
+inline typename CircularArray<T>::reference CircularArray<T>::
+operator()(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(end_position != start_position,
- "The array \"" << this->id << "\" is empty");
- AKANTU_DEBUG_ASSERT((i < (end_position - start_position + this->allocated_size) % this->allocated_size + 1)
- && (j < this->nb_component),
- "The value at position [" << i << "," << j
- << "] is out of range in array \"" << this->id << "\"");
- return this->values[((i+start_position)%this->allocated_size)*this->nb_component + j];
+ "The array \"" << this->id << "\" is empty");
+ AKANTU_DEBUG_ASSERT(
+ (i < (end_position - start_position + this->allocated_size) %
+ this->allocated_size +
+ 1) &&
+ (j < this->nb_component),
+ "The value at position [" << i << "," << j
+ << "] is out of range in array \"" << this->id
+ << "\"");
+ return this->values[((i + start_position) % this->allocated_size) *
+ this->nb_component +
+ j];
}
/* -------------------------------------------------------------------------- */
template <typename T>
-inline typename CircularArray<T>::const_reference CircularArray<T>::operator()(UInt i, UInt j) const {
+inline typename CircularArray<T>::const_reference CircularArray<T>::
+operator()(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(end_position != start_position,
- "The array \"" << this->id << "\" is empty");
- AKANTU_DEBUG_ASSERT((i < (end_position - start_position + this->allocated_size) % this->allocated_size + 1)
- && (j < this->nb_component),
- "The value at position [" << i << "," << j
- << "] is out of range in array \"" << this->id << "\"");
- return this->values[((i+start_position)%this->allocated_size)*this->nb_component + j];
+ "The array \"" << this->id << "\" is empty");
+ AKANTU_DEBUG_ASSERT(
+ (i < (end_position - start_position + this->allocated_size) %
+ this->allocated_size +
+ 1) &&
+ (j < this->nb_component),
+ "The value at position [" << i << "," << j
+ << "] is out of range in array \"" << this->id
+ << "\"");
+ return this->values[((i + start_position) % this->allocated_size) *
+ this->nb_component +
+ j];
}
/* -------------------------------------------------------------------------- */
-template <class T>
-inline void CircularArray<T>::makeStep() {
+template <class T> inline void CircularArray<T>::makeStep() {
AKANTU_DEBUG_IN();
- start_position = (start_position+1) % this->allocated_size;
- end_position = (end_position+1) % this->allocated_size;
+ start_position = (start_position + 1) % this->allocated_size;
+ end_position = (end_position + 1) % this->allocated_size;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T>
void CircularArray<T>::printself(std::ostream & stream, int indent) const {
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
- stream << space << "CircularArray<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
- stream << space << " + start_position : " << this->start_position << std::endl;
+ stream << space << "CircularArray<" << debug::demangle(typeid(T).name())
+ << "> [" << std::endl;
+ stream << space << " + start_position : " << this->start_position
+ << std::endl;
stream << space << " + end_position : " << this->end_position << std::endl;
- Array<T>::printself(stream, indent+1);
+ Array<T>::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
-
diff --git a/src/common/aka_common.cc b/src/common/aka_common.cc
index d10b593ad..4449190bc 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,154 +1,153 @@
/**
* @file aka_common.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Tue Jan 19 2016
*
* @brief Initialization of global variables
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "aka_random_generator.hh"
#include "aka_static_memory.hh"
#include "communicator.hh"
-#include "aka_random_generator.hh"
-#include "parser.hh"
#include "cppargparse.hh"
+#include "parser.hh"
#include "communication_tag.hh"
/* -------------------------------------------------------------------------- */
#include <ctime>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
void initialize(int & argc, char **& argv) {
AKANTU_DEBUG_IN();
initialize("", argc, argv);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void initialize(const std::string & input_file, int & argc, char **& argv) {
AKANTU_DEBUG_IN();
StaticMemory::getStaticMemory();
- Communicator & comm =
- Communicator::getStaticCommunicator(argc, argv);
+ Communicator & comm = Communicator::getStaticCommunicator(argc, argv);
Tag::setMaxTag(comm.getMaxTag());
debug::debugger.setParallelContext(comm.whoAmI(), comm.getNbProc());
debug::setDebugLevel(dblError);
static_argparser.setParallelContext(comm.whoAmI(), comm.getNbProc());
static_argparser.setExternalExitFunction(debug::exit);
static_argparser.addArgument("--aka_input_file", "Akantu's input file", 1,
cppargparse::_string, std::string());
static_argparser.addArgument(
"--aka_debug_level",
std::string("Akantu's overall debug level") +
std::string(" (0: error, 1: exceptions, 4: warnings, 5: info, ..., "
"100: dump") +
std::string(" more info on levels can be foind in aka_error.hh)"),
1, cppargparse::_integer, int(dblWarning));
static_argparser.addArgument(
"--aka_print_backtrace",
"Should Akantu print a backtrace in case of error", 0,
cppargparse::_boolean, false, true);
static_argparser.parse(argc, argv, cppargparse::_remove_parsed);
std::string infile = static_argparser["aka_input_file"];
if (infile == "")
infile = input_file;
debug::debugger.printBacktrace(static_argparser["aka_print_backtrace"]);
if ("" != infile) {
readInputFile(infile);
}
long int seed;
try {
seed = static_parser.getParameter("seed", _ppsc_current_scope);
} catch (debug::Exception &) {
seed = time(nullptr);
}
seed *= (comm.whoAmI() + 1);
RandomGenerator<UInt>::seed(seed);
int dbl_level = static_argparser["aka_debug_level"];
debug::setDebugLevel(DebugLevel(dbl_level));
AKANTU_DEBUG_INFO("Random seed set to " << seed);
std::atexit(finalize);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void finalize() {
AKANTU_DEBUG_IN();
// if (StaticCommunicator::isInstantiated()) {
// StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
// delete &comm;
// }
if (StaticMemory::isInstantiated()) {
delete &(StaticMemory::getStaticMemory());
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void readInputFile(const std::string & input_file) {
static_parser.parse(input_file);
}
/* -------------------------------------------------------------------------- */
cppargparse::ArgumentParser & getStaticArgumentParser() {
return static_argparser;
}
/* -------------------------------------------------------------------------- */
Parser & getStaticParser() { return static_parser; }
/* -------------------------------------------------------------------------- */
const ParserSection & getUserParser() {
return *(static_parser.getSubSections(ParserType::_user).first);
}
std::unique_ptr<Communicator> Communicator::static_communicator;
} // akantu
diff --git a/src/common/aka_common_inline_impl.cc b/src/common/aka_common_inline_impl.cc
index acab4e2b1..a16615d07 100644
--- a/src/common/aka_common_inline_impl.cc
+++ b/src/common/aka_common_inline_impl.cc
@@ -1,459 +1,459 @@
/**
* @file aka_common_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 15 2015
*
* @brief inline implementations of common akantu type descriptions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* All common things to be included in the projects files
*
*/
/* -------------------------------------------------------------------------- */
+#include "aka_common.hh"
#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>
-#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_COMMON_INLINE_IMPL_CC__
#define __AKANTU_AKA_COMMON_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
/// standard output stream operator for GhostType
inline std::ostream & operator<<(std::ostream & stream, GhostType type) {
switch (type) {
case _not_ghost:
stream << "not_ghost";
break;
case _ghost:
stream << "ghost";
break;
case _casper:
stream << "Casper the friendly ghost";
break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for TimeStepSolverType
inline std::ostream & operator<<(std::ostream & stream,
const TimeStepSolverType & type) {
switch (type) {
case _tsst_static:
stream << "static";
break;
case _tsst_dynamic:
stream << "dynamic";
break;
case _tsst_dynamic_lumped:
stream << "dynamic_lumped";
break;
case _tsst_not_defined:
stream << "not defined time step solver";
break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard input stream operator for TimeStepSolverType
inline std::istream & operator>>(std::istream & stream,
TimeStepSolverType & type) {
std::string str;
stream >> str;
if (str == "static")
type = _tsst_static;
else if (str == "dynamic")
type = _tsst_dynamic;
else if (str == "dynamic_lumped")
type = _tsst_dynamic_lumped;
else {
- AKANTU_ERROR("The type "
- << str << " is not a recognized TimeStepSolverType");
+ AKANTU_ERROR("The type " << str
+ << " is not a recognized TimeStepSolverType");
stream.setstate(std::ios::failbit);
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for NonLinearSolverType
inline std::ostream & operator<<(std::ostream & stream,
const NonLinearSolverType & type) {
switch (type) {
case _nls_linear:
stream << "linear";
break;
case _nls_newton_raphson:
stream << "newton_raphson";
break;
case _nls_newton_raphson_modified:
stream << "newton_raphson_modified";
break;
case _nls_lumped:
stream << "lumped";
break;
case _nls_auto:
stream << "auto";
break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard input stream operator for NonLinearSolverType
inline std::istream & operator>>(std::istream & stream,
NonLinearSolverType & type) {
std::string str;
stream >> str;
if (str == "linear")
type = _nls_linear;
else if (str == "newton_raphson")
type = _nls_newton_raphson;
else if (str == "newton_raphson_modified")
type = _nls_newton_raphson_modified;
else if (str == "lumped")
type = _nls_lumped;
else if (str == "auto")
type = _nls_auto;
else
type = _nls_auto;
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for IntegrationSchemeType
inline std::ostream & operator<<(std::ostream & stream,
const IntegrationSchemeType & type) {
switch (type) {
case _ist_pseudo_time:
stream << "pseudo_time";
break;
case _ist_forward_euler:
stream << "forward_euler";
break;
case _ist_trapezoidal_rule_1:
stream << "trapezoidal_rule_1";
break;
case _ist_backward_euler:
stream << "backward_euler";
break;
case _ist_central_difference:
stream << "central_difference";
break;
case _ist_fox_goodwin:
stream << "fox_goodwin";
break;
case _ist_trapezoidal_rule_2:
stream << "trapezoidal_rule_2";
break;
case _ist_linear_acceleration:
stream << "linear_acceleration";
break;
case _ist_newmark_beta:
stream << "newmark_beta";
break;
case _ist_generalized_trapezoidal:
stream << "generalized_trapezoidal";
break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard input stream operator for IntegrationSchemeType
inline std::istream & operator>>(std::istream & stream,
IntegrationSchemeType & type) {
std::string str;
stream >> str;
if (str == "pseudo_time")
type = _ist_pseudo_time;
else if (str == "forward_euler")
type = _ist_forward_euler;
else if (str == "trapezoidal_rule_1")
type = _ist_trapezoidal_rule_1;
else if (str == "backward_euler")
type = _ist_backward_euler;
else if (str == "central_difference")
type = _ist_central_difference;
else if (str == "fox_goodwin")
type = _ist_fox_goodwin;
else if (str == "trapezoidal_rule_2")
type = _ist_trapezoidal_rule_2;
else if (str == "linear_acceleration")
type = _ist_linear_acceleration;
else if (str == "newmark_beta")
type = _ist_newmark_beta;
else if (str == "generalized_trapezoidal")
type = _ist_generalized_trapezoidal;
else {
- AKANTU_ERROR("The type "
- << str << " is not a recognized IntegrationSchemeType");
+ AKANTU_ERROR("The type " << str
+ << " is not a recognized IntegrationSchemeType");
stream.setstate(std::ios::failbit);
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for SynchronizationTag
inline std::ostream & operator<<(std::ostream & stream,
SynchronizationTag type) {
switch (type) {
case _gst_whatever:
stream << "_gst_whatever";
break;
case _gst_update:
stream << "_gst_update";
break;
case _gst_size:
stream << "_gst_size";
break;
case _gst_smm_mass:
stream << "_gst_smm_mass";
break;
case _gst_smm_for_gradu:
stream << "_gst_smm_for_gradu";
break;
case _gst_smm_boundary:
stream << "_gst_smm_boundary";
break;
case _gst_smm_uv:
stream << "_gst_smm_uv";
break;
case _gst_smm_res:
stream << "_gst_smm_res";
break;
case _gst_smm_init_mat:
stream << "_gst_smm_init_mat";
break;
case _gst_smm_stress:
stream << "_gst_smm_stress";
break;
case _gst_smmc_facets:
stream << "_gst_smmc_facets";
break;
case _gst_smmc_facets_conn:
stream << "_gst_smmc_facets_conn";
break;
case _gst_smmc_facets_stress:
stream << "_gst_smmc_facets_stress";
break;
case _gst_smmc_damage:
stream << "_gst_smmc_damage";
break;
case _gst_giu_global_conn:
stream << "_gst_giu_global_conn";
break;
case _gst_ce_groups:
stream << "_gst_ce_groups";
break;
case _gst_gm_clusters:
stream << "_gst_gm_clusters";
break;
case _gst_htm_capacity:
stream << "_gst_htm_capacity";
break;
case _gst_htm_temperature:
stream << "_gst_htm_temperature";
break;
case _gst_htm_gradient_temperature:
stream << "_gst_htm_gradient_temperature";
break;
case _gst_htm_phi:
stream << "_gst_htm_phi";
break;
case _gst_htm_gradient_phi:
stream << "_gst_htm_gradient_phi";
break;
case _gst_mnl_for_average:
stream << "_gst_mnl_for_average";
break;
case _gst_mnl_weight:
stream << "_gst_mnl_weight";
break;
case _gst_nh_criterion:
stream << "_gst_nh_criterion";
break;
case _gst_test:
stream << "_gst_test";
break;
case _gst_user_1:
stream << "_gst_user_1";
break;
case _gst_user_2:
stream << "_gst_user_2";
break;
case _gst_material_id:
stream << "_gst_material_id";
break;
case _gst_for_dump:
stream << "_gst_for_dump";
break;
case _gst_cf_nodal:
stream << "_gst_cf_nodal";
break;
case _gst_cf_incr:
stream << "_gst_cf_incr";
break;
case _gst_solver_solution:
stream << "_gst_solver_solution";
break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator for SolveConvergenceCriteria
inline std::ostream & operator<<(std::ostream & stream,
const SolveConvergenceCriteria & criteria) {
switch (criteria) {
case _scc_residual:
stream << "_scc_residual";
break;
case _scc_solution:
stream << "_scc_solution";
break;
case _scc_residual_mass_wgh:
stream << "_scc_residual_mass_wgh";
break;
}
return stream;
}
inline std::istream & operator>>(std::istream & stream,
SolveConvergenceCriteria & criteria) {
std::string str;
stream >> str;
if (str == "residual")
criteria = _scc_residual;
else if (str == "solution")
criteria = _scc_solution;
else if (str == "residual_mass_wgh")
criteria = _scc_residual_mass_wgh;
else {
stream.setstate(std::ios::failbit);
}
return stream;
}
/* -------------------------------------------------------------------------- */
inline std::string to_lower(const std::string & str) {
std::string lstr = str;
std::transform(lstr.begin(), lstr.end(), lstr.begin(), (int (*)(int))tolower);
return lstr;
}
/* -------------------------------------------------------------------------- */
inline std::string trim(const std::string & to_trim) {
std::string trimed = to_trim;
// left trim
trimed.erase(trimed.begin(),
std::find_if(trimed.begin(), trimed.end(),
std::not1(std::ptr_fun<int, int>(isspace))));
// right trim
trimed.erase(std::find_if(trimed.rbegin(), trimed.rend(),
std::not1(std::ptr_fun<int, int>(isspace)))
.base(),
trimed.end());
return trimed;
}
} // akantu
#include <cmath>
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename T> std::string printMemorySize(UInt size) {
Real real_size = size * sizeof(T);
UInt mult = 0;
if (real_size != 0)
mult = (std::log(real_size) / std::log(2)) / 10;
std::stringstream sstr;
real_size /= Real(1 << (10 * mult));
sstr << std::setprecision(2) << std::fixed << real_size;
std::string size_prefix;
switch (mult) {
case 0:
sstr << "";
break;
case 1:
sstr << "Ki";
break;
case 2:
sstr << "Mi";
break;
case 3:
sstr << "Gi";
break; // I started on this type of machines
// (32bit computers) (Nicolas)
case 4:
sstr << "Ti";
break;
case 5:
sstr << "Pi";
break;
case 6:
sstr << "Ei";
break; // theoritical limit of RAM of the current
// computers in 2014 (64bit computers) (Nicolas)
case 7:
sstr << "Zi";
break;
case 8:
sstr << "Yi";
break;
default:
AKANTU_ERROR(
"The programmer in 2014 didn't thought so far (even wikipedia does not "
"go further)."
<< " You have at least 1024 times more than a yobibit of RAM!!!"
<< " Just add the prefix corresponding in this switch case.");
}
sstr << "Byte";
return sstr.str();
}
} // akantu
#endif /* __AKANTU_AKA_COMMON_INLINE_IMPL_CC__ */
diff --git a/src/common/aka_error.cc b/src/common/aka_error.cc
index f766d3624..bbe935cb2 100644
--- a/src/common/aka_error.cc
+++ b/src/common/aka_error.cc
@@ -1,356 +1,360 @@
/**
* @file aka_error.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Sep 06 2010
* @date last modification: Tue Jan 19 2016
*
* @brief handling of errors
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_error.hh"
#include "aka_common.hh"
#include "aka_config.hh"
/* -------------------------------------------------------------------------- */
#include <csignal>
#include <iostream>
#if (defined(READLINK_COMMAND) || defined(ADDR2LINE_COMMAND)) && \
(not defined(_WIN32))
#include <execinfo.h>
#include <sys/wait.h>
#endif
#include <cmath>
#include <cstring>
#include <cxxabi.h>
#include <fstream>
#include <iomanip>
#include <map>
#include <sys/types.h>
#include <unistd.h>
#if defined(AKANTU_CORE_CXX11)
#include <chrono>
#elif defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef AKANTU_USE_MPI
#include <mpi.h>
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace debug {
static void printBacktraceAndExit(int) { std::terminate(); }
/* ------------------------------------------------------------------------ */
void initSignalHandler() { std::signal(SIGSEGV, &printBacktraceAndExit); }
/* ------------------------------------------------------------------------ */
std::string demangle(const char * symbol) {
int status;
std::string result;
char * demangled_name;
if ((demangled_name = abi::__cxa_demangle(symbol, nullptr, nullptr,
&status)) != nullptr) {
result = demangled_name;
free(demangled_name);
} else {
result = symbol;
}
return result;
}
/* ------------------------------------------------------------------------ */
#if (defined(READLINK_COMMAND) || defined(ADDR2LINK_COMMAND)) && \
(not defined(_WIN32))
std::string exec(const std::string & cmd) {
FILE * pipe = popen(cmd.c_str(), "r");
if (!pipe)
return "";
char buffer[1024];
std::string result = "";
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != nullptr)
result += buffer;
}
result = result.substr(0, result.size() - 1);
pclose(pipe);
return result;
}
#endif
/* ------------------------------------------------------------------------ */
void printBacktrace(__attribute__((unused)) int sig) {
AKANTU_DEBUG_INFO("Caught signal " << sig << "!");
#if not defined(_WIN32)
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
std::string me = "";
char buf[1024];
/* The manpage says it won't null terminate. Let's zero the buffer. */
memset(buf, 0, sizeof(buf));
/* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
if (readlink("/proc/self/exe", buf, sizeof(buf) - 1))
me = std::string(buf);
std::ifstream inmaps;
inmaps.open("/proc/self/maps");
std::map<std::string, size_t> addr_map;
std::string line;
while (inmaps.good()) {
std::getline(inmaps, line);
std::stringstream sstr(line);
size_t first = line.find('-');
std::stringstream sstra(line.substr(0, first));
size_t addr;
sstra >> std::hex >> addr;
std::string lib;
- sstr >> lib; sstr >> lib;
- sstr >> lib; sstr >> lib;
- sstr >> lib; sstr >> lib;
+ sstr >> lib;
+ sstr >> lib;
+ sstr >> lib;
+ sstr >> lib;
+ sstr >> lib;
+ sstr >> lib;
if (lib != "" && addr_map.find(lib) == addr_map.end()) {
addr_map[lib] = addr;
}
}
if (me != "")
addr_map[me] = 0;
#endif
/// \todo for windows this part could be coded using CaptureStackBackTrace
/// and SymFromAddr
const size_t max_depth = 100;
size_t stack_depth;
void * stack_addrs[max_depth];
char ** stack_strings;
size_t i;
stack_depth = backtrace(stack_addrs, max_depth);
stack_strings = backtrace_symbols(stack_addrs, stack_depth);
std::cerr << "BACKTRACE : " << stack_depth << " stack frames."
<< std::endl;
auto w = size_t(std::floor(log(double(stack_depth)) / std::log(10.)) + 1);
/// -1 to remove the call to the printBacktrace function
for (i = 1; i < stack_depth; i++) {
std::cerr << std::dec << " [" << std::setw(w) << i << "] ";
std::string bt_line(stack_strings[i]);
size_t first, second;
if ((first = bt_line.find('(')) != std::string::npos &&
(second = bt_line.find('+')) != std::string::npos) {
std::string location = bt_line.substr(0, first);
#if defined(READLINK_COMMAND)
- std::string location_cmd = std::string(BOOST_PP_STRINGIZE(READLINK_COMMAND)) +
- std::string(" -f ") + location;
+ std::string location_cmd =
+ std::string(BOOST_PP_STRINGIZE(READLINK_COMMAND)) +
+ std::string(" -f ") + location;
location = exec(location_cmd);
#endif
std::string call =
demangle(bt_line.substr(first + 1, second - first - 1).c_str());
size_t f = bt_line.find('[');
size_t s = bt_line.find(']');
std::string address = bt_line.substr(f + 1, s - f - 1);
std::stringstream sstra(address);
size_t addr;
sstra >> std::hex >> addr;
std::cerr << location << " [" << call << "]";
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
auto it = addr_map.find(location);
if (it != addr_map.end()) {
std::stringstream syscom;
syscom << BOOST_PP_STRINGIZE(ADDR2LINE_COMMAND) << " 0x" << std::hex
<< (addr - it->second) << " -i -e " << location;
std::string line = exec(syscom.str());
std::cerr << " (" << line << ")" << std::endl;
} else {
#endif
std::cerr << " (0x" << std::hex << addr << ")" << std::endl;
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
}
#endif
} else {
std::cerr << bt_line << std::endl;
}
}
free(stack_strings);
std::cerr << "END BACKTRACE" << std::endl;
#endif
}
/* ------------------------------------------------------------------------ */
namespace {
void terminate_handler() {
auto eptr = std::current_exception();
auto t = abi::__cxa_current_exception_type();
auto name = t ? demangle(t->name()) : std::string("unknown");
try {
if (eptr)
std::rethrow_exception(eptr);
else
std::cerr << "!! Execution terminated for unknown reasons !!"
<< std::endl;
} catch (std::exception & e) {
std::cerr << "!! Uncaught exception of type " << name
<< " !!\nwhat(): \"" << e.what() << "\"" << std::endl;
} catch (...) {
std::cerr << "!! Something strange of type \"" << name
<< "\" was thrown.... !!" << std::endl;
}
if (debugger.printBacktrace())
printBacktrace(15);
}
} // namespace
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
Debugger::Debugger() {
cout = &std::cerr;
level = dblWarning;
parallel_context = "";
file_open = false;
print_backtrace = false;
initSignalHandler();
std::set_terminate(terminate_handler);
}
/* ------------------------------------------------------------------------ */
Debugger::~Debugger() {
if (file_open) {
dynamic_cast<std::ofstream *>(cout)->close();
delete cout;
}
}
/* ------------------------------------------------------------------------ */
void Debugger::exit(int status) {
if (status != 0)
std::terminate();
std::exit(0);
}
/*------------------------------------------------------------------------- */
void Debugger::throwException(const std::string & info,
const std::string & file, unsigned int line,
__attribute__((unused)) bool silent,
__attribute__((unused))
const std::string & location) const
noexcept(false) {
#if !defined(AKANTU_NDEBUG)
if (!silent) {
printMessage("###", dblWarning, info + location);
}
#endif
debug::Exception ex(info, file, line);
throw ex;
}
/* ------------------------------------------------------------------------ */
void Debugger::printMessage(const std::string & prefix,
const DebugLevel & level,
const std::string & info) const {
if (this->level >= level) {
#if defined(AKANTU_CORE_CXX11)
double timestamp =
std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(
std::chrono::system_clock::now().time_since_epoch())
.count();
#elif defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
struct timeval time;
gettimeofday(&time, NULL);
double timestamp = time.tv_sec * 1e6 + time.tv_usec; /*in us*/
#else
struct timespec time;
clock_gettime(CLOCK_REALTIME_COARSE, &time);
double timestamp = time.tv_sec * 1e6 + time.tv_nsec * 1e-3; /*in us*/
#endif
*(cout) << parallel_context << "{" << (size_t)timestamp << "} " << prefix
<< " " << info << std::endl;
}
}
/* ------------------------------------------------------------------------ */
void Debugger::setDebugLevel(const DebugLevel & level) {
this->level = level;
}
/* ------------------------------------------------------------------------ */
const DebugLevel & Debugger::getDebugLevel() const { return this->level; }
/* ------------------------------------------------------------------------ */
void Debugger::setLogFile(const std::string & filename) {
if (file_open) {
dynamic_cast<std::ofstream *>(cout)->close();
delete cout;
}
auto * fileout = new std::ofstream(filename.c_str());
file_open = true;
cout = fileout;
}
std::ostream & Debugger::getOutputStream() { return *cout; }
/* ------------------------------------------------------------------------ */
void Debugger::setParallelContext(int rank, int size) {
std::stringstream sstr;
UInt pad = std::ceil(std::log10(size));
sstr << "<" << getpid() << ">[R" << std::setfill(' ') << std::right
<< std::setw(pad) << rank << "|S" << size << "] ";
parallel_context = sstr.str();
}
void setDebugLevel(const DebugLevel & level) {
debugger.setDebugLevel(level);
}
const DebugLevel & getDebugLevel() { return debugger.getDebugLevel(); }
/* --------------------------------------------------------------------------
*/
void exit(int status) { debugger.exit(status); }
} // namespace debug
} // namespace akantu
diff --git a/src/common/aka_error.hh b/src/common/aka_error.hh
index 18ed1a070..d06b8bb97 100644
--- a/src/common/aka_error.hh
+++ b/src/common/aka_error.hh
@@ -1,339 +1,339 @@
/**
* @file aka_error.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Mon Jul 13 2015
*
* @brief error management and internal exceptions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <sstream>
#include <typeinfo>
#include <utility>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ERROR_HH__
#define __AKANTU_ERROR_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
enum DebugLevel {
dbl0 = 0,
dblError = 0,
dblAssert = 0,
dbl1 = 1,
dblException = 1,
dblCritical = 1,
dbl2 = 2,
dblMajor = 2,
dbl3 = 3,
dblCall = 3,
dblSecondary = 3,
dblHead = 3,
dbl4 = 4,
dblWarning = 4,
dbl5 = 5,
dblInfo = 5,
dbl6 = 6,
dblIn = 6,
dblOut = 6,
dbl7 = 7,
dbl8 = 8,
dblTrace = 8,
dbl9 = 9,
dblAccessory = 9,
dbl10 = 10,
dblDebug = 42,
dbl100 = 100,
dblDump = 100,
dblTest = 1337
};
/* -------------------------------------------------------------------------- */
#define AKANTU_LOCATION \
"(" << __func__ << "(): " << __FILE__ << ":" << __LINE__ << ")"
/* -------------------------------------------------------------------------- */
namespace debug {
void setDebugLevel(const DebugLevel & level);
const DebugLevel & getDebugLevel();
void initSignalHandler();
std::string demangle(const char * symbol);
#ifndef SWIG
std::string exec(const std::string & cmd);
#endif
void printBacktrace(int sig);
void exit(int status) __attribute__((noreturn));
/* ------------------------------------------------------------------------ */
/// exception class that can be thrown by akantu
class Exception : public std::exception {
/* ---------------------------------------------------------------------- */
/* Constructors/Destructors */
/* ---------------------------------------------------------------------- */
protected:
explicit Exception(std::string info = "")
: _info(std::move(info)), _file("") {}
public:
//! full constructor
Exception(std::string info, std::string file, unsigned int line)
: _info(std::move(info)), _file(std::move(file)), _line(line) {}
//! destructor
~Exception() noexcept override = default;
/* ---------------------------------------------------------------------- */
/* Methods */
/* ---------------------------------------------------------------------- */
public:
const char * what() const noexcept override { return _info.c_str(); }
virtual const std::string info() const noexcept {
std::stringstream stream;
stream << debug::demangle(typeid(*this).name()) << " : " << _info << " ["
<< _file << ":" << _line << "]";
return stream.str();
}
public:
void setInfo(const std::string & info) { _info = info; }
void setFile(const std::string & file) { _file = file; }
void setLine(unsigned int line) { _line = line; }
/* ---------------------------------------------------------------------- */
/* Class Members */
/* ---------------------------------------------------------------------- */
protected:
/// exception description and additionals
std::string _info;
private:
/// file it is thrown from
std::string _file;
/// ligne it is thrown from
unsigned int _line{0};
};
class CriticalError : public Exception {};
class AssertException : public Exception {};
class NotImplementedException : public Exception {};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const Exception & _this) {
stream << _this.what();
return stream;
}
/* --------------------------------------------------------------------------
*/
class Debugger {
public:
Debugger();
virtual ~Debugger();
Debugger(const Debugger &) = default;
Debugger & operator=(const Debugger &) = default;
void exit(int status) __attribute__((noreturn));
void throwException(const std::string & info, const std::string & file,
unsigned int line, bool, const std::string &) const
noexcept(false) __attribute__((noreturn));
/*----------------------------------------------------------------------- */
template <class Except>
void throwCustomException(const Except & ex, const std::string & info,
const std::string & file, unsigned int line) const
noexcept(false) __attribute__((noreturn));
/*----------------------------------------------------------------------- */
template <class Except>
void throwCustomException(const Except & ex, const std::string & file,
unsigned int line) const noexcept(false)
__attribute__((noreturn));
void printMessage(const std::string & prefix, const DebugLevel & level,
const std::string & info) const;
void setOutStream(std::ostream & out) { cout = &out; }
std::ostream & getOutStream() { return *cout; }
public:
void setParallelContext(int rank, int size);
void setDebugLevel(const DebugLevel & level);
const DebugLevel & getDebugLevel() const;
void setLogFile(const std::string & filename);
std::ostream & getOutputStream();
inline bool testLevel(const DebugLevel & level) const {
return (this->level >= (level));
}
void printBacktrace(bool on_off) { this->print_backtrace = on_off; }
bool printBacktrace() { return this->print_backtrace; }
private:
std::string parallel_context;
std::ostream * cout;
bool file_open;
DebugLevel level;
bool print_backtrace;
};
extern Debugger debugger;
} // namespace debug
/* -------------------------------------------------------------------------- */
#define AKANTU_STRINGSTREAM_IN(_str, _sstr) \
; \
do { \
std::stringstream _dbg_s_info; \
_dbg_s_info << _sstr; \
_str = _dbg_s_info.str(); \
} while (false)
/* -------------------------------------------------------------------------- */
#define AKANTU_EXCEPTION(info) AKANTU_EXCEPTION_(info, false)
#define AKANTU_SILENT_EXCEPTION(info) AKANTU_EXCEPTION_(info, true)
#define AKANTU_EXCEPTION_(info, silent) \
do { \
std::stringstream _dbg_str; \
_dbg_str << info; \
std::stringstream _dbg_loc; \
_dbg_loc << AKANTU_LOCATION; \
::akantu::debug::debugger.throwException( \
_dbg_str.str(), __FILE__, __LINE__, silent, _dbg_loc.str()); \
} while (false)
#define AKANTU_CUSTOM_EXCEPTION_INFO(ex, info) \
do { \
std::stringstream _dbg_str; \
_dbg_str << info; \
::akantu::debug::debugger.throwCustomException(ex, _dbg_str.str(), \
__FILE__, __LINE__); \
} while (false)
#define AKANTU_CUSTOM_EXCEPTION(ex) \
do { \
::akantu::debug::debugger.throwCustomException(ex, __FILE__, __LINE__); \
} while (false)
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_NDEBUG
#define AKANTU_DEBUG_TEST(level) (false)
#define AKANTU_DEBUG_LEVEL_IS_TEST() \
(::akantu::debug::debugger.testLevel(dblTest))
#define AKANTU_DEBUG(level, info)
#define AKANTU_DEBUG_(pref, level, info)
#define AKANTU_DEBUG_IN()
#define AKANTU_DEBUG_OUT()
#define AKANTU_DEBUG_INFO(info)
#define AKANTU_DEBUG_WARNING(info)
#define AKANTU_DEBUG_TRACE(info)
#define AKANTU_DEBUG_ASSERT(test, info)
-#define AKANTU_ERROR(info) \
+#define AKANTU_ERROR(info) \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::CriticalError(), info)
/* -------------------------------------------------------------------------- */
#else
#define AKANTU_DEBUG(level, info) AKANTU_DEBUG_(" ", level, info)
#define AKANTU_DEBUG_(pref, level, info) \
do { \
std::string _dbg_str; \
AKANTU_STRINGSTREAM_IN(_dbg_str, info << " " << AKANTU_LOCATION); \
::akantu::debug::debugger.printMessage(pref, level, _dbg_str); \
} while (false)
#define AKANTU_DEBUG_TEST(level) (::akantu::debug::debugger.testLevel(level))
#define AKANTU_DEBUG_LEVEL_IS_TEST() \
(::akantu::debug::debugger.testLevel(dblTest))
#define AKANTU_DEBUG_IN() \
AKANTU_DEBUG_("==>", ::akantu::dblIn, __func__ << "()")
#define AKANTU_DEBUG_OUT() \
AKANTU_DEBUG_("<==", ::akantu::dblOut, __func__ << "()")
#define AKANTU_DEBUG_INFO(info) AKANTU_DEBUG_("---", ::akantu::dblInfo, info)
#define AKANTU_DEBUG_WARNING(info) \
AKANTU_DEBUG_("/!\\", ::akantu::dblWarning, info)
#define AKANTU_DEBUG_TRACE(info) AKANTU_DEBUG_(">>>", ::akantu::dblTrace, info)
#define AKANTU_DEBUG_ASSERT(test, info) \
do { \
if (not(test)) \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::AssertException(), \
"assert [" << #test << "] " << info); \
} while (false)
-#define AKANTU_ERROR(info) \
+#define AKANTU_ERROR(info) \
do { \
AKANTU_DEBUG_("!!! ", ::akantu::dblError, info); \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::CriticalError(), info); \
} while (false)
#endif // AKANTU_NDEBUG
-#define AKANTU_TO_IMPLEMENT() \
+#define AKANTU_TO_IMPLEMENT() \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::NotImplementedException(), \
__func__ << " : not implemented yet !")
/* -------------------------------------------------------------------------- */
namespace debug {
/* ------------------------------------------------------------------------ */
template <class Except>
void Debugger::throwCustomException(const Except & ex,
const std::string & info,
const std::string & file,
unsigned int line) const noexcept(false) {
auto & nc_ex = const_cast<Except &>(ex);
nc_ex.setInfo(info);
nc_ex.setFile(file);
nc_ex.setLine(line);
throw ex;
}
/* ------------------------------------------------------------------------ */
template <class Except>
void Debugger::throwCustomException(const Except & ex,
const std::string & file,
unsigned int line) const noexcept(false) {
auto & nc_ex = const_cast<Except &>(ex);
nc_ex.setFile(file);
nc_ex.setLine(line);
throw ex;
}
} // namespace debug
} // namespace akantu
#endif /* __AKANTU_ERROR_HH__ */
diff --git a/src/common/aka_factory.hh b/src/common/aka_factory.hh
index 1b6afdfe6..64bd867f6 100644
--- a/src/common/aka_factory.hh
+++ b/src/common/aka_factory.hh
@@ -1,79 +1,83 @@
/**
* @file aka_factory.hh
*
* @author Nicolas Richart
*
* @date creation Thu Jul 06 2017
*
* @brief This is a generic factory
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
+#include <functional>
#include <map>
#include <memory>
-#include <functional>
#include <string>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_FACTORY_HH__
#define __AKANTU_AKA_FACTORY_HH__
namespace akantu {
template <class Base, class T = ID, class... Args> class Factory {
using allocator_t = std::function<std::unique_ptr<Base>(Args...)>;
+
private:
Factory() = default;
+
public:
Factory(const Factory &) = delete;
Factory & operator=(const Factory &) = delete;
static Factory & getInstance() {
static Factory instance;
return instance;
}
/* ------------------------------------------------------------------------ */
bool registerAllocator(const T & id, const allocator_t & allocator) {
if (allocators.find(id) != allocators.end())
AKANTU_EXCEPTION("The id " << id << " is already registered in the "
- << debug::demangle(typeid(Base).name()) << " factory");
+ << debug::demangle(typeid(Base).name())
+ << " factory");
allocators[id] = allocator;
return true;
}
- template<typename... AArgs>
- std::unique_ptr<Base> allocate(const T & id, AArgs&& ... args) const {
+ template <typename... AArgs>
+ std::unique_ptr<Base> allocate(const T & id, AArgs &&... args) const {
if (allocators.find(id) == allocators.end())
AKANTU_EXCEPTION("The id " << id << " is not registered in the "
<< debug::demangle(typeid(Base).name())
<< " factory.");
- return std::forward<std::unique_ptr<Base>>(allocators.at(id)(std::forward<AArgs>(args)...));
+ return std::forward<std::unique_ptr<Base>>(
+ allocators.at(id)(std::forward<AArgs>(args)...));
}
private:
std::map<T, allocator_t> allocators;
};
} // namespace akantu
#endif /* __AKANTU_AKA_FACTORY_HH__ */
diff --git a/src/common/aka_grid_dynamic.hh b/src/common/aka_grid_dynamic.hh
index db86a0bdb..f43007915 100644
--- a/src/common/aka_grid_dynamic.hh
+++ b/src/common/aka_grid_dynamic.hh
@@ -1,512 +1,512 @@
/**
* @file aka_grid_dynamic.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Sat Sep 26 2015
*
* @brief Grid that is auto balanced
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "aka_common.hh"
#include "aka_types.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_GRID_DYNAMIC_HH__
#define __AKANTU_AKA_GRID_DYNAMIC_HH__
namespace akantu {
class Mesh;
template <typename T> class SpatialGrid {
public:
explicit SpatialGrid(UInt dimension)
: dimension(dimension), spacing(dimension), center(dimension),
lower(dimension), upper(dimension), empty_cell() {}
SpatialGrid(UInt dimension, const Vector<Real> & spacing,
const Vector<Real> & center)
: dimension(dimension), spacing(spacing), center(center),
lower(dimension), upper(dimension), empty_cell() {
for (UInt i = 0; i < dimension; ++i) {
lower(i) = std::numeric_limits<Real>::max();
upper(i) = -std::numeric_limits<Real>::max();
}
}
virtual ~SpatialGrid() = default;
class neighbor_cells_iterator;
class cells_iterator;
class CellID {
public:
CellID() : ids() {}
explicit CellID(UInt dimention) : ids(dimention) {}
void setID(UInt dir, Int id) { ids(dir) = id; }
Int getID(UInt dir) const { return ids(dir); }
bool operator<(const CellID & id) const {
return std::lexicographical_compare(
ids.storage(), ids.storage() + ids.size(), id.ids.storage(),
id.ids.storage() + id.ids.size());
}
bool operator==(const CellID & id) const {
return std::equal(ids.storage(), ids.storage() + ids.size(),
id.ids.storage());
}
bool operator!=(const CellID & id) const { return !(operator==(id)); }
class neighbor_cells_iterator
: private std::iterator<std::forward_iterator_tag, UInt> {
public:
neighbor_cells_iterator(const CellID & cell_id, bool end)
: cell_id(cell_id), position(cell_id.ids.size(), end ? 1 : -1) {
this->updateIt();
if (end)
this->it++;
}
neighbor_cells_iterator & operator++() {
UInt i = 0;
for (; i < position.size() && position(i) == 1; ++i)
;
if (i == position.size()) {
++it;
return *this;
}
for (UInt j = 0; j < i; ++j)
position(j) = -1;
position(i)++;
updateIt();
return *this;
}
neighbor_cells_iterator operator++(int) {
neighbor_cells_iterator tmp(*this);
operator++();
return tmp;
};
bool operator==(const neighbor_cells_iterator & rhs) const {
return cell_id == rhs.cell_id && it == rhs.it;
};
bool operator!=(const neighbor_cells_iterator & rhs) const {
return !operator==(rhs);
};
CellID operator*() const {
CellID cur_cell_id(cell_id);
cur_cell_id.ids += position;
return cur_cell_id;
};
private:
void updateIt() {
it = 0;
for (UInt i = 0; i < position.size(); ++i)
it = it * 3 + (position(i) + 1);
}
private:
/// central cell id
const CellID & cell_id;
// number representing the current neighbor in base 3;
UInt it;
// current cell shift
Vector<Int> position;
};
class Neighbors {
public:
explicit Neighbors(const CellID & cell_id) : cell_id(cell_id) {}
decltype(auto) begin() { return neighbor_cells_iterator(cell_id, false); }
decltype(auto) end() { return neighbor_cells_iterator(cell_id, true); }
private:
const CellID & cell_id;
};
decltype(auto) neighbors() { return Neighbors(*this); }
private:
friend class cells_iterator;
Vector<Int> ids;
};
/* ------------------------------------------------------------------------ */
class Cell {
public:
using iterator = typename std::vector<T>::iterator;
using const_iterator = typename std::vector<T>::const_iterator;
Cell() : id(), data() {}
explicit Cell(const CellID & cell_id) : id(cell_id), data() {}
bool operator==(const Cell & cell) const { return id == cell.id; }
bool operator!=(const Cell & cell) const { return id != cell.id; }
Cell & add(const T & d) {
data.push_back(d);
return *this;
}
iterator begin() { return data.begin(); }
const_iterator begin() const { return data.begin(); }
iterator end() { return data.end(); }
const_iterator end() const { return data.end(); }
private:
CellID id;
std::vector<T> data;
};
private:
using cells_container = std::map<CellID, Cell>;
public:
const Cell & getCell(const CellID & cell_id) const {
auto it = cells.find(cell_id);
if (it != cells.end())
return it->second;
return empty_cell;
}
decltype(auto) beginCell(const CellID & cell_id) {
auto it = cells.find(cell_id);
if (it != cells.end())
return it->second.begin();
return empty_cell.begin();
}
decltype(auto) endCell(const CellID & cell_id) {
auto it = cells.find(cell_id);
if (it != cells.end())
return it->second.end();
return empty_cell.end();
}
decltype(auto) beginCell(const CellID & cell_id) const {
auto it = cells.find(cell_id);
if (it != cells.end())
return it->second.begin();
return empty_cell.begin();
}
decltype(auto) endCell(const CellID & cell_id) const {
auto it = cells.find(cell_id);
if (it != cells.end())
return it->second.end();
return empty_cell.end();
}
/* ------------------------------------------------------------------------ */
class cells_iterator
: private std::iterator<std::forward_iterator_tag, CellID> {
public:
explicit cells_iterator(typename std::map<CellID, Cell>::const_iterator it)
: it(it) {}
cells_iterator & operator++() {
this->it++;
return *this;
}
cells_iterator operator++(int) {
cells_iterator tmp(*this);
operator++();
return tmp;
};
bool operator==(const cells_iterator & rhs) const { return it == rhs.it; };
bool operator!=(const cells_iterator & rhs) const {
return !operator==(rhs);
};
CellID operator*() const {
CellID cur_cell_id(this->it->first);
return cur_cell_id;
};
private:
/// map iterator
typename std::map<CellID, Cell>::const_iterator it;
};
public:
template <class vector_type>
Cell & insert(const T & d, const vector_type & position) {
auto && cell_id = getCellID(position);
auto && it = cells.find(cell_id);
if (it == cells.end()) {
Cell cell(cell_id);
auto & tmp = (cells[cell_id] = cell).add(d);
for (UInt i = 0; i < dimension; ++i) {
Real posl = center(i) + cell_id.getID(i) * spacing(i);
Real posu = posl + spacing(i);
if (posl < lower(i))
lower(i) = posl;
if (posu > upper(i))
upper(i) = posu;
}
return tmp;
} else {
return it->second.add(d);
}
}
/* ------------------------------------------------------------------------ */
inline decltype(auto) begin() const {
auto begin = this->cells.begin();
return cells_iterator(begin);
}
inline decltype(auto) end() const {
auto end = this->cells.end();
return cells_iterator(end);
}
template <class vector_type>
CellID getCellID(const vector_type & position) const {
CellID cell_id(dimension);
for (UInt i = 0; i < dimension; ++i) {
cell_id.setID(i, getCellID(position(i), i));
}
return cell_id;
}
void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
std::streamsize prec = stream.precision();
std::ios_base::fmtflags ff = stream.flags();
stream.setf(std::ios_base::showbase);
stream.precision(5);
stream << space << "SpatialGrid<" << debug::demangle(typeid(T).name())
<< "> [" << std::endl;
stream << space << " + dimension : " << this->dimension << std::endl;
stream << space << " + lower bounds : {";
for (UInt i = 0; i < lower.size(); ++i) {
if (i != 0)
stream << ", ";
stream << lower(i);
};
stream << "}" << std::endl;
stream << space << " + upper bounds : {";
for (UInt i = 0; i < upper.size(); ++i) {
if (i != 0)
stream << ", ";
stream << upper(i);
};
stream << "}" << std::endl;
stream << space << " + spacing : {";
for (UInt i = 0; i < spacing.size(); ++i) {
if (i != 0)
stream << ", ";
stream << spacing(i);
};
stream << "}" << std::endl;
stream << space << " + center : {";
for (UInt i = 0; i < center.size(); ++i) {
if (i != 0)
stream << ", ";
stream << center(i);
};
stream << "}" << std::endl;
stream << space << " + nb_cells : " << this->cells.size() << "/";
Vector<Real> dist(this->dimension);
dist = upper;
dist -= lower;
for (UInt i = 0; i < this->dimension; ++i) {
dist(i) /= spacing(i);
}
UInt nb_cells = std::ceil(dist(0));
for (UInt i = 1; i < this->dimension; ++i) {
nb_cells *= std::ceil(dist(i));
}
stream << nb_cells << std::endl;
stream << space << "]" << std::endl;
stream.precision(prec);
stream.flags(ff);
}
void saveAsMesh(Mesh & mesh) const;
private:
/* --------------------------------------------------------------------------
*/
inline UInt getCellID(Real position, UInt direction) const {
- AKANTU_DEBUG_ASSERT(direction < center.size(), "The direction asked ("
- << direction
- << ") is out of range "
- << center.size());
+ AKANTU_DEBUG_ASSERT(direction < center.size(),
+ "The direction asked (" << direction
+ << ") is out of range "
+ << center.size());
Real dist_center = position - center(direction);
Int id = std::floor(dist_center / spacing(direction));
// if(dist_center < 0) id--;
return id;
}
friend class GridSynchronizer;
public:
AKANTU_GET_MACRO(LowerBounds, lower, const Vector<Real> &);
AKANTU_GET_MACRO(UpperBounds, upper, const Vector<Real> &);
AKANTU_GET_MACRO(Spacing, spacing, const Vector<Real> &);
protected:
UInt dimension;
cells_container cells;
Vector<Real> spacing;
Vector<Real> center;
Vector<Real> lower;
Vector<Real> upper;
Cell empty_cell;
};
/// standard output stream operator
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
const SpatialGrid<T> & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "mesh.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename T> void SpatialGrid<T>::saveAsMesh(Mesh & mesh) const {
auto & nodes = const_cast<Array<Real> &>(mesh.getNodes());
ElementType type;
switch (dimension) {
case 1:
type = _segment_2;
break;
case 2:
type = _quadrangle_4;
break;
case 3:
type = _hexahedron_8;
break;
}
mesh.addConnectivityType(type);
auto & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type));
auto & uint_data = mesh.getDataPointer<UInt>("tag_1", type);
Vector<Real> pos(dimension);
UInt global_id = 0;
for (auto & cell_pair : cells) {
UInt cur_node = nodes.size();
UInt cur_elem = connectivity.size();
const CellID & cell_id = cell_pair.first;
for (UInt i = 0; i < dimension; ++i)
pos(i) = center(i) + cell_id.getID(i) * spacing(i);
nodes.push_back(pos);
for (UInt i = 0; i < dimension; ++i)
pos(i) += spacing(i);
nodes.push_back(pos);
connectivity.push_back(cur_node);
switch (dimension) {
case 1:
connectivity(cur_elem, 1) = cur_node + 1;
break;
case 2:
pos(0) -= spacing(0);
nodes.push_back(pos);
pos(0) += spacing(0);
pos(1) -= spacing(1);
nodes.push_back(pos);
connectivity(cur_elem, 1) = cur_node + 3;
connectivity(cur_elem, 2) = cur_node + 1;
connectivity(cur_elem, 3) = cur_node + 2;
break;
case 3:
pos(1) -= spacing(1);
pos(2) -= spacing(2);
nodes.push_back(pos);
pos(1) += spacing(1);
nodes.push_back(pos);
pos(0) -= spacing(0);
nodes.push_back(pos);
pos(1) -= spacing(1);
pos(2) += spacing(2);
nodes.push_back(pos);
pos(0) += spacing(0);
nodes.push_back(pos);
pos(0) -= spacing(0);
pos(1) += spacing(1);
nodes.push_back(pos);
connectivity(cur_elem, 1) = cur_node + 2;
connectivity(cur_elem, 2) = cur_node + 3;
connectivity(cur_elem, 3) = cur_node + 4;
connectivity(cur_elem, 4) = cur_node + 5;
connectivity(cur_elem, 5) = cur_node + 6;
connectivity(cur_elem, 6) = cur_node + 1;
connectivity(cur_elem, 7) = cur_node + 7;
break;
}
uint_data.push_back(global_id);
++global_id;
}
}
} // namespace akantu
#endif /* __AKANTU_AKA_GRID_DYNAMIC_HH__ */
diff --git a/src/common/aka_math_tmpl.hh b/src/common/aka_math_tmpl.hh
index 3c49bbdde..2e0bdb5a7 100644
--- a/src/common/aka_math_tmpl.hh
+++ b/src/common/aka_math_tmpl.hh
@@ -1,784 +1,784 @@
/**
* @file aka_math_tmpl.hh
*
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Mathilde Radiguet <mathilde.radiguet@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
* @author Peter Spijker <peter.spijker@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Aug 04 2010
* @date last modification: Wed Oct 21 2015
*
* @brief Implementation of the inline functions of the math toolkit
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
} // akantu
#include <cmath>
#include <cstring>
#include <typeinfo>
#include "aka_blas_lapack.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
inline void Math::matrix_vector(UInt im, UInt in, Real * A, Real * x, Real * y,
Real alpha) {
#ifdef AKANTU_USE_BLAS
/// y = alpha*op(A)*x + beta*y
char tran_A = 'N';
int incx = 1;
int incy = 1;
double beta = 0.;
int m = im;
int n = in;
aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
#else
memset(y, 0, im * sizeof(Real));
for (UInt i = 0; i < im; ++i) {
for (UInt j = 0; j < in; ++j) {
y[i] += A[i + j * im] * x[j];
}
y[i] *= alpha;
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrixt_vector(UInt im, UInt in, Real * A, Real * x, Real * y,
Real alpha) {
#ifdef AKANTU_USE_BLAS
/// y = alpha*op(A)*x + beta*y
char tran_A = 'T';
int incx = 1;
int incy = 1;
double beta = 0.;
int m = im;
int n = in;
aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
#else
memset(y, 0, in * sizeof(Real));
for (UInt i = 0; i < im; ++i) {
for (UInt j = 0; j < in; ++j) {
y[j] += A[j * im + i] * x[i];
}
y[i] *= alpha;
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix_matrix(UInt im, UInt in, UInt ik, Real * A, Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'N';
char trans_b = 'N';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &k, &beta, C, &m);
#else
memset(C, 0, im * in * sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jb = j * ik;
UInt _jc = j * im;
for (UInt i = 0; i < im; ++i) {
for (UInt l = 0; l < ik; ++l) {
UInt _la = l * im;
C[i + _jc] += A[i + _la] * B[l + _jb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrixt_matrix(UInt im, UInt in, UInt ik, Real * A, Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'T';
char trans_b = 'N';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &k, &beta, C, &m);
#else
memset(C, 0, im * in * sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jc = j * im;
UInt _jb = j * ik;
for (UInt i = 0; i < im; ++i) {
UInt _ia = i * ik;
for (UInt l = 0; l < ik; ++l) {
C[i + _jc] += A[l + _ia] * B[l + _jb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix_matrixt(UInt im, UInt in, UInt ik, Real * A, Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'N';
char trans_b = 'T';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &n, &beta, C, &m);
#else
memset(C, 0, im * in * sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jc = j * im;
for (UInt i = 0; i < im; ++i) {
for (UInt l = 0; l < ik; ++l) {
UInt _la = l * im;
UInt _lb = l * in;
C[i + _jc] += A[i + _la] * B[j + _lb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::matrixt_matrixt(UInt im, UInt in, UInt ik, Real * A, Real * B,
Real * C, Real alpha) {
#ifdef AKANTU_USE_BLAS
/// C := alpha*op(A)*op(B) + beta*C
char trans_a = 'T';
char trans_b = 'T';
double beta = 0.;
int m = im, n = in, k = ik;
aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &n, &beta, C, &m);
#else
memset(C, 0, im * in * sizeof(Real));
for (UInt j = 0; j < in; ++j) {
UInt _jc = j * im;
for (UInt i = 0; i < im; ++i) {
UInt _ia = i * ik;
for (UInt l = 0; l < ik; ++l) {
UInt _lb = l * in;
C[i + _jc] += A[l + _ia] * B[j + _lb];
}
C[i + _jc] *= alpha;
}
}
#endif
}
/* -------------------------------------------------------------------------- */
inline void Math::aXplusY(UInt n, Real alpha, Real * x, Real * y) {
#ifdef AKANTU_USE_BLAS
/// y := alpha x + y
int incx = 1, incy = 1;
aka_axpy(&n, &alpha, x, &incx, y, &incy);
#else
for (UInt i = 0; i < n; ++i)
*(y++) += alpha * *(x++);
#endif
}
/* -------------------------------------------------------------------------- */
inline Real Math::vectorDot(Real * v1, Real * v2, UInt in) {
#ifdef AKANTU_USE_BLAS
/// d := v1 . v2
int incx = 1, incy = 1, n = in;
Real d = aka_dot(&n, v1, &incx, v2, &incy);
#else
Real d = 0;
for (UInt i = 0; i < in; ++i) {
d += v1[i] * v2[i];
}
#endif
return d;
}
/* -------------------------------------------------------------------------- */
template <bool tr_A, bool tr_B>
inline void Math::matMul(UInt m, UInt n, UInt k, Real alpha, Real * A, Real * B,
__attribute__((unused)) Real beta, Real * C) {
if (tr_A) {
if (tr_B)
matrixt_matrixt(m, n, k, A, B, C, alpha);
else
matrixt_matrix(m, n, k, A, B, C, alpha);
} else {
if (tr_B)
matrix_matrixt(m, n, k, A, B, C, alpha);
else
matrix_matrix(m, n, k, A, B, C, alpha);
}
}
/* -------------------------------------------------------------------------- */
template <bool tr_A>
inline void Math::matVectMul(UInt m, UInt n, Real alpha, Real * A, Real * x,
__attribute__((unused)) Real beta, Real * y) {
if (tr_A) {
matrixt_vector(m, n, A, x, y, alpha);
} else {
matrix_vector(m, n, A, x, y, alpha);
}
}
/* -------------------------------------------------------------------------- */
template <typename T> inline void Math::matrixEig(UInt n, T * A, T * d, T * V) {
// Matrix A is row major, so the lapack function in fortran will process
// A^t. Asking for the left eigenvectors of A^t will give the transposed right
// eigenvectors of A so in the C++ code the right eigenvectors.
char jobvr, jobvl;
if (V != nullptr)
jobvr = 'V'; // compute left eigenvectors
else
jobvr = 'N'; // compute left eigenvectors
jobvl = 'N'; // compute right eigenvectors
auto * di = new T[n]; // imaginary part of the eigenvalues
int info;
int N = n;
T wkopt;
int lwork = -1;
// query and allocate the optimal workspace
aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, &wkopt,
&lwork, &info);
lwork = int(wkopt);
auto * work = new T[lwork];
// solve the eigenproblem
aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, work,
&lwork, &info);
AKANTU_DEBUG_ASSERT(
info == 0,
"Problem computing eigenvalues/vectors. DGEEV exited with the value "
<< info);
delete[] work;
delete[] di; // I hope for you that there was no complex eigenvalues !!!
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix22_eigenvalues(Real * A, Real * Adiag) {
/// d = determinant of Matrix A
Real d = det2(A);
/// b = trace of Matrix A
Real b = A[0] + A[3];
Real c = sqrt(b * b - 4 * d);
Adiag[0] = .5 * (b + c);
Adiag[1] = .5 * (b - c);
}
/* -------------------------------------------------------------------------- */
inline void Math::matrix33_eigenvalues(Real * A, Real * Adiag) {
matrixEig(3, A, Adiag);
}
/* -------------------------------------------------------------------------- */
template <UInt dim> inline void Math::eigenvalues(Real * A, Real * d) {
if (dim == 1) {
d[0] = A[0];
} else if (dim == 2) {
matrix22_eigenvalues(A, d);
}
// else if(dim == 3) { matrix33_eigenvalues(A, d); }
else
matrixEig(dim, A, d);
}
/* -------------------------------------------------------------------------- */
inline Real Math::det2(const Real * mat) {
return mat[0] * mat[3] - mat[1] * mat[2];
}
/* -------------------------------------------------------------------------- */
inline Real Math::det3(const Real * mat) {
return mat[0] * (mat[4] * mat[8] - mat[7] * mat[5]) -
mat[3] * (mat[1] * mat[8] - mat[7] * mat[2]) +
mat[6] * (mat[1] * mat[5] - mat[4] * mat[2]);
}
/* -------------------------------------------------------------------------- */
template <UInt n> inline Real Math::det(const Real * mat) {
if (n == 1)
return *mat;
else if (n == 2)
return det2(mat);
else if (n == 3)
return det3(mat);
else
return det(n, mat);
}
/* -------------------------------------------------------------------------- */
template <typename T> inline T Math::det(UInt n, const T * A) {
int N = n;
int info;
auto * ipiv = new int[N + 1];
auto * LU = new T[N * N];
std::copy(A, A + N * N, LU);
// LU factorization of A
aka_getrf(&N, &N, LU, &N, ipiv, &info);
if (info > 0) {
AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
- << " )");
+ << " )");
}
// det(A) = det(L) * det(U) = 1 * det(U) = product_i U_{ii}
T det = 1.;
for (int i = 0; i < N; ++i)
det *= (2 * (ipiv[i] == i) - 1) * LU[i * n + i];
delete[] ipiv;
delete[] LU;
return det;
}
/* -------------------------------------------------------------------------- */
inline void Math::normal2(const Real * vec, Real * normal) {
normal[0] = vec[1];
normal[1] = -vec[0];
Math::normalize2(normal);
}
/* -------------------------------------------------------------------------- */
inline void Math::normal3(const Real * vec1, const Real * vec2, Real * normal) {
Math::vectorProduct3(vec1, vec2, normal);
Math::normalize3(normal);
}
/* -------------------------------------------------------------------------- */
inline void Math::normalize2(Real * vec) {
Real norm = Math::norm2(vec);
vec[0] /= norm;
vec[1] /= norm;
}
/* -------------------------------------------------------------------------- */
inline void Math::normalize3(Real * vec) {
Real norm = Math::norm3(vec);
vec[0] /= norm;
vec[1] /= norm;
vec[2] /= norm;
}
/* -------------------------------------------------------------------------- */
inline Real Math::norm2(const Real * vec) {
return sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::norm3(const Real * vec) {
return sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::norm(UInt n, const Real * vec) {
Real norm = 0.;
for (UInt i = 0; i < n; ++i) {
norm += vec[i] * vec[i];
}
return sqrt(norm);
}
/* -------------------------------------------------------------------------- */
inline void Math::inv2(const Real * mat, Real * inv) {
Real det_mat = det2(mat);
inv[0] = mat[3] / det_mat;
inv[1] = -mat[1] / det_mat;
inv[2] = -mat[2] / det_mat;
inv[3] = mat[0] / det_mat;
}
/* -------------------------------------------------------------------------- */
inline void Math::inv3(const Real * mat, Real * inv) {
Real det_mat = det3(mat);
inv[0] = (mat[4] * mat[8] - mat[7] * mat[5]) / det_mat;
inv[1] = (mat[2] * mat[7] - mat[8] * mat[1]) / det_mat;
inv[2] = (mat[1] * mat[5] - mat[4] * mat[2]) / det_mat;
inv[3] = (mat[5] * mat[6] - mat[8] * mat[3]) / det_mat;
inv[4] = (mat[0] * mat[8] - mat[6] * mat[2]) / det_mat;
inv[5] = (mat[2] * mat[3] - mat[5] * mat[0]) / det_mat;
inv[6] = (mat[3] * mat[7] - mat[6] * mat[4]) / det_mat;
inv[7] = (mat[1] * mat[6] - mat[7] * mat[0]) / det_mat;
inv[8] = (mat[0] * mat[4] - mat[3] * mat[1]) / det_mat;
}
/* -------------------------------------------------------------------------- */
template <UInt n> inline void Math::inv(const Real * A, Real * Ainv) {
if (n == 1)
*Ainv = 1. / *A;
else if (n == 2)
inv2(A, Ainv);
else if (n == 3)
inv3(A, Ainv);
else
inv(n, A, Ainv);
}
/* -------------------------------------------------------------------------- */
template <typename T> inline void Math::inv(UInt n, const T * A, T * invA) {
int N = n;
int info;
auto * ipiv = new int[N + 1];
int lwork = N * N;
auto * work = new T[lwork];
std::copy(A, A + n * n, invA);
aka_getrf(&N, &N, invA, &N, ipiv, &info);
if (info > 0) {
AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
- << " )");
+ << " )");
}
aka_getri(&N, invA, &N, ipiv, work, &lwork, &info);
if (info != 0) {
AKANTU_ERROR("Cannot invert the matrix (info: " << info << " )");
}
delete[] ipiv;
delete[] work;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Math::solve(UInt n, const T * A, T * x, const T * b) {
int N = n;
int info;
auto * ipiv = new int[N];
auto * lu_A = new T[N * N];
std::copy(A, A + N * N, lu_A);
aka_getrf(&N, &N, lu_A, &N, ipiv, &info);
if (info > 0) {
AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
- << " )");
+ << " )");
}
char trans = 'N';
int nrhs = 1;
std::copy(b, b + N, x);
aka_getrs(&trans, &N, &nrhs, lu_A, &N, ipiv, x, &N, &info);
if (info != 0) {
AKANTU_ERROR("Cannot solve the system (info: " << info << " )");
}
delete[] ipiv;
delete[] lu_A;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
inline Real Math::matrixDoubleDot22(Real * A, Real * B) {
Real d;
d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3];
return d;
}
/* -------------------------------------------------------------------------- */
inline Real Math::matrixDoubleDot33(Real * A, Real * B) {
Real d;
d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3] + A[4] * B[4] +
A[5] * B[5] + A[6] * B[6] + A[7] * B[7] + A[8] * B[8];
return d;
}
/* -------------------------------------------------------------------------- */
inline Real Math::matrixDoubleDot(UInt n, Real * A, Real * B) {
Real d = 0.;
for (UInt i = 0; i < n; ++i) {
for (UInt j = 0; j < n; ++j) {
d += A[i * n + j] * B[i * n + j];
}
}
return d;
}
/* -------------------------------------------------------------------------- */
inline void Math::vectorProduct3(const Real * v1, const Real * v2, Real * res) {
res[0] = v1[1] * v2[2] - v1[2] * v2[1];
res[1] = v1[2] * v2[0] - v1[0] * v2[2];
res[2] = v1[0] * v2[1] - v1[1] * v2[0];
}
/* -------------------------------------------------------------------------- */
inline Real Math::vectorDot2(const Real * v1, const Real * v2) {
return (v1[0] * v2[0] + v1[1] * v2[1]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::vectorDot3(const Real * v1, const Real * v2) {
return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
}
/* -------------------------------------------------------------------------- */
inline Real Math::distance_2d(const Real * x, const Real * y) {
return sqrt((y[0] - x[0]) * (y[0] - x[0]) + (y[1] - x[1]) * (y[1] - x[1]));
}
/* -------------------------------------------------------------------------- */
inline Real Math::triangle_inradius(const Real * coord1, const Real * coord2,
const Real * coord3) {
/**
* @f{eqnarray*}{
* r &=& A / s \\
* A &=& 1/4 * \sqrt{(a + b + c) * (a - b + c) * (a + b - c) (-a + b + c)} \\
* s &=& \frac{a + b + c}{2}
* @f}
*/
Real a, b, c;
a = distance_2d(coord1, coord2);
b = distance_2d(coord2, coord3);
c = distance_2d(coord1, coord3);
Real s;
s = (a + b + c) * 0.5;
return sqrt((s - a) * (s - b) * (s - c) / s);
}
/* -------------------------------------------------------------------------- */
inline Real Math::distance_3d(const Real * x, const Real * y) {
return sqrt((y[0] - x[0]) * (y[0] - x[0]) + (y[1] - x[1]) * (y[1] - x[1]) +
(y[2] - x[2]) * (y[2] - x[2]));
}
/* -------------------------------------------------------------------------- */
inline Real Math::tetrahedron_volume(const Real * coord1, const Real * coord2,
const Real * coord3, const Real * coord4) {
Real xx[9], vol;
xx[0] = coord2[0];
xx[1] = coord2[1];
xx[2] = coord2[2];
xx[3] = coord3[0];
xx[4] = coord3[1];
xx[5] = coord3[2];
xx[6] = coord4[0];
xx[7] = coord4[1];
xx[8] = coord4[2];
vol = det3(xx);
xx[0] = coord1[0];
xx[1] = coord1[1];
xx[2] = coord1[2];
xx[3] = coord3[0];
xx[4] = coord3[1];
xx[5] = coord3[2];
xx[6] = coord4[0];
xx[7] = coord4[1];
xx[8] = coord4[2];
vol -= det3(xx);
xx[0] = coord1[0];
xx[1] = coord1[1];
xx[2] = coord1[2];
xx[3] = coord2[0];
xx[4] = coord2[1];
xx[5] = coord2[2];
xx[6] = coord4[0];
xx[7] = coord4[1];
xx[8] = coord4[2];
vol += det3(xx);
xx[0] = coord1[0];
xx[1] = coord1[1];
xx[2] = coord1[2];
xx[3] = coord2[0];
xx[4] = coord2[1];
xx[5] = coord2[2];
xx[6] = coord3[0];
xx[7] = coord3[1];
xx[8] = coord3[2];
vol -= det3(xx);
vol /= 6;
return vol;
}
/* -------------------------------------------------------------------------- */
inline Real Math::tetrahedron_inradius(const Real * coord1, const Real * coord2,
const Real * coord3,
const Real * coord4) {
Real l12, l13, l14, l23, l24, l34;
l12 = distance_3d(coord1, coord2);
l13 = distance_3d(coord1, coord3);
l14 = distance_3d(coord1, coord4);
l23 = distance_3d(coord2, coord3);
l24 = distance_3d(coord2, coord4);
l34 = distance_3d(coord3, coord4);
Real s1, s2, s3, s4;
s1 = (l12 + l23 + l13) * 0.5;
s1 = sqrt(s1 * (s1 - l12) * (s1 - l23) * (s1 - l13));
s2 = (l12 + l24 + l14) * 0.5;
s2 = sqrt(s2 * (s2 - l12) * (s2 - l24) * (s2 - l14));
s3 = (l23 + l34 + l24) * 0.5;
s3 = sqrt(s3 * (s3 - l23) * (s3 - l34) * (s3 - l24));
s4 = (l13 + l34 + l14) * 0.5;
s4 = sqrt(s4 * (s4 - l13) * (s4 - l34) * (s4 - l14));
Real volume = Math::tetrahedron_volume(coord1, coord2, coord3, coord4);
return 3 * volume / (s1 + s2 + s3 + s4);
}
/* -------------------------------------------------------------------------- */
inline void Math::barycenter(const Real * coord, UInt nb_points,
UInt spatial_dimension, Real * barycenter) {
memset(barycenter, 0, spatial_dimension * sizeof(Real));
for (UInt n = 0; n < nb_points; ++n) {
UInt offset = n * spatial_dimension;
for (UInt i = 0; i < spatial_dimension; ++i) {
barycenter[i] += coord[offset + i] / (Real)nb_points;
}
}
}
/* -------------------------------------------------------------------------- */
inline void Math::vector_2d(const Real * x, const Real * y, Real * res) {
res[0] = y[0] - x[0];
res[1] = y[1] - x[1];
}
/* -------------------------------------------------------------------------- */
inline void Math::vector_3d(const Real * x, const Real * y, Real * res) {
res[0] = y[0] - x[0];
res[1] = y[1] - x[1];
res[2] = y[2] - x[2];
}
/* -------------------------------------------------------------------------- */
/// Combined absolute and relative tolerance test proposed in
/// Real-time collision detection by C. Ericson (2004)
inline bool Math::are_float_equal(const Real x, const Real y) {
Real abs_max = std::max(std::abs(x), std::abs(y));
abs_max = std::max(abs_max, Real(1.));
return std::abs(x - y) <= (tolerance * abs_max);
}
/* -------------------------------------------------------------------------- */
inline bool Math::isnan(Real x) {
#if defined(__INTEL_COMPILER)
#pragma warning(push)
#pragma warning(disable : 1572)
#endif // defined(__INTEL_COMPILER)
// x = x return false means x = quiet_NaN
return !(x == x);
#if defined(__INTEL_COMPILER)
#pragma warning(pop)
#endif // defined(__INTEL_COMPILER)
}
/* -------------------------------------------------------------------------- */
inline bool Math::are_vector_equal(UInt n, Real * x, Real * y) {
bool test = true;
for (UInt i = 0; i < n; ++i) {
test &= are_float_equal(x[i], y[i]);
}
return test;
}
/* -------------------------------------------------------------------------- */
inline bool Math::intersects(Real x_min, Real x_max, Real y_min, Real y_max) {
return !((x_max <= y_min) || (x_min >= y_max));
}
/* -------------------------------------------------------------------------- */
inline bool Math::is_in_range(Real a, Real x_min, Real x_max) {
return ((a >= x_min) && (a <= x_max));
}
/* -------------------------------------------------------------------------- */
template <UInt p, typename T> inline T Math::pow(T x) {
return (pow<p - 1, T>(x) * x);
}
template <> inline UInt Math::pow<0, UInt>(__attribute__((unused)) UInt x) {
return (1);
}
template <> inline Real Math::pow<0, Real>(__attribute__((unused)) Real x) {
return (1.);
}
/* -------------------------------------------------------------------------- */
template <class Functor>
Real Math::NewtonRaphson::solve(const Functor & funct, Real x_0) {
Real x = x_0;
Real f_x = funct.f(x);
UInt iter = 0;
while (std::abs(f_x) > this->tolerance && iter < this->max_iteration) {
x -= f_x / funct.f_prime(x);
f_x = funct.f(x);
iter++;
}
AKANTU_DEBUG_ASSERT(iter < this->max_iteration,
"Newton Raphson ("
<< funct.name << ") solve did not converge in "
<< this->max_iteration << " iterations (tolerance: "
<< this->tolerance << ")");
return x;
}
diff --git a/src/common/aka_memory.cc b/src/common/aka_memory.cc
index 3dca00a23..006134ced 100644
--- a/src/common/aka_memory.cc
+++ b/src/common/aka_memory.cc
@@ -1,65 +1,64 @@
/**
* @file aka_memory.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief static memory wrapper
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <utility>
#include "aka_memory.hh"
#include "aka_static_memory.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
Memory::Memory(ID id, MemoryID memory_id)
: static_memory(StaticMemory::getStaticMemory()), id(std::move(id)),
memory_id(memory_id) {}
/* -------------------------------------------------------------------------- */
Memory::~Memory() {
- if(StaticMemory::isInstantiated()) {
+ if (StaticMemory::isInstantiated()) {
std::list<ID>::iterator it;
- for (it = handeld_vectors_id.begin(); it != handeld_vectors_id.end(); ++it) {
+ for (it = handeld_vectors_id.begin(); it != handeld_vectors_id.end();
+ ++it) {
AKANTU_DEBUG(dblAccessory, "Deleting the vector " << *it);
static_memory.sfree(memory_id, *it);
}
static_memory.destroy();
}
handeld_vectors_id.clear();
}
/* -------------------------------------------------------------------------- */
} // akantu
-
-
diff --git a/src/common/aka_memory.hh b/src/common/aka_memory.hh
index 55e8c076d..a5db23abb 100644
--- a/src/common/aka_memory.hh
+++ b/src/common/aka_memory.hh
@@ -1,115 +1,115 @@
/**
* @file aka_memory.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief wrapper for the static_memory, all object which wants
* to access the static_memory as to inherit from the class memory
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MEMORY_HH__
#define __AKANTU_MEMORY_HH__
/* -------------------------------------------------------------------------- */
+#include "aka_array.hh"
#include "aka_common.hh"
#include "aka_static_memory.hh"
-#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#include <list>
/* -------------------------------------------------------------------------- */
namespace akantu {
class Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
protected:
Memory(ID id, MemoryID memory_id = 0);
virtual ~Memory();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// malloc
template <class T>
inline Array<T> & alloc(const ID & name, UInt size, UInt nb_component);
/// malloc
template <class T>
inline Array<T> & alloc(const ID & name, UInt size, UInt nb_component,
const T & init_value);
/* ------------------------------------------------------------------------ */
/// free an array
inline void dealloc(const ID & name);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
protected:
template <typename T> inline Array<T> & getArray(const ID & name);
template <typename T> inline const Array<T> & getArray(const ID & name) const;
public:
AKANTU_GET_MACRO(MemoryID, memory_id, const MemoryID &);
AKANTU_GET_MACRO(ID, id, const ID &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the static memory instance
StaticMemory & static_memory;
/// list of allocated vectors id
std::list<ID> handeld_vectors_id;
protected:
ID id;
/// the id registred in the static memory
MemoryID memory_id;
};
/* -------------------------------------------------------------------------- */
/* Inline functions */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_INCLUDE_INLINE_IMPL)
#include "aka_memory_inline_impl.cc"
#endif
} // akantu
#endif /* __AKANTU_MEMORY_HH__ */
diff --git a/src/common/aka_memory_inline_impl.cc b/src/common/aka_memory_inline_impl.cc
index b7a864564..eec8da71a 100644
--- a/src/common/aka_memory_inline_impl.cc
+++ b/src/common/aka_memory_inline_impl.cc
@@ -1,66 +1,66 @@
/**
* @file aka_memory_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the inline functions of the class Memory
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-template<class T> inline Array<T> & Memory::alloc(const ID & name,
- UInt size,
- UInt nb_component) {
+template <class T>
+inline Array<T> & Memory::alloc(const ID & name, UInt size, UInt nb_component) {
handeld_vectors_id.push_back(name);
- return static_memory.smalloc<T>(memory_id, name,
- size, nb_component);
+ return static_memory.smalloc<T>(memory_id, name, size, nb_component);
}
/* -------------------------------------------------------------------------- */
-template<class T> inline Array<T> & Memory::alloc(const ID & name,
- UInt size,
- UInt nb_component,
- const T & init_value) {
+template <class T>
+inline Array<T> & Memory::alloc(const ID & name, UInt size, UInt nb_component,
+ const T & init_value) {
handeld_vectors_id.push_back(name);
- return static_memory.smalloc<T>(memory_id, name,
- size, nb_component, init_value);
+ return static_memory.smalloc<T>(memory_id, name, size, nb_component,
+ init_value);
}
/* -------------------------------------------------------------------------- */
inline void Memory::dealloc(const ID & name) {
AKANTU_DEBUG(dblAccessory, "Deleting the vector " << name);
static_memory.sfree(memory_id, name);
handeld_vectors_id.remove(name);
}
/* -------------------------------------------------------------------------- */
-template<class T> inline Array<T> & Memory::getArray(const ID & name) {
- return static_cast< Array<T> & >(const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
+template <class T> inline Array<T> & Memory::getArray(const ID & name) {
+ return static_cast<Array<T> &>(
+ const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
}
/* -------------------------------------------------------------------------- */
-template<class T> inline const Array<T> & Memory::getArray(const ID & name) const {
- return static_cast< Array<T> & >(const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
+template <class T>
+inline const Array<T> & Memory::getArray(const ID & name) const {
+ return static_cast<Array<T> &>(
+ const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
}
diff --git a/src/common/aka_named_argument.hh b/src/common/aka_named_argument.hh
index 145e44719..2f8f8f3d7 100644
--- a/src/common/aka_named_argument.hh
+++ b/src/common/aka_named_argument.hh
@@ -1,165 +1,164 @@
/**
* @file aka_named_argument.hh
*
* @author Marco Arena
*
* @date creation Fri Jun 16 2017
*
* @brief A Documented file.
*
* @section LICENSE
*
* Public Domain ? https://gist.github.com/ilpropheta/7576dce4c3249df89f85
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_compatibilty_with_cpp_standard.hh"
/* -------------------------------------------------------------------------- */
#include <tuple>
#include <type_traits>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_NAMED_ARGUMENT_HH__
#define __AKANTU_AKA_NAMED_ARGUMENT_HH__
namespace akantu {
namespace named_argument {
struct param_t_trait {};
/* -- Pack utils (proxy version) ------------------------------------------ */
/// Proxy containing [tag, value]
template <typename tag, typename type> struct param_t : param_t_trait {
using _tag = tag;
using _type = type;
template <typename T>
explicit param_t(T && value) : _value(std::forward<T>(value)) {}
type _value;
};
/*
* Tagged proxy that allows syntax _name = value
* operator=(T&&) returns a param_t instance
**/
template <typename tag> struct param_proxy {
using _tag = tag;
template <typename T> decltype(auto) operator=(T && value) {
return param_t<tag, decltype(value)>{std::forward<T>(value)};
}
};
/* Same as type_at but it's supposed to be used by passing
a pack of param_t (_tag is looked for instead of a
plain type). This and type_at should be refactored.
*/
template <typename T, typename head, typename... tail> struct type_at_p {
enum {
_tmp = (std::is_same<T, typename std::decay_t<head>::_tag>::value)
? 0
: type_at_p<T, tail...>::_pos
};
enum { _pos = _tmp == -1 ? -1 : 1 + _tmp };
};
template <typename T, typename head> struct type_at_p<T, head> {
enum {
_pos =
(std::is_same<T, typename std::decay<head>::type::_tag>::value ? 1
: -1)
};
};
template <typename... Ts> struct type_at {
enum { _pos = -1 };
};
template <typename T, typename head, typename... tail>
struct type_at<T, head, tail...> {
enum { _tmp = type_at_p<T, head, tail...>::_pos };
enum { _pos = _tmp == 1 ? 0 : (_tmp == -1 ? -1 : _tmp - 1) };
};
/* Same as get_at but it's supposed to be used by passing
a pack of param_t (_type is retrieved instead)
This and get_at should be refactored.
*/
template <int pos, int curr> struct get_at {
static_assert(pos >= 0, "Required parameter");
template <typename head, typename... tail>
static decltype(auto) get(head &&, tail &&... t) {
return get_at<pos, curr + 1>::get(std::forward<tail>(t)...);
}
};
template <int pos> struct get_at<pos, pos> {
static_assert(pos >= 0, "Required parameter");
template <typename head, typename... tail>
static decltype(auto) get(head && h, tail &&...) {
return std::forward<decltype(h._value)>(h._value);
}
};
// Optional version
template <int pos, int curr> struct get_optional {
template <typename T, typename... pack>
static decltype(auto) get(T &&, pack &&... _pack) {
return get_at<pos, curr>::get(std::forward<pack>(_pack)...);
}
};
template <int curr> struct get_optional<-1, curr> {
template <typename T, typename... pack>
static decltype(auto) get(T && _default, pack &&...) {
return std::forward<T>(_default);
}
};
} // namespace named_argument
// CONVENIENCE MACROS FOR CLASS DESIGNERS ==========
#define TAG_OF_ARGUMENT(_name) p_##_name
#define TAG_OF_ARGUMENT_WNS(_name) TAG_OF_ARGUMENT(_name)
#define REQUIRED_NAMED_ARG(_name) \
named_argument::get_at< \
named_argument::type_at<TAG_OF_ARGUMENT_WNS(_name), pack...>::_pos, \
0>::get(std::forward<pack>(_pack)...)
#define REQUIRED_NAMED_ARG(_name) \
named_argument::get_at< \
named_argument::type_at<TAG_OF_ARGUMENT_WNS(_name), pack...>::_pos, \
0>::get(std::forward<pack>(_pack)...)
#define OPTIONAL_NAMED_ARG(_name, _defaultVal) \
named_argument::get_optional< \
named_argument::type_at<TAG_OF_ARGUMENT_WNS(_name), pack...>::_pos, \
0>::get(_defaultVal, std::forward<pack>(_pack)...)
#define DECLARE_NAMED_ARGUMENT(name) \
struct TAG_OF_ARGUMENT(name) {}; \
named_argument::param_proxy<TAG_OF_ARGUMENT_WNS(name)> _##name \
__attribute__((unused))
namespace {
struct use_named_args_t {};
use_named_args_t use_named_args __attribute__((unused));
} // namespace
template <typename T> struct is_named_argument : public std::false_type {};
template <typename... type>
struct is_named_argument<named_argument::param_t<type...>>
: public std::true_type {};
template <typename... pack>
using are_named_argument =
aka::conjunction<is_named_argument<std::decay_t<pack>>...>;
-
} // namespace akantu
#endif /* __AKANTU_AKA_NAMED_ARGUMENT_HH__ */
diff --git a/src/common/aka_random_generator.hh b/src/common/aka_random_generator.hh
index 73fa4952b..7cda1a505 100644
--- a/src/common/aka_random_generator.hh
+++ b/src/common/aka_random_generator.hh
@@ -1,268 +1,268 @@
/**
* @file aka_random_generator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Wed Nov 11 2015
*
* @brief generic random generator
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#include <random>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_RANDOM_GENERATOR_HH__
#define __AKANTU_AKA_RANDOM_GENERATOR_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
/* List of available distributions */
/* -------------------------------------------------------------------------- */
// clang-format off
#define AKANTU_RANDOM_DISTRIBUTION_TYPES \
((uniform , std::uniform_real_distribution )) \
((exponential , std::exponential_distribution )) \
((gamma , std::gamma_distribution )) \
((weibull , std::weibull_distribution )) \
((extreme_value, std::extreme_value_distribution)) \
((normal , std::normal_distribution )) \
((lognormal , std::lognormal_distribution )) \
((chi_squared , std::chi_squared_distribution )) \
((cauchy , std::cauchy_distribution )) \
((fisher_f , std::fisher_f_distribution )) \
((student_t , std::student_t_distribution ))
// clang-format on
#define AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_rdt_, elem)
#define AKANTU_RANDOM_DISTRIBUTION_PREFIX(s, data, elem) \
AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))
enum RandomDistributionType {
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_RANDOM_DISTRIBUTION_PREFIX, _,
AKANTU_RANDOM_DISTRIBUTION_TYPES)),
_rdt_not_defined
};
/* -------------------------------------------------------------------------- */
/* Generator */
/* -------------------------------------------------------------------------- */
template <typename T> class RandomGenerator {
/* ------------------------------------------------------------------------ */
public:
inline T operator()() { return generator(); }
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int) const {
stream << "RandGenerator [seed=" << _seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
static void seed(long int s) {
_seed = s;
generator.seed(_seed);
}
static long int seed() { return _seed; }
static constexpr T min() { return generator.min(); }
static constexpr T max() { return generator.max(); }
/* ------------------------------------------------------------------------ */
private:
static long int _seed;
static std::default_random_engine generator;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#undef AKANTU_RANDOM_DISTRIBUTION_PREFIX
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE(r, data, elem) \
case AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX( \
BOOST_PP_TUPLE_ELEM(2, 0, elem)): { \
stream << BOOST_PP_STRINGIZE(AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX( \
BOOST_PP_TUPLE_ELEM(2, 0, elem))); \
break; \
}
inline std::ostream & operator<<(std::ostream & stream,
RandomDistributionType type) {
switch (type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE, _,
AKANTU_RANDOM_DISTRIBUTION_TYPES)
default:
stream << UInt(type) << " not a RandomDistributionType";
break;
}
return stream;
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE
/* -------------------------------------------------------------------------- */
/* Some Helper */
/* -------------------------------------------------------------------------- */
template <typename T, class Distribution> class RandomDistributionTypeHelper {
enum { value = _rdt_not_defined };
};
/* -------------------------------------------------------------------------- */
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE(r, data, elem) \
template <typename T> \
- struct RandomDistributionTypeHelper<T, BOOST_PP_TUPLE_ELEM(2, 1, elem) < \
- T>> { \
+ struct RandomDistributionTypeHelper< \
+ T, BOOST_PP_TUPLE_ELEM(2, 1, elem) < T>> { \
enum { \
value = AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX( \
BOOST_PP_TUPLE_ELEM(2, 0, elem)) \
}; \
\
static void printself(std::ostream & stream) { \
stream << BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem)); \
} \
};
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE, _,
AKANTU_RANDOM_DISTRIBUTION_TYPES)
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE
/* -------------------------------------------------------------------------- */
template <class T> class RandomDistribution {
public:
virtual ~RandomDistribution() = default;
virtual T operator()(RandomGenerator<UInt> & gen) = 0;
virtual std::unique_ptr<RandomDistribution<T>> make_unique() const = 0;
virtual void printself(std::ostream & stream, int = 0) const = 0;
};
template <class T, class Distribution>
class RandomDistributionProxy : public RandomDistribution<T> {
public:
explicit RandomDistributionProxy(Distribution dist)
: distribution(std::move(dist)) {}
T operator()(RandomGenerator<UInt> & gen) override {
return distribution(gen);
}
std::unique_ptr<RandomDistribution<T>> make_unique() const override {
return std::make_unique<RandomDistributionProxy<T, Distribution>>(
distribution);
}
void printself(std::ostream & stream, int = 0) const override {
RandomDistributionTypeHelper<T, Distribution>::printself(stream);
stream << " [ " << distribution << " ]";
}
private:
Distribution distribution;
};
/* -------------------------------------------------------------------------- */
/* RandomParameter */
/* -------------------------------------------------------------------------- */
template <typename T> class RandomParameter {
public:
template <class Distribution>
explicit RandomParameter(T base_value, Distribution dist)
: base_value(base_value),
type(RandomDistributionType(
RandomDistributionTypeHelper<T, Distribution>::value)),
distribution_proxy(
std::make_unique<RandomDistributionProxy<T, Distribution>>(
std::move(dist))) {}
explicit RandomParameter(T base_value)
: base_value(base_value),
type(RandomDistributionType(
RandomDistributionTypeHelper<
T, std::uniform_real_distribution<T>>::value)),
distribution_proxy(
std::make_unique<
RandomDistributionProxy<T, std::uniform_real_distribution<T>>>(
std::uniform_real_distribution<T>(0., 0.))) {}
RandomParameter(const RandomParameter & other)
: base_value(other.base_value), type(other.type),
distribution_proxy(other.distribution_proxy->make_unique()) {}
RandomParameter & operator=(const RandomParameter & other) {
distribution_proxy = other.distribution_proxy->make_unique();
base_value = other.base_value;
type = other.type;
return *this;
}
virtual ~RandomParameter() = default;
inline void setBaseValue(const T & value) { this->base_value = value; }
inline T getBaseValue() const { return this->base_value; }
template <template <typename> class Generator, class iterator>
void setValues(iterator it, iterator end) {
RandomGenerator<UInt> gen;
for (; it != end; ++it)
*it = this->base_value + (*distribution_proxy)(gen);
}
virtual void printself(std::ostream & stream,
__attribute__((unused)) int indent = 0) const {
stream << base_value;
stream << " + " << *distribution_proxy;
}
private:
/// Value with no random variations
T base_value;
/// Random distribution type
RandomDistributionType type;
/// Proxy to store a std random distribution
std::unique_ptr<RandomDistribution<T>> distribution_proxy;
};
/* -------------------------------------------------------------------------- */
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
RandomDistribution<T> & _this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
RandomParameter<T> & _this) {
_this.printself(stream);
return stream;
}
} // akantu
#endif /* __AKANTU_AKA_RANDOM_GENERATOR_HH__ */
diff --git a/src/common/aka_safe_enum.hh b/src/common/aka_safe_enum.hh
index b129b7fbd..b27885dd1 100644
--- a/src/common/aka_safe_enum.hh
+++ b/src/common/aka_safe_enum.hh
@@ -1,86 +1,86 @@
/**
* @file aka_safe_enum.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Safe enums type (see More C++ Idioms/Type Safe Enum on Wikibooks
* http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum)
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_SAFE_ENUM_HH__
#define __AKANTU_AKA_SAFE_ENUM_HH__
namespace akantu {
/// Safe enumerated type
-template<typename def, typename inner = typename def::type>
+template <typename def, typename inner = typename def::type>
class safe_enum : public def {
using type = typename def::type;
public:
explicit safe_enum(type v = def::_end_) : val(v) {}
safe_enum(safe_enum && other) = default;
- safe_enum& operator=(safe_enum && other) = default;
+ safe_enum & operator=(safe_enum && other) = default;
inner underlying() const { return val; }
- bool operator == (const safe_enum & s) const { return this->val == s.val; }
- bool operator != (const safe_enum & s) const { return this->val != s.val; }
- bool operator < (const safe_enum & s) const { return this->val < s.val; }
- bool operator <= (const safe_enum & s) const { return this->val <= s.val; }
- bool operator > (const safe_enum & s) const { return this->val > s.val; }
- bool operator >= (const safe_enum & s) const { return this->val >= s.val; }
+ bool operator==(const safe_enum & s) const { return this->val == s.val; }
+ bool operator!=(const safe_enum & s) const { return this->val != s.val; }
+ bool operator<(const safe_enum & s) const { return this->val < s.val; }
+ bool operator<=(const safe_enum & s) const { return this->val <= s.val; }
+ bool operator>(const safe_enum & s) const { return this->val > s.val; }
+ bool operator>=(const safe_enum & s) const { return this->val >= s.val; }
operator inner() { return val; };
public:
// Works only if enumerations are contiguous.
class iterator {
public:
- explicit iterator(type v) : it(v) { }
- iterator & operator++() { ++it; return *this; }
+ explicit iterator(type v) : it(v) {}
+ iterator & operator++() {
+ ++it;
+ return *this;
+ }
safe_enum operator*() { return safe_enum(static_cast<type>(it)); }
bool operator!=(iterator const & it) { return it.it != this->it; }
+
private:
int it;
};
- static iterator begin() {
- return iterator(def::_begin_);
- }
+ static iterator begin() { return iterator(def::_begin_); }
- static iterator end() {
- return iterator(def::_end_);
- }
+ static iterator end() { return iterator(def::_end_); }
protected:
inner val;
};
} // akantu
#endif /* __AKANTU_AKA_SAFE_ENUM_HH__ */
diff --git a/src/common/aka_static_memory.cc b/src/common/aka_static_memory.cc
index e613d8bdb..a3a18b7aa 100644
--- a/src/common/aka_static_memory.cc
+++ b/src/common/aka_static_memory.cc
@@ -1,156 +1,161 @@
/**
* @file aka_static_memory.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Wed Jan 06 2016
*
* @brief Memory management
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <stdexcept>
#include <sstream>
+#include <stdexcept>
/* -------------------------------------------------------------------------- */
#include "aka_static_memory.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
bool StaticMemory::is_instantiated = false;
StaticMemory * StaticMemory::single_static_memory = nullptr;
UInt StaticMemory::nb_reference = 0;
/* -------------------------------------------------------------------------- */
StaticMemory & StaticMemory::getStaticMemory() {
- if(!single_static_memory) {
+ if (!single_static_memory) {
single_static_memory = new StaticMemory();
is_instantiated = true;
}
nb_reference++;
return *single_static_memory;
}
/* -------------------------------------------------------------------------- */
void StaticMemory::destroy() {
nb_reference--;
- if(nb_reference == 0) {
+ if (nb_reference == 0) {
delete single_static_memory;
}
}
/* -------------------------------------------------------------------------- */
StaticMemory::~StaticMemory() {
AKANTU_DEBUG_IN();
MemoryMap::iterator memory_it;
- for(memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
+ for (memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
ArrayMap::iterator vector_it;
- for(vector_it = (memory_it->second).begin();
- vector_it != (memory_it->second).end();
- ++vector_it) {
+ for (vector_it = (memory_it->second).begin();
+ vector_it != (memory_it->second).end(); ++vector_it) {
delete vector_it->second;
}
(memory_it->second).clear();
}
memories.clear();
is_instantiated = false;
StaticMemory::single_static_memory = nullptr;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void StaticMemory::sfree(const MemoryID & memory_id,
- const ID & name) {
+void StaticMemory::sfree(const MemoryID & memory_id, const ID & name) {
AKANTU_DEBUG_IN();
try {
auto & vectors = const_cast<ArrayMap &>(getMemory(memory_id));
ArrayMap::iterator vector_it;
vector_it = vectors.find(name);
- if(vector_it != vectors.end()) {
- AKANTU_DEBUG_INFO("Array " << name << " removed from the static memory number " << memory_id);
+ if (vector_it != vectors.end()) {
+ AKANTU_DEBUG_INFO("Array " << name
+ << " removed from the static memory number "
+ << memory_id);
delete vector_it->second;
vectors.erase(vector_it);
AKANTU_DEBUG_OUT();
return;
}
} catch (debug::Exception e) {
- AKANTU_EXCEPTION("The memory " << memory_id << " does not exist (perhaps already freed) ["
- << e.what() << "]");
+ AKANTU_EXCEPTION("The memory "
+ << memory_id << " does not exist (perhaps already freed) ["
+ << e.what() << "]");
AKANTU_DEBUG_OUT();
return;
}
- AKANTU_DEBUG_INFO("The vector " << name << " does not exist (perhaps already freed)");
+ AKANTU_DEBUG_INFO("The vector " << name
+ << " does not exist (perhaps already freed)");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void StaticMemory::printself(std::ostream & stream, int indent) const{
+void StaticMemory::printself(std::ostream & stream, int indent) const {
std::string space = "";
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
- std::streamsize prec = stream.precision();
+ std::streamsize prec = stream.precision();
stream.precision(2);
stream << space << "StaticMemory [" << std::endl;
UInt nb_memories = memories.size();
stream << space << " + nb memories : " << nb_memories << std::endl;
Real tot_size = 0;
MemoryMap::const_iterator memory_it;
- for(memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
+ for (memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
Real mem_size = 0;
stream << space << AKANTU_INDENT << "Memory [" << std::endl;
UInt mem_id = memory_it->first;
- stream << space << AKANTU_INDENT << " + memory id : "
- << mem_id << std::endl;
+ stream << space << AKANTU_INDENT << " + memory id : " << mem_id
+ << std::endl;
UInt nb_vectors = (memory_it->second).size();
- stream << space << AKANTU_INDENT << " + nb vectors : "
- << nb_vectors << std::endl;
+ stream << space << AKANTU_INDENT << " + nb vectors : " << nb_vectors
+ << std::endl;
stream.precision(prec);
ArrayMap::const_iterator vector_it;
- for(vector_it = (memory_it->second).begin();
- vector_it != (memory_it->second).end();
- ++vector_it) {
+ for (vector_it = (memory_it->second).begin();
+ vector_it != (memory_it->second).end(); ++vector_it) {
(vector_it->second)->printself(stream, indent + 2);
mem_size += (vector_it->second)->getMemorySize();
}
- stream << space << AKANTU_INDENT << " + total size : " << printMemorySize<char>(mem_size) << std::endl;
+ stream << space << AKANTU_INDENT
+ << " + total size : " << printMemorySize<char>(mem_size)
+ << std::endl;
stream << space << AKANTU_INDENT << "]" << std::endl;
tot_size += mem_size;
}
- stream << space << " + total size : " << printMemorySize<char>(tot_size) << std::endl;
+ stream << space << " + total size : " << printMemorySize<char>(tot_size)
+ << std::endl;
stream << space << "]" << std::endl;
stream.precision(prec);
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/common/aka_static_memory_inline_impl.cc b/src/common/aka_static_memory_inline_impl.cc
index 2a10c3a87..cc245ebaf 100644
--- a/src/common/aka_static_memory_inline_impl.cc
+++ b/src/common/aka_static_memory_inline_impl.cc
@@ -1,64 +1,65 @@
/**
* @file aka_static_memory_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Fri May 22 2015
*
* @brief Implementation of inline functions of the class StaticMemory
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-inline const ArrayMap & StaticMemory::getMemory(const MemoryID & memory_id) const {
+inline const ArrayMap &
+StaticMemory::getMemory(const MemoryID & memory_id) const {
AKANTU_DEBUG_IN();
MemoryMap::const_iterator memory_it;
memory_it = memories.find(memory_id);
- if(memory_it == memories.end()) {
+ if (memory_it == memories.end()) {
AKANTU_SILENT_EXCEPTION("StaticMemory as no memory with ID " << memory_id);
}
AKANTU_DEBUG_OUT();
return memory_it->second;
}
/* -------------------------------------------------------------------------- */
inline const ArrayBase & StaticMemory::getArray(const MemoryID & memory_id,
- const ID & name) const {
+ const ID & name) const {
AKANTU_DEBUG_IN();
const ArrayMap & vectors = getMemory(memory_id);
ArrayMap::const_iterator vectors_it;
vectors_it = vectors.find(name);
- if(vectors_it == vectors.end()) {
- AKANTU_SILENT_EXCEPTION("StaticMemory as no array named " << name
- << " for the Memory " << memory_id);
+ if (vectors_it == vectors.end()) {
+ AKANTU_SILENT_EXCEPTION("StaticMemory as no array named "
+ << name << " for the Memory " << memory_id);
}
AKANTU_DEBUG_OUT();
return *(vectors_it->second);
}
/* -------------------------------------------------------------------------- */
diff --git a/src/common/aka_static_memory_tmpl.hh b/src/common/aka_static_memory_tmpl.hh
index 0bf3003d1..484f7f125 100644
--- a/src/common/aka_static_memory_tmpl.hh
+++ b/src/common/aka_static_memory_tmpl.hh
@@ -1,87 +1,87 @@
/**
* @file aka_static_memory_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Sun Oct 19 2014
*
* @brief template part of the StaticMemory
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-template<typename T>
-Array<T> & StaticMemory::smalloc(const MemoryID & memory_id,
- const ID & name,
- UInt size,
- UInt nb_component) {
+template <typename T>
+Array<T> & StaticMemory::smalloc(const MemoryID & memory_id, const ID & name,
+ UInt size, UInt nb_component) {
AKANTU_DEBUG_IN();
MemoryMap::iterator memory_it;
memory_it = memories.find(memory_id);
- if(memory_it == memories.end()){
+ if (memory_it == memories.end()) {
memories[memory_id] = ArrayMap();
memory_it = memories.find(memory_id);
}
- if((memory_it->second).find(name) != (memory_it->second).end()) {
- AKANTU_ERROR("The vector \"" << name << "\" is already registred in the memory " << memory_id);
+ if ((memory_it->second).find(name) != (memory_it->second).end()) {
+ AKANTU_ERROR("The vector \"" << name
+ << "\" is already registred in the memory "
+ << memory_id);
}
auto * tmp_vect = new Array<T>(size, nb_component, name);
(memory_it->second)[name] = tmp_vect;
AKANTU_DEBUG_OUT();
return *tmp_vect;
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-Array<T> & StaticMemory::smalloc(const MemoryID & memory_id,
- const ID & name,
- UInt size,
- UInt nb_component,
- const T & init_value) {
+template <typename T>
+Array<T> & StaticMemory::smalloc(const MemoryID & memory_id, const ID & name,
+ UInt size, UInt nb_component,
+ const T & init_value) {
AKANTU_DEBUG_IN();
MemoryMap::iterator memory_it;
memory_it = memories.find(memory_id);
- if(memory_it == memories.end()){
+ if (memory_it == memories.end()) {
memories[memory_id] = ArrayMap();
memory_it = memories.find(memory_id);
}
- if((memory_it->second).find(name) != (memory_it->second).end()) {
- AKANTU_ERROR("The vector \"" << name << "\" is already registred in the memory " << memory_id);
+ if ((memory_it->second).find(name) != (memory_it->second).end()) {
+ AKANTU_ERROR("The vector \"" << name
+ << "\" is already registred in the memory "
+ << memory_id);
}
auto * tmp_vect = new Array<T>(size, nb_component, init_value, name);
(memory_it->second)[name] = tmp_vect;
AKANTU_DEBUG_OUT();
return *tmp_vect;
}
/* -------------------------------------------------------------------------- */
diff --git a/src/common/aka_typelist.hh b/src/common/aka_typelist.hh
index d4d5d22df..1eb75cdfe 100644
--- a/src/common/aka_typelist.hh
+++ b/src/common/aka_typelist.hh
@@ -1,184 +1,155 @@
/**
* @file aka_typelist.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Objects that support the visitor design pattern
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TYPELIST_HH__
#define __AKANTU_TYPELIST_HH__
#include "aka_common.hh"
namespace akantu {
struct Empty_type {};
class Null_type {};
-template <class T, class U>
-struct Typelist {
- typedef T Head;
- typedef U Tail;
+template <class T, class U> struct Typelist {
+ typedef T Head;
+ typedef U Tail;
};
-template <
-typename T1 = Null_type, typename T2 = Null_type, typename T3 = Null_type,
-typename T4 = Null_type, typename T5 = Null_type, typename T6 = Null_type,
-typename T7 = Null_type, typename T8 = Null_type, typename T9 = Null_type,
-typename T10 = Null_type, typename T11 = Null_type, typename T12 = Null_type,
-typename T13 = Null_type, typename T14 = Null_type, typename T15 = Null_type,
-typename T16 = Null_type, typename T17 = Null_type, typename T18 = Null_type,
-typename T19 = Null_type, typename T20 = Null_type
->
-struct MakeTypelist
-{
+template <typename T1 = Null_type, typename T2 = Null_type,
+ typename T3 = Null_type, typename T4 = Null_type,
+ typename T5 = Null_type, typename T6 = Null_type,
+ typename T7 = Null_type, typename T8 = Null_type,
+ typename T9 = Null_type, typename T10 = Null_type,
+ typename T11 = Null_type, typename T12 = Null_type,
+ typename T13 = Null_type, typename T14 = Null_type,
+ typename T15 = Null_type, typename T16 = Null_type,
+ typename T17 = Null_type, typename T18 = Null_type,
+ typename T19 = Null_type, typename T20 = Null_type>
+struct MakeTypelist {
private:
- typedef typename MakeTypelist
- <
- T2 , T3 , T4 ,
- T5 , T6 , T7 ,
- T8 , T9 , T10,
- T11, T12, T13,
- T14, T15, T16,
- T17, T18, T19, T20
- >
- ::Result TailResult;
-
+ typedef typename MakeTypelist<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+ T13, T14, T15, T16, T17, T18, T19, T20>::Result
+ TailResult;
+
public:
- typedef Typelist<T1, TailResult> Result;
+ typedef Typelist<T1, TailResult> Result;
};
-template<>
-struct MakeTypelist<> {
- typedef Null_type Result;
-};
+template <> struct MakeTypelist<> { typedef Null_type Result; };
////////////////////////////////////////////////////////////////////////////////
// class template Length
// Computes the length of a typelist
// Invocation (TList is a typelist):
// Length<TList>::value
// returns a compile-time constant containing the length of TList, not counting
// the end terminator (which by convention is Null_type)
////////////////////////////////////////////////////////////////////////////////
template <class TList> struct Length;
-template <> struct Length<Null_type>
-{
- enum { value = 0 };
+template <> struct Length<Null_type> {
+ enum { value = 0 };
};
-template <class T, class U>
-struct Length< Typelist<T, U> >
-{
- enum { value = 1 + Length<U>::value };
+template <class T, class U> struct Length<Typelist<T, U>> {
+ enum { value = 1 + Length<U>::value };
};
////////////////////////////////////////////////////////////////////////////////
// class template TypeAt
// Finds the type at a given index in a typelist
-// Invocation (TList is a typelist and index is a compile-time integral
+// Invocation (TList is a typelist and index is a compile-time integral
// constant):
// TypeAt<TList, index>::Result
// returns the type in position 'index' in TList
// If you pass an out-of-bounds index, the result is a compile-time error
////////////////////////////////////////////////////////////////////////////////
template <class TList, unsigned int index> struct TypeAt;
-template <class Head, class Tail>
-struct TypeAt<Typelist<Head, Tail>, 0>
-{
- typedef Head Result;
+template <class Head, class Tail> struct TypeAt<Typelist<Head, Tail>, 0> {
+ typedef Head Result;
};
template <class Head, class Tail, unsigned int i>
-struct TypeAt<Typelist<Head, Tail>, i>
-{
- typedef typename TypeAt<Tail, i - 1>::Result Result;
+struct TypeAt<Typelist<Head, Tail>, i> {
+ typedef typename TypeAt<Tail, i - 1>::Result Result;
};
-
-
////////////////////////////////////////////////////////////////////////////////
// class template Erase
// Erases the first occurence, if any, of a type in a typelist
// Invocation (TList is a typelist and T is a type):
// Erase<TList, T>::Result
// returns a typelist that is TList without the first occurence of T
////////////////////////////////////////////////////////////////////////////////
template <class TList, class T> struct Erase;
-template <class T> // Specialization 1
-struct Erase<Null_type, T>
-{
- typedef Null_type Result;
+template <class T> // Specialization 1
+struct Erase<Null_type, T> {
+ typedef Null_type Result;
};
-template <class T, class Tail> // Specialization 2
-struct Erase<Typelist<T, Tail>, T>
-{
- typedef Tail Result;
+template <class T, class Tail> // Specialization 2
+struct Erase<Typelist<T, Tail>, T> {
+ typedef Tail Result;
};
template <class Head, class Tail, class T> // Specialization 3
-struct Erase<Typelist<Head, Tail>, T>
-{
- typedef Typelist<Head,
- typename Erase<Tail, T>::Result>
- Result;
+struct Erase<Typelist<Head, Tail>, T> {
+ typedef Typelist<Head, typename Erase<Tail, T>::Result> Result;
};
-
template <class TList, class T> struct IndexOf;
-template <class T>
-struct IndexOf<Null_type, T>
-{
- enum { value = -1 };
+template <class T> struct IndexOf<Null_type, T> {
+ enum { value = -1 };
};
-template <class T, class Tail>
-struct IndexOf<Typelist<T, Tail>, T>
-{
- enum { value = 0 };
+template <class T, class Tail> struct IndexOf<Typelist<T, Tail>, T> {
+ enum { value = 0 };
};
template <class Head, class Tail, class T>
-struct IndexOf<Typelist<Head, Tail>, T>
-{
+struct IndexOf<Typelist<Head, Tail>, T> {
private:
- enum { temp = IndexOf<Tail, T>::value };
+ enum { temp = IndexOf<Tail, T>::value };
+
public:
- enum { value = (temp == -1 ? -1 : 1 + temp) };
+ enum { value = (temp == -1 ? -1 : 1 + temp) };
};
} // akantu
#endif /* __AKANTU_TYPELIST_HH__ */
diff --git a/src/common/aka_types.hh b/src/common/aka_types.hh
index 7de980376..09c422ee7 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,1302 +1,1302 @@
/**
* @file aka_types.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 17 2011
* @date last modification: Fri Jan 22 2016
*
* @brief description of the "simple" types
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_error.hh"
#include "aka_fwd.hh"
#include "aka_math.hh"
/* -------------------------------------------------------------------------- */
#include <initializer_list>
#include <iomanip>
#include <type_traits>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_TYPES_HH__
#define __AKANTU_AKA_TYPES_HH__
namespace akantu {
enum NormType { L_1 = 1, L_2 = 2, L_inf = UInt(-1) };
/**
* DimHelper is a class to generalize the setup of a dim array from 3
* values. This gives a common interface in the TensorStorage class
* independently of its derived inheritance (Vector, Matrix, Tensor3)
* @tparam dim
*/
template <UInt dim> struct DimHelper {
static inline void setDims(UInt m, UInt n, UInt p, UInt dims[dim]);
};
/* -------------------------------------------------------------------------- */
template <> struct DimHelper<1> {
static inline void setDims(UInt m, __attribute__((unused)) UInt n,
__attribute__((unused)) UInt p, UInt dims[1]) {
dims[0] = m;
}
};
/* -------------------------------------------------------------------------- */
template <> struct DimHelper<2> {
static inline void setDims(UInt m, UInt n, __attribute__((unused)) UInt p,
UInt dims[2]) {
dims[0] = m;
dims[1] = n;
}
};
/* -------------------------------------------------------------------------- */
template <> struct DimHelper<3> {
static inline void setDims(UInt m, UInt n, UInt p, UInt dims[3]) {
dims[0] = m;
dims[1] = n;
dims[2] = p;
}
};
/* -------------------------------------------------------------------------- */
template <typename T, UInt ndim, class RetType> class TensorStorage;
/* -------------------------------------------------------------------------- */
/* Proxy classes */
/* -------------------------------------------------------------------------- */
namespace tensors {
template <class A, class B> struct is_copyable {
enum : bool { value = false };
};
template <class A> struct is_copyable<A, A> {
enum : bool { value = true };
};
template <class A> struct is_copyable<A, typename A::RetType> {
enum : bool { value = true };
};
template <class A> struct is_copyable<A, typename A::RetType::proxy> {
enum : bool { value = true };
};
} // namespace tensors
/**
* @class TensorProxy aka_types.hh
* @desc The TensorProxy class is a proxy class to the TensorStorage it handles
* the
* wrapped case. That is to say if an accessor should give access to a Tensor
* wrapped on some data, like the Array<T>::iterator they can return a
* TensorProxy that will be automatically transformed as a TensorStorage wrapped
* on the same data
* @tparam T stored type
* @tparam ndim order of the tensor
* @tparam RetType real derived type
*/
template <typename T, UInt ndim, class _RetType> class TensorProxy {
protected:
using RetTypeProxy = typename _RetType::proxy;
constexpr TensorProxy(T * data, UInt m, UInt n, UInt p) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->values = data;
}
#ifndef SWIG
template <class Other,
typename = std::enable_if_t<
tensors::is_copyable<TensorProxy, Other>::value>>
explicit TensorProxy(const Other & other) {
this->values = other.storage();
for (UInt i = 0; i < ndim; ++i)
this->n[i] = other.size(i);
}
#endif
public:
using RetType = _RetType;
UInt size(UInt i) const {
AKANTU_DEBUG_ASSERT(i < ndim,
"This tensor has only " << ndim << " dimensions, not "
<< (i + 1));
return n[i];
}
inline UInt size() const {
UInt _size = 1;
for (UInt d = 0; d < ndim; ++d)
_size *= this->n[d];
return _size;
}
T * storage() const { return values; }
#ifndef SWIG
template <class Other,
typename = std::enable_if_t<
tensors::is_copyable<TensorProxy, Other>::value>>
inline TensorProxy & operator=(const Other & other) {
AKANTU_DEBUG_ASSERT(
other.size() == this->size(),
"You are trying to copy two tensors with different sizes");
memcpy(this->values, other.storage(), this->size() * sizeof(T));
return *this;
}
#endif
// template <class Other, typename = std::enable_if_t<
// tensors::is_copyable<TensorProxy, Other>::value>>
// inline TensorProxy & operator=(const Other && other) {
// AKANTU_DEBUG_ASSERT(
// other.size() == this->size(),
// "You are trying to copy two tensors with different sizes");
// memcpy(this->values, other.storage(), this->size() * sizeof(T));
// return *this;
// }
template <typename O> inline RetTypeProxy & operator*=(const O & o) {
RetType(*this) *= o;
return static_cast<RetTypeProxy &>(*this);
}
template <typename O> inline RetTypeProxy & operator/=(const O & o) {
RetType(*this) /= o;
return static_cast<RetTypeProxy &>(*this);
}
protected:
T * values;
UInt n[ndim];
};
/* -------------------------------------------------------------------------- */
template <typename T> class VectorProxy : public TensorProxy<T, 1, Vector<T>> {
using parent = TensorProxy<T, 1, Vector<T>>;
using type = Vector<T>;
public:
constexpr VectorProxy(T * data, UInt n) : parent(data, n, 0, 0) {}
template <class Other> explicit VectorProxy(Other & src) : parent(src) {}
/* ---------------------------------------------------------------------- */
template <class Other>
inline VectorProxy<T> & operator=(const Other & other) {
parent::operator=(other);
return *this;
}
// inline VectorProxy<T> & operator=(const VectorProxy && other) {
// parent::operator=(other);
// return *this;
// }
/* ------------------------------------------------------------------------ */
T & operator()(UInt index) { return this->values[index]; };
const T & operator()(UInt index) const { return this->values[index]; };
};
template <typename T> class MatrixProxy : public TensorProxy<T, 2, Matrix<T>> {
using parent = TensorProxy<T, 2, Matrix<T>>;
using type = Matrix<T>;
public:
MatrixProxy(T * data, UInt m, UInt n) : parent(data, m, n, 0) {}
template <class Other> explicit MatrixProxy(Other & src) : parent(src) {}
/* ---------------------------------------------------------------------- */
template <class Other>
inline MatrixProxy<T> & operator=(const Other & other) {
parent::operator=(other);
return *this;
}
};
template <typename T>
class Tensor3Proxy : public TensorProxy<T, 3, Tensor3<T>> {
using parent = TensorProxy<T, 3, Tensor3<T>>;
using type = Tensor3<T>;
public:
Tensor3Proxy(const T * data, UInt m, UInt n, UInt k)
: parent(data, m, n, k) {}
Tensor3Proxy(const Tensor3Proxy & src) : parent(src) {}
Tensor3Proxy(const Tensor3<T> & src) : parent(src) {}
/* ---------------------------------------------------------------------- */
template <class Other>
inline Tensor3Proxy<T> & operator=(const Other & other) {
parent::operator=(other);
return *this;
}
};
/* -------------------------------------------------------------------------- */
/* Tensor base class */
/* -------------------------------------------------------------------------- */
template <typename T, UInt ndim, class RetType>
class TensorStorage : public TensorTrait {
public:
using value_type = T;
friend class Array<T>;
protected:
template <class TensorType> void copySize(const TensorType & src) {
for (UInt d = 0; d < ndim; ++d)
this->n[d] = src.size(d);
this->_size = src.size();
}
TensorStorage() : values(nullptr) {
for (UInt d = 0; d < ndim; ++d)
this->n[d] = 0;
_size = 0;
}
TensorStorage(const TensorProxy<T, ndim, RetType> & proxy) {
this->copySize(proxy);
this->values = proxy.storage();
this->wrapped = true;
}
public:
TensorStorage(const TensorStorage & src) = delete;
TensorStorage(const TensorStorage & src, bool deep_copy) : values(nullptr) {
if (deep_copy)
this->deepCopy(src);
else
this->shallowCopy(src);
}
protected:
TensorStorage(UInt m, UInt n, UInt p, const T & def) {
static_assert(std::is_trivially_constructible<T>{},
"Cannot create a tensor on non trivial types");
DimHelper<ndim>::setDims(m, n, p, this->n);
this->computeSize();
this->values = new T[this->_size];
this->set(def);
this->wrapped = false;
}
TensorStorage(T * data, UInt m, UInt n, UInt p) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->computeSize();
this->values = data;
this->wrapped = true;
}
public:
/* ------------------------------------------------------------------------ */
template <class TensorType> inline void shallowCopy(const TensorType & src) {
this->copySize(src);
if (!this->wrapped)
delete[] this->values;
this->values = src.storage();
this->wrapped = true;
}
/* ------------------------------------------------------------------------ */
template <class TensorType> inline void deepCopy(const TensorType & src) {
this->copySize(src);
if (!this->wrapped)
delete[] this->values;
static_assert(std::is_trivially_constructible<T>{},
"Cannot create a tensor on non trivial types");
this->values = new T[this->_size];
static_assert(std::is_trivially_copyable<T>{},
"Cannot copy a tensor on non trivial types");
memcpy((void *)this->values, (void *)src.storage(),
this->_size * sizeof(T));
this->wrapped = false;
}
virtual ~TensorStorage() {
if (!this->wrapped)
delete[] this->values;
}
/* ------------------------------------------------------------------------ */
inline TensorStorage & operator=(const TensorStorage & src) {
return this->operator=(dynamic_cast<RetType &>(src));
}
/* ------------------------------------------------------------------------ */
inline TensorStorage & operator=(const RetType & src) {
if (this != &src) {
if (this->wrapped) {
static_assert(std::is_trivially_copyable<T>{},
"Cannot copy a tensor on non trivial types");
// this test is not sufficient for Tensor of order higher than 1
AKANTU_DEBUG_ASSERT(this->_size == src.size(),
"Tensors of different size");
memcpy((void *)this->values, (void *)src.storage(),
this->_size * sizeof(T));
} else {
deepCopy(src);
}
}
return *this;
}
/* ------------------------------------------------------------------------ */
template <class R>
inline RetType & operator+=(const TensorStorage<T, ndim, R> & other) {
T * a = this->storage();
T * b = other.storage();
AKANTU_DEBUG_ASSERT(
_size == other.size(),
"The two tensors do not have the same size, they cannot be subtracted");
for (UInt i = 0; i < _size; ++i)
*(a++) += *(b++);
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
template <class R>
inline RetType & operator-=(const TensorStorage<T, ndim, R> & other) {
T * a = this->storage();
T * b = other.storage();
AKANTU_DEBUG_ASSERT(
_size == other.size(),
"The two tensors do not have the same size, they cannot be subtracted");
for (UInt i = 0; i < _size; ++i)
*(a++) -= *(b++);
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator+=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i)
*(a++) += x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator-=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i)
*(a++) -= x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator*=(const T & x) {
T * a = this->storage();
for (UInt i = 0; i < _size; ++i)
*(a++) *= x;
return *(static_cast<RetType *>(this));
}
/* ---------------------------------------------------------------------- */
inline RetType & operator/=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i)
*(a++) /= x;
return *(static_cast<RetType *>(this));
}
/// Y = \alpha X + Y
inline RetType & aXplusY(const TensorStorage & other, const T & alpha = 1.) {
AKANTU_DEBUG_ASSERT(
_size == other.size(),
"The two tensors do not have the same size, they cannot be subtracted");
Math::aXplusY(this->_size, alpha, other.storage(), this->storage());
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
T * storage() const { return values; }
UInt size() const { return _size; }
UInt size(UInt i) const {
AKANTU_DEBUG_ASSERT(i < ndim,
"This tensor has only " << ndim << " dimensions, not "
<< (i + 1));
return n[i];
};
/* ------------------------------------------------------------------------ */
inline void clear() { memset(values, 0, _size * sizeof(T)); };
inline void set(const T & t) { std::fill_n(values, _size, t); };
template <class TensorType> inline void copy(const TensorType & other) {
AKANTU_DEBUG_ASSERT(
_size == other.size(),
"The two tensors do not have the same size, they cannot be copied");
memcpy(values, other.storage(), _size * sizeof(T));
}
bool isWrapped() const { return this->wrapped; }
protected:
inline void computeSize() {
_size = 1;
for (UInt d = 0; d < ndim; ++d)
_size *= this->n[d];
}
protected:
template <typename R, NormType norm_type> struct NormHelper {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm += std::pow(std::abs(*it), norm_type);
return std::pow(_norm, 1. / norm_type);
}
};
template <typename R> struct NormHelper<R, L_1> {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm += std::abs(*it);
return _norm;
}
};
template <typename R> struct NormHelper<R, L_2> {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm += *it * *it;
return sqrt(_norm);
}
};
template <typename R> struct NormHelper<R, L_inf> {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm = std::max(std::abs(*it), _norm);
return _norm;
}
};
public:
/*----------------------------------------------------------------------- */
/// "Entrywise" norm norm<L_p> @f[ \|\boldsymbol{T}\|_p = \left(
/// \sum_i^{n[0]}\sum_j^{n[1]}\sum_k^{n[2]} |T_{ijk}|^p \right)^{\frac{1}{p}}
/// @f]
template <NormType norm_type> inline T norm() const {
return NormHelper<T, norm_type>::norm(*this);
}
protected:
UInt n[ndim];
UInt _size;
T * values;
bool wrapped{false};
};
/* -------------------------------------------------------------------------- */
/* Vector */
/* -------------------------------------------------------------------------- */
template <typename T> class Vector : public TensorStorage<T, 1, Vector<T>> {
using parent = TensorStorage<T, 1, Vector<T>>;
public:
using value_type = typename parent::value_type;
using proxy = VectorProxy<T>;
public:
Vector() : parent() {}
explicit Vector(UInt n, const T & def = T()) : parent(n, 0, 0, def) {}
Vector(T * data, UInt n) : parent(data, n, 0, 0) {}
Vector(const Vector & src, bool deep_copy = true) : parent(src, deep_copy) {}
Vector(const TensorProxy<T, 1, Vector> & src) : parent(src) {}
Vector(std::initializer_list<T> list) : parent(list.size(), 0, 0, T()) {
UInt i = 0;
for (auto val : list) {
operator()(i++) = val;
}
}
public:
~Vector() override = default;
/* ------------------------------------------------------------------------ */
inline Vector & operator=(const Vector & src) {
parent::operator=(src);
return *this;
}
/* ------------------------------------------------------------------------ */
inline T & operator()(UInt i) {
AKANTU_DEBUG_ASSERT((i < this->n[0]),
"Access out of the vector! "
<< "Index (" << i
<< ") is out of the vector of size (" << this->n[0]
<< ")");
return *(this->values + i);
}
inline const T & operator()(UInt i) const {
AKANTU_DEBUG_ASSERT((i < this->n[0]),
"Access out of the vector! "
<< "Index (" << i
<< ") is out of the vector of size (" << this->n[0]
<< ")");
return *(this->values + i);
}
inline T & operator[](UInt i) { return this->operator()(i); }
inline const T & operator[](UInt i) const { return this->operator()(i); }
/* ------------------------------------------------------------------------ */
inline Vector<T> & operator*=(Real x) { return parent::operator*=(x); }
inline Vector<T> & operator/=(Real x) { return parent::operator/=(x); }
/* ------------------------------------------------------------------------ */
inline Vector<T> & operator*=(const Vector<T> & vect) {
T * a = this->storage();
T * b = vect.storage();
for (UInt i = 0; i < this->_size; ++i)
*(a++) *= *(b++);
return *this;
}
/* ------------------------------------------------------------------------ */
inline Real dot(const Vector<T> & vect) const {
return Math::vectorDot(this->values, vect.storage(), this->_size);
}
/* ------------------------------------------------------------------------ */
inline Real mean() const {
Real mean = 0;
T * a = this->storage();
for (UInt i = 0; i < this->_size; ++i)
mean += *(a++);
return mean / this->_size;
}
/* ------------------------------------------------------------------------ */
inline Vector & crossProduct(const Vector<T> & v1, const Vector<T> & v2) {
AKANTU_DEBUG_ASSERT(this->size() == 3,
"crossProduct is only defined in 3D (n=" << this->size()
<< ")");
AKANTU_DEBUG_ASSERT(
this->size() == v1.size() && this->size() == v2.size(),
"crossProduct is not a valid operation non matching size vectors");
Math::vectorProduct3(v1.storage(), v2.storage(), this->values);
return *this;
}
inline Vector crossProduct(const Vector<T> & v) {
Vector<T> tmp(this->size());
tmp.crossProduct(*this, v);
return tmp;
}
/* ------------------------------------------------------------------------ */
inline void solve(const Matrix<T> & A, const Vector<T> & b) {
AKANTU_DEBUG_ASSERT(
this->size() == A.rows() && this->_size == A.cols(),
"The size of the solution vector mismatches the size of the matrix");
AKANTU_DEBUG_ASSERT(
this->_size == b._size,
"The rhs vector has a mismatch in size with the matrix");
Math::solve(this->_size, A.storage(), this->values, b.storage());
}
/* ------------------------------------------------------------------------ */
template <bool tr_A>
inline void mul(const Matrix<T> & A, const Vector<T> & x, Real alpha = 1.0);
/* ------------------------------------------------------------------------ */
inline Real norm() const { return parent::template norm<L_2>(); }
template <NormType nt> inline Real norm() const {
return parent::template norm<nt>();
}
/* ------------------------------------------------------------------------ */
inline Vector<Real> & normalize() {
Real n = norm();
operator/=(n);
return *this;
}
/* ------------------------------------------------------------------------ */
/// norm of (*this - x)
inline Real distance(const Vector<T> & y) const {
Real * vx = this->values;
Real * vy = y.storage();
Real sum_2 = 0;
for (UInt i = 0; i < this->_size; ++i, ++vx, ++vy)
sum_2 += (*vx - *vy) * (*vx - *vy);
return sqrt(sum_2);
}
/* ------------------------------------------------------------------------ */
inline bool equal(const Vector<T> & v,
Real tolerance = Math::getTolerance()) const {
T * a = this->storage();
T * b = v.storage();
UInt i = 0;
while (i < this->_size && (std::abs(*(a++) - *(b++)) < tolerance))
++i;
return i == this->_size;
}
/* ------------------------------------------------------------------------ */
inline short compare(const Vector<T> & v,
Real tolerance = Math::getTolerance()) const {
T * a = this->storage();
T * b = v.storage();
for (UInt i(0); i < this->_size; ++i, ++a, ++b) {
if (std::abs(*a - *b) > tolerance)
return (((*a - *b) > tolerance) ? 1 : -1);
}
return 0;
}
/* ------------------------------------------------------------------------ */
inline bool operator==(const Vector<T> & v) const { return equal(v); }
inline bool operator!=(const Vector<T> & v) const { return !operator==(v); }
inline bool operator<(const Vector<T> & v) const { return compare(v) == -1; }
inline bool operator>(const Vector<T> & v) const { return compare(v) == 1; }
/* ------------------------------------------------------------------------ */
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << "[";
for (UInt i = 0; i < this->_size; ++i) {
if (i != 0)
stream << ", ";
stream << this->values[i];
}
stream << "]";
}
// friend class ::akantu::Array<T>;
};
using RVector = Vector<Real>;
/* ------------------------------------------------------------------------ */
template <>
inline bool Vector<UInt>::equal(const Vector<UInt> & v,
__attribute__((unused)) Real tolerance) const {
UInt * a = this->storage();
UInt * b = v.storage();
UInt i = 0;
while (i < this->_size && (*(a++) == *(b++)))
++i;
return i == this->_size;
}
/* ------------------------------------------------------------------------ */
/* Matrix */
/* ------------------------------------------------------------------------ */
template <typename T> class Matrix : public TensorStorage<T, 2, Matrix<T>> {
using parent = TensorStorage<T, 2, Matrix<T>>;
public:
using value_type = typename parent::value_type;
using proxy = MatrixProxy<T>;
public:
Matrix() : parent() {}
Matrix(UInt m, UInt n, const T & def = T()) : parent(m, n, 0, def) {}
Matrix(T * data, UInt m, UInt n) : parent(data, m, n, 0) {}
Matrix(const Matrix & src, bool deep_copy = true) : parent(src, deep_copy) {}
Matrix(const MatrixProxy<T> & src) : parent(src) {}
Matrix(std::initializer_list<std::initializer_list<T>> list) {
static_assert(std::is_trivially_copyable<T>{},
"Cannot create a tensor on non trivial types");
std::size_t n = 0;
std::size_t m = list.size();
for (auto row : list) {
n = std::max(n, row.size());
}
DimHelper<2>::setDims(m, n, 0, this->n);
this->computeSize();
this->values = new T[this->_size];
this->set(0);
UInt i = 0, j = 0;
for (auto & row : list) {
for (auto & val : row) {
at(i, j++) = val;
}
++i;
j = 0;
}
}
~Matrix() override = default;
/* ------------------------------------------------------------------------ */
inline Matrix & operator=(const Matrix & src) {
parent::operator=(src);
return *this;
}
public:
/* ---------------------------------------------------------------------- */
UInt rows() const { return this->n[0]; }
UInt cols() const { return this->n[1]; }
/* ---------------------------------------------------------------------- */
inline T & at(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
"Access out of the matrix! "
<< "Index (" << i << ", " << j
<< ") is out of the matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return *(this->values + i + j * this->n[0]);
}
inline const T & at(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
"Access out of the matrix! "
<< "Index (" << i << ", " << j
<< ") is out of the matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return *(this->values + i + j * this->n[0]);
}
/* ------------------------------------------------------------------------ */
inline T & operator()(UInt i, UInt j) { return this->at(i, j); }
inline const T & operator()(UInt i, UInt j) const { return this->at(i, j); }
/// give a line vector wrapped on the column i
inline VectorProxy<T> operator()(UInt j) {
AKANTU_DEBUG_ASSERT(j < this->n[1],
"Access out of the matrix! "
<< "You are trying to access the column vector "
<< j << " in a matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return VectorProxy<T>(this->values + j * this->n[0], this->n[0]);
}
inline const VectorProxy<T> operator()(UInt j) const {
AKANTU_DEBUG_ASSERT(j < this->n[1],
"Access out of the matrix! "
<< "You are trying to access the column vector "
<< j << " in a matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return VectorProxy<T>(this->values + j * this->n[0], this->n[0]);
}
inline void block(const Matrix & block, UInt pos_i, UInt pos_j) {
AKANTU_DEBUG_ASSERT(pos_i + block.rows() <= rows(),
"The block size or position are not correct");
AKANTU_DEBUG_ASSERT(pos_i + block.cols() <= cols(),
"The block size or position are not correct");
for (UInt i = 0; i < block.rows(); ++i)
for (UInt j = 0; j < block.cols(); ++j)
this->at(i + pos_i, j + pos_j) = block(i, j);
}
inline Matrix block(UInt pos_i, UInt pos_j, UInt block_rows,
UInt block_cols) const {
AKANTU_DEBUG_ASSERT(pos_i + block_rows <= rows(),
"The block size or position are not correct");
AKANTU_DEBUG_ASSERT(pos_i + block_cols <= cols(),
"The block size or position are not correct");
Matrix block(block_rows, block_cols);
for (UInt i = 0; i < block_rows; ++i)
for (UInt j = 0; j < block_cols; ++j)
block(i, j) = this->at(i + pos_i, j + pos_j);
return block;
}
inline T & operator[](UInt idx) { return *(this->values + idx); };
inline const T & operator[](UInt idx) const { return *(this->values + idx); };
/* ---------------------------------------------------------------------- */
inline Matrix operator*(const Matrix & B) {
Matrix C(this->rows(), B.cols());
C.mul<false, false>(*this, B);
return C;
}
/* ----------------------------------------------------------------------- */
inline Matrix & operator*=(const T & x) { return parent::operator*=(x); }
inline Matrix & operator*=(const Matrix & B) {
Matrix C(*this);
this->mul<false, false>(C, B);
return *this;
}
/* ---------------------------------------------------------------------- */
template <bool tr_A, bool tr_B>
inline void mul(const Matrix & A, const Matrix & B, T alpha = 1.0) {
UInt k = A.cols();
if (tr_A)
k = A.rows();
#ifndef AKANTU_NDEBUG
if (tr_B) {
AKANTU_DEBUG_ASSERT(k == B.cols(),
"matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.rows(),
"matrices to multiply have no fit dimensions");
} else {
AKANTU_DEBUG_ASSERT(k == B.rows(),
"matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.cols(),
"matrices to multiply have no fit dimensions");
}
if (tr_A) {
AKANTU_DEBUG_ASSERT(this->rows() == A.cols(),
"matrices to multiply have no fit dimensions");
} else {
AKANTU_DEBUG_ASSERT(this->rows() == A.rows(),
"matrices to multiply have no fit dimensions");
}
#endif // AKANTU_NDEBUG
Math::matMul<tr_A, tr_B>(this->rows(), this->cols(), k, alpha, A.storage(),
B.storage(), 0., this->storage());
}
/* ---------------------------------------------------------------------- */
inline void outerProduct(const Vector<T> & A, const Vector<T> & B) {
AKANTU_DEBUG_ASSERT(
A.size() == this->rows() && B.size() == this->cols(),
"A and B are not compatible with the size of the matrix");
for (UInt i = 0; i < this->rows(); ++i) {
for (UInt j = 0; j < this->cols(); ++j) {
this->values[i + j * this->rows()] += A[i] * B[j];
}
}
}
private:
class EigenSorter {
public:
EigenSorter(const Vector<T> & eigs) : eigs(eigs) {}
bool operator()(const UInt & a, const UInt & b) const {
return (eigs(a) > eigs(b));
}
private:
const Vector<T> & eigs;
};
public:
/* ---------------------------------------------------------------------- */
inline void eig(Vector<T> & eigenvalues, Matrix<T> & eigenvectors) const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"eig is not a valid operation on a rectangular matrix");
AKANTU_DEBUG_ASSERT(eigenvalues.size() == this->cols(),
"eigenvalues should be of size " << this->cols()
<< ".");
#ifndef AKANTU_NDEBUG
if (eigenvectors.storage() != nullptr)
AKANTU_DEBUG_ASSERT((eigenvectors.rows() == eigenvectors.cols()) &&
(eigenvectors.rows() == this->cols()),
"Eigenvectors needs to be a square matrix of size "
<< this->cols() << " x " << this->cols() << ".");
#endif
Matrix<T> tmp = *this;
Vector<T> tmp_eigs(eigenvalues.size());
Matrix<T> tmp_eig_vects(eigenvectors.rows(), eigenvectors.cols());
if (tmp_eig_vects.rows() == 0 || tmp_eig_vects.cols() == 0)
Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage());
else
Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage(),
tmp_eig_vects.storage());
Vector<UInt> perm(eigenvalues.size());
for (UInt i = 0; i < perm.size(); ++i)
perm(i) = i;
std::sort(perm.storage(), perm.storage() + perm.size(),
EigenSorter(tmp_eigs));
for (UInt i = 0; i < perm.size(); ++i)
eigenvalues(i) = tmp_eigs(perm(i));
if (tmp_eig_vects.rows() != 0 && tmp_eig_vects.cols() != 0)
for (UInt i = 0; i < perm.size(); ++i) {
for (UInt j = 0; j < eigenvectors.rows(); ++j) {
eigenvectors(j, i) = tmp_eig_vects(j, perm(i));
}
}
}
/* ---------------------------------------------------------------------- */
inline void eig(Vector<T> & eigenvalues) const {
Matrix<T> empty;
eig(eigenvalues, empty);
}
/* ---------------------------------------------------------------------- */
inline void eye(T alpha = 1.) {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"eye is not a valid operation on a rectangular matrix");
this->clear();
for (UInt i = 0; i < this->cols(); ++i) {
this->values[i + i * this->rows()] = alpha;
}
}
/* ---------------------------------------------------------------------- */
static inline Matrix<T> eye(UInt m, T alpha = 1.) {
Matrix<T> tmp(m, m);
tmp.eye(alpha);
return tmp;
}
/* ---------------------------------------------------------------------- */
inline T trace() const {
AKANTU_DEBUG_ASSERT(
this->cols() == this->rows(),
"trace is not a valid operation on a rectangular matrix");
T trace = 0.;
for (UInt i = 0; i < this->rows(); ++i) {
trace += this->values[i + i * this->rows()];
}
return trace;
}
/* ---------------------------------------------------------------------- */
inline Matrix transpose() const {
Matrix tmp(this->cols(), this->rows());
for (UInt i = 0; i < this->rows(); ++i) {
for (UInt j = 0; j < this->cols(); ++j) {
tmp(j, i) = operator()(i, j);
}
}
return tmp;
}
/* ---------------------------------------------------------------------- */
inline void inverse(const Matrix & A) {
AKANTU_DEBUG_ASSERT(A.cols() == A.rows(),
"inv is not a valid operation on a rectangular matrix");
AKANTU_DEBUG_ASSERT(this->cols() == A.cols(),
"the matrix should have the same size as its inverse");
if (this->cols() == 1)
*this->values = 1. / *A.storage();
else if (this->cols() == 2)
Math::inv2(A.storage(), this->values);
else if (this->cols() == 3)
Math::inv3(A.storage(), this->values);
else
Math::inv(this->cols(), A.storage(), this->values);
}
inline Matrix inverse() {
Matrix inv(this->rows(), this->cols());
inv.inverse(*this);
return inv;
}
/* --------------------------------------------------------------------- */
inline T det() const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"inv is not a valid operation on a rectangular matrix");
if (this->cols() == 1)
return *(this->values);
else if (this->cols() == 2)
return Math::det2(this->values);
else if (this->cols() == 3)
return Math::det3(this->values);
else
return Math::det(this->cols(), this->values);
}
/* --------------------------------------------------------------------- */
inline T doubleDot(const Matrix<T> & other) const {
AKANTU_DEBUG_ASSERT(
this->cols() == this->rows(),
"doubleDot is not a valid operation on a rectangular matrix");
if (this->cols() == 1)
return *(this->values) * *(other.storage());
else if (this->cols() == 2)
return Math::matrixDoubleDot22(this->values, other.storage());
else if (this->cols() == 3)
return Math::matrixDoubleDot33(this->values, other.storage());
else
AKANTU_ERROR("doubleDot is not defined for other spatial dimensions"
- << " than 1, 2 or 3.");
+ << " than 1, 2 or 3.");
return T();
}
/* ---------------------------------------------------------------------- */
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << "[";
for (UInt i = 0; i < this->n[0]; ++i) {
if (i != 0)
stream << ", ";
stream << "[";
for (UInt j = 0; j < this->n[1]; ++j) {
if (j != 0)
stream << ", ";
stream << operator()(i, j);
}
stream << "]";
}
stream << "]";
};
};
/* ------------------------------------------------------------------------ */
template <typename T>
template <bool tr_A>
inline void Vector<T>::mul(const Matrix<T> & A, const Vector<T> & x,
Real alpha) {
#ifndef AKANTU_NDEBUG
UInt n = x.size();
if (tr_A) {
AKANTU_DEBUG_ASSERT(n == A.rows(),
"matrix and vector to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->size() == A.cols(),
"matrix and vector to multiply have no fit dimensions");
} else {
AKANTU_DEBUG_ASSERT(n == A.cols(),
"matrix and vector to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->size() == A.rows(),
"matrix and vector to multiply have no fit dimensions");
}
#endif
Math::matVectMul<tr_A>(A.rows(), A.cols(), alpha, A.storage(), x.storage(),
0., this->storage());
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
const Matrix<T> & _this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
const Vector<T> & _this) {
_this.printself(stream);
return stream;
}
/* ------------------------------------------------------------------------ */
/* Tensor3 */
/* ------------------------------------------------------------------------ */
template <typename T> class Tensor3 : public TensorStorage<T, 3, Tensor3<T>> {
using parent = TensorStorage<T, 3, Tensor3<T>>;
public:
using value_type = typename parent::value_type;
using proxy = Tensor3Proxy<T>;
public:
Tensor3() : parent(){};
Tensor3(UInt m, UInt n, UInt p, const T & def = T()) : parent(m, n, p, def) {}
Tensor3(T * data, UInt m, UInt n, UInt p) : parent(data, m, n, p) {}
Tensor3(const Tensor3 & src, bool deep_copy = true)
: parent(src, deep_copy) {}
Tensor3(const proxy & src) : parent(src) {}
public:
/* ------------------------------------------------------------------------ */
inline Tensor3 & operator=(const Tensor3 & src) {
parent::operator=(src);
return *this;
}
/* ---------------------------------------------------------------------- */
inline T & operator()(UInt i, UInt j, UInt k) {
AKANTU_DEBUG_ASSERT(
(i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the element "
<< "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return *(this->values + (k * this->n[0] + i) * this->n[1] + j);
}
inline const T & operator()(UInt i, UInt j, UInt k) const {
AKANTU_DEBUG_ASSERT(
(i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the element "
<< "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return *(this->values + (k * this->n[0] + i) * this->n[1] + j);
}
inline MatrixProxy<T> operator()(UInt k) {
AKANTU_DEBUG_ASSERT((k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the slice " << k
<< " in a tensor3 of size (" << this->n[0] << ", "
<< this->n[1] << ", " << this->n[2] << ")");
return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
this->n[0], this->n[1]);
}
inline const MatrixProxy<T> operator()(UInt k) const {
AKANTU_DEBUG_ASSERT((k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the slice " << k
<< " in a tensor3 of size (" << this->n[0] << ", "
<< this->n[1] << ", " << this->n[2] << ")");
return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
this->n[0], this->n[1]);
}
inline MatrixProxy<T> operator[](UInt k) {
return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
this->n[0], this->n[1]);
}
inline const MatrixProxy<T> operator[](UInt k) const {
return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
this->n[0], this->n[1]);
}
};
/* -------------------------------------------------------------------------- */
// support operations for the creation of other vectors
/* -------------------------------------------------------------------------- */
template <typename T>
Vector<T> operator*(const T & scalar, const Vector<T> & a) {
Vector<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Vector<T> operator*(const Vector<T> & a, const T & scalar) {
Vector<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Vector<T> operator/(const Vector<T> & a, const T & scalar) {
Vector<T> r(a);
r /= scalar;
return r;
}
template <typename T>
Vector<T> operator*(const Vector<T> & a, const Vector<T> & b) {
Vector<T> r(a);
r *= b;
return r;
}
template <typename T>
Vector<T> operator+(const Vector<T> & a, const Vector<T> & b) {
Vector<T> r(a);
r += b;
return r;
}
template <typename T>
Vector<T> operator-(const Vector<T> & a, const Vector<T> & b) {
Vector<T> r(a);
r -= b;
return r;
}
template <typename T>
Vector<T> operator*(const Matrix<T> & A, const Vector<T> & b) {
Vector<T> r(b.size());
r.template mul<false>(A, b);
return r;
}
/* -------------------------------------------------------------------------- */
template <typename T>
Matrix<T> operator*(const T & scalar, const Matrix<T> & a) {
Matrix<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Matrix<T> operator*(const Matrix<T> & a, const T & scalar) {
Matrix<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Matrix<T> operator/(const Matrix<T> & a, const T & scalar) {
Matrix<T> r(a);
r /= scalar;
return r;
}
template <typename T>
Matrix<T> operator+(const Matrix<T> & a, const Matrix<T> & b) {
Matrix<T> r(a);
r += b;
return r;
}
template <typename T>
Matrix<T> operator-(const Matrix<T> & a, const Matrix<T> & b) {
Matrix<T> r(a);
r -= b;
return r;
}
} // namespace akantu
#endif /* __AKANTU_AKA_TYPES_HH__ */
diff --git a/src/common/aka_visitor.hh b/src/common/aka_visitor.hh
index 3c3bcd800..b16fe120e 100644
--- a/src/common/aka_visitor.hh
+++ b/src/common/aka_visitor.hh
@@ -1,175 +1,164 @@
/**
* @file aka_visitor.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Objects that support the visitor design pattern
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_VISITOR_HH__
#define __AKANTU_VISITOR_HH__
#include "aka_typelist.hh"
namespace akantu {
///////////////////////////////////////////////////////////////////////////
-// visitor class template, adapted from the Andrei Alexandrescu's
+// visitor class template, adapted from the Andrei Alexandrescu's
// "Modern C++ Design"
enum Visit_type { Mutable, Immutable };
-template <class T, typename R = void, Visit_type = Mutable>
-class StrictVisitor;
+template <class T, typename R = void, Visit_type = Mutable> class StrictVisitor;
-template <class T, typename R>
-class StrictVisitor<T, R, Mutable>
-{
+template <class T, typename R> class StrictVisitor<T, R, Mutable> {
public:
- typedef R ReturnType;
- typedef T ParamType;
- virtual ~StrictVisitor() {}
- virtual ReturnType Visit(ParamType&) = 0;
+ typedef R ReturnType;
+ typedef T ParamType;
+ virtual ~StrictVisitor() {}
+ virtual ReturnType Visit(ParamType &) = 0;
};
-template <class T, typename R>
-class StrictVisitor<T, R, Immutable>
-{
+template <class T, typename R> class StrictVisitor<T, R, Immutable> {
public:
- typedef R ReturnType;
- typedef const T ParamType;
- virtual ~StrictVisitor() {}
- virtual ReturnType Visit(ParamType&) = 0;
+ typedef R ReturnType;
+ typedef const T ParamType;
+ virtual ~StrictVisitor() {}
+ virtual ReturnType Visit(ParamType &) = 0;
};
/// class template StrictVisitor (specialization)
template <class Head, class Tail, typename R>
class StrictVisitor<Typelist<Head, Tail>, R, Mutable>
-: public StrictVisitor<Head, R, Mutable>, public StrictVisitor<Tail, R, Mutable>
-{
+ : public StrictVisitor<Head, R, Mutable>,
+ public StrictVisitor<Tail, R, Mutable> {
public:
- typedef R ReturnType;
- typedef Head ParamType;
- // using StrictVisitor<Head, R>::Visit;
- // using StrictVisitor<Tail, R>::Visit;
+ typedef R ReturnType;
+ typedef Head ParamType;
+ // using StrictVisitor<Head, R>::Visit;
+ // using StrictVisitor<Tail, R>::Visit;
};
template <class Head, typename R>
-class StrictVisitor<Typelist<Head, Null_type>, R, Mutable> : public StrictVisitor<Head, R, Mutable>
-{
+class StrictVisitor<Typelist<Head, Null_type>, R, Mutable>
+ : public StrictVisitor<Head, R, Mutable> {
public:
- typedef R ReturnType;
- typedef Head ParamType;
- using StrictVisitor<Head, R, Mutable>::Visit;
+ typedef R ReturnType;
+ typedef Head ParamType;
+ using StrictVisitor<Head, R, Mutable>::Visit;
};
template <class Head, class Tail, typename R>
class StrictVisitor<Typelist<Head, Tail>, R, Immutable>
-: public StrictVisitor<Head, R, Immutable>, public StrictVisitor<Tail, R, Immutable>
-{
+ : public StrictVisitor<Head, R, Immutable>,
+ public StrictVisitor<Tail, R, Immutable> {
public:
- typedef R ReturnType;
- typedef Head ParamType;
- // using StrictVisitor<Head, R>::Visit;
- // using StrictVisitor<Tail, R>::Visit;
+ typedef R ReturnType;
+ typedef Head ParamType;
+ // using StrictVisitor<Head, R>::Visit;
+ // using StrictVisitor<Tail, R>::Visit;
};
template <class Head, typename R>
-class StrictVisitor<Typelist<Head, Null_type>, R, Immutable> : public StrictVisitor<Head, R, Immutable>
-{
+class StrictVisitor<Typelist<Head, Null_type>, R, Immutable>
+ : public StrictVisitor<Head, R, Immutable> {
public:
- typedef R ReturnType;
- typedef Head ParamType;
- using StrictVisitor<Head, R, Immutable>::Visit;
+ typedef R ReturnType;
+ typedef Head ParamType;
+ using StrictVisitor<Head, R, Immutable>::Visit;
};
////////////////////////////////////////////////////////////////////////////////
// class template NonStrictVisitor
// Implements non-strict visitation (you can implement only part of the Visit
// functions)
//
-template <class R>
-struct DefaultFunctor {
- template <class T>
- R operator()(T&) { return R(); }
+template <class R> struct DefaultFunctor {
+ template <class T> R operator()(T &) { return R(); }
};
-template <class T, typename R = void, Visit_type V = Mutable, class F = DefaultFunctor<R> > class BaseVisitorImpl;
+template <class T, typename R = void, Visit_type V = Mutable,
+ class F = DefaultFunctor<R>>
+class BaseVisitorImpl;
template <class Head, class Tail, typename R, Visit_type V, class F>
class BaseVisitorImpl<Typelist<Head, Tail>, R, V, F>
-: public StrictVisitor<Head, R, V>, public BaseVisitorImpl<Tail, R, V, F> {
+ : public StrictVisitor<Head, R, V>, public BaseVisitorImpl<Tail, R, V, F> {
public:
- typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
- virtual R Visit(ParamType& h)
- { return F()(h); }
+ typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
+ virtual R Visit(ParamType & h) { return F()(h); }
};
-template <class Head, typename R, Visit_type V, class F >
-class BaseVisitorImpl<Typelist<Head, Null_type>, R, V, F> : public StrictVisitor<Head, R, V>
-{
+template <class Head, typename R, Visit_type V, class F>
+class BaseVisitorImpl<Typelist<Head, Null_type>, R, V, F>
+ : public StrictVisitor<Head, R, V> {
public:
- typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
- virtual R Visit(ParamType& h)
- { return F()(h); }
+ typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
+ virtual R Visit(ParamType & h) { return F()(h); }
};
-
/// Visitor
-template <class R>
-struct Strict {};
+template <class R> struct Strict {};
-template <typename R, class TList, Visit_type V = Mutable, template <class> class FunctorPolicy = DefaultFunctor>
-class Visitor : public BaseVisitorImpl<TList, R, V, FunctorPolicy<R> > {
+template <typename R, class TList, Visit_type V = Mutable,
+ template <class> class FunctorPolicy = DefaultFunctor>
+class Visitor : public BaseVisitorImpl<TList, R, V, FunctorPolicy<R>> {
public:
- typedef R ReturnType;
-
- template <class Visited>
- ReturnType GenericVisit(Visited& host) {
- StrictVisitor<Visited, ReturnType, V>& subObj = *this;
- return subObj.Visit(host);
- }
-};
+ typedef R ReturnType;
+ template <class Visited> ReturnType GenericVisit(Visited & host) {
+ StrictVisitor<Visited, ReturnType, V> & subObj = *this;
+ return subObj.Visit(host);
+ }
+};
template <typename R, class TList, Visit_type V>
class Visitor<R, TList, V, Strict> : public StrictVisitor<TList, R, V> {
public:
- typedef R ReturnType;
-
- template <class Visited>
- ReturnType GenericVisit(Visited& host) {
- StrictVisitor<Visited, ReturnType, V>& subObj = *this;
- return subObj.Visit(host);
- }
+ typedef R ReturnType;
+
+ template <class Visited> ReturnType GenericVisit(Visited & host) {
+ StrictVisitor<Visited, ReturnType, V> & subObj = *this;
+ return subObj.Visit(host);
+ }
};
} // akantu
#endif /* __AKANTU_VISITOR_HH__ */
diff --git a/src/common/aka_voigthelper.cc b/src/common/aka_voigthelper.cc
index 32111160c..13bdbbb3b 100644
--- a/src/common/aka_voigthelper.cc
+++ b/src/common/aka_voigthelper.cc
@@ -1,68 +1,68 @@
/**
* @file aka_voigthelper.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Dec 20 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Voigt indices
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
#include "aka_voigthelper.hh"
+#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/* clang-format off */
template <> const UInt VoigtHelper<1>::mat[][1] = {{0}};
template <> const UInt VoigtHelper<2>::mat[][2] = {{0, 2},
{3, 1}};
template <> const UInt VoigtHelper<3>::mat[][3] = {{0, 5, 4},
{8, 1, 3},
{7, 6, 2}};
template <> const UInt VoigtHelper<1>::vec[][2] = {{0, 0}};
template <> const UInt VoigtHelper<2>::vec[][2] = {{0, 0},
{1, 1},
{0, 1},
{1, 0}};
template <> const UInt VoigtHelper<3>::vec[][2] = {{0, 0},
{1, 1},
{2, 2},
{1, 2},
{0, 2},
{0, 1},
{2, 1},
{2, 0},
{1, 0}};
template <> const Real VoigtHelper<1>::factors[] = {1.};
template <> const Real VoigtHelper<2>::factors[] = {1., 1., 2.};
template <> const Real VoigtHelper<3>::factors[] = {1., 1., 1.,
2., 2., 2.};
/* clang-format on */
} // akantu
diff --git a/src/common/aka_voigthelper.hh b/src/common/aka_voigthelper.hh
index 23b3a41d7..25a0cd79b 100644
--- a/src/common/aka_voigthelper.hh
+++ b/src/common/aka_voigthelper.hh
@@ -1,78 +1,79 @@
/**
* @file aka_voigthelper.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Dec 20 2013
* @date last modification: Fri Jan 22 2016
*
* @brief Helper file for Voigt notation
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKA_VOIGTHELPER_HH__
#define __AKA_VOIGTHELPER_HH__
#include "aka_common.hh"
#include "aka_types.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt dim> class VoigtHelper {
static_assert(dim != 0, "Cannot be 0D");
+
public:
/// transfer the B matrix to a Voigt notation B matrix
inline static void transferBMatrixToSymVoigtBMatrix(
const Matrix<Real> & B, Matrix<Real> & Bvoigt, UInt nb_nodes_per_element);
/// transfer the BNL matrix to a Voigt notation B matrix (See Bathe et al.
/// IJNME vol 9, 1975)
inline static void transferBMatrixToBNL(const Matrix<Real> & B,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element);
/// transfer the BL2 matrix to a Voigt notation B matrix (See Bathe et al.
/// IJNME vol 9, 1975)
inline static void transferBMatrixToBL2(const Matrix<Real> & B,
const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element);
public:
static constexpr UInt size{(dim * (dim - 1)) / 2 + dim};
// matrix of vector index I as function of tensor indices i,j
static const UInt mat[dim][dim];
// array of matrix indices ij as function of vector index I
static const UInt vec[dim * dim][2];
// factors to multiply the strain by for voigt notation
static const Real factors[size];
};
} // akantu
#include "aka_voigthelper_tmpl.hh"
#endif
diff --git a/src/common/aka_voigthelper_tmpl.hh b/src/common/aka_voigthelper_tmpl.hh
index e69d506a4..1c7cec16d 100644
--- a/src/common/aka_voigthelper_tmpl.hh
+++ b/src/common/aka_voigthelper_tmpl.hh
@@ -1,150 +1,149 @@
/**
* @file aka_voigthelper_tmpl.hh
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @date Wed Nov 16 12:22:58 2016
*/
/* -------------------------------------------------------------------------- */
#include "aka_voigthelper.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_VOIGTHELPER_TMPL_HH__
#define __AKANTU_AKA_VOIGTHELPER_TMPL_HH__
namespace akantu {
-template <UInt dim>
-constexpr UInt VoigtHelper<dim>::size;
+template <UInt dim> constexpr UInt VoigtHelper<dim>::size;
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
const Matrix<Real> & B, Matrix<Real> & Bvoigt, UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt i = 0; i < dim; ++i)
for (UInt n = 0; n < nb_nodes_per_element; ++n)
Bvoigt(i, i + n * dim) = B(i, n);
if (dim == 2) {
/// in 2D, fill the @f$ [\frac{\partial N_i}{\partial x}, \frac{\partial
/// N_i}{\partial y}]@f$ row
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
Bvoigt(2, 1 + n * 2) = B(0, n);
Bvoigt(2, 0 + n * 2) = B(1, n);
}
}
if (dim == 3) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
Real dndx = B(0, n);
Real dndy = B(1, n);
Real dndz = B(2, n);
/// in 3D, fill the @f$ [0, \frac{\partial N_i}{\partial y},
/// \frac{N_i}{\partial z}]@f$ row
Bvoigt(3, 1 + n * 3) = dndz;
Bvoigt(3, 2 + n * 3) = dndy;
/// in 3D, fill the @f$ [\frac{\partial N_i}{\partial x}, 0,
/// \frac{N_i}{\partial z}]@f$ row
Bvoigt(4, 0 + n * 3) = dndz;
Bvoigt(4, 2 + n * 3) = dndx;
/// in 3D, fill the @f$ [\frac{\partial N_i}{\partial x},
/// \frac{N_i}{\partial y}, 0]@f$ row
Bvoigt(5, 0 + n * 3) = dndy;
Bvoigt(5, 1 + n * 3) = dndx;
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void VoigtHelper<dim>::transferBMatrixToBNL(const Matrix<Real> & B,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
// see Finite element formulations for large deformation dynamic analysis,
// Bathe et al. IJNME vol 9, 1975, page 364 B_{NL}
for (UInt i = 0; i < dim; ++i) {
for (UInt m = 0; m < nb_nodes_per_element; ++m) {
for (UInt n = 0; n < dim; ++n) {
// std::cout << B(n, m) << std::endl;
Bvoigt(i * dim + n, m * dim + i) = B(n, m);
}
}
}
// TODO: Verify the 2D and 1D case
}
/* -------------------------------------------------------------------------- */
template <>
inline void VoigtHelper<1>::transferBMatrixToBL2(const Matrix<Real> & B,
const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt j = 0; j < nb_nodes_per_element; ++j)
for (UInt k = 0; k < 2; ++k)
Bvoigt(0, j * 2 + k) = grad_u(k, 0) * B(0, j);
}
/* -------------------------------------------------------------------------- */
template <>
inline void VoigtHelper<3>::transferBMatrixToBL2(const Matrix<Real> & B,
const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt i = 0; i < 3; ++i)
for (UInt j = 0; j < nb_nodes_per_element; ++j)
for (UInt k = 0; k < 3; ++k)
Bvoigt(i, j * 3 + k) = grad_u(k, i) * B(i, j);
for (UInt i = 3; i < 6; ++i) {
for (UInt j = 0; j < nb_nodes_per_element; ++j) {
for (UInt k = 0; k < 3; ++k) {
UInt aux = i - 3;
for (UInt m = 0; m < 3; ++m) {
if (m != aux) {
UInt index1 = m;
UInt index2 = 3 - m - aux;
Bvoigt(i, j * 3 + k) += grad_u(k, index1) * B(index2, j);
}
}
}
}
}
}
/* -------------------------------------------------------------------------- */
template <>
inline void VoigtHelper<2>::transferBMatrixToBL2(const Matrix<Real> & B,
const Matrix<Real> & grad_u,
Matrix<Real> & Bvoigt,
UInt nb_nodes_per_element) {
Bvoigt.clear();
for (UInt i = 0; i < 2; ++i)
for (UInt j = 0; j < nb_nodes_per_element; ++j)
for (UInt k = 0; k < 2; ++k)
Bvoigt(i, j * 2 + k) = grad_u(k, i) * B(i, j);
for (UInt j = 0; j < nb_nodes_per_element; ++j) {
for (UInt k = 0; k < 2; ++k) {
for (UInt m = 0; m < 2; ++m) {
UInt index1 = m;
UInt index2 = (2 - 1) - m;
Bvoigt(2, j * 2 + k) += grad_u(k, index1) * B(index2, j);
}
}
}
}
} // akantu
#endif /* __AKANTU_AKA_VOIGTHELPER_TMPL_HH__ */
diff --git a/src/common/aka_warning.hh b/src/common/aka_warning.hh
index a4fd654b7..21db7d188 100644
--- a/src/common/aka_warning.hh
+++ b/src/common/aka_warning.hh
@@ -1,23 +1,25 @@
// Intel warnings
#if defined(__INTEL_COMPILER)
-# if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
-# endif
+#if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
+#endif
// Clang Warnings
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
-# pragma clang diagnostic push
-# if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
-# pragma clang diagnostic ignored "-Wunused-parameter"
-# endif
+#elif defined(__clang__) // test clang to be sure that when we test for gnu it
+ // is only gnu
+#pragma clang diagnostic push
+#if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#endif
// GCC warnings
#elif (defined(__GNUC__) || defined(__GNUG__))
-# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-# if GCC_VERSION > 40600
-# pragma GCC diagnostic push
-# endif
-# if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-# endif
+#define GCC_VERSION \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION > 40600
+#pragma GCC diagnostic push
+#endif
+#if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
#endif
diff --git a/src/common/aka_warning_restore.hh b/src/common/aka_warning_restore.hh
index 466150767..6f123debb 100644
--- a/src/common/aka_warning_restore.hh
+++ b/src/common/aka_warning_restore.hh
@@ -1,15 +1,16 @@
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
-# pragma clang diagnostic pop
+#elif defined(__clang__) // test clang to be sure that when we test for gnu it
+ // is only gnu
+#pragma clang diagnostic pop
#elif defined(__GNUG__)
-# if GCC_VERSION > 40600
-# pragma GCC diagnostic pop
-# else
-# if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
-# pragma GCC diagnostic warning "-Wunused-parameter"
-# endif
-# endif
+#if GCC_VERSION > 40600
+#pragma GCC diagnostic pop
+#else
+#if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
+#pragma GCC diagnostic warning "-Wunused-parameter"
+#endif
+#endif
#endif
#undef AKANTU_WARNING_IGNORE_UNUSED_PARAMETER
diff --git a/src/fe_engine/element.hh b/src/fe_engine/element.hh
index a0198b308..fd5f4d668 100644
--- a/src/fe_engine/element.hh
+++ b/src/fe_engine/element.hh
@@ -1,112 +1,112 @@
/**
* @file element.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Sat Jul 11 2015
*
* @brief Element helper class
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_HH__
#define __AKANTU_ELEMENT_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
/* Element */
/* -------------------------------------------------------------------------- */
class Element {
public:
ElementType type;
UInt element;
GhostType ghost_type;
// ElementKind kind;
// ElementType type{_not_defined};
// UInt element{0};
// GhostType ghost_type{_not_ghost};
// ElementKind kind{_ek_regular};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline ElementKind kind() const;
inline bool operator==(const Element & elem) const {
return std::tie(type, element, ghost_type) ==
std::tie(elem.type, elem.element, elem.ghost_type);
}
inline bool operator!=(const Element & elem) const {
return std::tie(type, element, ghost_type) !=
std::tie(elem.type, elem.element, elem.ghost_type);
}
// inline bool operator==(const Element & elem) const {
// return ((element == elem.element) && (type == elem.type) &&
// (ghost_type == elem.ghost_type) && (kind == elem.kind));
// }
// inline bool operator!=(const Element & elem) const {
// return ((element != elem.element) || (type != elem.type) ||
// (ghost_type != elem.ghost_type) || (kind != elem.kind));
// }
inline bool operator<(const Element & rhs) const;
};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream, const Element & _this) {
stream << "Element [" << _this.type << ", " << _this.element << ", "
<< _this.ghost_type << "]";
return stream;
}
namespace {
-const Element ElementNull{_not_defined, UInt(-1), _casper};
-// Element{_not_defined, 0, _casper, _ek_not_defined};
+ const Element ElementNull{_not_defined, UInt(-1), _casper};
+ // Element{_not_defined, 0, _casper, _ek_not_defined};
}
/* -------------------------------------------------------------------------- */
inline bool Element::operator<(const Element & rhs) const {
// bool res =
// (rhs == ElementNull) ||
// ((this->kind < rhs.kind) ||
// ((this->kind == rhs.kind) &&
// ((this->ghost_type < rhs.ghost_type) ||
// ((this->ghost_type == rhs.ghost_type) &&
// ((this->type < rhs.type) ||
// ((this->type == rhs.type) && (this->element < rhs.element)))))));
return ((rhs == ElementNull) ||
std::tie(ghost_type, type, element) <
std::tie(rhs.ghost_type, rhs.type, rhs.element));
}
} // namespace akantu
#endif /* __AKANTU_ELEMENT_HH__ */
diff --git a/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc b/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc
index 8d79e01c5..03972b2a0 100644
--- a/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc
@@ -1,180 +1,179 @@
/**
* @file element_class_hermite_inline_impl.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type
_hermite
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
--x-----q1----|----q2-----x---> x
-1 0 1
@endverbatim
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{ll}
* M_1(\xi) &= 1/4(\xi^{3}/-3\xi+2)\\
* M_2(\xi) &= -1/4(\xi^{3}-3\xi-2)
* \end{array}
*
* \begin{array}{ll}
* L_1(\xi) &= 1/4(\xi^{3}-\xi^{2}-\xi+1)\\
* L_2(\xi) &= 1/4(\xi^{3}+\xi^{2}-\xi-1)
* \end{array}
*
* \begin{array}{ll}
* M'_1(\xi) &= 3/4(\xi^{2}-1)\\
* M'_2(\xi) &= -3/4(\xi^{2}-1)
* \end{array}
*
* \begin{array}{ll}
* L'_1(\xi) &= 1/4(3\xi^{2}-2\xi-1)\\
* L'_2(\xi) &= 1/4(3\xi^{2}+2\xi-1)
* \end{array}
*@f]
*
* @subsection dnds Shape derivatives
*
*@f[
* \begin{array}{ll}
* N'_1(\xi) &= -1/2\\
* N'_2(\xi) &= 1/2
* \end{array}]
*
* \begin{array}{ll}
* -M''_1(\xi) &= -3\xi/2\\
* -M''_2(\xi) &= 3\xi/2\\
* \end{array}
*
* \begin{array}{ll}
* -L''_1(\xi) &= -1/2a(3\xi/a-1)\\
* -L''_2(\xi) &= -1/2a(3\xi/a+1)
* \end{array}
*@f]
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_static_if.hh"
#include "element_class_structural.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_CLASS_HERMITE_INLINE_IMPL_CC__
#define __AKANTU_ELEMENT_CLASS_HERMITE_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_hermite_2,
_itp_lagrange_segment_2, 2,
1, 4);
/* -------------------------------------------------------------------------- */
namespace {
namespace details {
inline Real computeLength(const Matrix<Real> & real_coord) {
Vector<Real> x1 = real_coord(0);
Vector<Real> x2 = real_coord(1);
return x1.distance(x2);
}
- inline void computeShapes(const Vector<Real> & natural_coords, Real a, Matrix<Real> & N) {
+ inline void computeShapes(const Vector<Real> & natural_coords, Real a,
+ Matrix<Real> & N) {
/// natural coordinate
Real xi = natural_coords(0);
// Cubic Hermite splines interpolating displacement
auto M1 = 1. / 4. * Math::pow<2>(xi - 1) * (xi + 2);
auto M2 = 1. / 4. * Math::pow<2>(xi + 1) * (2 - xi);
auto L1 = a / 4. * Math::pow<2>(xi - 1) * (xi + 1);
auto L2 = a / 4. * Math::pow<2>(xi + 1) * (xi - 1);
#if 1 // Version where we also interpolate the rotations
// Derivatives (with respect to x) of previous functions interpolating
// rotations
auto M1_ = 3. / (4. * a) * (xi * xi - 1);
auto M2_ = 3. / (4. * a) * (1 - xi * xi);
- auto L1_ = 1 / 4. *
- (3 * xi * xi - 2 * xi - 1);
- auto L2_ = 1 / 4. *
- (3 * xi * xi + 2 * xi - 1);
+ auto L1_ = 1 / 4. * (3 * xi * xi - 2 * xi - 1);
+ auto L2_ = 1 / 4. * (3 * xi * xi + 2 * xi - 1);
// clang-format off
// v1 t1 v2 t2
N = {{M1 , L1 , M2 , L2}, // displacement interpolation
{M1_, L1_, M2_, L2_}}; // rotation interpolation
- // clang-format on
+// clang-format on
#else // Version where we only interpolate displacements
// clang-format off
// v1 t1 v2 t2
N = {{M1, L1, M2, L2}};
- // clang-format on
+// clang-format on
#endif
}
/* ---------------------------------------------------------------------- */
inline void computeDNDS(const Vector<Real> & natural_coords, Real a,
- Matrix<Real> & B) {
+ Matrix<Real> & B) {
// natural coordinate
Real xi = natural_coords(0);
// Derivatives with respect to xi for rotations
auto M1__ = 3. / 2. * xi;
auto M2__ = 3. / 2. * (-xi);
auto L1__ = a / 2. * (3 * xi - 1);
auto L2__ = a / 2. * (3 * xi + 1);
// v1 t1 v2 t2
B = {{M1__, L1__, M2__, L2__}}; // computing curvature : {chi} = [B]{d}
B /= a; // to account for first order deriv w/r to x
}
} // namespace details
} // namespace
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes(
const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
Matrix<Real> & N) {
auto L = details::computeLength(real_coord);
details::computeShapes(natural_coords, L / 2, N);
}
/* -------------------------------------------------------------------------- */
template <>
inline void InterpolationElement<_itp_hermite_2, _itk_structural>::computeDNDS(
const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
Matrix<Real> & B) {
auto L = details::computeLength(real_coord);
details::computeDNDS(natural_coords, L / 2, B);
}
} // namespace akantu
#endif /* __AKANTU_ELEMENT_CLASS_HERMITE_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc b/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
index dfee018d7..9fb1cc1ac 100644
--- a/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
@@ -1,215 +1,254 @@
/**
* @file element_class_hexahedron_8_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Peter Spijker <peter.spijker@epfl.ch>
*
* @date creation: Mon Mar 14 2011
* @date last modification: Sat Sep 12 2015
*
* @brief Specialization of the element_class class for the type _hexahedron_8
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
\zeta
^
(-1,1,1) | (1,1,1)
7---|------6
/| | /|
/ | | / |
(-1,-1,1) 4----------5 | (1,-1,1)
| | | | |
| | | | |
| | +---|-------> \xi
| | / | |
(-1,1,-1) | 3-/-----|--2 (1,1,-1)
| / / | /
|/ / |/
0-/--------1
(-1,-1,-1) / (1,-1,-1)
/
\eta
@endverbatim
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{llll}
* N1 = (1 - \xi) (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N1}{\partial \xi} = - (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N1}{\partial \eta} = - (1 - \xi) (1 - \zeta) / 8
* & \frac{\partial N1}{\partial \zeta} = - (1 - \xi) (1 - \eta) / 8 \\
* N2 = (1 + \xi) (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N2}{\partial \xi} = (1 - \eta) (1 - \zeta) / 8
* & \frac{\partial N2}{\partial \eta} = - (1 + \xi) (1 - \zeta) / 8
* & \frac{\partial N2}{\partial \zeta} = - (1 + \xi) (1 - \eta) / 8 \\
* N3 = (1 + \xi) (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N3}{\partial \xi} = (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N3}{\partial \eta} = (1 + \xi) (1 - \zeta) / 8
* & \frac{\partial N3}{\partial \zeta} = - (1 + \xi) (1 + \eta) / 8 \\
* N4 = (1 - \xi) (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N4}{\partial \xi} = - (1 + \eta) (1 - \zeta) / 8
* & \frac{\partial N4}{\partial \eta} = (1 - \xi) (1 - \zeta) / 8
* & \frac{\partial N4}{\partial \zeta} = - (1 - \xi) (1 + \eta) / 8 \\
* N5 = (1 - \xi) (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N5}{\partial \xi} = - (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N5}{\partial \eta} = - (1 - \xi) (1 + \zeta) / 8
* & \frac{\partial N5}{\partial \zeta} = (1 - \xi) (1 - \eta) / 8 \\
* N6 = (1 + \xi) (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N6}{\partial \xi} = (1 - \eta) (1 + \zeta) / 8
* & \frac{\partial N6}{\partial \eta} = - (1 + \xi) (1 + \zeta) / 8
* & \frac{\partial N6}{\partial \zeta} = (1 + \xi) (1 - \eta) / 8 \\
* N7 = (1 + \xi) (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N7}{\partial \xi} = (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N7}{\partial \eta} = (1 + \xi) (1 + \zeta) / 8
* & \frac{\partial N7}{\partial \zeta} = (1 + \xi) (1 + \eta) / 8 \\
* N8 = (1 - \xi) (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N8}{\partial \xi} = - (1 + \eta) (1 + \zeta) / 8
* & \frac{\partial N8}{\partial \eta} = (1 - \xi) (1 + \zeta) / 8
* & \frac{\partial N8}{\partial \zeta} = (1 - \xi) (1 + \eta) / 8 \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
- * \xi_{q0} &=& -1/\sqrt{3} \qquad \eta_{q0} = -1/\sqrt{3} \qquad \zeta_{q0} = -1/\sqrt{3} \\
- * \xi_{q1} &=& 1/\sqrt{3} \qquad \eta_{q1} = -1/\sqrt{3} \qquad \zeta_{q1} = -1/\sqrt{3} \\
- * \xi_{q2} &=& 1/\sqrt{3} \qquad \eta_{q2} = 1/\sqrt{3} \qquad \zeta_{q2} = -1/\sqrt{3} \\
- * \xi_{q3} &=& -1/\sqrt{3} \qquad \eta_{q3} = 1/\sqrt{3} \qquad \zeta_{q3} = -1/\sqrt{3} \\
- * \xi_{q4} &=& -1/\sqrt{3} \qquad \eta_{q4} = -1/\sqrt{3} \qquad \zeta_{q4} = 1/\sqrt{3} \\
- * \xi_{q5} &=& 1/\sqrt{3} \qquad \eta_{q5} = -1/\sqrt{3} \qquad \zeta_{q5} = 1/\sqrt{3} \\
- * \xi_{q6} &=& 1/\sqrt{3} \qquad \eta_{q6} = 1/\sqrt{3} \qquad \zeta_{q6} = 1/\sqrt{3} \\
- * \xi_{q7} &=& -1/\sqrt{3} \qquad \eta_{q7} = 1/\sqrt{3} \qquad \zeta_{q7} = 1/\sqrt{3} \\
+ * \xi_{q0} &=& -1/\sqrt{3} \qquad \eta_{q0} = -1/\sqrt{3} \qquad \zeta_{q0} =
+ -1/\sqrt{3} \\
+ * \xi_{q1} &=& 1/\sqrt{3} \qquad \eta_{q1} = -1/\sqrt{3} \qquad \zeta_{q1} =
+ -1/\sqrt{3} \\
+ * \xi_{q2} &=& 1/\sqrt{3} \qquad \eta_{q2} = 1/\sqrt{3} \qquad \zeta_{q2} =
+ -1/\sqrt{3} \\
+ * \xi_{q3} &=& -1/\sqrt{3} \qquad \eta_{q3} = 1/\sqrt{3} \qquad \zeta_{q3} =
+ -1/\sqrt{3} \\
+ * \xi_{q4} &=& -1/\sqrt{3} \qquad \eta_{q4} = -1/\sqrt{3} \qquad \zeta_{q4} =
+ 1/\sqrt{3} \\
+ * \xi_{q5} &=& 1/\sqrt{3} \qquad \eta_{q5} = -1/\sqrt{3} \qquad \zeta_{q5} =
+ 1/\sqrt{3} \\
+ * \xi_{q6} &=& 1/\sqrt{3} \qquad \eta_{q6} = 1/\sqrt{3} \qquad \zeta_{q6} =
+ 1/\sqrt{3} \\
+ * \xi_{q7} &=& -1/\sqrt{3} \qquad \eta_{q7} = 1/\sqrt{3} \qquad \zeta_{q7} =
+ 1/\sqrt{3} \\
* @f}
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_hexahedron_8,
- _gt_hexahedron_8,
- _itp_lagrange_hexahedron_8,
- _ek_regular,
- 3,
- _git_segment, 2);
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_hexahedron_8, _gt_hexahedron_8,
+ _itp_lagrange_hexahedron_8, _ek_regular, 3,
+ _git_segment, 2);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_hexahedron_8>::computeShapes(const vector_type & c,
- vector_type & N) {
+inline void InterpolationElement<_itp_lagrange_hexahedron_8>::computeShapes(
+ const vector_type & c, vector_type & N) {
/// Natural coordinates
N(0) = .125 * (1 - c(0)) * (1 - c(1)) * (1 - c(2)); /// N1(q_0)
N(1) = .125 * (1 + c(0)) * (1 - c(1)) * (1 - c(2)); /// N2(q_0)
N(2) = .125 * (1 + c(0)) * (1 + c(1)) * (1 - c(2)); /// N3(q_0)
N(3) = .125 * (1 - c(0)) * (1 + c(1)) * (1 - c(2)); /// N4(q_0)
N(4) = .125 * (1 - c(0)) * (1 - c(1)) * (1 + c(2)); /// N5(q_0)
N(5) = .125 * (1 + c(0)) * (1 - c(1)) * (1 + c(2)); /// N6(q_0)
N(6) = .125 * (1 + c(0)) * (1 + c(1)) * (1 + c(2)); /// N7(q_0)
N(7) = .125 * (1 - c(0)) * (1 + c(1)) * (1 + c(2)); /// N8(q_0)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_hexahedron_8>::computeDNDS(const vector_type & c,
- matrix_type & dnds) {
+inline void InterpolationElement<_itp_lagrange_hexahedron_8>::computeDNDS(
+ const vector_type & c, matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccccc}
- * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
- * & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi}
- * & \frac{\partial N5}{\partial \xi} & \frac{\partial N6}{\partial \xi}
- * & \frac{\partial N7}{\partial \xi} & \frac{\partial N8}{\partial \xi}\\
- * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
- * & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta}
- * & \frac{\partial N5}{\partial \eta} & \frac{\partial N6}{\partial \eta}
- * & \frac{\partial N7}{\partial \eta} & \frac{\partial N8}{\partial \eta}\\
- * \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial \zeta}
- * & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial \zeta}
- * & \frac{\partial N5}{\partial \zeta} & \frac{\partial N6}{\partial \zeta}
- * & \frac{\partial N7}{\partial \zeta} & \frac{\partial N8}{\partial \zeta}
+ * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial
+ * \xi}
+ * & \frac{\partial N3}{\partial \xi} & \frac{\partial
+ * N4}{\partial \xi}
+ * & \frac{\partial N5}{\partial \xi} & \frac{\partial
+ * N6}{\partial \xi}
+ * & \frac{\partial N7}{\partial \xi} & \frac{\partial
+ * N8}{\partial \xi}\\
+ * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
+ * \eta}
+ * & \frac{\partial N3}{\partial \eta} & \frac{\partial
+ * N4}{\partial \eta}
+ * & \frac{\partial N5}{\partial \eta} & \frac{\partial
+ * N6}{\partial \eta}
+ * & \frac{\partial N7}{\partial \eta} & \frac{\partial
+ * N8}{\partial \eta}\\
+ * \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial
+ * \zeta}
+ * & \frac{\partial N3}{\partial \zeta} & \frac{\partial
+ * N4}{\partial \zeta}
+ * & \frac{\partial N5}{\partial \zeta} & \frac{\partial
+ * N6}{\partial \zeta}
+ * & \frac{\partial N7}{\partial \zeta} & \frac{\partial
+ * N8}{\partial \zeta}
* \end{array}
* \right)
* @f]
*/
- dnds(0, 0) = - .125 * (1 - c(1)) * (1 - c(2));;
- dnds(0, 1) = .125 * (1 - c(1)) * (1 - c(2));;
- dnds(0, 2) = .125 * (1 + c(1)) * (1 - c(2));;
- dnds(0, 3) = - .125 * (1 + c(1)) * (1 - c(2));;
- dnds(0, 4) = - .125 * (1 - c(1)) * (1 + c(2));;
- dnds(0, 5) = .125 * (1 - c(1)) * (1 + c(2));;
- dnds(0, 6) = .125 * (1 + c(1)) * (1 + c(2));;
- dnds(0, 7) = - .125 * (1 + c(1)) * (1 + c(2));;
+ dnds(0, 0) = -.125 * (1 - c(1)) * (1 - c(2));
+ ;
+ dnds(0, 1) = .125 * (1 - c(1)) * (1 - c(2));
+ ;
+ dnds(0, 2) = .125 * (1 + c(1)) * (1 - c(2));
+ ;
+ dnds(0, 3) = -.125 * (1 + c(1)) * (1 - c(2));
+ ;
+ dnds(0, 4) = -.125 * (1 - c(1)) * (1 + c(2));
+ ;
+ dnds(0, 5) = .125 * (1 - c(1)) * (1 + c(2));
+ ;
+ dnds(0, 6) = .125 * (1 + c(1)) * (1 + c(2));
+ ;
+ dnds(0, 7) = -.125 * (1 + c(1)) * (1 + c(2));
+ ;
- dnds(1, 0) = - .125 * (1 - c(0)) * (1 - c(2));;
- dnds(1, 1) = - .125 * (1 + c(0)) * (1 - c(2));;
- dnds(1, 2) = .125 * (1 + c(0)) * (1 - c(2));;
- dnds(1, 3) = .125 * (1 - c(0)) * (1 - c(2));;
- dnds(1, 4) = - .125 * (1 - c(0)) * (1 + c(2));;
- dnds(1, 5) = - .125 * (1 + c(0)) * (1 + c(2));;
- dnds(1, 6) = .125 * (1 + c(0)) * (1 + c(2));;
- dnds(1, 7) = .125 * (1 - c(0)) * (1 + c(2));;
+ dnds(1, 0) = -.125 * (1 - c(0)) * (1 - c(2));
+ ;
+ dnds(1, 1) = -.125 * (1 + c(0)) * (1 - c(2));
+ ;
+ dnds(1, 2) = .125 * (1 + c(0)) * (1 - c(2));
+ ;
+ dnds(1, 3) = .125 * (1 - c(0)) * (1 - c(2));
+ ;
+ dnds(1, 4) = -.125 * (1 - c(0)) * (1 + c(2));
+ ;
+ dnds(1, 5) = -.125 * (1 + c(0)) * (1 + c(2));
+ ;
+ dnds(1, 6) = .125 * (1 + c(0)) * (1 + c(2));
+ ;
+ dnds(1, 7) = .125 * (1 - c(0)) * (1 + c(2));
+ ;
- dnds(2, 0) = - .125 * (1 - c(0)) * (1 - c(1));;
- dnds(2, 1) = - .125 * (1 + c(0)) * (1 - c(1));;
- dnds(2, 2) = - .125 * (1 + c(0)) * (1 + c(1));;
- dnds(2, 3) = - .125 * (1 - c(0)) * (1 + c(1));;
- dnds(2, 4) = .125 * (1 - c(0)) * (1 - c(1));;
- dnds(2, 5) = .125 * (1 + c(0)) * (1 - c(1));;
- dnds(2, 6) = .125 * (1 + c(0)) * (1 + c(1));;
- dnds(2, 7) = .125 * (1 - c(0)) * (1 + c(1));;
+ dnds(2, 0) = -.125 * (1 - c(0)) * (1 - c(1));
+ ;
+ dnds(2, 1) = -.125 * (1 + c(0)) * (1 - c(1));
+ ;
+ dnds(2, 2) = -.125 * (1 + c(0)) * (1 + c(1));
+ ;
+ dnds(2, 3) = -.125 * (1 - c(0)) * (1 + c(1));
+ ;
+ dnds(2, 4) = .125 * (1 - c(0)) * (1 - c(1));
+ ;
+ dnds(2, 5) = .125 * (1 + c(0)) * (1 - c(1));
+ ;
+ dnds(2, 6) = .125 * (1 + c(0)) * (1 + c(1));
+ ;
+ dnds(2, 7) = .125 * (1 - c(0)) * (1 + c(1));
+ ;
}
/* -------------------------------------------------------------------------- */
-template<>
+template <>
inline Real
GeometricalElement<_gt_hexahedron_8>::getInradius(const Matrix<Real> & coord) {
Vector<Real> u0 = coord(0);
Vector<Real> u1 = coord(1);
Vector<Real> u2 = coord(2);
Vector<Real> u3 = coord(3);
Vector<Real> u4 = coord(4);
Vector<Real> u5 = coord(5);
Vector<Real> u6 = coord(6);
Vector<Real> u7 = coord(7);
Real a = u0.distance(u1);
Real b = u1.distance(u2);
Real c = u2.distance(u3);
Real d = u3.distance(u0);
Real e = u0.distance(u4);
Real f = u1.distance(u5);
Real g = u2.distance(u6);
Real h = u3.distance(u7);
Real i = u4.distance(u5);
Real j = u5.distance(u6);
Real k = u6.distance(u7);
Real l = u7.distance(u4);
Real x = std::min(a, std::min(b, std::min(c, d)));
Real y = std::min(e, std::min(f, std::min(g, h)));
Real z = std::min(i, std::min(j, std::min(k, l)));
Real p = std::min(x, std::min(y, z));
return p;
}
diff --git a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
index 08fcce9f9..b74beaa9e 100644
--- a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
@@ -1,212 +1,212 @@
/**
* @file element_class_kirchhoff_shell_inline_impl.cc
*
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 04 2014
* @date last modification: Sun Oct 19 2014
*
* @brief Element class Kirchhoff Shell
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class_structural.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__
#define __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(
_itp_discrete_kirchhoff_triangle_18, _itp_lagrange_triangle_3, 6, 6, 21);
AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(
_discrete_kirchhoff_triangle_18, _gt_triangle_3,
_itp_discrete_kirchhoff_triangle_18, _triangle_3, _ek_structural, 3,
_git_triangle, 2);
/* -------------------------------------------------------------------------- */
namespace detail {
inline void computeBasisChangeMatrix(Matrix<Real> & P,
const Matrix<Real> & X) {
Vector<Real> X1 = X(0);
Vector<Real> X2 = X(1);
Vector<Real> X3 = X(2);
Vector<Real> a1 = X2 - X1;
Vector<Real> a2 = X3 - X1;
a1.normalize();
Vector<Real> e3 = a1.crossProduct(a2);
e3.normalize();
Vector<Real> e2 = e3.crossProduct(a1);
P(0) = a1;
P(1) = e2;
P(2) = e3;
P = P.transpose();
}
}
/* -------------------------------------------------------------------------- */
template <>
inline void
ElementClass<_discrete_kirchhoff_triangle_18>::computeRotationMatrix(
Matrix<Real> & R, const Matrix<Real> & X, const Vector<Real> &) {
auto dim = X.rows();
Matrix<Real> P(dim, dim);
detail::computeBasisChangeMatrix(P, X);
R.clear();
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
R(i + dim, j + dim) = R(i, j) = P(i, j);
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_discrete_kirchhoff_triangle_18>::computeShapes(
const Vector<Real> & /*natural_coords*/,
const Matrix<Real> & /*real_coord*/, Matrix<Real> & /*N*/) {}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_discrete_kirchhoff_triangle_18>::computeDNDS(
const Vector<Real> & natural_coords, const Matrix<Real> & real_coordinates,
Matrix<Real> & B) {
auto dim = real_coordinates.cols();
Matrix<Real> P(dim, dim);
detail::computeBasisChangeMatrix(P, real_coordinates);
auto X = P * real_coordinates;
Vector<Real> X1 = X(0);
Vector<Real> X2 = X(1);
Vector<Real> X3 = X(2);
std::array<Vector<Real>, 3> A = {X2 - X1, X3 - X2, X1 - X3};
std::array<Real, 3> L, C, S;
// Setting all last coordinates to 0
std::for_each(A.begin(), A.end(), [](auto & a) { a(2) = 0; });
// Computing lengths
std::transform(A.begin(), A.end(), L.begin(),
[](auto & a) { return a.template norm<L_2>(); });
// Computing cosines
std::transform(A.begin(), A.end(), L.begin(), C.begin(),
[](auto & a, auto & l) { return a(0) / l; });
// Computing sines
std::transform(A.begin(), A.end(), L.begin(), S.begin(),
[](auto & a, auto & l) { return a(1) / l; });
// Natural coordinates
Real xi = natural_coords(0);
Real eta = natural_coords(1);
// Derivative of quadratic interpolation functions
Matrix<Real> dP = {{4 * (1 - 2 * xi - eta), 4 * eta, -4 * eta},
{-4 * xi, 4 * xi, 4 * (1 - xi - 2 * eta)}};
Matrix<Real> dNx1 = {
{3. / 2 * (dP(0, 0) * C[0] / L[0] - dP(0, 2) * C[2] / L[2]),
3. / 2 * (dP(0, 1) * C[1] / L[1] - dP(0, 0) * C[0] / L[0]),
3. / 2 * (dP(0, 2) * C[2] / L[2] - dP(0, 1) * C[1] / L[1])},
{3. / 2 * (dP(1, 0) * C[0] / L[0] - dP(1, 2) * C[2] / L[2]),
3. / 2 * (dP(1, 1) * C[1] / L[1] - dP(1, 0) * C[0] / L[0]),
3. / 2 * (dP(1, 2) * C[2] / L[2] - dP(1, 1) * C[1] / L[1])}};
Matrix<Real> dNx2 = {
// clang-format off
{-1 - 3. / 4 * (dP(0, 0) * C[0] * C[0] + dP(0, 2) * C[2] * C[2]),
1 - 3. / 4 * (dP(0, 1) * C[1] * C[1] + dP(0, 0) * C[0] * C[0]),
- 3. / 4 * (dP(0, 2) * C[2] * C[2] + dP(0, 1) * C[1] * C[1])},
{-1 - 3. / 4 * (dP(1, 0) * C[0] * C[0] + dP(1, 2) * C[2] * C[2]),
- 3. / 4 * (dP(1, 1) * C[1] * C[1] + dP(1, 0) * C[0] * C[0]),
1 - 3. / 4 * (dP(1, 2) * C[2] * C[2] + dP(1, 1) * C[1] * C[1])}};
// clang-format on
Matrix<Real> dNx3 = {
{-3. / 4 * (dP(0, 0) * C[0] * S[0] + dP(0, 2) * C[2] * S[2]),
-3. / 4 * (dP(0, 1) * C[1] * S[1] + dP(0, 0) * C[0] * S[0]),
-3. / 4 * (dP(0, 2) * C[2] * S[2] + dP(0, 1) * C[1] * S[1])},
{-3. / 4 * (dP(1, 0) * C[0] * S[0] + dP(1, 2) * C[2] * S[2]),
-3. / 4 * (dP(1, 1) * C[1] * S[1] + dP(1, 0) * C[0] * S[0]),
-3. / 4 * (dP(1, 2) * C[2] * S[2] + dP(1, 1) * C[1] * S[1])}};
Matrix<Real> dNy1 = {
{3. / 2 * (dP(0, 0) * S[0] / L[0] - dP(0, 2) * S[2] / L[2]),
3. / 2 * (dP(0, 1) * S[1] / L[1] - dP(0, 0) * S[0] / L[0]),
3. / 2 * (dP(0, 2) * S[2] / L[2] - dP(0, 1) * S[1] / L[1])},
{3. / 2 * (dP(1, 0) * S[0] / L[0] - dP(1, 2) * S[2] / L[2]),
3. / 2 * (dP(1, 1) * S[1] / L[1] - dP(1, 0) * S[0] / L[0]),
3. / 2 * (dP(1, 2) * S[2] / L[2] - dP(1, 1) * S[1] / L[1])}};
Matrix<Real> dNy2 = dNx3;
Matrix<Real> dNy3 = {
// clang-format off
{-1 - 3. / 4 * (dP(0, 0) * S[0] * S[0] + dP(0, 2) * S[2] * S[2]),
1 - 3. / 4 * (dP(0, 1) * S[1] * S[1] + dP(0, 0) * S[0] * S[0]),
- 3. / 4 * (dP(0, 2) * S[2] * S[2] + dP(0, 1) * S[1] * S[1])},
{-1 - 3. / 4 * (dP(1, 0) * S[0] * S[0] + dP(1, 2) * S[2] * S[2]),
- 3. / 4 * (dP(1, 1) * S[1] * S[1] + dP(1, 0) * S[0] * S[0]),
1 - 3. / 4 * (dP(1, 2) * S[2] * S[2] + dP(1, 1) * S[1] * S[1])}};
// clang-format on
// Derivative of linear (membrane mode) functions
Matrix<Real> dNm(2, 3);
InterpolationElement<_itp_lagrange_triangle_3, _itk_lagrangian>::computeDNDS(
natural_coords, dNm);
-
+
UInt i = 0;
for (const Matrix<Real> & mat : {dNm, dNx1, dNx2, dNx3, dNy1, dNy2, dNy3}) {
B.block(mat, 0, i);
i += mat.cols();
}
}
/* -------------------------------------------------------------------------- */
template <>
inline void
InterpolationElement<_itp_discrete_kirchhoff_triangle_18,
_itk_structural>::arrangeInVoigt(const Matrix<Real> & dnds,
Matrix<Real> & B) {
Matrix<Real> dNm(2, 3), dNx1(2, 3), dNx2(2, 3), dNx3(2, 3), dNy1(2, 3),
dNy2(2, 3), dNy3(2, 3);
UInt i = 0;
for (Matrix<Real> * mat : {&dNm, &dNx1, &dNx2, &dNx3, &dNy1, &dNy2, &dNy3}) {
*mat = dnds.block(0, i, 2, 3);
i += mat->cols();
}
for (UInt i = 0; i < 3; ++i) {
// clang-format off
Matrix<Real> Bm = {{dNm(0, i), 0, 0, 0, 0, 0},
{0, dNm(1, i), 0, 0, 0, 0},
{dNm(1, i), dNm(0, i), 0, 0, 0, 0}};
Matrix<Real> Bf = {{0, 0, dNx1(0, i), -dNx3(0, i), dNx2(0, i), 0},
{0, 0, dNy1(1, i), -dNy3(1, i), dNy2(1, i), 0},
{0, 0, dNx1(1, i) + dNy1(0, i), -dNx3(1, i) - dNy3(0, i), dNx2(1, i) + dNy2(0, i), 0}};
// clang-format on
B.block(Bm, 0, i * 6);
B.block(Bf, 3, i * 6);
}
}
} // namespace akantu
#endif /* __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc b/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
index 6683e8a82..f204bc660 100644
--- a/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
@@ -1,150 +1,155 @@
/**
* @file element_class_quadrangle_4_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Mon Dec 08 2014
*
* @brief Specialization of the element_class class for the type _quadrangle_4
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
\eta
- ^
+ ^
(-1,1) | (1,1)
x---------x
| | |
| | |
--|---------|-----> \xi
| | |
| | |
x---------x
(-1,-1) | (1,-1)
@endverbatim
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{lll}
* N1 = (1 - \xi) (1 - \eta) / 4
* & \frac{\partial N1}{\partial \xi} = - (1 - \eta) / 4
* & \frac{\partial N1}{\partial \eta} = - (1 - \xi) / 4 \\
* N2 = (1 + \xi) (1 - \eta) / 4 \\
* & \frac{\partial N2}{\partial \xi} = (1 - \eta) / 4
* & \frac{\partial N2}{\partial \eta} = - (1 + \xi) / 4 \\
* N3 = (1 + \xi) (1 + \eta) / 4 \\
* & \frac{\partial N3}{\partial \xi} = (1 + \eta) / 4
* & \frac{\partial N3}{\partial \eta} = (1 + \xi) / 4 \\
* N4 = (1 - \xi) (1 + \eta) / 4
* & \frac{\partial N4}{\partial \xi} = - (1 + \eta) / 4
* & \frac{\partial N4}{\partial \eta} = (1 - \xi) / 4 \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 0 \qquad \eta_{q0} = 0
* @f}
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_quadrangle_4, _gt_quadrangle_4, _itp_lagrange_quadrangle_4, _ek_regular, 2,
- _git_segment, 2);
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_quadrangle_4, _gt_quadrangle_4,
+ _itp_lagrange_quadrangle_4, _ek_regular, 2,
+ _git_segment, 2);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_quadrangle_4>::computeShapes(const vector_type & c,
- vector_type & N) {
- N(0) = 1./4. * (1. - c(0)) * (1. - c(1)); /// N1(q_0)
- N(1) = 1./4. * (1. + c(0)) * (1. - c(1)); /// N2(q_0)
- N(2) = 1./4. * (1. + c(0)) * (1. + c(1)); /// N3(q_0)
- N(3) = 1./4. * (1. - c(0)) * (1. + c(1)); /// N4(q_0)
+inline void InterpolationElement<_itp_lagrange_quadrangle_4>::computeShapes(
+ const vector_type & c, vector_type & N) {
+ N(0) = 1. / 4. * (1. - c(0)) * (1. - c(1)); /// N1(q_0)
+ N(1) = 1. / 4. * (1. + c(0)) * (1. - c(1)); /// N2(q_0)
+ N(2) = 1. / 4. * (1. + c(0)) * (1. + c(1)); /// N3(q_0)
+ N(3) = 1. / 4. * (1. - c(0)) * (1. + c(1)); /// N4(q_0)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_quadrangle_4>::computeDNDS(const vector_type & c,
- matrix_type & dnds) {
+inline void InterpolationElement<_itp_lagrange_quadrangle_4>::computeDNDS(
+ const vector_type & c, matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccc}
- * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
- * & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi}\\
- * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
- * & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta}
+ * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial
+ * \xi}
+ * & \frac{\partial N3}{\partial \xi} & \frac{\partial
+ * N4}{\partial \xi}\\
+ * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
+ * \eta}
+ * & \frac{\partial N3}{\partial \eta} & \frac{\partial
+ * N4}{\partial \eta}
* \end{array}
* \right)
* @f]
*/
- dnds(0, 0) = - 1./4. * (1. - c(1));
- dnds(0, 1) = 1./4. * (1. - c(1));
- dnds(0, 2) = 1./4. * (1. + c(1));
- dnds(0, 3) = - 1./4. * (1. + c(1));
+ dnds(0, 0) = -1. / 4. * (1. - c(1));
+ dnds(0, 1) = 1. / 4. * (1. - c(1));
+ dnds(0, 2) = 1. / 4. * (1. + c(1));
+ dnds(0, 3) = -1. / 4. * (1. + c(1));
- dnds(1, 0) = - 1./4. * (1. - c(0));
- dnds(1, 1) = - 1./4. * (1. + c(0));
- dnds(1, 2) = 1./4. * (1. + c(0));
- dnds(1, 3) = 1./4. * (1. - c(0));
+ dnds(1, 0) = -1. / 4. * (1. - c(0));
+ dnds(1, 1) = -1. / 4. * (1. + c(0));
+ dnds(1, 2) = 1. / 4. * (1. + c(0));
+ dnds(1, 3) = 1. / 4. * (1. - c(0));
}
/* -------------------------------------------------------------------------- */
template <>
inline void
-InterpolationElement<_itp_lagrange_quadrangle_4>::computeSpecialJacobian(const Matrix<Real> & J,
- Real & jac){
+InterpolationElement<_itp_lagrange_quadrangle_4>::computeSpecialJacobian(
+ const Matrix<Real> & J, Real & jac) {
Vector<Real> vprod(J.cols());
Matrix<Real> Jt(J.transpose(), true);
vprod.crossProduct(Jt(0), Jt(1));
jac = vprod.norm();
}
/* -------------------------------------------------------------------------- */
-template<>
+template <>
inline Real
GeometricalElement<_gt_quadrangle_4>::getInradius(const Matrix<Real> & coord) {
Vector<Real> u0 = coord(0);
Vector<Real> u1 = coord(1);
Vector<Real> u2 = coord(2);
Vector<Real> u3 = coord(3);
Real a = u0.distance(u1);
Real b = u1.distance(u2);
Real c = u2.distance(u3);
Real d = u3.distance(u0);
// Real septimetre = (a + b + c + d) / 2.;
// Real p = Math::distance_2d(coord + 0, coord + 4);
// Real q = Math::distance_2d(coord + 2, coord + 6);
- // Real area = sqrt(4*(p*p * q*q) - (a*a + b*b + c*c + d*d)*(a*a + c*c - b*b - d*d)) / 4.;
+ // Real area = sqrt(4*(p*p * q*q) - (a*a + b*b + c*c + d*d)*(a*a + c*c - b*b -
+ // d*d)) / 4.;
// Real h = sqrt(area); // to get a length
- // Real h = area / septimetre; // formula of inradius for circumscritable quadrelateral
+ // Real h = area / septimetre; // formula of inradius for circumscritable
+ // quadrelateral
Real h = std::min(a, std::min(b, std::min(c, d)));
return h;
}
diff --git a/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc b/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
index 3fa83ddc8..710de16f9 100644
--- a/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
@@ -1,106 +1,106 @@
/**
* @file element_class_segment_3_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _segment_3
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
-1 0 1
- -----x---------x---------x-----> x
- 1 3 2
+ -----x---------x---------x-----> x
+ 1 3 2
@endverbatim
*
* @subsection coords Nodes coordinates
*
* @f[
* \begin{array}{lll}
* x_{1} = -1 & x_{2} = 1 & x_{3} = 0
* \end{array}
* @f]
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{ll}
* w_1(x) = \frac{x}{2}(x - 1) & w'_1(x) = x - \frac{1}{2}\\
* w_2(x) = \frac{x}{2}(x + 1) & w'_2(x) = x + \frac{1}{2}\\
* w_3(x) = 1-x^2 & w'_3(x) = -2x
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f[
* \begin{array}{ll}
* x_{q1} = -1/\sqrt{3} & x_{q2} = 1/\sqrt{3}
* \end{array}
* @f]
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_segment_3, _gt_segment_3, _itp_lagrange_segment_3, _ek_regular, 1,
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_segment_3, _gt_segment_3,
+ _itp_lagrange_segment_3, _ek_regular, 1,
_git_segment, 2);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_segment_3>::computeShapes(const vector_type & natural_coords,
- vector_type & N) {
+inline void InterpolationElement<_itp_lagrange_segment_3>::computeShapes(
+ const vector_type & natural_coords, vector_type & N) {
Real c = natural_coords(0);
N(0) = (c - 1) * c / 2;
N(1) = (c + 1) * c / 2;
N(2) = 1 - c * c;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_segment_3>::computeDNDS(const vector_type & natural_coords,
- matrix_type & dnds){
+inline void InterpolationElement<_itp_lagrange_segment_3>::computeDNDS(
+ const vector_type & natural_coords, matrix_type & dnds) {
Real c = natural_coords(0);
- dnds(0, 0) = c - .5;
- dnds(0, 1) = c + .5;
- dnds(0, 2) = -2 * c;
+ dnds(0, 0) = c - .5;
+ dnds(0, 1) = c + .5;
+ dnds(0, 2) = -2 * c;
}
/* -------------------------------------------------------------------------- */
template <>
inline void
-InterpolationElement<_itp_lagrange_segment_3>::computeSpecialJacobian(const Matrix<Real> & dxds,
- Real & jac) {
+InterpolationElement<_itp_lagrange_segment_3>::computeSpecialJacobian(
+ const Matrix<Real> & dxds, Real & jac) {
jac = Math::norm2(dxds.storage());
}
/* -------------------------------------------------------------------------- */
-template<> inline Real
+template <>
+inline Real
GeometricalElement<_gt_segment_3>::getInradius(const Matrix<Real> & coord) {
Real dist1 = std::abs(coord(0, 0) - coord(0, 1));
Real dist2 = std::abs(coord(0, 1) - coord(0, 2));
return std::min(dist1, dist2);
}
diff --git a/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc b/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
index b585f209e..f5dab36fa 100644
--- a/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
@@ -1,263 +1,278 @@
/**
* @file element_class_tetrahedron_10_inline_impl.cc
*
* @author Peter Spijker <peter.spijker@epfl.ch>
*
* @date creation: Fri Jul 16 2010
* @date last modification: Sun Oct 19 2014
*
- * @brief Specialization of the element_class class for the type _tetrahedron_10
+ * @brief Specialization of the element_class class for the type
+ _tetrahedron_10
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
\zeta
^
|
(0,0,1)
x
|` .
| ` .
| ` .
| ` . (0,0.5,0.5)
| ` x.
| q4 o ` . \eta
| ` . -,
(0,0,0.5) x ` x (0.5,0,0.5) -
| ` x-(0,1,0)
| q3 o` - '
| (0,0.5,0) - ` '
| x- ` x (0.5,0.5,0)
| q1 o - o q2` '
| - ` '
| - ` '
x---------------x--------------` x-----> \xi
(0,0,0) (0.5,0,0) (1,0,0)
@endverbatim
*
* @subsection coords Nodes coordinates
*
* @f[
* \begin{array}{lll}
* \xi_{0} = 0 & \eta_{0} = 0 & \zeta_{0} = 0 \\
* \xi_{1} = 1 & \eta_{1} = 0 & \zeta_{1} = 0 \\
* \xi_{2} = 0 & \eta_{2} = 1 & \zeta_{2} = 0 \\
* \xi_{3} = 0 & \eta_{3} = 0 & \zeta_{3} = 1 \\
* \xi_{4} = 1/2 & \eta_{4} = 0 & \zeta_{4} = 0 \\
* \xi_{5} = 1/2 & \eta_{5} = 1/2 & \zeta_{5} = 0 \\
* \xi_{6} = 0 & \eta_{6} = 1/2 & \zeta_{6} = 0 \\
* \xi_{7} = 0 & \eta_{7} = 0 & \zeta_{7} = 1/2 \\
* \xi_{8} = 1/2 & \eta_{8} = 0 & \zeta_{8} = 1/2 \\
* \xi_{9} = 0 & \eta_{9} = 1/2 & \zeta_{9} = 1/2
* \end{array}
* @f]
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{llll}
* N1 = (1 - \xi - \eta - \zeta) (1 - 2 \xi - 2 \eta - 2 \zeta)
- * & \frac{\partial N1}{\partial \xi} = 4 \xi + 4 \eta + 4 \zeta - 3
- * & \frac{\partial N1}{\partial \eta} = 4 \xi + 4 \eta + 4 \zeta - 3
- * & \frac{\partial N1}{\partial \zeta} = 4 \xi + 4 \eta + 4 \zeta - 3 \\
+ * & \frac{\partial N1}{\partial \xi} = 4 \xi + 4 \eta + 4 \zeta -
+ 3
+ * & \frac{\partial N1}{\partial \eta} = 4 \xi + 4 \eta + 4 \zeta -
+ 3
+ * & \frac{\partial N1}{\partial \zeta} = 4 \xi + 4 \eta + 4 \zeta -
+ 3 \\
* N2 = \xi (2 \xi - 1)
* & \frac{\partial N2}{\partial \xi} = 4 \xi - 1
* & \frac{\partial N2}{\partial \eta} = 0
* & \frac{\partial N2}{\partial \zeta} = 0 \\
* N3 = \eta (2 \eta - 1)
* & \frac{\partial N3}{\partial \xi} = 0
* & \frac{\partial N3}{\partial \eta} = 4 \eta - 1
* & \frac{\partial N3}{\partial \zeta} = 0 \\
* N4 = \zeta (2 \zeta - 1)
* & \frac{\partial N4}{\partial \xi} = 0
* & \frac{\partial N4}{\partial \eta} = 0
* & \frac{\partial N4}{\partial \zeta} = 4 \zeta - 1 \\
* N5 = 4 \xi (1 - \xi - \eta - \zeta)
- * & \frac{\partial N5}{\partial \xi} = 4 - 8 \xi - 4 \eta - 4 \zeta
+ * & \frac{\partial N5}{\partial \xi} = 4 - 8 \xi - 4 \eta - 4
+ \zeta
* & \frac{\partial N5}{\partial \eta} = -4 \xi
* & \frac{\partial N5}{\partial \zeta} = -4 \xi \\
* N6 = 4 \xi \eta
* & \frac{\partial N6}{\partial \xi} = 4 \eta
* & \frac{\partial N6}{\partial \eta} = 4 \xi
* & \frac{\partial N6}{\partial \zeta} = 0 \\
* N7 = 4 \eta (1 - \xi - \eta - \zeta)
* & \frac{\partial N7}{\partial \xi} = -4 \eta
- * & \frac{\partial N7}{\partial \eta} = 4 - 4 \xi - 8 \eta - 4 \zeta
+ * & \frac{\partial N7}{\partial \eta} = 4 - 4 \xi - 8 \eta - 4
+ \zeta
* & \frac{\partial N7}{\partial \zeta} = -4 \eta \\
* N8 = 4 \zeta (1 - \xi - \eta - \zeta)
* & \frac{\partial N8}{\partial \xi} = -4 \zeta
* & \frac{\partial N8}{\partial \eta} = -4 \zeta
- * & \frac{\partial N8}{\partial \zeta} = 4 - 4 \xi - 4 \eta - 8 \zeta \\
+ * & \frac{\partial N8}{\partial \zeta} = 4 - 4 \xi - 4 \eta - 8
+ \zeta \\
* N9 = 4 \zeta \xi
* & \frac{\partial N9}{\partial \xi} = 4 \zeta
* & \frac{\partial N9}{\partial \eta} = 0
* & \frac{\partial N9}{\partial \zeta} = 4 \xi \\
* N10 = 4 \eta \zeta
* & \frac{\partial N10}{\partial \xi} = 0
* & \frac{\partial N10}{\partial \eta} = 4 \zeta
* & \frac{\partial N10}{\partial \zeta} = 4 \eta \\
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f[
* a = \frac{5 - \sqrt{5}}{20}\\
* b = \frac{5 + 3 \sqrt{5}}{20}
* \begin{array}{lll}
* \xi_{q_0} = a & \eta_{q_0} = a & \zeta_{q_0} = a \\
* \xi_{q_1} = b & \eta_{q_1} = a & \zeta_{q_1} = a \\
* \xi_{q_2} = a & \eta_{q_2} = b & \zeta_{q_2} = a \\
* \xi_{q_3} = a & \eta_{q_3} = a & \zeta_{q_3} = b
* \end{array}
* @f]
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_10, _gt_tetrahedron_10, _itp_lagrange_tetrahedron_10, _ek_regular, 3,
- _git_tetrahedron, 2);
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_10, _gt_tetrahedron_10,
+ _itp_lagrange_tetrahedron_10, _ek_regular,
+ 3, _git_tetrahedron, 2);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_tetrahedron_10>::computeShapes(const vector_type & natural_coords,
- vector_type & N) {
+inline void InterpolationElement<_itp_lagrange_tetrahedron_10>::computeShapes(
+ const vector_type & natural_coords, vector_type & N) {
/// Natural coordinates
Real xi = natural_coords(0);
Real eta = natural_coords(1);
Real zeta = natural_coords(2);
Real sum = xi + eta + zeta;
- Real c0 = 1 - sum;
- Real c1 = 1 - 2*sum;
- Real c2 = 2*xi - 1;
- Real c3 = 2*eta - 1;
- Real c4 = 2*zeta - 1;
+ Real c0 = 1 - sum;
+ Real c1 = 1 - 2 * sum;
+ Real c2 = 2 * xi - 1;
+ Real c3 = 2 * eta - 1;
+ Real c4 = 2 * zeta - 1;
/// Shape functions
- N(0) = c0 * c1;
- N(1) = xi * c2;
- N(2) = eta * c3;
+ N(0) = c0 * c1;
+ N(1) = xi * c2;
+ N(2) = eta * c3;
N(3) = zeta * c4;
- N(4) = 4 * xi * c0;
+ N(4) = 4 * xi * c0;
N(5) = 4 * xi * eta;
N(6) = 4 * eta * c0;
N(7) = 4 * zeta * c0;
N(8) = 4 * xi * zeta;
N(9) = 4 * eta * zeta;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_tetrahedron_10>::computeDNDS(const vector_type & natural_coords,
- matrix_type & dnds) {
+inline void InterpolationElement<_itp_lagrange_tetrahedron_10>::computeDNDS(
+ const vector_type & natural_coords, matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccccccc}
- * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
- * & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi}
- * & \frac{\partial N5}{\partial \xi} & \frac{\partial N6}{\partial \xi}
- * & \frac{\partial N7}{\partial \xi} & \frac{\partial N8}{\partial \xi}
- * & \frac{\partial N9}{\partial \xi} & \frac{\partial N10}{\partial \xi} \\
- * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
- * & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta}
- * & \frac{\partial N5}{\partial \eta} & \frac{\partial N6}{\partial \eta}
- * & \frac{\partial N7}{\partial \eta} & \frac{\partial N8}{\partial \eta}
- * & \frac{\partial N9}{\partial \eta} & \frac{\partial N10}{\partial \eta} \\
- * \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial \zeta}
- * & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial \zeta}
- * & \frac{\partial N5}{\partial \zeta} & \frac{\partial N6}{\partial \zeta}
- * & \frac{\partial N7}{\partial \zeta} & \frac{\partial N8}{\partial \zeta}
- * & \frac{\partial N9}{\partial \zeta} & \frac{\partial N10}{\partial \zeta}
+ * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial
+ * \xi}
+ * & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial
+ * \xi}
+ * & \frac{\partial N5}{\partial \xi} & \frac{\partial N6}{\partial
+ * \xi}
+ * & \frac{\partial N7}{\partial \xi} & \frac{\partial N8}{\partial
+ * \xi}
+ * & \frac{\partial N9}{\partial \xi} & \frac{\partial
+ * N10}{\partial \xi} \\
+ * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
+ * \eta}
+ * & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial
+ * \eta}
+ * & \frac{\partial N5}{\partial \eta} & \frac{\partial N6}{\partial
+ * \eta}
+ * & \frac{\partial N7}{\partial \eta} & \frac{\partial N8}{\partial
+ * \eta}
+ * & \frac{\partial N9}{\partial \eta} & \frac{\partial
+ * N10}{\partial \eta} \\
+ * \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial
+ * \zeta}
+ * & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial
+ * \zeta}
+ * & \frac{\partial N5}{\partial \zeta} & \frac{\partial N6}{\partial
+ * \zeta}
+ * & \frac{\partial N7}{\partial \zeta} & \frac{\partial N8}{\partial
+ * \zeta}
+ * & \frac{\partial N9}{\partial \zeta} & \frac{\partial
+ * N10}{\partial \zeta}
* \end{array}
* \right)
* @f]
*/
/// Natural coordinates
- Real xi = natural_coords(0);
- Real eta = natural_coords(1);
+ Real xi = natural_coords(0);
+ Real eta = natural_coords(1);
Real zeta = natural_coords(2);
Real sum = xi + eta + zeta;
/// \frac{\partial N_i}{\partial \xi}
- dnds(0, 0) = 4 * sum - 3;
- dnds(0, 1) = 4 * xi - 1;
- dnds(0, 2) = 0;
- dnds(0, 3) = 0;
- dnds(0, 4) = 4 * (1 - sum - xi);
- dnds(0, 5) = 4 * eta;
+ dnds(0, 0) = 4 * sum - 3;
+ dnds(0, 1) = 4 * xi - 1;
+ dnds(0, 2) = 0;
+ dnds(0, 3) = 0;
+ dnds(0, 4) = 4 * (1 - sum - xi);
+ dnds(0, 5) = 4 * eta;
dnds(0, 6) = -4 * eta;
dnds(0, 7) = -4 * zeta;
- dnds(0, 8) = 4 * zeta;
- dnds(0, 9) = 0;
+ dnds(0, 8) = 4 * zeta;
+ dnds(0, 9) = 0;
/// \frac{\partial N_i}{\partial \eta}
- dnds(1, 0) = 4 * sum - 3;
- dnds(1, 1) = 0;
- dnds(1, 2) = 4 * eta - 1;
- dnds(1, 3) = 0;
+ dnds(1, 0) = 4 * sum - 3;
+ dnds(1, 1) = 0;
+ dnds(1, 2) = 4 * eta - 1;
+ dnds(1, 3) = 0;
dnds(1, 4) = -4 * xi;
- dnds(1, 5) = 4 * xi;
- dnds(1, 6) = 4 * (1 - sum - eta);
+ dnds(1, 5) = 4 * xi;
+ dnds(1, 6) = 4 * (1 - sum - eta);
dnds(1, 7) = -4 * zeta;
- dnds(1, 8) = 0;
- dnds(1, 9) = 4 * zeta;
+ dnds(1, 8) = 0;
+ dnds(1, 9) = 4 * zeta;
/// \frac{\partial N_i}{\partial \zeta}
- dnds(2, 0) = 4 * sum - 3;
- dnds(2, 1) = 0;
- dnds(2, 2) = 0;
- dnds(2, 3) = 4 * zeta - 1;
+ dnds(2, 0) = 4 * sum - 3;
+ dnds(2, 1) = 0;
+ dnds(2, 2) = 0;
+ dnds(2, 3) = 4 * zeta - 1;
dnds(2, 4) = -4 * xi;
- dnds(2, 5) = 0;
+ dnds(2, 5) = 0;
dnds(2, 6) = -4 * eta;
- dnds(2, 7) = 4 * (1 - sum - zeta);
- dnds(2, 8) = 4 * xi;
- dnds(2, 9) = 4 * eta;
-
+ dnds(2, 7) = 4 * (1 - sum - zeta);
+ dnds(2, 8) = 4 * xi;
+ dnds(2, 9) = 4 * eta;
}
/* -------------------------------------------------------------------------- */
-template<>
-inline Real
-GeometricalElement<_gt_tetrahedron_10>::getInradius(const Matrix<Real> & coord) {
+template <>
+inline Real GeometricalElement<_gt_tetrahedron_10>::getInradius(
+ const Matrix<Real> & coord) {
// Only take the four corner tetrahedra
UInt tetrahedra[4][4] = {
- {0, 4, 6, 7},
- {4, 1, 5, 8},
- {6, 5, 2, 9},
- {7, 8, 9, 3}
- };
+ {0, 4, 6, 7}, {4, 1, 5, 8}, {6, 5, 2, 9}, {7, 8, 9, 3}};
Real inradius = std::numeric_limits<Real>::max();
for (UInt t = 0; t < 4; t++) {
- Real ir = Math::tetrahedron_inradius(coord(tetrahedra[t][0]).storage(),
- coord(tetrahedra[t][1]).storage(),
- coord(tetrahedra[t][2]).storage(),
- coord(tetrahedra[t][3]).storage());
+ Real ir = Math::tetrahedron_inradius(
+ coord(tetrahedra[t][0]).storage(), coord(tetrahedra[t][1]).storage(),
+ coord(tetrahedra[t][2]).storage(), coord(tetrahedra[t][3]).storage());
inradius = std::min(ir, inradius);
}
return inradius;
}
diff --git a/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc b/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
index 262843501..76f6d85bc 100644
--- a/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
@@ -1,123 +1,134 @@
/**
* @file element_class_tetrahedron_4_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _tetrahedron_4
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
\eta
^
|
x (0,0,1,0)
|`
| ` ° \xi
| ` ° -
| ` x (0,0,0,1)
| q.` - '
| -` '
| - ` '
| - ` '
x------------------x-----> \zeta
(1,0,0,0) (0,1,0,0)
@endverbatim
*
* @subsection shapes Shape functions
* @f{eqnarray*}{
* N1 &=& 1 - \xi - \eta - \zeta \\
* N2 &=& \xi \\
* N3 &=& \eta \\
* N4 &=& \zeta
* @f}
*
* @subsection quad_points Position of quadrature points
* @f[
* \xi_{q0} = 1/4 \qquad \eta_{q0} = 1/4 \qquad \zeta_{q0} = 1/4
* @f]
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_4, _gt_tetrahedron_4, _itp_lagrange_tetrahedron_4, _ek_regular, 3,
- _git_tetrahedron, 1);
-
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_4, _gt_tetrahedron_4,
+ _itp_lagrange_tetrahedron_4, _ek_regular,
+ 3, _git_tetrahedron, 1);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_tetrahedron_4>::computeShapes(const vector_type & natural_coords,
- vector_type & N) {
+inline void InterpolationElement<_itp_lagrange_tetrahedron_4>::computeShapes(
+ const vector_type & natural_coords, vector_type & N) {
- Real c0 = 1 - natural_coords(0) - natural_coords(1) - natural_coords(2);/// @f$ c2 = 1 - \xi - \eta - \zeta @f$
+ Real c0 = 1 - natural_coords(0) - natural_coords(1) -
+ natural_coords(2); /// @f$ c2 = 1 - \xi - \eta - \zeta @f$
Real c1 = natural_coords(1); /// @f$ c0 = \xi @f$
Real c2 = natural_coords(2); /// @f$ c1 = \eta @f$
Real c3 = natural_coords(0); /// @f$ c2 = \zeta @f$
N(0) = c0;
N(1) = c1;
N(2) = c2;
N(3) = c3;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_tetrahedron_4>::computeDNDS(__attribute__ ((unused)) const vector_type & natural_coords,
- matrix_type & dnds) {
+inline void InterpolationElement<_itp_lagrange_tetrahedron_4>::computeDNDS(
+ __attribute__((unused)) const vector_type & natural_coords,
+ matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccc}
- * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi}
- * & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial \xi} \\
- * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta}
- * & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial \eta} \\
- * \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial \zeta}
- * & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial \zeta}
+ * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial
+ * \xi}
+ * & \frac{\partial N3}{\partial \xi} & \frac{\partial N4}{\partial
+ * \xi} \\
+ * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
+ * \eta}
+ * & \frac{\partial N3}{\partial \eta} & \frac{\partial N4}{\partial
+ * \eta} \\
+ * \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial
+ * \zeta}
+ * & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial
+ * \zeta}
* \end{array}
* \right)
* @f]
*/
- dnds(0, 0) = -1.; dnds(0, 1) = 1.; dnds(0, 2) = 0.; dnds(0, 3) = 0.;
- dnds(1, 0) = -1.; dnds(1, 1) = 0.; dnds(1, 2) = 1.; dnds(1, 3) = 0.;
- dnds(2, 0) = -1.; dnds(2, 1) = 0.; dnds(2, 2) = 0.; dnds(2, 3) = 1.;
-
-
+ dnds(0, 0) = -1.;
+ dnds(0, 1) = 1.;
+ dnds(0, 2) = 0.;
+ dnds(0, 3) = 0.;
+ dnds(1, 0) = -1.;
+ dnds(1, 1) = 0.;
+ dnds(1, 2) = 1.;
+ dnds(1, 3) = 0.;
+ dnds(2, 0) = -1.;
+ dnds(2, 1) = 0.;
+ dnds(2, 2) = 0.;
+ dnds(2, 3) = 1.;
}
/* -------------------------------------------------------------------------- */
-template<>
+template <>
inline Real
GeometricalElement<_gt_tetrahedron_4>::getInradius(const Matrix<Real> & coord) {
- return Math::tetrahedron_inradius(coord(0).storage(),
- coord(1).storage(),
- coord(2).storage(),
- coord(3).storage());
+ return Math::tetrahedron_inradius(coord(0).storage(), coord(1).storage(),
+ coord(2).storage(), coord(3).storage());
}
diff --git a/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc b/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
index ce9633036..1b17994d1 100644
--- a/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
@@ -1,132 +1,134 @@
/**
* @file element_class_triangle_3_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _triangle_3
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
\eta
- ^
- |
- x (0,0,1)
- |`
- | `
- | q `
- | ° `
- x--------x-----> \xi
+ ^
+ |
+ x (0,0,1)
+ |`
+ | `
+ | q `
+ | ° `
+ x--------x-----> \xi
(1,0,0) (0,1,0)
@endverbatim
*
* @subsection shapes Shape functions
* @f{eqnarray*}{
* N1 &=& 1 - \xi - \eta \\
* N2 &=& \xi \\
* N3 &=& \eta
* @f}
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 1/3 \qquad \eta_{q0} = 1/3
* @f}
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_3, _gt_triangle_3, _itp_lagrange_triangle_3, _ek_regular, 2,
- _git_triangle, 1);
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_3, _gt_triangle_3,
+ _itp_lagrange_triangle_3, _ek_regular, 2,
+ _git_triangle, 1);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_triangle_3>::computeShapes(const vector_type & natural_coords,
- vector_type & N) {
+inline void InterpolationElement<_itp_lagrange_triangle_3>::computeShapes(
+ const vector_type & natural_coords, vector_type & N) {
/// Natural coordinates
- Real c0 = 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
- Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
- Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
+ Real c0 =
+ 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
+ Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
+ Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
N(0) = c0; /// N1(q_0)
N(1) = c1; /// N2(q_0)
N(2) = c2; /// N3(q_0)
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_triangle_3>::computeDNDS(__attribute__ ((unused)) const vector_type & natural_coords,
- matrix_type & dnds) {
+inline void InterpolationElement<_itp_lagrange_triangle_3>::computeDNDS(
+ __attribute__((unused)) const vector_type & natural_coords,
+ matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccc}
- * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial \xi} & \frac{\partial N3}{\partial \xi} \\
- * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial \eta} & \frac{\partial N3}{\partial \eta}
+ * \frac{\partial N1}{\partial \xi} & \frac{\partial N2}{\partial
+ * \xi} & \frac{\partial N3}{\partial \xi} \\
+ * \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
+ * \eta} & \frac{\partial N3}{\partial \eta}
* \end{array}
* \right)
* @f]
*/
- dnds(0, 0) = -1.; dnds(0, 1) = 1.; dnds(0, 2) = 0.;
- dnds(1, 0) = -1.; dnds(1, 1) = 0.; dnds(1, 2) = 1.;
+ dnds(0, 0) = -1.;
+ dnds(0, 1) = 1.;
+ dnds(0, 2) = 0.;
+ dnds(1, 0) = -1.;
+ dnds(1, 1) = 0.;
+ dnds(1, 2) = 1.;
}
-
/* -------------------------------------------------------------------------- */
template <>
inline void
-InterpolationElement<_itp_lagrange_triangle_3>::computeSpecialJacobian(const Matrix<Real> & J,
- Real & jac) {
+InterpolationElement<_itp_lagrange_triangle_3>::computeSpecialJacobian(
+ const Matrix<Real> & J, Real & jac) {
Vector<Real> vprod(J.cols());
Matrix<Real> Jt(J.transpose(), true);
vprod.crossProduct(Jt(0), Jt(1));
jac = vprod.norm();
}
-
-
/* -------------------------------------------------------------------------- */
-template<>
+template <>
inline Real
GeometricalElement<_gt_triangle_3>::getInradius(const Matrix<Real> & coord) {
- return Math::triangle_inradius(coord(0).storage(),
- coord(1).storage(),
- coord(2).storage());
+ return Math::triangle_inradius(coord(0).storage(), coord(1).storage(),
+ coord(2).storage());
}
/* -------------------------------------------------------------------------- */
-// template<> inline bool ElementClass<_triangle_3>::contains(const Vector<Real> & natural_coords) {
+// template<> inline bool ElementClass<_triangle_3>::contains(const Vector<Real>
+// & natural_coords) {
// if (natural_coords[0] < 0.) return false;
// if (natural_coords[0] > 1.) return false;
// if (natural_coords[1] < 0.) return false;
// if (natural_coords[1] > 1.) return false;
// if (natural_coords[0]+natural_coords[1] > 1.) return false;
// return true;
// }
/* -------------------------------------------------------------------------- */
-
-
diff --git a/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc b/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
index f3ae35402..7ccb1a5a3 100644
--- a/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
@@ -1,204 +1,200 @@
/**
* @file element_class_triangle_6_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 16 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Specialization of the element_class class for the type _triangle_6
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @verbatim
- \eta
- ^
- |
- x 2
- | `
- | `
- | . `
- | q2 `
- 5 x x 4
- | `
- | `
- | .q0 q1. `
- | `
- x---------x---------x-----> \xi
- 0 3 1
+ \eta
+ ^
+ |
+ x 2
+ | `
+ | `
+ | . `
+ | q2 `
+ 5 x x 4
+ | `
+ | `
+ | .q0 q1. `
+ | `
+ x---------x---------x-----> \xi
+ 0 3 1
@endverbatim
*
* @subsection coords Nodes coordinates
*
* @f[
* \begin{array}{ll}
* \xi_{0} = 0 & \eta_{0} = 0 \\
* \xi_{1} = 1 & \eta_{1} = 0 \\
* \xi_{2} = 0 & \eta_{2} = 1 \\
* \xi_{3} = 1/2 & \eta_{3} = 0 \\
* \xi_{4} = 1/2 & \eta_{4} = 1/2 \\
* \xi_{5} = 0 & \eta_{5} = 1/2
* \end{array}
* @f]
*
* @subsection shapes Shape functions
* @f[
* \begin{array}{lll}
* N1 = -(1 - \xi - \eta) (1 - 2 (1 - \xi - \eta))
* & \frac{\partial N1}{\partial \xi} = 1 - 4(1 - \xi - \eta)
* & \frac{\partial N1}{\partial \eta} = 1 - 4(1 - \xi - \eta) \\
* N2 = - \xi (1 - 2 \xi)
* & \frac{\partial N2}{\partial \xi} = - 1 + 4 \xi
* & \frac{\partial N2}{\partial \eta} = 0 \\
* N3 = - \eta (1 - 2 \eta)
* & \frac{\partial N3}{\partial \xi} = 0
* & \frac{\partial N3}{\partial \eta} = - 1 + 4 \eta \\
* N4 = 4 \xi (1 - \xi - \eta)
* & \frac{\partial N4}{\partial \xi} = 4 (1 - 2 \xi - \eta)
* & \frac{\partial N4}{\partial \eta} = - 4 \xi \\
* N5 = 4 \xi \eta
* & \frac{\partial N5}{\partial \xi} = 4 \eta
* & \frac{\partial N5}{\partial \eta} = 4 \xi \\
* N6 = 4 \eta (1 - \xi - \eta)
* & \frac{\partial N6}{\partial \xi} = - 4 \eta
* & \frac{\partial N6}{\partial \eta} = 4 (1 - \xi - 2 \eta)
* \end{array}
* @f]
*
* @subsection quad_points Position of quadrature points
* @f{eqnarray*}{
* \xi_{q0} &=& 1/6 \qquad \eta_{q0} = 1/6 \\
* \xi_{q1} &=& 2/3 \qquad \eta_{q1} = 1/6 \\
* \xi_{q2} &=& 1/6 \qquad \eta_{q2} = 2/3
* @f}
*/
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_6, _gt_triangle_6, _itp_lagrange_triangle_6, _ek_regular, 2,
- _git_triangle, 2);
+AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_6, _gt_triangle_6,
+ _itp_lagrange_triangle_6, _ek_regular, 2,
+ _git_triangle, 2);
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type>
-inline void
-InterpolationElement<_itp_lagrange_triangle_6>::computeShapes(const vector_type & natural_coords,
- vector_type & N) {
+inline void InterpolationElement<_itp_lagrange_triangle_6>::computeShapes(
+ const vector_type & natural_coords, vector_type & N) {
/// Natural coordinates
- Real c0 = 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
- Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
- Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
+ Real c0 =
+ 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
+ Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
+ Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
N(0) = c0 * (2 * c0 - 1.);
N(1) = c1 * (2 * c1 - 1.);
N(2) = c2 * (2 * c2 - 1.);
N(3) = 4 * c0 * c1;
N(4) = 4 * c1 * c2;
N(5) = 4 * c2 * c0;
}
/* -------------------------------------------------------------------------- */
template <>
template <class vector_type, class matrix_type>
-inline void
-InterpolationElement<_itp_lagrange_triangle_6>::computeDNDS(const vector_type & natural_coords,
- matrix_type & dnds) {
+inline void InterpolationElement<_itp_lagrange_triangle_6>::computeDNDS(
+ const vector_type & natural_coords, matrix_type & dnds) {
/**
* @f[
* dnds = \left(
* \begin{array}{cccccc}
* \frac{\partial N1}{\partial \xi}
* & \frac{\partial N2}{\partial \xi}
* & \frac{\partial N3}{\partial \xi}
* & \frac{\partial N4}{\partial \xi}
* & \frac{\partial N5}{\partial \xi}
* & \frac{\partial N6}{\partial \xi} \\
*
* \frac{\partial N1}{\partial \eta}
* & \frac{\partial N2}{\partial \eta}
* & \frac{\partial N3}{\partial \eta}
* & \frac{\partial N4}{\partial \eta}
* & \frac{\partial N5}{\partial \eta}
* & \frac{\partial N6}{\partial \eta}
* \end{array}
* \right)
* @f]
*/
/// Natural coordinates
- Real c0 = 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
- Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
- Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
+ Real c0 =
+ 1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
+ Real c1 = natural_coords(0); /// @f$ c1 = \xi @f$
+ Real c2 = natural_coords(1); /// @f$ c2 = \eta @f$
- dnds(0, 0) = 1 - 4 * c0;
- dnds(0, 1) = 4 * c1 - 1.;
- dnds(0, 2) = 0.;
- dnds(0, 3) = 4 * (c0 - c1);
- dnds(0, 4) = 4 * c2;
- dnds(0, 5) = - 4 * c2;
+ dnds(0, 0) = 1 - 4 * c0;
+ dnds(0, 1) = 4 * c1 - 1.;
+ dnds(0, 2) = 0.;
+ dnds(0, 3) = 4 * (c0 - c1);
+ dnds(0, 4) = 4 * c2;
+ dnds(0, 5) = -4 * c2;
dnds(1, 0) = 1 - 4 * c0;
dnds(1, 1) = 0.;
dnds(1, 2) = 4 * c2 - 1.;
- dnds(1, 3) = - 4 * c1;
+ dnds(1, 3) = -4 * c1;
dnds(1, 4) = 4 * c1;
dnds(1, 5) = 4 * (c0 - c2);
}
-
/* -------------------------------------------------------------------------- */
template <>
inline void
-InterpolationElement<_itp_lagrange_triangle_6>::computeSpecialJacobian( const Matrix<Real> & J,
- Real & jac){
+InterpolationElement<_itp_lagrange_triangle_6>::computeSpecialJacobian(
+ const Matrix<Real> & J, Real & jac) {
Vector<Real> vprod(J.cols());
Matrix<Real> Jt(J.transpose(), true);
vprod.crossProduct(Jt(0), Jt(1));
jac = vprod.norm();
}
/* -------------------------------------------------------------------------- */
-template<>
+template <>
inline Real
GeometricalElement<_gt_triangle_6>::getInradius(const Matrix<Real> & coord) {
- UInt triangles[4][3] = {
- {0, 3, 5},
- {3, 1, 4},
- {3, 4, 5},
- {5, 4, 2}
- };
+ UInt triangles[4][3] = {{0, 3, 5}, {3, 1, 4}, {3, 4, 5}, {5, 4, 2}};
Real inradius = std::numeric_limits<Real>::max();
for (UInt t = 0; t < 4; t++) {
Real ir = Math::triangle_inradius(coord(triangles[t][0]).storage(),
- coord(triangles[t][1]).storage(),
- coord(triangles[t][2]).storage());
+ coord(triangles[t][1]).storage(),
+ coord(triangles[t][2]).storage());
inradius = std::min(ir, inradius);
}
return inradius;
}
/* -------------------------------------------------------------------------- */
-// template<> inline bool ElementClass<_triangle_6>::contains(const Vector<Real> & natural_coords) {
+// template<> inline bool ElementClass<_triangle_6>::contains(const Vector<Real>
+// & natural_coords) {
// return ElementClass<_triangle_3>::contains(natural_coords);
// }
diff --git a/src/fe_engine/element_type_conversion.hh b/src/fe_engine/element_type_conversion.hh
index bbd629113..bf9ac699e 100644
--- a/src/fe_engine/element_type_conversion.hh
+++ b/src/fe_engine/element_type_conversion.hh
@@ -1,53 +1,55 @@
/**
* @file element_type_conversion.hh
*
* @author Nicolas Richart
*
* @date creation Thu Jul 27 2017
*
* @brief conversion between different types
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_TYPE_CONVERSION_HH__
#define __AKANTU_ELEMENT_TYPE_CONVERSION_HH__
namespace akantu {
-template<class InType, class OutType>
-OutType convertType(const InType &) { return OutType(); }
+template <class InType, class OutType> OutType convertType(const InType &) {
+ return OutType();
+}
-template<>
-inline InterpolationType convertType<ElementType, InterpolationType>(const ElementType & type) {
+template <>
+inline InterpolationType
+convertType<ElementType, InterpolationType>(const ElementType & type) {
InterpolationType itp_type = _itp_not_defined;
#define GET_ITP(type) itp_type = ElementClassProperty<type>::interpolation_type;
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_ITP);
#undef GET_ITP
return itp_type;
}
} // namespace akantu
#endif /* __AKANTU_ELEMENT_TYPE_CONVERSION_HH__ */
diff --git a/src/fe_engine/fe_engine_inline_impl.cc b/src/fe_engine/fe_engine_inline_impl.cc
index 2eb5a757e..48940bdb0 100644
--- a/src/fe_engine/fe_engine_inline_impl.cc
+++ b/src/fe_engine/fe_engine_inline_impl.cc
@@ -1,199 +1,199 @@
/**
* @file fe_engine_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jul 20 2010
* @date last modification: Sat Sep 05 2015
*
* @brief Implementation of the inline functions of the FEEngine Class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include "element_class.hh"
#include "fe_engine.hh"
#include "mesh.hh"
-#include "element_class.hh"
/* -------------------------------------------------------------------------- */
#include "element_type_conversion.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FE_ENGINE_INLINE_IMPL_CC__
#define __AKANTU_FE_ENGINE_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline Real FEEngine::getElementInradius(const Matrix<Real> & coord,
const ElementType & type) {
AKANTU_DEBUG_IN();
Real inradius = 0;
#define GET_INRADIUS(type) inradius = ElementClass<type>::getInradius(coord);
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_INRADIUS);
#undef GET_INRADIUS
AKANTU_DEBUG_OUT();
return inradius;
}
/* -------------------------------------------------------------------------- */
inline InterpolationType
FEEngine::getInterpolationType(const ElementType & type) {
return convertType<ElementType, InterpolationType>(type);
}
/* -------------------------------------------------------------------------- */
/// @todo rewrite this function in order to get the cohesive element
/// type directly from the facet
#if defined(AKANTU_COHESIVE_ELEMENT)
inline ElementType FEEngine::getCohesiveElementType(const ElementType & type) {
AKANTU_DEBUG_IN();
ElementType ctype;
#define GET_COHESIVE_TYPE(type) \
ctype = CohesiveFacetProperty<type>::cohesive_type;
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_COHESIVE_TYPE);
#undef GET_COHESIVE_TYPE
AKANTU_DEBUG_OUT();
return ctype;
}
#else
inline ElementType
FEEngine::getCohesiveElementType(__attribute__((unused))
const ElementType & type_facet) {
return _not_defined;
}
#endif
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
} // akantu
#include "igfem_helper.hh"
namespace akantu {
inline Vector<ElementType>
FEEngine::getIGFEMElementTypes(const ElementType & type) {
#define GET_IGFEM_ELEMENT_TYPES(type) \
return IGFEMHelper::getIGFEMElementTypes<type>();
AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(GET_IGFEM_ELEMENT_TYPES);
#undef GET_IGFEM_ELEMENT_TYPES
}
#endif
/* -------------------------------------------------------------------------- */
template <typename T>
void FEEngine::extractNodalToElementField(const Mesh & mesh,
const Array<T> & nodal_f,
Array<T> & elemental_f,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_degree_of_freedom = nodal_f.getNbComponent();
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
if (filter_elements != empty_filter) {
nb_element = filter_elements.size();
}
elemental_f.resize(nb_element);
T * nodal_f_val = nodal_f.storage();
T * f_val = elemental_f.storage();
UInt * el_conn;
for (UInt el = 0; el < nb_element; ++el) {
if (filter_elements != empty_filter)
el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
else
el_conn = conn_val + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = *(el_conn + n);
std::copy(nodal_f_val + node * nb_degree_of_freedom,
nodal_f_val + (node + 1) * nb_degree_of_freedom, f_val);
f_val += nb_degree_of_freedom;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T>
void FEEngine::filterElementalData(const Mesh & mesh, const Array<T> & elem_f,
Array<T> & filtered_f,
const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (nb_element == 0) {
filtered_f.resize(0);
return;
}
UInt nb_degree_of_freedom = elem_f.getNbComponent();
UInt nb_data_per_element = elem_f.size() / nb_element;
if (filter_elements != empty_filter) {
nb_element = filter_elements.size();
}
filtered_f.resize(nb_element * nb_data_per_element);
T * elem_f_val = elem_f.storage();
T * f_val = filtered_f.storage();
UInt el_offset;
for (UInt el = 0; el < nb_element; ++el) {
if (filter_elements != empty_filter)
el_offset = filter_elements(el);
else
el_offset = el;
std::copy(elem_f_val +
el_offset * nb_data_per_element * nb_degree_of_freedom,
elem_f_val +
(el_offset + 1) * nb_data_per_element * nb_degree_of_freedom,
f_val);
f_val += nb_degree_of_freedom * nb_data_per_element;
}
AKANTU_DEBUG_OUT();
}
} // akantu
#endif /* __AKANTU_FE_ENGINE_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/fe_engine_template_cohesive.cc b/src/fe_engine/fe_engine_template_cohesive.cc
index 2f1482353..d93f779f0 100644
--- a/src/fe_engine/fe_engine_template_cohesive.cc
+++ b/src/fe_engine/fe_engine_template_cohesive.cc
@@ -1,133 +1,133 @@
/**
* @file fe_engine_template_cohesive.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Oct 31 2012
* @date last modification: Thu Oct 15 2015
*
* @brief Specialization of the FEEngineTemplate for cohesive element
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fe_engine_template.hh"
-#include "shape_cohesive.hh"
#include "integrator_gauss.hh"
+#include "shape_cohesive.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/* compatibility functions */
/* -------------------------------------------------------------------------- */
template <>
Real FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
DefaultIntegrationOrderFunctor>::
integrate(const Array<Real> & f, const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
#ifndef AKANTU_NDEBUG
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (filter_elements != empty_filter)
nb_element = filter_elements.size();
UInt nb_quadrature_points = getNbIntegrationPoints(type);
AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
"The vector f("
<< f.getID()
<< ") has not the good number of component.");
#endif
Real integral = 0.;
#define INTEGRATE(type) \
integral = integrator.integrate<type>(f, ghost_type, filter_elements);
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
#undef INTEGRATE
AKANTU_DEBUG_OUT();
return integral;
}
/* -------------------------------------------------------------------------- */
template <>
void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
DefaultIntegrationOrderFunctor>::
integrate(const Array<Real> & f, Array<Real> & intf,
UInt nb_degree_of_freedom, const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
#ifndef AKANTU_NDEBUG
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (filter_elements == filter_elements)
nb_element = filter_elements.size();
UInt nb_quadrature_points = getNbIntegrationPoints(type);
AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID() << " size " << f.size()
<< ") has not the good size ("
<< nb_element << ").");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
"The vector f("
<< f.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
"The vector intf("
<< intf.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.size() == nb_element,
"The vector intf(" << intf.getID()
<< ") has not the good size.");
#endif
#define INTEGRATE(type) \
integrator.integrate<type>(f, intf, nb_degree_of_freedom, ghost_type, \
filter_elements);
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
#undef INTEGRATE
}
/* -------------------------------------------------------------------------- */
template <>
void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
DefaultIntegrationOrderFunctor>::
gradientOnIntegrationPoints(const Array<Real> &, Array<Real> &, const UInt,
const ElementType &, const GhostType &,
const Array<UInt> &) const {
AKANTU_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/fe_engine/fe_engine_template_tmpl_struct.hh b/src/fe_engine/fe_engine_template_tmpl_struct.hh
index 2c1046745..410af8f66 100644
--- a/src/fe_engine/fe_engine_template_tmpl_struct.hh
+++ b/src/fe_engine/fe_engine_template_tmpl_struct.hh
@@ -1,101 +1,99 @@
/**
* @file fe_engine_template_tmpl_struct.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 07 2014
* @date last modification: Thu Oct 15 2015
*
* @brief Template implementation of FEEngineTemplate for Structural Element
* Kinds
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "shape_structural.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <ElementKind kind, typename = void>
struct AssembleFieldMatrixStructHelper {};
template <ElementKind kind>
struct AssembleFieldMatrixStructHelper<
kind, typename std::enable_if<kind == _ek_structural>::type> {
template <template <ElementKind, class> class I,
template <ElementKind> class S, ElementKind k, class IOF>
static void call(const FEEngineTemplate<I, S, k, IOF> & fem,
const Array<Real> & field_1, UInt nb_degree_of_freedom,
SparseMatrix & M, Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const ElementType & type, const GhostType & ghost_type) {
#define ASSEMBLE_MATRIX(type) \
fem.template assembleFieldMatrix<type>(field_1, nb_degree_of_freedom, M, n, \
rotation_mat, ghost_type)
AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_MATRIX, _ek_structural);
#undef ASSEMBLE_MATRIX
}
};
template <template <ElementKind, class> class I, template <ElementKind> class S,
ElementKind kind, class IntegrationOrderFunctor>
inline void
FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix(
const Array<Real> & field_1, UInt nb_degree_of_freedom, SparseMatrix & M,
Array<Real> * n, ElementTypeMapArray<Real> & rotation_mat,
const ElementType & type, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AssembleFieldMatrixStructHelper<kind>::template call(
*this, field_1, nb_degree_of_freedom, M, n, rotation_mat, type,
ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <template <ElementKind, class> class I, template <ElementKind> class S,
ElementKind kind, class IntegrationOrderFunctor>
inline void
FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeShapesMatrix(
- const ElementType &, UInt, UInt, Array<Real> *,
- UInt, UInt, UInt, const bool,
- const GhostType &) const {
+ const ElementType &, UInt, UInt, Array<Real> *, UInt, UInt, UInt,
+ const bool, const GhostType &) const {
AKANTU_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template <template <ElementKind, class> class I, template <ElementKind> class S,
ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline void
FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix(
- const Array<Real> & , UInt , SparseMatrix &,
- Array<Real> * , ElementTypeMapArray<Real> & ,
- const GhostType & ) const {
+ const Array<Real> &, UInt, SparseMatrix &, Array<Real> *,
+ ElementTypeMapArray<Real> &, const GhostType &) const {
AKANTU_TO_IMPLEMENT();
}
} // akantu
diff --git a/src/fe_engine/geometrical_element_property.cc b/src/fe_engine/geometrical_element_property.cc
index 2b42fd1ca..c7086bbed 100644
--- a/src/fe_engine/geometrical_element_property.cc
+++ b/src/fe_engine/geometrical_element_property.cc
@@ -1,60 +1,60 @@
/**
* @file geometrical_element_property.cc
*
* @author Nicolas Richart
*
* @date creation Wed Nov 29 2017
*
* @brief A Documented file.
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
/* -------------------------------------------------------------------------- */
#include <boost/preprocessor.hpp>
/* -------------------------------------------------------------------------- */
namespace akantu {
#define AKANTU_INSTANTIATE_TYPES(r, data, type) \
constexpr std::array<UInt, ElementClass<type>::getNbFacetTypes()> \
GeometricalElementProperty< \
ElementClassProperty<type>::geometrical_type>::nb_facets; \
constexpr std::array<UInt, ElementClass<type>::getNbFacetTypes()> \
GeometricalElementProperty< \
ElementClassProperty<type>::geometrical_type>::nb_nodes_per_facet; \
constexpr std::array< \
UInt, detail::sizeFacetConnectivity<GeometricalElementProperty< \
ElementClassProperty<type>::geometrical_type>>()> \
GeometricalElementProperty<ElementClassProperty< \
type>::geometrical_type>::facet_connectivity_vect; \
constexpr std::array<ElementType, ElementClass<type>::getNbFacetTypes()> \
ElementClassExtraGeometryProperties<type>::facet_type;
BOOST_PP_SEQ_FOR_EACH(AKANTU_INSTANTIATE_TYPES, _,
- (_not_defined) AKANTU_ek_regular_ELEMENT_TYPE)
+ (_not_defined)AKANTU_ek_regular_ELEMENT_TYPE)
#if defined(AKANTU_COHESIVE_ELEMENT)
BOOST_PP_SEQ_FOR_EACH(AKANTU_INSTANTIATE_TYPES, _,
AKANTU_ek_cohesive_ELEMENT_TYPE)
#endif
} // akantu
diff --git a/src/fe_engine/integration_point.hh b/src/fe_engine/integration_point.hh
index 596aca80f..9c8eb8056 100644
--- a/src/fe_engine/integration_point.hh
+++ b/src/fe_engine/integration_point.hh
@@ -1,168 +1,169 @@
/**
* @file integration_point.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Jun 17 2015
* @date last modification: Sun Nov 15 2015
*
* @brief definition of the class IntegrationPoint
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_types.hh"
#include "element.hh"
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_QUADRATURE_POINT_H
#define AKANTU_QUADRATURE_POINT_H
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
class IntegrationPoint;
extern const IntegrationPoint IntegrationPointNull;
/* -------------------------------------------------------------------------- */
class IntegrationPoint : public Element {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
using position_type = Vector<Real>;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegrationPoint(const Element & element, UInt num_point = 0,
UInt nb_quad_per_element = 0)
: Element(element), num_point(num_point),
global_num(element.element * nb_quad_per_element + num_point),
position(nullptr, 0){};
IntegrationPoint(ElementType type = _not_defined, UInt element = 0,
UInt num_point = 0, GhostType ghost_type = _not_ghost)
: Element{type, element, ghost_type}, num_point(num_point),
position(nullptr, 0){};
IntegrationPoint(UInt element, UInt num_point, UInt global_num,
const position_type & position, ElementType type,
GhostType ghost_type = _not_ghost)
: Element{type, element, ghost_type}, num_point(num_point),
global_num(global_num), position(nullptr, 0) {
this->position.shallowCopy(position);
};
IntegrationPoint(const IntegrationPoint & quad)
: Element(quad), num_point(quad.num_point), global_num(quad.global_num),
position(nullptr, 0) {
position.shallowCopy(quad.position);
};
virtual ~IntegrationPoint() = default;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
inline bool operator==(const IntegrationPoint & quad) const {
return Element::operator==(quad) && this->num_point == quad.num_point;
}
inline bool operator!=(const IntegrationPoint & quad) const {
- return Element::operator!=(quad) || (num_point != quad.num_point) || (global_num != quad.global_num);
+ return Element::operator!=(quad) || (num_point != quad.num_point) ||
+ (global_num != quad.global_num);
}
bool operator<(const IntegrationPoint & rhs) const {
bool res = Element::operator<(rhs) ||
(Element::operator==(rhs) && this->num_point < rhs.num_point);
return res;
}
inline IntegrationPoint & operator=(const IntegrationPoint & q) {
if (this != &q) {
element = q.element;
type = q.type;
ghost_type = q.ghost_type;
num_point = q.num_point;
global_num = q.global_num;
position.shallowCopy(q.position);
}
return *this;
}
/// get the position of the integration point
AKANTU_GET_MACRO(Position, position, const position_type &);
/// set the position of the integration point
void setPosition(const position_type & position) {
this->position.shallowCopy(position);
}
/// deep copy of the position of the integration point
void copyPosition(const position_type & position) {
this->position.deepCopy(position);
}
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "IntegrationPoint [";
stream << *static_cast<const Element *>(this);
stream << ", " << num_point << "(" << global_num << ")"
<< "]";
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
/// number of quadrature point in the element
UInt num_point;
/// global number of the quadrature point
UInt global_num{0};
// TODO might be temporary: however this class should be tought maybe...
std::string material_id;
private:
/// position of the quadrature point
position_type position;
};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const IntegrationPoint & _this) {
_this.printself(stream);
return stream;
}
} // akantu
#endif /* AKANTU_QUADRATURE_POINT_H */
diff --git a/src/fe_engine/integrator_gauss.hh b/src/fe_engine/integrator_gauss.hh
index 792758e0a..4b76a5962 100644
--- a/src/fe_engine/integrator_gauss.hh
+++ b/src/fe_engine/integrator_gauss.hh
@@ -1,199 +1,199 @@
/**
* @file integrator_gauss.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 22 2015
*
* @brief Gauss integration facilities
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "integrator.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTEGRATOR_GAUSS_HH__
#define __AKANTU_INTEGRATOR_GAUSS_HH__
namespace akantu {
namespace integrator {
namespace details {
template <ElementKind> struct GaussIntegratorComputeJacobiansHelper;
} // namespace details
} // namespace fe_engine
-
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
class IntegratorGauss : public Integrator {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegratorGauss(const Mesh & mesh, const ID & id = "integrator_gauss",
const MemoryID & memory_id = 0);
~IntegratorGauss() override = default;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initIntegrator(const Array<Real> & nodes, const ElementType & type,
const GhostType & ghost_type);
template <ElementType type>
inline void initIntegrator(const Array<Real> & nodes,
const GhostType & ghost_type);
/// integrate f on the element "elem" of type "type"
template <ElementType type>
inline void integrateOnElement(const Array<Real> & f, Real * intf,
UInt nb_degree_of_freedom, const UInt elem,
const GhostType & ghost_type) const;
/// integrate f for all elements of type "type"
template <ElementType type>
void integrate(const Array<Real> & in_f, Array<Real> & intf,
UInt nb_degree_of_freedom, const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// integrate scalar field in_f
template <ElementType type, UInt polynomial_degree>
Real integrate(const Array<Real> & in_f,
const GhostType & ghost_type = _not_ghost) const;
/// integrate partially around a quadrature point (@f$ intf_q = f_q * J_q *
/// w_q @f$)
template <ElementType type>
Real integrate(const Vector<Real> & in_f, UInt index,
const GhostType & ghost_type) const;
/// integrate scalar field in_f
template <ElementType type>
Real integrate(const Array<Real> & in_f, const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// integrate a field without using the pre-computed values
template <ElementType type, UInt polynomial_degree>
void integrate(const Array<Real> & in_f, Array<Real> & intf,
UInt nb_degree_of_freedom, const GhostType & ghost_type) const;
/// integrate partially around a quadrature point (@f$ intf_q = f_q * J_q *
/// w_q @f$)
template <ElementType type>
void integrateOnIntegrationPoints(const Array<Real> & in_f,
Array<Real> & intf,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const;
/// return a matrix with quadrature points natural coordinates
template <ElementType type>
const Matrix<Real> & getIntegrationPoints(const GhostType & ghost_type) const;
/// return number of quadrature points
template <ElementType type>
UInt getNbIntegrationPoints(const GhostType & ghost_type) const;
template <ElementType type, UInt n> Matrix<Real> getIntegrationPoints() const;
template <ElementType type, UInt n>
Vector<Real> getIntegrationWeights() const;
protected:
- friend struct integrator::details::GaussIntegratorComputeJacobiansHelper<kind>;
+ friend struct integrator::details::GaussIntegratorComputeJacobiansHelper<
+ kind>;
template <ElementType type>
void computeJacobiansOnIntegrationPoints(
const Array<Real> & nodes, const Matrix<Real> & quad_points,
Array<Real> & jacobians, const GhostType & ghost_type,
const Array<UInt> & filter_elements = empty_filter) const;
void computeJacobiansOnIntegrationPoints(
const Array<Real> & nodes, const Matrix<Real> & quad_points,
Array<Real> & jacobians, const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements = empty_filter) const;
/// precompute jacobians on elements of type "type"
template <ElementType type>
void precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
const GhostType & ghost_type);
// multiply the jacobians by the integration weights and stores the results in
// jacobians
template <ElementType type, UInt polynomial_degree>
void multiplyJacobiansByWeights(Array<Real> & jacobians) const;
/// compute the vector of quadrature points natural coordinates
template <ElementType type>
void computeQuadraturePoints(const GhostType & ghost_type);
/// check that the jacobians are not negative
template <ElementType type>
void checkJacobians(const GhostType & ghost_type) const;
/// internal integrate partially around a quadrature point (@f$ intf_q = f_q *
/// J_q *
/// w_q @f$)
void integrateOnIntegrationPoints(const Array<Real> & in_f,
Array<Real> & intf,
UInt nb_degree_of_freedom,
const Array<Real> & jacobians,
UInt nb_element) const;
void integrate(const Array<Real> & in_f, Array<Real> & intf,
UInt nb_degree_of_freedom, const Array<Real> & jacobians,
UInt nb_element) const;
public:
/// compute the jacobians on quad points for a given element
template <ElementType type>
void
computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
const Matrix<Real> & integration_points,
Vector<Real> & jacobians) const;
public:
void onElementsAdded(const Array<Element> & elements) override;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// integrate the field f with the jacobian jac -> inte
inline void integrate(Real * f, Real * jac, Real * inte,
UInt nb_degree_of_freedom,
UInt nb_quadrature_points) const;
private:
/// ElementTypeMap of the quadrature points
ElementTypeMap<Matrix<Real>> quadrature_points;
};
} // namespace akantu
#include "integrator_gauss_inline_impl.cc"
#endif /* __AKANTU_INTEGRATOR_GAUSS_HH__ */
diff --git a/src/fe_engine/integrator_gauss_inline_impl.cc b/src/fe_engine/integrator_gauss_inline_impl.cc
index adadb20ae..681123e63 100644
--- a/src/fe_engine/integrator_gauss_inline_impl.cc
+++ b/src/fe_engine/integrator_gauss_inline_impl.cc
@@ -1,706 +1,709 @@
/**
* @file integrator_gauss_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Feb 15 2011
* @date last modification: Thu Nov 19 2015
*
* @brief inline function of gauss integrator
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "mesh_iterators.hh"
#if defined(AKANTU_DEBUG_TOOLS)
#include "aka_debug_tools.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace debug {
-struct IntegratorGaussException : public Exception {};
+ struct IntegratorGaussException : public Exception {};
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrateOnElement(
const Array<Real> & f, Real * intf, UInt nb_degree_of_freedom,
const UInt elem, const GhostType & ghost_type) const {
Array<Real> & jac_loc = jacobians(type, ghost_type);
UInt nb_quadrature_points = ElementClass<type>::getNbQuadraturePoints();
AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
- "The vector f do not have the good number of component.");
+ "The vector f do not have the good number of component.");
Real * f_val = f.storage() + elem * f.getNbComponent();
Real * jac_val = jac_loc.storage() + elem * nb_quadrature_points;
integrate(f_val, jac_val, intf, nb_degree_of_freedom, nb_quadrature_points);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
const Vector<Real> & in_f, UInt index, const GhostType & ghost_type) const {
const Array<Real> & jac_loc = jacobians(type, ghost_type);
UInt nb_quadrature_points =
GaussIntegrationElement<type>::getNbQuadraturePoints();
AKANTU_DEBUG_ASSERT(in_f.size() == nb_quadrature_points,
- "The vector f do not have nb_quadrature_points entries.");
+ "The vector f do not have nb_quadrature_points entries.");
Real * jac_val = jac_loc.storage() + index * nb_quadrature_points;
Real intf;
integrate(in_f.storage(), jac_val, &intf, 1, nb_quadrature_points);
return intf;
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
Real * f, Real * jac, Real * inte, UInt nb_degree_of_freedom,
UInt nb_quadrature_points) const {
memset(inte, 0, nb_degree_of_freedom * sizeof(Real));
Real * cjac = jac;
for (UInt q = 0; q < nb_quadrature_points; ++q) {
for (UInt dof = 0; dof < nb_degree_of_freedom; ++dof) {
inte[dof] += *f * *cjac;
++f;
}
++cjac;
}
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline const Matrix<Real> &
IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints(
const GhostType & ghost_type) const {
AKANTU_DEBUG_ASSERT(
quadrature_points.exists(type, ghost_type),
"Quadrature points for type "
- << quadrature_points.printType(type, ghost_type)
- << " have not been initialized."
- << " Did you use 'computeQuadraturePoints' function ?");
+ << quadrature_points.printType(type, ghost_type)
+ << " have not been initialized."
+ << " Did you use 'computeQuadraturePoints' function ?");
return quadrature_points(type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline UInt
IntegratorGauss<kind, IntegrationOrderFunctor>::getNbIntegrationPoints(
const GhostType & ghost_type) const {
AKANTU_DEBUG_ASSERT(
quadrature_points.exists(type, ghost_type),
"Quadrature points for type "
- << quadrature_points.printType(type, ghost_type)
- << " have not been initialized."
- << " Did you use 'computeQuadraturePoints' function ?");
+ << quadrature_points.printType(type, ghost_type)
+ << " have not been initialized."
+ << " Did you use 'computeQuadraturePoints' function ?");
return quadrature_points(type, ghost_type).cols();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type, UInt polynomial_degree>
inline Matrix<Real>
IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints() const {
return GaussIntegrationElement<type,
- polynomial_degree>::getQuadraturePoints();
+ polynomial_degree>::getQuadraturePoints();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type, UInt polynomial_degree>
inline Vector<Real>
IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationWeights() const {
return GaussIntegrationElement<type, polynomial_degree>::getWeights();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline void
IntegratorGauss<kind, IntegrationOrderFunctor>::computeQuadraturePoints(
const GhostType & ghost_type) {
Matrix<Real> & quads = quadrature_points(type, ghost_type);
const UInt polynomial_degree =
IntegrationOrderFunctor::template getOrder<type>();
quads =
GaussIntegrationElement<type, polynomial_degree>::getQuadraturePoints();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline void IntegratorGauss<kind, IntegrationOrderFunctor>::
computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
- const Matrix<Real> & quad,
- Vector<Real> & jacobians) const {
+ const Matrix<Real> & quad,
+ Vector<Real> & jacobians) const {
// jacobian
ElementClass<type>::computeJacobian(quad, node_coords, jacobians);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
IntegratorGauss<kind, IntegrationOrderFunctor>::IntegratorGauss(
const Mesh & mesh, const ID & id, const MemoryID & memory_id)
: Integrator(mesh, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
void IntegratorGauss<kind, IntegrationOrderFunctor>::checkJacobians(
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = this->quadrature_points(type, ghost_type).cols();
UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
Real * jacobians_val = jacobians(type, ghost_type).storage();
for (UInt i = 0; i < nb_element * nb_quadrature_points;
++i, ++jacobians_val) {
if (*jacobians_val < 0)
AKANTU_CUSTOM_EXCEPTION_INFO(debug::IntegratorGaussException{},
- "Negative jacobian computed,"
- << " possible problem in the element node ordering (Quadrature Point "
- << i % nb_quadrature_points << ":" << i / nb_quadrature_points << ":"
- << type << ":" << ghost_type << ")");
+ "Negative jacobian computed,"
+ << " possible problem in the element "
+ "node ordering (Quadrature Point "
+ << i % nb_quadrature_points << ":"
+ << i / nb_quadrature_points << ":"
+ << type << ":" << ghost_type << ")");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
void IntegratorGauss<kind, IntegrationOrderFunctor>::
computeJacobiansOnIntegrationPoints(
- const Array<Real> & nodes, const Matrix<Real> & quad_points,
- Array<Real> & jacobians, const GhostType & ghost_type,
- const Array<UInt> & filter_elements) const {
+ const Array<Real> & nodes, const Matrix<Real> & quad_points,
+ Array<Real> & jacobians, const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = quad_points.cols();
UInt nb_element = mesh.getNbElement(type, ghost_type);
jacobians.resize(nb_element * nb_quadrature_points);
auto jacobians_it =
jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
auto jacobians_begin = jacobians_it;
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
- filter_elements);
+ filter_elements);
auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
nb_element = x_el.size();
// Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
const Matrix<Real> & x = *x_it;
Vector<Real> & J = *jacobians_it;
computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
if (filter_elements == empty_filter) {
++jacobians_it;
} else {
jacobians_it = jacobians_begin + filter_elements(elem);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_STRUCTURAL_MECHANICS)
template <>
template <ElementType type>
void IntegratorGauss<_ek_structural, DefaultIntegrationOrderFunctor>::
computeJacobiansOnIntegrationPoints(
- const Array<Real> & nodes, const Matrix<Real> & quad_points,
- Array<Real> & jacobians, const GhostType & ghost_type,
- const Array<UInt> & filter_elements) const {
+ const Array<Real> & nodes, const Matrix<Real> & quad_points,
+ Array<Real> & jacobians, const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
const UInt spatial_dimension = mesh.getSpatialDimension();
const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const UInt nb_quadrature_points = quad_points.cols();
const UInt nb_dofs = ElementClass<type>::getNbDegreeOfFreedom();
UInt nb_element = mesh.getNbElement(type, ghost_type);
jacobians.resize(nb_element * nb_quadrature_points);
auto jacobians_it =
jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
auto jacobians_begin = jacobians_it;
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
- filter_elements);
+ filter_elements);
auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
nb_element = x_el.size();
const bool has_extra_normal =
mesh.hasData<Real>("extra_normal", type, ghost_type);
Array<Real>::const_vector_iterator extra_normal, extra_normal_begin;
if (has_extra_normal) {
extra_normal = mesh.getData<Real>("extra_normal", type, ghost_type)
- .begin(spatial_dimension);
+ .begin(spatial_dimension);
extra_normal_begin = extra_normal;
}
// Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
const Matrix<Real> & X = *x_it;
Vector<Real> & J = *jacobians_it;
Matrix<Real> R(nb_dofs, nb_dofs);
if (has_extra_normal)
ElementClass<type>::computeRotationMatrix(R, X, *extra_normal);
else
ElementClass<type>::computeRotationMatrix(R, X, Vector<Real>(X.rows()));
// Extracting relevant lines
auto x = (R.block(0, 0, spatial_dimension, spatial_dimension) * X)
- .block(0, 0, ElementClass<type>::getNaturalSpaceDimension(),
- ElementClass<type>::getNbNodesPerElement());
+ .block(0, 0, ElementClass<type>::getNaturalSpaceDimension(),
+ ElementClass<type>::getNbNodesPerElement());
computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
if (filter_elements == empty_filter) {
++jacobians_it;
++extra_normal;
} else {
jacobians_it = jacobians_begin + filter_elements(elem);
extra_normal = extra_normal_begin + filter_elements(elem);
}
}
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
template <>
template <ElementType type>
void IntegratorGauss<_ek_cohesive, DefaultIntegrationOrderFunctor>::
computeJacobiansOnIntegrationPoints(
- const Array<Real> & nodes, const Matrix<Real> & quad_points,
- Array<Real> & jacobians, const GhostType & ghost_type,
- const Array<UInt> & filter_elements) const {
+ const Array<Real> & nodes, const Matrix<Real> & quad_points,
+ Array<Real> & jacobians, const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = quad_points.cols();
UInt nb_element = mesh.getNbElement(type, ghost_type);
jacobians.resize(nb_element * nb_quadrature_points);
auto jacobians_it =
jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
auto jacobians_begin = jacobians_it;
Vector<Real> weights = GaussIntegrationElement<type>::getWeights();
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
- filter_elements);
+ filter_elements);
auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
UInt nb_nodes_per_subelement = nb_nodes_per_element / 2;
Matrix<Real> x(spatial_dimension, nb_nodes_per_subelement);
nb_element = x_el.size();
auto compute = [&](const auto & el) {
Vector<Real> J(jacobians_begin[el]);
for (UInt s = 0; s < spatial_dimension; ++s)
for (UInt n = 0; n < nb_nodes_per_subelement; ++n)
- x(s, n) =
- ((*x_it)(s, n) + (*x_it)(s, n + nb_nodes_per_subelement)) * .5;
+ x(s, n) =
+ ((*x_it)(s, n) + (*x_it)(s, n + nb_nodes_per_subelement)) * .5;
if (type == _cohesive_1d_2)
J(0) = 1;
else
this->computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
};
- for_each_element(nb_element, filter_elements, compute);AKANTU_DEBUG_OUT();
+ for_each_element(nb_element, filter_elements, compute);
+ AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
void IntegratorGauss<kind, IntegrationOrderFunctor>::
precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Array<Real> & jacobians_tmp = jacobians.alloc(0, 1, type, ghost_type);
this->computeJacobiansOnIntegrationPoints<type>(
nodes, quadrature_points(type, ghost_type), jacobians_tmp, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type, UInt polynomial_degree>
void IntegratorGauss<kind, IntegrationOrderFunctor>::multiplyJacobiansByWeights(
Array<Real> & jacobians) const {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points =
GaussIntegrationElement<type, polynomial_degree>::getNbQuadraturePoints();
UInt nb_element = jacobians.size() / nb_quadrature_points;
Vector<Real> weights =
GaussIntegrationElement<type, polynomial_degree>::getWeights();
auto jacobians_it =
jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
auto jacobians_end =
jacobians.end_reinterpret(nb_quadrature_points, nb_element);
for (; jacobians_it != jacobians_end; ++jacobians_it) {
Vector<Real> & J = *jacobians_it;
J *= weights;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
const Array<Real> & jacobians, UInt nb_element) const {
AKANTU_DEBUG_IN();
intf.resize(nb_element);
if (nb_element == 0)
return;
UInt nb_points = jacobians.size() / nb_element;
Array<Real>::const_matrix_iterator J_it;
Array<Real>::matrix_iterator inte_it;
Array<Real>::const_matrix_iterator f_it;
f_it = in_f.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
inte_it = intf.begin_reinterpret(nb_degree_of_freedom, 1, nb_element);
J_it = jacobians.begin_reinterpret(nb_points, 1, nb_element);
for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
const Matrix<Real> & f = *f_it;
const Matrix<Real> & J = *J_it;
Matrix<Real> & inte_f = *inte_it;
inte_f.mul<false, false>(f, J);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
"No jacobians for the type "
<< jacobians.printType(type, ghost_type));
const Array<Real> & jac_loc = jacobians(type, ghost_type);
if (filter_elements != empty_filter) {
UInt nb_element = filter_elements.size();
Array<Real> * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
filter_elements);
this->integrate(in_f, intf, nb_degree_of_freedom, *filtered_J, nb_element);
delete filtered_J;
} else {
UInt nb_element = mesh.getNbElement(type, ghost_type);
this->integrate(in_f, intf, nb_degree_of_freedom, jac_loc, nb_element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type, UInt polynomial_degree>
void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
Matrix<Real> quads = this->getIntegrationPoints<type, polynomial_degree>();
Array<Real> jacobians;
this->computeJacobiansOnIntegrationPoints<type>(mesh.getNodes(), quads,
jacobians, ghost_type);
this->multiplyJacobiansByWeights<type, polynomial_degree>(jacobians);
this->integrate(in_f, intf, nb_degree_of_freedom, jacobians,
mesh.getNbElement(type, ghost_type));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type, UInt polynomial_degree>
Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
const Array<Real> & in_f, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
Array<Real> intfv(0, 1);
integrate<type, polynomial_degree>(in_f, intfv, 1, ghost_type);
Real res = Math::reduce(intfv);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
const Array<Real> & in_f, const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
"No jacobians for the type "
<< jacobians.printType(type, ghost_type));
Array<Real> intfv(0, 1);
integrate<type>(in_f, intfv, 1, ghost_type, filter_elements);
Real res = Math::reduce(intfv);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
void IntegratorGauss<kind, IntegrationOrderFunctor>::
integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
UInt nb_degree_of_freedom,
const Array<Real> & jacobians,
UInt nb_element) const {
AKANTU_DEBUG_IN();
UInt nb_points = jacobians.size() / nb_element;
intf.resize(nb_element * nb_points);
auto J_it = jacobians.begin();
auto f_it = in_f.begin(nb_degree_of_freedom);
auto inte_it = intf.begin(nb_degree_of_freedom);
for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
const Real & J = *J_it;
const Vector<Real> & f = *f_it;
Vector<Real> & inte_f = *inte_it;
inte_f = f;
inte_f *= J;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
void IntegratorGauss<kind, IntegrationOrderFunctor>::
integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
"No jacobians for the type "
<< jacobians.printType(type, ghost_type));
const Array<Real> & jac_loc = this->jacobians(type, ghost_type);
if (filter_elements != empty_filter) {
UInt nb_element = filter_elements.size();
Array<Real> * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
filter_elements);
this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
*filtered_J, nb_element);
} else {
UInt nb_element = mesh.getNbElement(type, ghost_type);
this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
jac_loc, nb_element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
void IntegratorGauss<kind, IntegrationOrderFunctor>::onElementsAdded(
const Array<Element> & new_elements) {
const auto & nodes = mesh.getNodes();
for (auto elements_range : MeshElementsByTypes(new_elements)) {
auto type = elements_range.getType();
auto ghost_type = elements_range.getGhostType();
if (mesh.getKind(type) != kind)
continue;
auto & elements = elements_range.getElements();
if (not jacobians.exists(type, ghost_type))
jacobians.alloc(0, 1, type, ghost_type);
this->computeJacobiansOnIntegrationPoints(
nodes, quadrature_points(type, ghost_type), jacobians(type, ghost_type),
type, ghost_type, elements);
}
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind, class IntegrationOrderFunctor>
template <ElementType type>
inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
const Array<Real> & nodes, const GhostType & ghost_type) {
computeQuadraturePoints<type>(ghost_type);
precomputeJacobiansOnQuadraturePoints<type>(nodes, ghost_type);
checkJacobians<type>(ghost_type);
constexpr UInt polynomial_degree =
IntegrationOrderFunctor::template getOrder<type>();
multiplyJacobiansByWeights<type, polynomial_degree>(
this->jacobians(type, ghost_type));
}
namespace integrator {
namespace details {
template <ElementKind kind> struct GaussIntegratorInitHelper {};
#define INIT_INTEGRATOR(type) \
_int.template initIntegrator<type>(nodes, ghost_type)
#define AKANTU_GAUSS_INTERGRATOR_INIT_HELPER(kind) \
template <> struct GaussIntegratorInitHelper<kind> { \
template <ElementKind k, class IOF> \
static void call(IntegratorGauss<k, IOF> & _int, \
const Array<Real> & nodes, const ElementType & type, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INIT_INTEGRATOR, kind); \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_INIT_HELPER)
#undef AKANTU_GAUSS_INTERGRATOR_INIT_HELPER
#undef INIT_INTEGRATOR
} // namespace details
} // namespace integrator
template <ElementKind kind, class IntegrationOrderFunctor>
inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
const Array<Real> & nodes, const ElementType & type,
const GhostType & ghost_type) {
integrator::details::GaussIntegratorInitHelper<kind>::call(*this, nodes, type,
ghost_type);
}
namespace integrator {
namespace details {
template <ElementKind kind> struct GaussIntegratorComputeJacobiansHelper {};
#define AKANTU_COMPUTE_JACOBIANS(type) \
_int.template computeJacobiansOnIntegrationPoints<type>( \
nodes, quad_points, jacobians, ghost_type, filter_elements);
#define AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS(kind) \
template <> struct GaussIntegratorComputeJacobiansHelper<kind> { \
template <ElementKind k, class IOF> \
static void \
call(const IntegratorGauss<k, IOF> & _int, const Array<Real> & nodes, \
const Matrix<Real> & quad_points, Array<Real> & jacobians, \
const ElementType & type, const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_JACOBIANS, kind); \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS)
#undef AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS
#undef AKANTU_COMPUTE_JACOBIANS
} // namespace details
} // namespace integrator
template <ElementKind kind, class IntegrationOrderFunctor>
void IntegratorGauss<kind, IntegrationOrderFunctor>::
computeJacobiansOnIntegrationPoints(
const Array<Real> & nodes, const Matrix<Real> & quad_points,
Array<Real> & jacobians, const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
integrator::details::GaussIntegratorComputeJacobiansHelper<kind>::call(
*this, nodes, quad_points, jacobians, type, ghost_type, filter_elements);
}
} // namespace akantu
diff --git a/src/fe_engine/interpolation_element_tmpl.hh b/src/fe_engine/interpolation_element_tmpl.hh
index 53c70a35d..9507deb58 100644
--- a/src/fe_engine/interpolation_element_tmpl.hh
+++ b/src/fe_engine/interpolation_element_tmpl.hh
@@ -1,59 +1,73 @@
/**
* @file interpolation_element_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jun 06 2013
* @date last modification: Tue Apr 07 2015
*
* @brief interpolation property description
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTERPOLATION_ELEMENT_TMPL_HH__
#define __AKANTU_INTERPOLATION_ELEMENT_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
/* Regular Elements */
/* -------------------------------------------------------------------------- */
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_not_defined, _itk_not_defined, 0, 0);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_point_1, _itk_lagrangian, 1, 0);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_2, _itk_lagrangian, 2, 1);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_3, _itk_lagrangian, 3, 1);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_3, _itk_lagrangian, 3, 2);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_6, _itk_lagrangian, 6, 2);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_4, _itk_lagrangian, 4, 3);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_10, _itk_lagrangian, 10, 3);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_quadrangle_4, _itk_lagrangian, 4, 2);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_quadrangle_8, _itk_lagrangian, 8, 2);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_hexahedron_8, _itk_lagrangian, 8, 3);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_hexahedron_20, _itk_lagrangian, 20, 3);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_6, _itk_lagrangian, 6, 3);
-AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_15, _itk_lagrangian, 15, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_not_defined, _itk_not_defined, 0,
+ 0);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_point_1,
+ _itk_lagrangian, 1, 0);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_2,
+ _itk_lagrangian, 2, 1);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_3,
+ _itk_lagrangian, 3, 1);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_3,
+ _itk_lagrangian, 3, 2);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_6,
+ _itk_lagrangian, 6, 2);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_4,
+ _itk_lagrangian, 4, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_10,
+ _itk_lagrangian, 10, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_quadrangle_4,
+ _itk_lagrangian, 4, 2);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_quadrangle_8,
+ _itk_lagrangian, 8, 2);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_hexahedron_8,
+ _itk_lagrangian, 8, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_hexahedron_20,
+ _itk_lagrangian, 20, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_6,
+ _itk_lagrangian, 6, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_15,
+ _itk_lagrangian, 15, 3);
-} // akantu
+} // akantu
#endif /* __AKANTU_INTERPOLATION_ELEMENT_TMPL_HH__ */
diff --git a/src/fe_engine/shape_functions.hh b/src/fe_engine/shape_functions.hh
index 3d07d72bd..8d2626a4a 100644
--- a/src/fe_engine/shape_functions.hh
+++ b/src/fe_engine/shape_functions.hh
@@ -1,216 +1,215 @@
/**
* @file shape_functions.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 22 2015
*
* @brief shape function class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_FUNCTIONS_HH__
#define __AKANTU_SHAPE_FUNCTIONS_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
class ShapeFunctions : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ShapeFunctions(const Mesh & mesh, const ID & id = "shape",
const MemoryID & memory_id = 0);
~ShapeFunctions() override = default;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "Shapes [" << std::endl;
integration_points.printself(stream, indent + 1);
// shapes.printself(stream, indent + 1);
// shapes_derivatives.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/// set the integration points for a given element
template <ElementType type>
void setIntegrationPointsByType(const Matrix<Real> & integration_points,
const GhostType & ghost_type);
/// Build pre-computed matrices for interpolation of field form integration
/// points at other given positions (interpolation_points)
void initElementalFieldInterpolationFromIntegrationPoints(
const ElementTypeMapArray<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const ElementTypeMapArray<Real> & quadrature_points_coordinates,
const ElementTypeMapArray<UInt> * element_filter) const;
/// Interpolate field at given position from given values of this field at
/// integration points (field)
/// using matrices precomputed with
/// initElementalFieldInterplationFromIntegrationPoints
void interpolateElementalFieldFromIntegrationPoints(
const ElementTypeMapArray<Real> & field,
const ElementTypeMapArray<Real> &
interpolation_points_coordinates_matrices,
const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
const ElementTypeMapArray<UInt> * element_filter) const;
protected:
/// interpolate nodal values stored by element on the integration points
template <ElementType type>
void interpolateElementalFieldOnIntegrationPoints(
const Array<Real> & u_el, Array<Real> & uq, const GhostType & ghost_type,
const Array<Real> & shapes,
const Array<UInt> & filter_elements = empty_filter) const;
/// gradient of nodal values stored by element on the control points
template <ElementType type>
void gradientElementalFieldOnIntegrationPoints(
const Array<Real> & u_el, Array<Real> & out_nablauq,
const GhostType & ghost_type, const Array<Real> & shapes_derivatives,
const Array<UInt> & filter_elements) const;
protected:
/// By element versions of non-templated eponym methods
template <ElementType type>
inline void interpolateElementalFieldFromIntegrationPoints(
const Array<Real> & field,
const Array<Real> & interpolation_points_coordinates_matrices,
const Array<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
const Array<UInt> & element_filter) const;
/// Interpolate field at given position from given values of this field at
/// integration points (field)
/// using matrices precomputed with
/// initElementalFieldInterplationFromIntegrationPoints
template <ElementType type>
inline void initElementalFieldInterpolationFromIntegrationPoints(
const Array<Real> & interpolation_points_coordinates,
ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
const Array<Real> & quadrature_points_coordinates,
const GhostType & ghost_type, const Array<UInt> & element_filter) const;
/// build matrix for the interpolation of field form integration points
template <ElementType type>
inline void buildElementalFieldInterpolationMatrix(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order =
ElementClassProperty<type>::polynomial_degree) const;
/// build the so called interpolation matrix (first collumn is 1, then the
/// other collumns are the traansposed coordinates)
inline void buildInterpolationMatrix(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const;
public:
virtual void onElementsAdded(const Array<Element> &) {
AKANTU_TO_IMPLEMENT();
}
virtual void onElementsRemoved(const Array<Element> &,
const ElementTypeMapArray<UInt> &) {
AKANTU_TO_IMPLEMENT();
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the size of the shapes returned by the element class
static inline UInt getShapeSize(const ElementType & type);
/// get the size of the shapes derivatives returned by the element class
static inline UInt getShapeDerivativesSize(const ElementType & type);
inline const Matrix<Real> &
getIntegrationPoints(const ElementType & type,
const GhostType & ghost_type) const {
return integration_points(type, ghost_type);
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get a the shapes vector
inline const Array<Real> &
getShapes(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/// get a the shapes derivatives vector
inline const Array<Real> &
getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// shape functions for all elements
ElementTypeMapArray<Real, InterpolationType> shapes;
/// shape functions derivatives for all elements
ElementTypeMapArray<Real, InterpolationType> shapes_derivatives;
/// associated mesh
const Mesh & mesh;
/// shape functions for all elements
ElementTypeMap<Matrix<Real>> integration_points;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const ShapeFunctions & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "shape_functions_inline_impl.cc"
#endif /* __AKANTU_SHAPE_FUNCTIONS_HH__ */
diff --git a/src/fe_engine/shape_functions_inline_impl.cc b/src/fe_engine/shape_functions_inline_impl.cc
index be1d9b5fc..f7d05f8c4 100644
--- a/src/fe_engine/shape_functions_inline_impl.cc
+++ b/src/fe_engine/shape_functions_inline_impl.cc
@@ -1,402 +1,402 @@
/**
* @file shape_functions_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Oct 27 2010
* @date last modification: Thu Oct 15 2015
*
* @brief ShapeFunctions inline implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "shape_functions.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__
#define __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline const Array<Real> &
ShapeFunctions::getShapes(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
inline const Array<Real> &
ShapeFunctions::getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes_derivatives(FEEngine::getInterpolationType(el_type),
ghost_type);
}
/* -------------------------------------------------------------------------- */
inline UInt ShapeFunctions::getShapeSize(const ElementType & type) {
AKANTU_DEBUG_IN();
UInt shape_size = 0;
#define GET_SHAPE_SIZE(type) shape_size = ElementClass<type>::getShapeSize()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_SIZE); // ,
#undef GET_SHAPE_SIZE
AKANTU_DEBUG_OUT();
return shape_size;
}
/* -------------------------------------------------------------------------- */
inline UInt ShapeFunctions::getShapeDerivativesSize(const ElementType & type) {
AKANTU_DEBUG_IN();
UInt shape_derivatives_size = 0;
#define GET_SHAPE_DERIVATIVES_SIZE(type) \
shape_derivatives_size = ElementClass<type>::getShapeDerivativesSize()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_DERIVATIVES_SIZE); // ,
#undef GET_SHAPE_DERIVATIVES_SIZE
AKANTU_DEBUG_OUT();
return shape_derivatives_size;
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeFunctions::setIntegrationPointsByType(const Matrix<Real> & points,
const GhostType & ghost_type) {
if (not this->integration_points.exists(type, ghost_type))
this->integration_points(type, ghost_type).shallowCopy(points);
}
/* -------------------------------------------------------------------------- */
inline void
ShapeFunctions::buildInterpolationMatrix(const Matrix<Real> & coordinates,
Matrix<Real> & coordMatrix,
UInt integration_order) const {
switch (integration_order) {
case 1: {
for (UInt i = 0; i < coordinates.cols(); ++i)
coordMatrix(i, 0) = 1;
break;
}
case 2: {
UInt nb_quadrature_points = coordMatrix.cols();
for (UInt i = 0; i < coordinates.cols(); ++i) {
coordMatrix(i, 0) = 1;
for (UInt j = 1; j < nb_quadrature_points; ++j)
coordMatrix(i, j) = coordinates(j - 1, i);
}
break;
}
default: {
AKANTU_TO_IMPLEMENT();
break;
}
}
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix(
const Matrix<Real> &, Matrix<Real> &, UInt) const {
AKANTU_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template <>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_2>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template <>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_3>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template <>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_3>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template <>
inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_6>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template <>
inline void
ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_4>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/* -------------------------------------------------------------------------- */
template <>
inline void
ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_10>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
}
/**
* @todo Write a more efficient interpolation for quadrangles by
* dropping unnecessary quadrature points
*
*/
/* -------------------------------------------------------------------------- */
template <>
inline void
ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_4>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
if (integration_order !=
ElementClassProperty<_quadrangle_4>::polynomial_degree) {
AKANTU_TO_IMPLEMENT();
} else {
for (UInt i = 0; i < coordinates.cols(); ++i) {
Real x = coordinates(0, i);
Real y = coordinates(1, i);
coordMatrix(i, 0) = 1;
coordMatrix(i, 1) = x;
coordMatrix(i, 2) = y;
coordMatrix(i, 3) = x * y;
}
}
}
/* -------------------------------------------------------------------------- */
template <>
inline void
ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_8>(
const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
UInt integration_order) const {
if (integration_order !=
ElementClassProperty<_quadrangle_8>::polynomial_degree) {
AKANTU_TO_IMPLEMENT();
} else {
for (UInt i = 0; i < coordinates.cols(); ++i) {
- //UInt j = 0;
+ // UInt j = 0;
Real x = coordinates(0, i);
Real y = coordinates(1, i);
coordMatrix(i, 0) = 1;
coordMatrix(i, 1) = x;
coordMatrix(i, 2) = y;
coordMatrix(i, 3) = x * y;
// for (UInt e = 0; e <= 2; ++e) {
// for (UInt n = 0; n <= 2; ++n) {
// coordMatrix(i, j) = std::pow(x, e) * std::pow(y, n);
// ++j;
// }
// }
}
}
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
inline void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints(
const Array<Real> & field,
const Array<Real> & interpolation_points_coordinates_matrices,
const Array<Real> & quad_points_coordinates_inv_matrices,
ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
const Array<UInt> & element_filter) const {
AKANTU_DEBUG_IN();
auto nb_element = this->mesh.getNbElement(type, ghost_type);
auto nb_quad_per_element =
GaussIntegrationElement<type>::getNbQuadraturePoints();
auto nb_interpolation_points_per_elem =
interpolation_points_coordinates_matrices.getNbComponent() /
nb_quad_per_element;
if (!result.exists(type, ghost_type))
result.alloc(nb_element * nb_interpolation_points_per_elem,
field.getNbComponent(), type, ghost_type);
if (element_filter != empty_filter)
nb_element = element_filter.size();
Matrix<Real> coefficients(nb_quad_per_element, field.getNbComponent());
auto & result_vec = result(type, ghost_type);
auto field_it = field.begin_reinterpret(field.getNbComponent(),
nb_quad_per_element, nb_element);
auto interpolation_points_coordinates_it =
interpolation_points_coordinates_matrices.begin(
nb_interpolation_points_per_elem, nb_quad_per_element);
auto result_begin = result_vec.begin_reinterpret(
field.getNbComponent(), nb_interpolation_points_per_elem,
result_vec.size() / nb_interpolation_points_per_elem);
auto inv_quad_coord_it = quad_points_coordinates_inv_matrices.begin(
nb_quad_per_element, nb_quad_per_element);
/// loop over the elements of the current filter and element type
for (UInt el = 0; el < nb_element; ++el, ++field_it, ++inv_quad_coord_it,
++interpolation_points_coordinates_it) {
/**
* matrix containing the inversion of the quadrature points'
* coordinates
*/
const auto & inv_quad_coord_matrix = *inv_quad_coord_it;
/**
* multiply it by the field values over quadrature points to get
* the interpolation coefficients
*/
coefficients.mul<false, true>(inv_quad_coord_matrix, *field_it);
/// matrix containing the points' coordinates
const auto & coord = *interpolation_points_coordinates_it;
/// multiply the coordinates matrix by the coefficients matrix and store the
/// result
Matrix<Real> res(result_begin[element_filter(el)]);
res.mul<true, true>(coefficients, coord);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
inline void ShapeFunctions::interpolateElementalFieldOnIntegrationPoints(
const Array<Real> & u_el, Array<Real> & uq, const GhostType & ghost_type,
const Array<Real> & shapes, const Array<UInt> & filter_elements) const {
auto nb_element = mesh.getNbElement(type, ghost_type);
auto nb_nodes_per_element = ElementClass<type>::getShapeSize();
auto nb_points = shapes.size() / mesh.getNbElement(type, ghost_type);
auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
Array<Real>::const_matrix_iterator N_it;
Array<Real> * filtered_N = nullptr;
if (filter_elements != empty_filter) {
nb_element = filter_elements.size();
filtered_N = new Array<Real>(0, shapes.getNbComponent());
FEEngine::filterElementalData(mesh, shapes, *filtered_N, type, ghost_type,
filter_elements);
N_it = filtered_N->begin_reinterpret(nb_nodes_per_element, nb_points,
nb_element);
} else {
N_it =
shapes.begin_reinterpret(nb_nodes_per_element, nb_points, nb_element);
}
uq.resize(nb_element * nb_points);
auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
auto inter_u_it =
uq.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
for (UInt el = 0; el < nb_element; ++el, ++N_it, ++u_it, ++inter_u_it) {
const auto & u = *u_it;
const auto & N = *N_it;
auto & inter_u = *inter_u_it;
inter_u.template mul<false, false>(u, N);
}
delete filtered_N;
}
/* -------------------------------------------------------------------------- */
template <ElementType type>
void ShapeFunctions::gradientElementalFieldOnIntegrationPoints(
const Array<Real> & u_el, Array<Real> & out_nablauq,
const GhostType & ghost_type, const Array<Real> & shapes_derivatives,
const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
auto nb_nodes_per_element =
ElementClass<type>::getNbNodesPerInterpolationElement();
auto nb_points = integration_points(type, ghost_type).cols();
auto element_dimension = ElementClass<type>::getNaturalSpaceDimension();
auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
auto nb_element = mesh.getNbElement(type, ghost_type);
Array<Real>::const_matrix_iterator B_it;
Array<Real> * filtered_B = nullptr;
if (filter_elements != empty_filter) {
nb_element = filter_elements.size();
filtered_B = new Array<Real>(0, shapes_derivatives.getNbComponent());
FEEngine::filterElementalData(mesh, shapes_derivatives, *filtered_B, type,
ghost_type, filter_elements);
B_it = filtered_B->begin(element_dimension, nb_nodes_per_element);
} else {
B_it = shapes_derivatives.begin(element_dimension, nb_nodes_per_element);
}
out_nablauq.resize(nb_element * nb_points);
auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
auto nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension);
for (UInt el = 0; el < nb_element; ++el, ++u_it) {
const auto & u = *u_it;
for (UInt q = 0; q < nb_points; ++q, ++B_it, ++nabla_u_it) {
const auto & B = *B_it;
- auto & nabla_u = *nabla_u_it;
+ auto & nabla_u = *nabla_u_it;
nabla_u.template mul<false, true>(u, B);
}
}
delete filtered_B;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
#endif /* __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/shape_lagrange.hh b/src/fe_engine/shape_lagrange.hh
index 0f7252700..36a3c321f 100644
--- a/src/fe_engine/shape_lagrange.hh
+++ b/src/fe_engine/shape_lagrange.hh
@@ -1,173 +1,172 @@
/**
* @file shape_lagrange.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Feb 15 2011
* @date last modification: Thu Nov 05 2015
*
* @brief lagrangian shape functions class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "shape_lagrange_base.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_LAGRANGE_HH__
#define __AKANTU_SHAPE_LAGRANGE_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Shape> class ShapeCohesive;
class ShapeIGFEM;
template <ElementKind kind> class ShapeLagrange : public ShapeLagrangeBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ShapeLagrange(const Mesh & mesh, const ID & id = "shape_lagrange",
const MemoryID & memory_id = 0);
~ShapeLagrange() override = default;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialization function for structural elements not yet implemented
inline void initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
/// computes the shape functions derivatives for given interpolation points
template <ElementType type>
void computeShapeDerivativesOnIntegrationPoints(
const Array<Real> & nodes, const Matrix<Real> & integration_points,
Array<Real> & shape_derivatives, const GhostType & ghost_type,
const Array<UInt> & filter_elements = empty_filter) const;
void computeShapeDerivativesOnIntegrationPoints(
const Array<Real> & nodes, const Matrix<Real> & integration_points,
Array<Real> & shape_derivatives, const ElementType & type,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const override;
/// pre compute all shapes on the element integration points from natural
/// coordinates
template <ElementType type>
void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
/// pre compute all shape derivatives on the element integration points from
/// natural coordinates
template <ElementType type>
void
precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
/// interpolate nodal values on the integration points
template <ElementType type>
void interpolateOnIntegrationPoints(
const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
template <ElementType type>
void interpolateOnIntegrationPoints(
const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
const Array<Real> & shapes, GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate on physical point
template <ElementType type>
void interpolate(const Vector<Real> & real_coords, UInt elem,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const GhostType & ghost_type) const;
/// compute the gradient of u on the integration points
template <ElementType type>
void gradientOnIntegrationPoints(
const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
template <ElementType type>
void computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
GhostType ghost_type,
const Array<UInt> & filter_elements) const;
template <ElementType type>
- void computeBtDB(const Array<Real> & Ds, Array<Real> & BtDBs,
- UInt order_d,
+ void computeBtDB(const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
GhostType ghost_type,
const Array<UInt> & filter_elements) const;
/// multiply a field by shape functions @f$ fts_{ij} = f_i * \varphi_j @f$
template <ElementType type>
void fieldTimesShapes(const Array<Real> & field,
Array<Real> & field_times_shapes,
GhostType ghost_type) const;
/// find natural coords from real coords provided an element
template <ElementType type>
void inverseMap(const Vector<Real> & real_coords, UInt element,
Vector<Real> & natural_coords,
const GhostType & ghost_type = _not_ghost) const;
/// return true if the coordinates provided are inside the element, false
/// otherwise
template <ElementType type>
bool contains(const Vector<Real> & real_coords, UInt elem,
const GhostType & ghost_type) const;
/// compute the shape on a provided point
template <ElementType type>
void computeShapes(const Vector<Real> & real_coords, UInt elem,
Vector<Real> & shapes, const GhostType & ghost_type) const;
/// compute the shape derivatives on a provided point
template <ElementType type>
void computeShapeDerivatives(const Matrix<Real> & real_coords, UInt elem,
Tensor3<Real> & shapes,
const GhostType & ghost_type) const;
protected:
/// compute the shape derivatives on integration points for a given element
template <ElementType type>
inline void
computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
const Matrix<Real> & natural_coords,
Tensor3<Real> & shapesd) const;
};
} // namespace akantu
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "shape_lagrange_inline_impl.cc"
#endif /* __AKANTU_SHAPE_LAGRANGE_HH__ */
diff --git a/src/fe_engine/shape_lagrange_base.cc b/src/fe_engine/shape_lagrange_base.cc
index ad9f1c4a6..30fa00208 100644
--- a/src/fe_engine/shape_lagrange_base.cc
+++ b/src/fe_engine/shape_lagrange_base.cc
@@ -1,159 +1,158 @@
/**
* @file shape_lagrange_base.cc
*
* @author Nicolas Richart
*
* @date creation Thu Jul 27 2017
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "shape_lagrange_base.hh"
#include "mesh_iterators.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
ShapeLagrangeBase::ShapeLagrangeBase(const Mesh & mesh,
const ElementKind & kind, const ID & id,
const MemoryID & memory_id)
- : ShapeFunctions(mesh, id, memory_id),
- _kind(kind) {}
+ : ShapeFunctions(mesh, id, memory_id), _kind(kind) {}
/* -------------------------------------------------------------------------- */
ShapeLagrangeBase::~ShapeLagrangeBase() = default;
/* -------------------------------------------------------------------------- */
#define AKANTU_COMPUTE_SHAPES(type) \
_this.template computeShapesOnIntegrationPoints<type>( \
nodes, integration_points, shapes, ghost_type, filter_elements)
namespace shape_lagrange {
namespace details {
template <ElementKind kind> struct Helper {
template <class S>
static void call(const S &, const Array<Real> &, const Matrix<Real> &,
Array<Real> &, const ElementType &, const GhostType &,
const Array<UInt> &) {
AKANTU_TO_IMPLEMENT();
}
};
#define AKANTU_COMPUTE_SHAPES_KIND(kind) \
template <> struct Helper<kind> { \
template <class S> \
static void call(const S & _this, const Array<Real> & nodes, \
const Matrix<Real> & integration_points, \
Array<Real> & shapes, const ElementType & type, \
const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_COMPUTE_SHAPES_KIND,
AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE)
} // namespace details
} // namespace shape_lagrange
/* -------------------------------------------------------------------------- */
void ShapeLagrangeBase::computeShapesOnIntegrationPoints(
const Array<Real> & nodes, const Matrix<Real> & integration_points,
Array<Real> & shapes, const ElementType & type,
const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
auto kind = Mesh::getKind(type);
#define AKANTU_COMPUTE_SHAPES_KIND_SWITCH(kind) \
shape_lagrange::details::Helper<kind>::call( \
*this, nodes, integration_points, shapes, type, ghost_type, \
filter_elements);
AKANTU_BOOST_LIST_SWITCH(
AKANTU_COMPUTE_SHAPES_KIND_SWITCH,
BOOST_PP_LIST_TO_SEQ(AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE), kind);
#undef AKANTU_COMPUTE_SHAPES
#undef AKANTU_COMPUTE_SHAPES_KIND
#undef AKANTU_COMPUTE_SHAPES_KIND_SWITCH
}
/* -------------------------------------------------------------------------- */
void ShapeLagrangeBase::onElementsAdded(const Array<Element> & new_elements) {
AKANTU_DEBUG_IN();
const auto & nodes = mesh.getNodes();
for (auto elements_range : MeshElementsByTypes(new_elements)) {
auto type = elements_range.getType();
auto ghost_type = elements_range.getGhostType();
if (mesh.getKind(type) != _kind)
continue;
auto & elements = elements_range.getElements();
auto itp_type = FEEngine::getInterpolationType(type);
if (not this->shapes_derivatives.exists(itp_type, ghost_type)) {
auto size_of_shapesd = this->getShapeDerivativesSize(type);
this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
}
if (not shapes.exists(itp_type, ghost_type)) {
auto size_of_shapes = this->getShapeSize(type);
this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
}
const auto & natural_coords = integration_points(type, ghost_type);
computeShapesOnIntegrationPoints(nodes, natural_coords,
shapes(itp_type, ghost_type), type,
ghost_type, elements);
computeShapeDerivativesOnIntegrationPoints(
nodes, natural_coords, shapes_derivatives(itp_type, ghost_type), type,
ghost_type, elements);
}
#undef INIT_SHAPE_FUNCTIONS
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ShapeLagrangeBase::onElementsRemoved(
const Array<Element> &, const ElementTypeMapArray<UInt> & new_numbering) {
this->shapes.onElementsRemoved(new_numbering);
this->shapes_derivatives.onElementsRemoved(new_numbering);
}
/* -------------------------------------------------------------------------- */
void ShapeLagrangeBase::printself(std::ostream & stream, int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "Shapes Lagrange [" << std::endl;
ShapeFunctions::printself(stream, indent + 1);
shapes.printself(stream, indent + 1);
shapes_derivatives.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
} // namespace akantu
diff --git a/src/fe_engine/shape_structural.cc b/src/fe_engine/shape_structural.cc
index 48edc1468..cf7315dd2 100644
--- a/src/fe_engine/shape_structural.cc
+++ b/src/fe_engine/shape_structural.cc
@@ -1,54 +1,53 @@
/**
* @file shape_structural.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Sun Oct 19 2014
*
* @brief ShapeStructural implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "shape_structural.hh"
#include "aka_memory.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <>
ShapeStructural<_ek_structural>::ShapeStructural(Mesh & mesh, const ID & id,
const MemoryID & memory_id)
: ShapeFunctions(mesh, id, memory_id),
rotation_matrices("rotation_matrices", id, memory_id) {}
/* -------------------------------------------------------------------------- */
template <> ShapeStructural<_ek_structural>::~ShapeStructural() = default;
/* -------------------------------------------------------------------------- */
-
} // namespace akantu
diff --git a/src/fe_engine/shape_structural.hh b/src/fe_engine/shape_structural.hh
index 840bc116c..bd888aa0e 100644
--- a/src/fe_engine/shape_structural.hh
+++ b/src/fe_engine/shape_structural.hh
@@ -1,177 +1,177 @@
/**
* @file shape_structural.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Feb 15 2011
* @date last modification: Thu Oct 22 2015
*
* @brief shape class for element with different set of shapes functions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "shape_functions.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_STRUCTURAL_HH__
#define __AKANTU_SHAPE_STRUCTURAL_HH__
namespace akantu {
template <ElementKind kind> class ShapeStructural : public ShapeFunctions {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
// Ctors/Dtors should be explicitely implemented for _ek_structural
public:
ShapeStructural(Mesh & mesh, const ID & id = "shape_structural",
const MemoryID & memory_id = 0);
~ShapeStructural() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to print the contain of the class
void printself(std::ostream & stream, int indent = 0) const override {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "ShapesStructural [" << std::endl;
rotation_matrices.printself(stream, indent + 1);
ShapeFunctions::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/// compute shape functions on given integration points
template <ElementType type>
void computeShapesOnIntegrationPoints(
const Array<Real> &, const Matrix<Real> & integration_points,
Array<Real> & shapes, const GhostType & ghost_type,
const Array<UInt> & filter_elements = empty_filter) const;
/// initialization function for structural elements
inline void initShapeFunctions(const Array<Real> & nodes,
const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
/// precompute the rotation matrices for the elements dofs
template <ElementType type>
void precomputeRotationMatrices(const Array<Real> & nodes,
const GhostType & ghost_type);
/// pre compute all shapes on the element integration points from natural
/// coordinates
template <ElementType type>
void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
/// pre compute all shapes on the element integration points from natural
/// coordinates
template <ElementType type>
void
precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
/// interpolate nodal values on the integration points
template <ElementType type>
void interpolateOnIntegrationPoints(
const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// compute the gradient of u on the integration points
template <ElementType type>
void gradientOnIntegrationPoints(
const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate on physical point
template <ElementType type>
void interpolate(const Vector<Real> & /*real_coords*/, UInt /*elem*/,
const Matrix<Real> & /*nodal_values*/,
Vector<Real> & /*interpolated*/,
const GhostType & /*ghost_type*/) const {
AKANTU_TO_IMPLEMENT();
}
/// compute the shapes on a provided point
template <ElementType type>
void computeShapes(const Vector<Real> & /*real_coords*/, UInt /*elem*/,
Vector<Real> & /*shapes*/,
const GhostType & /*ghost_type*/) const {
AKANTU_TO_IMPLEMENT();
}
-
+
/// compute the shape derivatives on a provided point
template <ElementType type>
- void computeShapeDerivatives(const Matrix<Real> & /*real_coords*/, UInt /*elem*/,
- Tensor3<Real> & /*shapes*/,
+ void computeShapeDerivatives(const Matrix<Real> & /*real_coords*/,
+ UInt /*elem*/, Tensor3<Real> & /*shapes*/,
const GhostType & /*ghost_type*/) const {
AKANTU_TO_IMPLEMENT();
}
/// multiply a field by shape functions
template <ElementType type>
void
fieldTimesShapes(__attribute__((unused)) const Array<Real> & field,
__attribute__((unused)) Array<Real> & field_times_shapes,
__attribute__((unused)) const GhostType & ghost_type) const {
AKANTU_TO_IMPLEMENT();
}
/// get the rotations vector
inline const Array<Real> &
getRotations(const ElementType & el_type,
__attribute__((unused))
const GhostType & ghost_type = _not_ghost) const {
return rotation_matrices(el_type);
}
template <ElementType type>
void computeBtD(const Array<Real> & /*Ds*/, Array<Real> & /*BtDs*/,
GhostType /*ghost_type*/,
const Array<UInt> & /*filter_elements*/) const {
AKANTU_TO_IMPLEMENT();
}
template <ElementType type>
void computeBtDB(const Array<Real> & /*Ds*/, Array<Real> & /*BtDBs*/,
UInt /*order_d*/, GhostType /*ghost_type*/,
const Array<UInt> & /*filter_elements*/) const {
AKANTU_TO_IMPLEMENT();
}
protected:
ElementTypeMapArray<Real> rotation_matrices;
};
} // namespace akantu
#include "shape_structural_inline_impl.cc"
#endif /* __AKANTU_SHAPE_STRUCTURAL_HH__ */
diff --git a/src/fe_engine/shape_structural_inline_impl.cc b/src/fe_engine/shape_structural_inline_impl.cc
index 978c89071..1919521a3 100644
--- a/src/fe_engine/shape_structural_inline_impl.cc
+++ b/src/fe_engine/shape_structural_inline_impl.cc
@@ -1,432 +1,430 @@
/**
* @file shape_structural_inline_impl.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Thu Oct 15 2015
*
* @brief ShapeStructural inline implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_iterators.hh"
#include "shape_structural.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__
#define __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__
namespace akantu {
namespace {
/// Extract nodal coordinates per elements
template <ElementType type>
std::unique_ptr<Array<Real>>
getNodesPerElement(const Mesh & mesh, const Array<Real> & nodes,
const GhostType & ghost_type) {
const auto dim = ElementClass<type>::getSpatialDimension();
const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- auto nodes_per_element = std::make_unique<Array<Real>>(0, dim * nb_nodes_per_element);
- FEEngine::extractNodalToElementField(mesh, nodes, *nodes_per_element, type, ghost_type);
+ auto nodes_per_element =
+ std::make_unique<Array<Real>>(0, dim * nb_nodes_per_element);
+ FEEngine::extractNodalToElementField(mesh, nodes, *nodes_per_element, type,
+ ghost_type);
return nodes_per_element;
}
}
template <ElementKind kind>
inline void ShapeStructural<kind>::initShapeFunctions(
const Array<Real> & /* unused */, const Matrix<Real> & /* unused */,
const ElementType & /* unused */, const GhostType & /* unused */) {
AKANTU_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
#define INIT_SHAPE_FUNCTIONS(type) \
setIntegrationPointsByType<type>(integration_points, ghost_type); \
precomputeRotationMatrices<type>(nodes, ghost_type); \
precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \
precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
template <>
inline void ShapeStructural<_ek_structural>::initShapeFunctions(
const Array<Real> & nodes, const Matrix<Real> & integration_points,
const ElementType & type, const GhostType & ghost_type) {
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
}
#undef INIT_SHAPE_FUNCTIONS
/* -------------------------------------------------------------------------- */
template <>
template <ElementType type>
void ShapeStructural<_ek_structural>::computeShapesOnIntegrationPoints(
const Array<Real> & nodes, const Matrix<Real> & integration_points,
Array<Real> & shapes, const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
UInt nb_points = integration_points.cols();
UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
shapes.resize(nb_element * nb_points);
UInt ndof = ElementClass<type>::getNbDegreeOfFreedom();
#if !defined(AKANTU_NDEBUG)
UInt size_of_shapes = ElementClass<type>::getShapeSize();
AKANTU_DEBUG_ASSERT(shapes.getNbComponent() == size_of_shapes,
"The shapes array does not have the correct "
<< "number of component");
#endif
auto shapes_it = shapes.begin_reinterpret(
ElementClass<type>::getNbNodesPerInterpolationElement(), ndof, nb_points,
nb_element);
auto shapes_begin = shapes_it;
if (filter_elements != empty_filter) {
nb_element = filter_elements.size();
}
auto nodes_per_element = getNodesPerElement<type>(mesh, nodes, ghost_type);
auto nodes_it = nodes_per_element->begin(mesh.getSpatialDimension(),
Mesh::getNbNodesPerElement(type));
auto nodes_begin = nodes_it;
for (UInt elem = 0; elem < nb_element; ++elem) {
if (filter_elements != empty_filter) {
shapes_it = shapes_begin + filter_elements(elem);
nodes_it = nodes_begin + filter_elements(elem);
}
Tensor3<Real> & N = *shapes_it;
auto & real_coord = *nodes_it;
ElementClass<type>::computeShapes(integration_points, real_coord, N);
if (filter_elements == empty_filter)
++shapes_it;
}
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeStructural<kind>::precomputeRotationMatrices(
const Array<Real> & nodes, const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
const auto spatial_dimension = mesh.getSpatialDimension();
const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const auto nb_element = mesh.getNbElement(type, ghost_type);
const auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
if (not this->rotation_matrices.exists(type, ghost_type)) {
this->rotation_matrices.alloc(0, nb_dof * nb_dof, type, ghost_type);
}
auto & rot_matrices = this->rotation_matrices(type, ghost_type);
rot_matrices.resize(nb_element);
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
bool has_extra_normal = mesh.hasData<Real>("extra_normal", type, ghost_type);
Array<Real>::const_vector_iterator extra_normal;
if (has_extra_normal)
extra_normal = mesh.getData<Real>("extra_normal", type, ghost_type)
.begin(spatial_dimension);
for (auto && tuple :
zip(make_view(x_el, spatial_dimension, nb_nodes_per_element),
make_view(rot_matrices, nb_dof, nb_dof))) {
// compute shape derivatives
auto & X = std::get<0>(tuple);
auto & R = std::get<1>(tuple);
if (has_extra_normal) {
ElementClass<type>::computeRotationMatrix(R, X, *extra_normal);
++extra_normal;
} else {
ElementClass<type>::computeRotationMatrix(
R, X, Vector<Real>(spatial_dimension));
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeStructural<kind>::precomputeShapesOnIntegrationPoints(
const Array<Real> & nodes, const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
const auto & natural_coords = integration_points(type, ghost_type);
auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
auto nb_points = integration_points(type, ghost_type).cols();
auto nb_element = mesh.getNbElement(type, ghost_type);
auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
const auto dim = ElementClass<type>::getSpatialDimension();
auto itp_type = FEEngine::getInterpolationType(type);
if (not shapes.exists(itp_type, ghost_type)) {
auto size_of_shapes = this->getShapeSize(type);
this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
}
auto & shapes_ = this->shapes(itp_type, ghost_type);
shapes_.resize(nb_element * nb_points);
auto nodes_per_element = getNodesPerElement<type>(mesh, nodes, ghost_type);
for (auto && tuple :
- zip(make_view(shapes_, nb_dof, nb_dof * nb_nodes_per_element, nb_points),
- make_view(*nodes_per_element, dim, nb_nodes_per_element))) {
+ zip(make_view(shapes_, nb_dof, nb_dof * nb_nodes_per_element, nb_points),
+ make_view(*nodes_per_element, dim, nb_nodes_per_element))) {
auto & N = std::get<0>(tuple);
auto & real_coord = std::get<1>(tuple);
ElementClass<type>::computeShapes(natural_coords, real_coord, N);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeStructural<kind>::precomputeShapeDerivativesOnIntegrationPoints(
const Array<Real> & nodes, const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
const auto & natural_coords = integration_points(type, ghost_type);
const auto spatial_dimension = mesh.getSpatialDimension();
const auto natural_spatial_dimension =
ElementClass<type>::getNaturalSpaceDimension();
const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const auto nb_points = natural_coords.cols();
const auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
const auto nb_element = mesh.getNbElement(type, ghost_type);
const auto nb_stress_components = ElementClass<type>::getNbStressComponents();
auto itp_type = FEEngine::getInterpolationType(type);
if (not this->shapes_derivatives.exists(itp_type, ghost_type)) {
auto size_of_shapesd = this->getShapeDerivativesSize(type);
this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
}
auto & rot_matrices = this->rotation_matrices(type, ghost_type);
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
auto & shapesd = this->shapes_derivatives(itp_type, ghost_type);
shapesd.resize(nb_element * nb_points);
-
for (auto && tuple :
zip(make_view(x_el, spatial_dimension, nb_nodes_per_element),
make_view(shapesd, nb_stress_components,
nb_nodes_per_element * nb_dof, nb_points),
make_view(rot_matrices, nb_dof, nb_dof))) {
// compute shape derivatives
auto & X = std::get<0>(tuple);
auto & B = std::get<1>(tuple);
auto & RDOFs = std::get<2>(tuple);
-
Tensor3<Real> dnds(natural_spatial_dimension,
ElementClass<type>::interpolation_property::dnds_columns,
B.size(2));
ElementClass<type>::computeDNDS(natural_coords, X, dnds);
Tensor3<Real> J(natural_spatial_dimension, natural_spatial_dimension,
natural_coords.cols());
// Computing the coordinates of the element in the natural space
auto R = RDOFs.block(0, 0, spatial_dimension, spatial_dimension);
Matrix<Real> T(B.size(1), B.size(1), 0);
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
T.block(RDOFs, i * RDOFs.rows(), i * RDOFs.rows());
}
// Rotate to local basis
auto x =
(R * X).block(0, 0, natural_spatial_dimension, nb_nodes_per_element);
ElementClass<type>::computeJMat(natural_coords, x, J);
ElementClass<type>::computeShapeDerivatives(J, dnds, T, B);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeStructural<kind>::interpolateOnIntegrationPoints(
const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_dof,
const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(out_uq.getNbComponent() == nb_dof,
"The output array shape is not correct");
auto itp_type = FEEngine::getInterpolationType(type);
const auto & shapes_ = shapes(itp_type, ghost_type);
auto nb_element = mesh.getNbElement(type, ghost_type);
auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
auto nb_quad_points_per_element = integration_points(type, ghost_type).cols();
Array<Real> u_el(0, nb_nodes_per_element * nb_dof);
FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
filter_elements);
auto nb_quad_points = nb_quad_points_per_element * u_el.size();
out_uq.resize(nb_quad_points);
auto out_it = out_uq.begin_reinterpret(nb_dof, 1, nb_quad_points_per_element,
u_el.size());
auto shapes_it =
shapes_.begin_reinterpret(nb_dof, nb_dof * nb_nodes_per_element,
nb_quad_points_per_element, nb_element);
auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1,
nb_quad_points_per_element, u_el.size());
for_each_element(nb_element, filter_elements, [&](auto && el) {
auto & uq = *out_it;
const auto & u = *u_it;
auto N = Tensor3<Real>(shapes_it[el]);
for (auto && q : arange(uq.size(2))) {
auto uq_q = Matrix<Real>(uq(q));
auto u_q = Matrix<Real>(u(q));
auto N_q = Matrix<Real>(N(q));
uq_q.mul<false, false>(N_q, u_q);
}
++out_it;
++u_it;
});
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeStructural<kind>::gradientOnIntegrationPoints(
const Array<Real> & in_u, Array<Real> & out_nablauq, UInt nb_dof,
const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
auto itp_type = FEEngine::getInterpolationType(type);
const auto & shapesd = shapes_derivatives(itp_type, ghost_type);
auto nb_element = mesh.getNbElement(type, ghost_type);
auto element_dimension = ElementClass<type>::getSpatialDimension();
auto nb_quad_points_per_element = integration_points(type, ghost_type).cols();
auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
Array<Real> u_el(0, nb_nodes_per_element * nb_dof);
FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
filter_elements);
auto nb_quad_points = nb_quad_points_per_element * u_el.size();
out_nablauq.resize(nb_quad_points);
auto out_it = out_nablauq.begin_reinterpret(
element_dimension, 1, nb_quad_points_per_element, u_el.size());
auto shapesd_it = shapesd.begin_reinterpret(
element_dimension, nb_dof * nb_nodes_per_element,
nb_quad_points_per_element, nb_element);
auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1,
nb_quad_points_per_element, u_el.size());
for_each_element(nb_element, filter_elements, [&](auto && el) {
auto & nablau = *out_it;
const auto & u = *u_it;
auto B = Tensor3<Real>(shapesd_it[el]);
for (auto && q : arange(nablau.size(2))) {
auto nablau_q = Matrix<Real>(nablau(q));
auto u_q = Matrix<Real>(u(q));
auto B_q = Matrix<Real>(B(q));
nablau_q.mul<false, false>(B_q, u_q);
}
++out_it;
++u_it;
});
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <>
template <ElementType type>
void ShapeStructural<_ek_structural>::computeBtD(
- const Array<Real> & Ds, Array<Real> & BtDs,
- GhostType ghost_type, const Array<UInt> & filter_elements) const {
+ const Array<Real> & Ds, Array<Real> & BtDs, GhostType ghost_type,
+ const Array<UInt> & filter_elements) const {
auto itp_type = ElementClassProperty<type>::interpolation_type;
auto nb_stress = ElementClass<type>::getNbStressComponents();
auto nb_dof_per_element = ElementClass<type>::getNbDegreeOfFreedom() *
mesh.getNbNodesPerElement(type);
const auto & shapes_derivatives =
this->shapes_derivatives(itp_type, ghost_type);
Array<Real> shapes_derivatives_filtered(0,
shapes_derivatives.getNbComponent());
auto && view = make_view(shapes_derivatives, nb_stress, nb_dof_per_element);
auto B_it = view.begin();
auto B_end = view.end();
if (filter_elements != empty_filter) {
FEEngine::filterElementalData(this->mesh, shapes_derivatives,
shapes_derivatives_filtered, type, ghost_type,
filter_elements);
auto && view =
make_view(shapes_derivatives_filtered, nb_stress, nb_dof_per_element);
B_it = view.begin();
B_end = view.end();
}
- for (auto && values :
- zip(range(B_it, B_end),
- make_view(Ds, nb_stress),
- make_view(BtDs, BtDs.getNbComponent()))) {
+ for (auto && values : zip(range(B_it, B_end), make_view(Ds, nb_stress),
+ make_view(BtDs, BtDs.getNbComponent()))) {
const auto & B = std::get<0>(values);
const auto & D = std::get<1>(values);
auto & Bt_D = std::get<2>(values);
Bt_D.template mul<true>(B, D);
}
}
} // namespace akantu
#endif /* __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__ */
diff --git a/src/geometry/aabb_primitives/aabb_primitive.hh b/src/geometry/aabb_primitives/aabb_primitive.hh
index 2fea28c96..af9ac05f4 100644
--- a/src/geometry/aabb_primitives/aabb_primitive.hh
+++ b/src/geometry/aabb_primitives/aabb_primitive.hh
@@ -1,90 +1,89 @@
/**
* @file aabb_primitive.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Fri Mar 13 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Macro classe (primitive) for AABB CGAL algos
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AABB_PRIMITIVE_HH__
#define __AKANTU_AABB_PRIMITIVE_HH__
#include "aka_common.hh"
#include "line_arc.hh"
-#include "triangle.hh"
#include "tetrahedron.hh"
+#include "triangle.hh"
#include "mesh_geom_common.hh"
namespace akantu {
/**
* This macro defines a class that is used in the CGAL AABB tree algorithm.
* All the `typedef`s and methods are required by the AABB module.
*
* The member variables are
* - the id of the element associated to the primitive
* - the geometric primitive of the element
*
* @param name the name of the primitive type
* @param kernel the name of the kernel used
*/
-#define AKANTU_AABB_CLASS(name, kernel) \
- class name##_primitive { \
- typedef std::list< name<kernel> >::iterator Iterator; \
- \
- public: \
- typedef UInt Id; \
- typedef kernel::Point_3 Point; \
- typedef kernel::name##_3 Datum; \
- \
- public: \
- name##_primitive() : meshId(0), primitive() {} \
- name##_primitive(Iterator it) : meshId(it->id()), primitive(*it) {} \
- \
- public: \
- const Datum & datum() const { return primitive; } \
- Point reference_point() const; \
- const Id & id() const { return meshId; } \
- \
- protected: \
- Id meshId; \
- name<kernel> primitive; \
- \
+#define AKANTU_AABB_CLASS(name, kernel) \
+ class name##_primitive { \
+ typedef std::list<name<kernel>>::iterator Iterator; \
+ \
+ public: \
+ typedef UInt Id; \
+ typedef kernel::Point_3 Point; \
+ typedef kernel::name##_3 Datum; \
+ \
+ public: \
+ name##_primitive() : meshId(0), primitive() {} \
+ name##_primitive(Iterator it) : meshId(it->id()), primitive(*it) {} \
+ \
+ public: \
+ const Datum & datum() const { return primitive; } \
+ Point reference_point() const; \
+ const Id & id() const { return meshId; } \
+ \
+ protected: \
+ Id meshId; \
+ name<kernel> primitive; \
}
-// If the primitive is supported by CGAL::intersection() then the
+// If the primitive is supported by CGAL::intersection() then the
// implementation process is really easy with this macro
AKANTU_AABB_CLASS(Triangle, cgal::Cartesian);
AKANTU_AABB_CLASS(Line_arc, cgal::Spherical);
#undef AKANTU_AABB_CLASS
} // akantu
#endif // __AKANTU_AABB_PRIMITIVE_HH__
diff --git a/src/geometry/aabb_primitives/line_arc.hh b/src/geometry/aabb_primitives/line_arc.hh
index 409cc91d8..603525067 100644
--- a/src/geometry/aabb_primitives/line_arc.hh
+++ b/src/geometry/aabb_primitives/line_arc.hh
@@ -1,78 +1,77 @@
/**
* @file line_arc.hh
*
* @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Thu Jan 14 2016
*
* @brief Segment classe (geometry) for AABB CGAL algos
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_LINE_ARC_HH__
#define __AKANTU_LINE_ARC_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
namespace akantu {
-
+
/* -------------------------------------------------------------------------- */
/// Class used for substitution of CGAL::Triangle_3 primitive
-template<typename K>
-class Line_arc : public CGAL::Line_arc_3<K> {
+template <typename K> class Line_arc : public CGAL::Line_arc_3<K> {
public:
/// Default constructor
- Line_arc() :
- CGAL::Line_arc_3<K>(), mesh_id(0), seg_id(0) {}
+ Line_arc() : CGAL::Line_arc_3<K>(), mesh_id(0), seg_id(0) {}
/// Copy constructor
- Line_arc(const Line_arc & other) :
- CGAL::Line_arc_3<K>(other), mesh_id(other.mesh_id), seg_id(other.seg_id) {}
+ Line_arc(const Line_arc & other)
+ : CGAL::Line_arc_3<K>(other), mesh_id(other.mesh_id),
+ seg_id(other.seg_id) {}
/// Construct from 3 points
// "CGAL-4.5/doc_html/Circular_kernel_3/classCGAL_1_1Line__arc__3.html"
Line_arc(const CGAL::Line_3<K> & l, const CGAL::Circular_arc_point_3<K> & a,
- const CGAL::Circular_arc_point_3<K> & b):
- CGAL::Line_arc_3<K>(l, a, b), mesh_id(0), seg_id(0) {}
+ const CGAL::Circular_arc_point_3<K> & b)
+ : CGAL::Line_arc_3<K>(l, a, b), mesh_id(0), seg_id(0) {}
public:
UInt id() const { return mesh_id; }
UInt segId() const { return seg_id; }
void setId(UInt newId) { mesh_id = newId; }
void setSegId(UInt newId) { seg_id = newId; }
protected:
/// Id of the element represented by the primitive
UInt mesh_id;
/// Id of the segment represented by the primitive
UInt seg_id;
};
} // akantu
#endif // __AKANTU_LINE_ARC_HH__
diff --git a/src/geometry/aabb_primitives/tetrahedron.hh b/src/geometry/aabb_primitives/tetrahedron.hh
index daf0d4145..c6d31b3de 100644
--- a/src/geometry/aabb_primitives/tetrahedron.hh
+++ b/src/geometry/aabb_primitives/tetrahedron.hh
@@ -1,74 +1,70 @@
/**
* @file tetrahedron.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Feb 27 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Tetrahedron classe (geometry) for AABB CGAL algos
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TETRAHEDRON_HH__
#define __AKANTU_TETRAHEDRON_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
namespace akantu {
-
+
/* -------------------------------------------------------------------------- */
/// Class used for substitution of CGAL::Tetrahedron_3 primitive
-template<typename K>
-class Tetrahedron : public CGAL::Tetrahedron_3<K> {
+template <typename K> class Tetrahedron : public CGAL::Tetrahedron_3<K> {
public:
/// Default constructor
- Tetrahedron() :
- CGAL::Tetrahedron_3<K>(), meshId(0) {}
+ Tetrahedron() : CGAL::Tetrahedron_3<K>(), meshId(0) {}
/// Copy constructor
- Tetrahedron(const Tetrahedron & other) :
- CGAL::Tetrahedron_3<K>(other), meshId(other.meshId) {}
+ Tetrahedron(const Tetrahedron & other)
+ : CGAL::Tetrahedron_3<K>(other), meshId(other.meshId) {}
/// Construct from 4 points
- Tetrahedron(const CGAL::Point_3<K> & a,
- const CGAL::Point_3<K> & b,
- const CGAL::Point_3<K> & c,
- const CGAL::Point_3<K> & d) :
- CGAL::Tetrahedron_3<K>(a, b, c, d), meshId(0) {}
+ Tetrahedron(const CGAL::Point_3<K> & a, const CGAL::Point_3<K> & b,
+ const CGAL::Point_3<K> & c, const CGAL::Point_3<K> & d)
+ : CGAL::Tetrahedron_3<K>(a, b, c, d), meshId(0) {}
public:
UInt id() const { return meshId; }
void setId(UInt newId) { meshId = newId; }
protected:
/// Id of the element represented by the primitive
UInt meshId;
};
} // akantu
#endif
diff --git a/src/geometry/aabb_primitives/triangle.hh b/src/geometry/aabb_primitives/triangle.hh
index d25912af9..90a36b4bd 100644
--- a/src/geometry/aabb_primitives/triangle.hh
+++ b/src/geometry/aabb_primitives/triangle.hh
@@ -1,71 +1,70 @@
/**
* @file triangle.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Thu Jan 14 2016
*
* @brief Triangle classe (geometry) for AABB CGAL algos
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TRIANGLE_HH__
#define __AKANTU_TRIANGLE_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
namespace akantu {
-
+
/* -------------------------------------------------------------------------- */
/// Class used for substitution of CGAL::Triangle_3 primitive
-template<typename K>
-class Triangle : public CGAL::Triangle_3<K> {
+template <typename K> class Triangle : public CGAL::Triangle_3<K> {
public:
/// Default constructor
- Triangle() :
- CGAL::Triangle_3<K>(), meshId(0) {}
+ Triangle() : CGAL::Triangle_3<K>(), meshId(0) {}
/// Copy constructor
- Triangle(const Triangle & other) :
- CGAL::Triangle_3<K>(other), meshId(other.meshId) {}
+ Triangle(const Triangle & other)
+ : CGAL::Triangle_3<K>(other), meshId(other.meshId) {}
/// Construct from 3 points
- Triangle(const CGAL::Point_3<K> & a, const CGAL::Point_3<K> & b, const CGAL::Point_3<K> & c):
- CGAL::Triangle_3<K>(a, b, c), meshId(0) {}
+ Triangle(const CGAL::Point_3<K> & a, const CGAL::Point_3<K> & b,
+ const CGAL::Point_3<K> & c)
+ : CGAL::Triangle_3<K>(a, b, c), meshId(0) {}
public:
UInt id() const { return meshId; }
void setId(UInt newId) { meshId = newId; }
protected:
/// Id of the element represented by the primitive
UInt meshId;
};
} // akantu
#endif // __AKANTU_TRIANGLE_HH__
diff --git a/src/geometry/mesh_abstract_intersector.hh b/src/geometry/mesh_abstract_intersector.hh
index 6c1222924..5467a673b 100644
--- a/src/geometry/mesh_abstract_intersector.hh
+++ b/src/geometry/mesh_abstract_intersector.hh
@@ -1,108 +1,121 @@
/**
* @file mesh_abstract_intersector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Abstract class for intersection computations
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
#define __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_geom_abstract.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
- * @brief Class used to perform intersections on a mesh and construct output data
+ * @brief Class used to perform intersections on a mesh and construct output
+ * data
*/
-template<class Query>
-class MeshAbstractIntersector : public MeshGeomAbstract {
+template <class Query> class MeshAbstractIntersector : public MeshGeomAbstract {
public:
/// Construct from mesh
explicit MeshAbstractIntersector(Mesh & mesh);
/// Destructor
virtual ~MeshAbstractIntersector();
public:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the new_node_per_elem array
AKANTU_GET_MACRO(NewNodePerElem, *new_node_per_elem, const Array<UInt> &);
/// get the intersection_points array
- AKANTU_GET_MACRO(IntersectionPoints, intersection_points, const Array<Real> *);
+ AKANTU_GET_MACRO(IntersectionPoints, intersection_points,
+ const Array<Real> *);
/// get the nb_seg_by_el UInt
AKANTU_GET_MACRO(NbSegByEl, nb_seg_by_el, UInt);
/**
* @brief Compute the intersection with a query object
*
- * This function needs to be implemented for every subclass. It computes the intersections
+ * This function needs to be implemented for every subclass. It computes the
+ * intersections
* with the tree of primitives and creates the data for the user.
- *
+ *
* @param query the CGAL primitive of the query object
*/
virtual void computeIntersectionQuery(const Query & query) = 0;
- /// Compute intersection points between the mesh primitives (segments) and a query (surface in 3D or a curve in 2D), double intersection points for the same primitives are not considered. A maximum intersection node per element is set : 2 in 2D and 4 in 3D
- virtual void computeMeshQueryIntersectionPoint(const Query & query, UInt nb_old_nodes) = 0;
+ /// Compute intersection points between the mesh primitives (segments) and a
+ /// query (surface in 3D or a curve in 2D), double intersection points for the
+ /// same primitives are not considered. A maximum intersection node per
+ /// element is set : 2 in 2D and 4 in 3D
+ virtual void computeMeshQueryIntersectionPoint(const Query & query,
+ UInt nb_old_nodes) = 0;
/// Compute intersection between the mesh and a list of queries
- virtual void computeIntersectionQueryList(const std::list<Query> & query_list);
+ virtual void
+ computeIntersectionQueryList(const std::list<Query> & query_list);
/// Compute intersection points between the mesh and a list of queries
- virtual void computeMeshQueryListIntersectionPoint(const std::list<Query> & query_list,
- UInt nb_old_nodes);
+ virtual void
+ computeMeshQueryListIntersectionPoint(const std::list<Query> & query_list,
+ UInt nb_old_nodes);
- /// Compute whatever result is needed from the user (should be move to the appropriate specific classe for genericity)
- virtual void buildResultFromQueryList(const std::list<Query> & query_list) = 0;
+ /// Compute whatever result is needed from the user (should be move to the
+ /// appropriate specific classe for genericity)
+ virtual void
+ buildResultFromQueryList(const std::list<Query> & query_list) = 0;
protected:
- /// new node per element (column 0: number of new nodes, then odd is the intersection node number and even the ID of the intersected segment)
+ /// new node per element (column 0: number of new nodes, then odd is the
+ /// intersection node number and even the ID of the intersected segment)
Array<UInt> * new_node_per_elem;
- /// intersection output: new intersection points (computeMeshQueryListIntersectionPoint)
+ /// intersection output: new intersection points
+ /// (computeMeshQueryListIntersectionPoint)
Array<Real> * intersection_points;
- /// number of segment in a considered element of the templated type of element specialized intersector
+ /// number of segment in a considered element of the templated type of element
+ /// specialized intersector
const UInt nb_seg_by_el;
};
} // akantu
#include "mesh_abstract_intersector_tmpl.hh"
#endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_abstract_intersector_tmpl.hh b/src/geometry/mesh_abstract_intersector_tmpl.hh
index 6d4b4d75f..8ed2a1da4 100644
--- a/src/geometry/mesh_abstract_intersector_tmpl.hh
+++ b/src/geometry/mesh_abstract_intersector_tmpl.hh
@@ -1,89 +1,83 @@
/**
* @file mesh_abstract_intersector_tmpl.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
* @date last modification: Thu Jan 14 2016
*
* @brief General class for intersection computations
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_abstract_intersector.hh"
namespace akantu {
-template<class Query>
-MeshAbstractIntersector<Query>::MeshAbstractIntersector(Mesh & mesh):
- MeshGeomAbstract(mesh),
- new_node_per_elem(NULL),
- intersection_points(NULL),
- nb_seg_by_el(0)
-{}
-
-template<class Query>
-MeshAbstractIntersector<Query>::~MeshAbstractIntersector()
-{}
-
-template<class Query>
+template <class Query>
+MeshAbstractIntersector<Query>::MeshAbstractIntersector(Mesh & mesh)
+ : MeshGeomAbstract(mesh), new_node_per_elem(NULL),
+ intersection_points(NULL), nb_seg_by_el(0) {}
+
+template <class Query>
+MeshAbstractIntersector<Query>::~MeshAbstractIntersector() {}
+
+template <class Query>
void MeshAbstractIntersector<Query>::computeIntersectionQueryList(
- const std::list<Query> & query_list) {
+ const std::list<Query> & query_list) {
AKANTU_DEBUG_IN();
-
- typename std::list<Query>::const_iterator
- query_it = query_list.begin(),
- query_end = query_list.end();
- for (; query_it != query_end ; ++query_it) {
+ typename std::list<Query>::const_iterator query_it = query_list.begin(),
+ query_end = query_list.end();
+
+ for (; query_it != query_end; ++query_it) {
computeIntersectionQuery(*query_it);
}
-
+
AKANTU_DEBUG_OUT();
}
-template<class Query>
+template <class Query>
void MeshAbstractIntersector<Query>::computeMeshQueryListIntersectionPoint(
- const std::list<Query> & query_list, UInt nb_old_nodes) {
+ const std::list<Query> & query_list, UInt nb_old_nodes) {
AKANTU_DEBUG_IN();
-
- typename std::list<Query>::const_iterator
- query_it = query_list.begin(),
- query_end = query_list.end();
- for (; query_it != query_end ; ++query_it) {
+ typename std::list<Query>::const_iterator query_it = query_list.begin(),
+ query_end = query_list.end();
+
+ for (; query_it != query_end; ++query_it) {
computeMeshQueryIntersectionPoint(*query_it, nb_old_nodes);
}
-
+
AKANTU_DEBUG_OUT();
}
} // akantu
#endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_geom_abstract.hh b/src/geometry/mesh_geom_abstract.hh
index a3b2f39b0..8805f7050 100644
--- a/src/geometry/mesh_geom_abstract.hh
+++ b/src/geometry/mesh_geom_abstract.hh
@@ -1,65 +1,65 @@
/**
* @file mesh_geom_abstract.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Thu Jan 14 2016
*
* @brief Class for constructing the CGAL primitives of a mesh
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_ABSTRACT_HH__
#define __AKANTU_MESH_GEOM_ABSTRACT_HH__
#include "aka_common.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/// Abstract class for mesh geometry operations
class MeshGeomAbstract {
public:
/// Construct from mesh
- explicit MeshGeomAbstract(Mesh & mesh) : mesh(mesh) {};
+ explicit MeshGeomAbstract(Mesh & mesh) : mesh(mesh){};
/// Destructor
- virtual ~MeshGeomAbstract() {};
+ virtual ~MeshGeomAbstract(){};
public:
/// Construct geometric data for computational geometry algorithms
virtual void constructData(GhostType ghost_type = _not_ghost) = 0;
protected:
/// Mesh used to construct the primitives
Mesh & mesh;
};
} // akantu
#endif // __AKANTU_MESH_GEOM_ABSTRACT_HH__
diff --git a/src/geometry/mesh_geom_common.hh b/src/geometry/mesh_geom_common.hh
index c514a67e4..ccc6f8d8b 100644
--- a/src/geometry/mesh_geom_common.hh
+++ b/src/geometry/mesh_geom_common.hh
@@ -1,57 +1,57 @@
/**
* @file mesh_geom_common.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Thu Jan 14 2016
*
* @brief Common file for MeshGeom module
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_MESH_GEOM_COMMON_HH__
#define __AKANTU_MESH_GEOM_COMMON_HH__
#include "aka_common.hh"
-#include <CGAL/MP_Float.h>
-#include <CGAL/Quotient.h>
-
+#include <CGAL/MP_Float.h>
+#include <CGAL/Quotient.h>
+
+#include <CGAL/Algebraic_kernel_for_spheres_2_3.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Spherical_kernel_3.h>
-#include <CGAL/Algebraic_kernel_for_spheres_2_3.h>
namespace akantu {
namespace cgal {
using Cartesian = CGAL::Simple_cartesian<Real>;
using Spherical = CGAL::Spherical_kernel_3<
CGAL::Simple_cartesian<CGAL::Quotient<CGAL::MP_Float>>,
CGAL::Algebraic_kernel_for_spheres_2_3<CGAL::Quotient<CGAL::MP_Float>>>;
} // cgal
} // akantu
#endif // __AKANTU_MESH_GEOM_COMMON_HH__
diff --git a/src/geometry/mesh_geom_factory.hh b/src/geometry/mesh_geom_factory.hh
index 651e447f0..68f1b927b 100644
--- a/src/geometry/mesh_geom_factory.hh
+++ b/src/geometry/mesh_geom_factory.hh
@@ -1,108 +1,107 @@
/**
* @file mesh_geom_factory.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Feb 27 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Class for constructing the CGAL primitives of a mesh
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_FACTORY_HH__
#define __AKANTU_MESH_GEOM_FACTORY_HH__
#include "aka_common.hh"
+#include "geom_helper_functions.hh"
#include "mesh.hh"
#include "mesh_geom_abstract.hh"
#include "tree_type_helper.hh"
-#include "geom_helper_functions.hh"
#include <algorithm>
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
* @brief Class used to construct AABB tree for intersection computations
*
* This class constructs a CGAL AABB tree of one type of element in a mesh
* for fast intersection computations.
*/
-template<UInt dim, ElementType el_type, class Primitive, class Kernel>
+template <UInt dim, ElementType el_type, class Primitive, class Kernel>
class MeshGeomFactory : public MeshGeomAbstract {
public:
/// Construct from mesh
explicit MeshGeomFactory(Mesh & mesh);
/// Desctructor
virtual ~MeshGeomFactory();
public:
/// Construct AABB tree for fast intersection computing
virtual void constructData(GhostType ghost_type = _not_ghost);
/**
* @brief Construct a primitive and add it to a list of primitives
*
- * This function needs to be specialized for every type that is wished to be supported.
+ * This function needs to be specialized for every type that is wished to be
+ * supported.
* @param node_coordinates coordinates of the nodes making up the element
* @param id element number
* @param list the primitive list (not used inside MeshGeomFactory)
*/
inline void addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id,
- typename TreeTypeHelper<Primitive, Kernel>::container_type & list
- );
+ const Matrix<Real> & node_coordinates, UInt id,
+ typename TreeTypeHelper<Primitive, Kernel>::container_type & list);
- inline void addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id
- );
+ inline void addPrimitive(const Matrix<Real> & node_coordinates, UInt id);
/// Getter for the AABB tree
- const typename TreeTypeHelper<Primitive, Kernel>::tree & getTree() const { return *data_tree; }
+ const typename TreeTypeHelper<Primitive, Kernel>::tree & getTree() const {
+ return *data_tree;
+ }
/// Getter for primitive list
- const typename TreeTypeHelper<Primitive, Kernel>::container_type & getPrimitiveList() const
- { return primitive_list; }
+ const typename TreeTypeHelper<Primitive, Kernel>::container_type &
+ getPrimitiveList() const {
+ return primitive_list;
+ }
protected:
/// AABB data tree
typename TreeTypeHelper<Primitive, Kernel>::tree * data_tree;
/// Primitive list
typename TreeTypeHelper<Primitive, Kernel>::container_type primitive_list;
};
} // akantu
#include "mesh_geom_factory_tmpl.hh"
-
#endif // __AKANTU_MESH_GEOM_FACTORY_HH__
diff --git a/src/geometry/mesh_geom_factory_tmpl.hh b/src/geometry/mesh_geom_factory_tmpl.hh
index f7ece3cfa..5caf3048b 100644
--- a/src/geometry/mesh_geom_factory_tmpl.hh
+++ b/src/geometry/mesh_geom_factory_tmpl.hh
@@ -1,259 +1,271 @@
/**
* @file mesh_geom_factory_tmpl.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Feb 27 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Class for constructing the CGAL primitives of a mesh
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
#define __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_geom_common.hh"
#include "mesh_geom_factory.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
-template<UInt dim, ElementType type, class Primitive, class Kernel>
-MeshGeomFactory<dim, type, Primitive, Kernel>::MeshGeomFactory(Mesh & mesh) :
- MeshGeomAbstract(mesh),
- data_tree(NULL),
- primitive_list()
-{}
-
-template<UInt dim, ElementType type, class Primitive, class Kernel>
+template <UInt dim, ElementType type, class Primitive, class Kernel>
+MeshGeomFactory<dim, type, Primitive, Kernel>::MeshGeomFactory(Mesh & mesh)
+ : MeshGeomAbstract(mesh), data_tree(NULL), primitive_list() {}
+
+template <UInt dim, ElementType type, class Primitive, class Kernel>
MeshGeomFactory<dim, type, Primitive, Kernel>::~MeshGeomFactory() {
delete data_tree;
}
/**
* This function loops over the elements of `type` in the mesh and creates the
* AABB tree of geometrical primitves (`data_tree`).
*/
-template<UInt dim, ElementType type, class Primitive, class Kernel>
-void MeshGeomFactory<dim, type, Primitive, Kernel>::constructData(GhostType ghost_type) {
+template <UInt dim, ElementType type, class Primitive, class Kernel>
+void MeshGeomFactory<dim, type, Primitive, Kernel>::constructData(
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
primitive_list.clear();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
const Array<Real> & nodes = mesh.getNodes();
UInt el_index = 0;
- Array<UInt>::const_vector_iterator it = connectivity.begin(nb_nodes_per_element);
- Array<UInt>::const_vector_iterator end = connectivity.end(nb_nodes_per_element);
+ Array<UInt>::const_vector_iterator it =
+ connectivity.begin(nb_nodes_per_element);
+ Array<UInt>::const_vector_iterator end =
+ connectivity.end(nb_nodes_per_element);
Matrix<Real> node_coordinates(dim, nb_nodes_per_element);
// This loop builds the list of primitives
- for (; it != end ; ++it, ++el_index) {
+ for (; it != end; ++it, ++el_index) {
const Vector<UInt> & el_connectivity = *it;
- for (UInt i = 0 ; i < nb_nodes_per_element ; i++)
- for (UInt j = 0 ; j < dim ; j++)
- node_coordinates(j, i) = nodes(el_connectivity(i), j);
+ for (UInt i = 0; i < nb_nodes_per_element; i++)
+ for (UInt j = 0; j < dim; j++)
+ node_coordinates(j, i) = nodes(el_connectivity(i), j);
// the unique elemental id assigned to the primitive is the
// linearized element index over ghost type
addPrimitive(node_coordinates, el_index);
}
delete data_tree;
// This condition allows the use of the mesh geom module
// even if types are not compatible with AABB tree algorithm
if (TreeTypeHelper<Primitive, Kernel>::is_valid)
- data_tree = new typename TreeTypeHelper<Primitive, Kernel>::tree(primitive_list.begin(), primitive_list.end());
+ data_tree = new typename TreeTypeHelper<Primitive, Kernel>::tree(
+ primitive_list.begin(), primitive_list.end());
AKANTU_DEBUG_OUT();
}
-template<UInt dim, ElementType type, class Primitive, class Kernel>
-void MeshGeomFactory<dim, type, Primitive, Kernel>::addPrimitive(const Matrix<Real> & node_coordinates,
- UInt id) {
+template <UInt dim, ElementType type, class Primitive, class Kernel>
+void MeshGeomFactory<dim, type, Primitive, Kernel>::addPrimitive(
+ const Matrix<Real> & node_coordinates, UInt id) {
this->addPrimitive(node_coordinates, id, this->primitive_list);
}
// (2D, _triangle_3) decomposed into Triangle<cgal::Cartesian>
-template<>
-inline void MeshGeomFactory<2, _triangle_3, Triangle<cgal::Cartesian>, cgal::Cartesian>::addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id,
- TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::container_type & list) {
-
- TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type
- a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
- b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
- c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+template <>
+inline void
+MeshGeomFactory<2, _triangle_3, Triangle<cgal::Cartesian>, cgal::Cartesian>::
+ addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
+ TreeTypeHelper<Triangle<cgal::Cartesian>,
+ cgal::Cartesian>::container_type & list) {
+
+ TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type a(
+ node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
Triangle<cgal::Cartesian> t(a, b, c);
t.setId(id);
list.push_back(t);
}
// (2D, _triangle_6) decomposed into Triangle<cgal::Cartesian>
-template<>
-inline void MeshGeomFactory<2, _triangle_6, Triangle<cgal::Cartesian>, cgal::Cartesian>::addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id,
- TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::container_type & list) {
-
- TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type
- a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
- b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
- c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+template <>
+inline void
+MeshGeomFactory<2, _triangle_6, Triangle<cgal::Cartesian>, cgal::Cartesian>::
+ addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
+ TreeTypeHelper<Triangle<cgal::Cartesian>,
+ cgal::Cartesian>::container_type & list) {
+
+ TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type a(
+ node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
Triangle<cgal::Cartesian> t(a, b, c);
t.setId(id);
list.push_back(t);
}
// (2D, _triangle_3) decomposed into Line_arc<cgal::Spherical>
-template<>
-inline void MeshGeomFactory<2, _triangle_3, Line_arc<cgal::Spherical>, cgal::Spherical>::addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id,
- TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::container_type & list) {
-
- TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type
- a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
- b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
- c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
-
+template <>
+inline void
+MeshGeomFactory<2, _triangle_3, Line_arc<cgal::Spherical>, cgal::Spherical>::
+ addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
+ TreeTypeHelper<Line_arc<cgal::Spherical>,
+ cgal::Spherical>::container_type & list) {
+
+ TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type a(
+ node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+
/*std::cout << "elem " << id << " node 1 : x_node=" << node_coordinates(0, 0)
- << ", x_arc_node=" << a.x() << ", y_node=" << node_coordinates(1, 0)
- << ", y_arc_node=" << a.y() << std::endl ;
+ << ", x_arc_node=" << a.x() << ", y_node=" << node_coordinates(1, 0)
+ << ", y_arc_node=" << a.y() << std::endl ;
std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 1)
- << ", x_arc_node=" << b.x() << ", y_node=" << node_coordinates(1, 1)
- << ", y_arc_node=" << b.y() << std::endl ;
+ << ", x_arc_node=" << b.x() << ", y_node=" << node_coordinates(1, 1)
+ << ", y_arc_node=" << b.y() << std::endl ;
std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 2)
- << ", x_arc_node=" << c.x() << ", y_node=" << node_coordinates(1, 2)
- << ", y_arc_node=" << c.y() << std::endl ;*/
+ << ", x_arc_node=" << c.x() << ", y_node=" << node_coordinates(1, 2)
+ << ", y_arc_node=" << c.y() << std::endl ;*/
CGAL::Line_3<cgal::Spherical> l1(a, b), l2(b, c), l3(c, a);
- Line_arc<cgal::Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
+ Line_arc<cgal::Spherical> s1(l1, a, b), s2(l2, b, c), s3(l3, c, a);
- s1.setId(id); s1.setSegId(0);
- s2.setId(id); s2.setSegId(1);
- s3.setId(id); s3.setSegId(2);
+ s1.setId(id);
+ s1.setSegId(0);
+ s2.setId(id);
+ s2.setSegId(1);
+ s3.setId(id);
+ s3.setSegId(2);
list.push_back(s1);
list.push_back(s2);
list.push_back(s3);
}
#if defined(AKANTU_IGFEM)
// (2D, _igfem_triangle_4) decomposed into Line_arc<cgal::Spherical>
-template<>
-inline void MeshGeomFactory<2, _igfem_triangle_4, Line_arc<cgal::Spherical>, cgal::Spherical>::addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id,
- TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::container_type & list) {
-
- TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type
- a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
- b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
- c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+template <>
+inline void MeshGeomFactory<2, _igfem_triangle_4, Line_arc<cgal::Spherical>,
+ cgal::Spherical>::
+ addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
+ TreeTypeHelper<Line_arc<cgal::Spherical>,
+ cgal::Spherical>::container_type & list) {
+
+ TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type a(
+ node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
CGAL::Line_3<cgal::Spherical> l1(a, b), l2(b, c), l3(c, a);
- Line_arc<cgal::Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
+ Line_arc<cgal::Spherical> s1(l1, a, b), s2(l2, b, c), s3(l3, c, a);
- s1.setId(id); s1.setSegId(0);
- s2.setId(id); s2.setSegId(1);
- s3.setId(id); s3.setSegId(2);
+ s1.setId(id);
+ s1.setSegId(0);
+ s2.setId(id);
+ s2.setSegId(1);
+ s3.setId(id);
+ s3.setSegId(2);
list.push_back(s1);
list.push_back(s2);
list.push_back(s3);
}
// (2D, _igfem_triangle_4) decomposed into Line_arc<cgal::Spherical>
-template<>
-inline void MeshGeomFactory<2, _igfem_triangle_5, Line_arc<cgal::Spherical>, cgal::Spherical>::addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id,
- TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::container_type & list) {
-
- TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type
- a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
- b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
- c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+template <>
+inline void MeshGeomFactory<2, _igfem_triangle_5, Line_arc<cgal::Spherical>,
+ cgal::Spherical>::
+ addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
+ TreeTypeHelper<Line_arc<cgal::Spherical>,
+ cgal::Spherical>::container_type & list) {
+
+ TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type a(
+ node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
CGAL::Line_3<cgal::Spherical> l1(a, b), l2(b, c), l3(c, a);
- Line_arc<cgal::Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
+ Line_arc<cgal::Spherical> s1(l1, a, b), s2(l2, b, c), s3(l3, c, a);
- s1.setId(id); s1.setSegId(0);
- s2.setId(id); s2.setSegId(1);
- s3.setId(id); s3.setSegId(2);
+ s1.setId(id);
+ s1.setSegId(0);
+ s2.setId(id);
+ s2.setSegId(1);
+ s3.setId(id);
+ s3.setSegId(2);
list.push_back(s1);
list.push_back(s2);
list.push_back(s3);
}
#endif
// (3D, _tetrahedron_4) decomposed into Triangle<cgal::Cartesian>
-template<>
-inline void MeshGeomFactory<3, _tetrahedron_4, Triangle<cgal::Cartesian>, cgal::Cartesian>::addPrimitive(
- const Matrix<Real> & node_coordinates,
- UInt id,
- TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::container_type & list) {
-
- TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type
- a(node_coordinates(0, 0), node_coordinates(1, 0), node_coordinates(2, 0)),
- b(node_coordinates(0, 1), node_coordinates(1, 1), node_coordinates(2, 1)),
- c(node_coordinates(0, 2), node_coordinates(1, 2), node_coordinates(2, 2)),
- d(node_coordinates(0, 3), node_coordinates(1, 3), node_coordinates(2, 3));
-
- Triangle<cgal::Cartesian>
- t1(a, b, c),
- t2(b, c, d),
- t3(c, d, a),
- t4(d, a, b);
+template <>
+inline void
+MeshGeomFactory<3, _tetrahedron_4, Triangle<cgal::Cartesian>, cgal::Cartesian>::
+ addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
+ TreeTypeHelper<Triangle<cgal::Cartesian>,
+ cgal::Cartesian>::container_type & list) {
+
+ TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type a(
+ node_coordinates(0, 0), node_coordinates(1, 0), node_coordinates(2, 0)),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), node_coordinates(2, 1)),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), node_coordinates(2, 2)),
+ d(node_coordinates(0, 3), node_coordinates(1, 3), node_coordinates(2, 3));
+
+ Triangle<cgal::Cartesian> t1(a, b, c), t2(b, c, d), t3(c, d, a), t4(d, a, b);
t1.setId(id);
t2.setId(id);
t3.setId(id);
t4.setId(id);
list.push_back(t1);
list.push_back(t2);
list.push_back(t3);
list.push_back(t4);
}
} // akantu
#endif // __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
diff --git a/src/geometry/mesh_geom_intersector.hh b/src/geometry/mesh_geom_intersector.hh
index ae1d3a633..d8552c6f3 100644
--- a/src/geometry/mesh_geom_intersector.hh
+++ b/src/geometry/mesh_geom_intersector.hh
@@ -1,72 +1,74 @@
/**
* @file mesh_geom_intersector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
* @date last modification: Thu Jan 14 2016
*
* @brief General class for intersection computations
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_INTERSECTOR_HH__
#define __AKANTU_MESH_GEOM_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_abstract_intersector.hh"
#include "mesh_geom_factory.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
- * @brief Class used to perform intersections on a mesh and construct output data
+ * @brief Class used to perform intersections on a mesh and construct output
+ * data
*/
-template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
+template <UInt dim, ElementType type, class Primitive, class Query,
+ class Kernel>
class MeshGeomIntersector : public MeshAbstractIntersector<Query> {
public:
/// Construct from mesh
explicit MeshGeomIntersector(Mesh & mesh);
/// Destructor
virtual ~MeshGeomIntersector();
public:
/// Construct the primitive tree object
virtual void constructData(GhostType ghost_type = _not_ghost);
protected:
/// Factory object containing the primitive tree
MeshGeomFactory<dim, type, Primitive, Kernel> factory;
};
} // akantu
#include "mesh_geom_intersector_tmpl.hh"
#endif // __AKANTU_MESH_GEOM_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_geom_intersector_tmpl.hh b/src/geometry/mesh_geom_intersector_tmpl.hh
index a1a5582b2..0e2ab5bb9 100644
--- a/src/geometry/mesh_geom_intersector_tmpl.hh
+++ b/src/geometry/mesh_geom_intersector_tmpl.hh
@@ -1,62 +1,64 @@
/**
* @file mesh_geom_intersector_tmpl.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Wed Apr 29 2015
* @date last modification: Thu Jan 14 2016
*
* @brief General class for intersection computations
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_geom_intersector.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
-template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
-MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::MeshGeomIntersector(Mesh & mesh) :
-MeshAbstractIntersector<Query>(mesh),
-factory(mesh)
-{}
-
-template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
-MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::~MeshGeomIntersector()
-{}
-
-template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
-void MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::constructData(GhostType ghost_type) {
+template <UInt dim, ElementType type, class Primitive, class Query,
+ class Kernel>
+MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::MeshGeomIntersector(
+ Mesh & mesh)
+ : MeshAbstractIntersector<Query>(mesh), factory(mesh) {}
+
+template <UInt dim, ElementType type, class Primitive, class Query,
+ class Kernel>
+MeshGeomIntersector<dim, type, Primitive, Query,
+ Kernel>::~MeshGeomIntersector() {}
+
+template <UInt dim, ElementType type, class Primitive, class Query,
+ class Kernel>
+void MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::constructData(
+ GhostType ghost_type) {
this->intersection_points->resize(0);
factory.constructData(ghost_type);
}
} // akantu
#endif // __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
-
diff --git a/src/geometry/mesh_segment_intersector.hh b/src/geometry/mesh_segment_intersector.hh
index 6d913f561..6e7c38e2d 100644
--- a/src/geometry/mesh_segment_intersector.hh
+++ b/src/geometry/mesh_segment_intersector.hh
@@ -1,103 +1,109 @@
/**
* @file mesh_segment_intersector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Computation of mesh intersection with segments
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
#define __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_geom_intersector.hh"
#include "mesh_geom_common.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
template <UInt dim, ElementType type>
class MeshSegmentIntersector
: public MeshGeomIntersector<dim, type, Triangle<cgal::Cartesian>,
cgal::Cartesian::Segment_3, cgal::Cartesian> {
using K = cgal::Cartesian;
/// Parent class type
- typedef MeshGeomIntersector<dim, type, Triangle<K>, K::Segment_3, K> parent_type;
+ typedef MeshGeomIntersector<dim, type, Triangle<K>, K::Segment_3, K>
+ parent_type;
/// Result of intersection function type
- typedef typename IntersectionTypeHelper<TreeTypeHelper< Triangle<K>, K>, K::Segment_3>::intersection_type result_type;
+ typedef typename IntersectionTypeHelper<TreeTypeHelper<Triangle<K>, K>,
+ K::Segment_3>::intersection_type
+ result_type;
/// Pair of segments and element id
typedef std::pair<K::Segment_3, UInt> pair_type;
public:
/// Construct from mesh
explicit MeshSegmentIntersector(Mesh & mesh, Mesh & result_mesh);
/// Destructor
virtual ~MeshSegmentIntersector();
public:
/**
* @brief Computes the intersection of the mesh with a segment
*
* @param query the segment to compute the intersections with the mesh
*/
virtual void computeIntersectionQuery(const K::Segment_3 & query);
/// Compute intersection points between the mesh and a query
- virtual void computeMeshQueryIntersectionPoint(const K::Segment_3 & query, UInt nb_old_nodes);
+ virtual void computeMeshQueryIntersectionPoint(const K::Segment_3 & query,
+ UInt nb_old_nodes);
/// Compute the embedded mesh
- virtual void buildResultFromQueryList(const std::list<K::Segment_3> & query_list);
+ virtual void
+ buildResultFromQueryList(const std::list<K::Segment_3> & query_list);
- void setPhysicalName(const std::string & other)
- { current_physical_name = other; }
+ void setPhysicalName(const std::string & other) {
+ current_physical_name = other;
+ }
protected:
/// Compute segments from intersection list
void computeSegments(const std::list<result_type> & intersections,
std::set<pair_type, segmentPairsLess> & segments,
const K::Segment_3 & query);
protected:
/// Result mesh
Mesh & result_mesh;
/// Physical name of the current batch of queries
std::string current_physical_name;
};
-
+
} // akantu
#include "mesh_segment_intersector_tmpl.hh"
#endif // __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_segment_intersector_tmpl.hh b/src/geometry/mesh_segment_intersector_tmpl.hh
index 73f27a071..92538a104 100644
--- a/src/geometry/mesh_segment_intersector_tmpl.hh
+++ b/src/geometry/mesh_segment_intersector_tmpl.hh
@@ -1,283 +1,283 @@
/**
* @file mesh_segment_intersector_tmpl.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 29 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Computation of mesh intersection with segments
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
#include "tree_type_helper.hh"
namespace akantu {
template <UInt dim, ElementType type>
MeshSegmentIntersector<dim, type>::MeshSegmentIntersector(Mesh & mesh,
Mesh & result_mesh)
: parent_type(mesh), result_mesh(result_mesh), current_physical_name() {
this->intersection_points = new Array<Real>(0, dim);
this->constructData();
}
template <UInt dim, ElementType type>
MeshSegmentIntersector<dim, type>::~MeshSegmentIntersector() {}
template <UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>::computeIntersectionQuery(
const K::Segment_3 & query) {
AKANTU_DEBUG_IN();
result_mesh.addConnectivityType(_segment_2, _not_ghost);
result_mesh.addConnectivityType(_segment_2, _ghost);
std::list<result_type> result_list;
std::set<std::pair<K::Segment_3, UInt>, segmentPairsLess> segment_set;
this->factory.getTree().all_intersections(query,
std::back_inserter(result_list));
this->computeSegments(result_list, segment_set, query);
// Arrays for storing nodes and connectivity
Array<Real> & nodes = result_mesh.getNodes();
Array<UInt> & connectivity = result_mesh.getConnectivity(_segment_2);
// Arrays for storing associated element and physical name
bool valid_elemental_data = true;
Array<Element> * associated_element = NULL;
Array<std::string> * associated_physical_name = NULL;
try {
associated_element =
&result_mesh.getData<Element>("associated_element", _segment_2);
associated_physical_name =
&result_mesh.getData<std::string>("physical_names", _segment_2);
} catch (debug::Exception & e) {
valid_elemental_data = false;
}
std::set<pair_type, segmentPairsLess>::iterator it = segment_set.begin(),
end = segment_set.end();
// Loop over the segment pairs
for (; it != end; ++it) {
if (!it->first.is_degenerate()) {
Vector<UInt> segment_connectivity(2);
segment_connectivity(0) = result_mesh.getNbNodes();
segment_connectivity(1) = result_mesh.getNbNodes() + 1;
connectivity.push_back(segment_connectivity);
// Copy nodes
Vector<Real> source(dim), target(dim);
for (UInt j = 0; j < dim; j++) {
source(j) = it->first.source()[j];
target(j) = it->first.target()[j];
}
nodes.push_back(source);
nodes.push_back(target);
// Copy associated element info
if (valid_elemental_data) {
associated_element->push_back(Element{type, it->second, _not_ghost});
associated_physical_name->push_back(current_physical_name);
}
}
}
AKANTU_DEBUG_OUT();
}
template <UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>::computeMeshQueryIntersectionPoint(
const K::Segment_3 & /*query*/, UInt /*nb_old_nodes*/) {
AKANTU_ERROR("The method: computeMeshQueryIntersectionPoint has not "
- "been implemented in class MeshSegmentIntersector!");
+ "been implemented in class MeshSegmentIntersector!");
}
template <UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>::buildResultFromQueryList(
const std::list<K::Segment_3> & query_list) {
AKANTU_DEBUG_IN();
this->computeIntersectionQueryList(query_list);
AKANTU_DEBUG_OUT();
}
template <UInt dim, ElementType type>
void MeshSegmentIntersector<dim, type>::computeSegments(
const std::list<result_type> & intersections,
std::set<pair_type, segmentPairsLess> & segments,
const K::Segment_3 & query) {
AKANTU_DEBUG_IN();
/*
* Number of intersections = 0 means
*
* - query is completely outside mesh
* - query is completely inside primitive
*
* We try to determine the case and still construct the segment list
*/
if (intersections.size() == 0) {
// We look at all the primitives intersected by two rays
// If there is one primitive in common, then query is inside
// that primitive
K::Ray_3 ray1(query.source(), query.target());
K::Ray_3 ray2(query.target(), query.source());
std::set<UInt> ray1_results, ray2_results;
this->factory.getTree().all_intersected_primitives(
ray1, std::inserter(ray1_results, ray1_results.begin()));
this->factory.getTree().all_intersected_primitives(
ray2, std::inserter(ray2_results, ray2_results.begin()));
bool inside_primitive = false;
UInt primitive_id = 0;
std::set<UInt>::iterator ray2_it = ray2_results.begin(),
ray2_end = ray2_results.end();
// Test if first list contains an element of second list
for (; ray2_it != ray2_end && !inside_primitive; ++ray2_it) {
if (ray1_results.find(*ray2_it) != ray1_results.end()) {
inside_primitive = true;
primitive_id = *ray2_it;
}
}
if (inside_primitive) {
segments.insert(std::make_pair(query, primitive_id));
}
}
else {
typename std::list<result_type>::const_iterator it = intersections.begin(),
end = intersections.end();
for (; it != end; ++it) {
UInt el = (*it)->second;
// Result of intersection is a segment
if (const K::Segment_3 * segment =
boost::get<K::Segment_3>(&((*it)->first))) {
// Check if the segment was alread created
segments.insert(std::make_pair(*segment, el));
}
// Result of intersection is a point
else if (const K::Point_3 * point =
boost::get<K::Point_3>(&((*it)->first))) {
// We only want to treat points differently if we're in 3D with Tetra4
// elements This should be optimized by compilator
if (dim == 3 && type == _tetrahedron_4) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
TreeTypeHelper<Triangle<K>, K>::container_type facets;
const Array<Real> & nodes = this->mesh.getNodes();
Array<UInt>::const_vector_iterator connectivity_vec =
this->mesh.getConnectivity(type).begin(nb_nodes_per_element);
const Vector<UInt> & el_connectivity = connectivity_vec[el];
Matrix<Real> node_coordinates(dim, nb_nodes_per_element);
for (UInt i = 0; i < nb_nodes_per_element; i++)
for (UInt j = 0; j < dim; j++)
node_coordinates(j, i) = nodes(el_connectivity(i), j);
this->factory.addPrimitive(node_coordinates, el, facets);
// Local tree
TreeTypeHelper<Triangle<K>, K>::tree * local_tree =
new TreeTypeHelper<Triangle<K>, K>::tree(facets.begin(),
facets.end());
// Compute local intersections (with current element)
std::list<result_type> local_intersections;
local_tree->all_intersections(
query, std::back_inserter(local_intersections));
bool out_point_found = false;
typename std::list<result_type>::const_iterator
local_it = local_intersections.begin(),
local_end = local_intersections.end();
for (; local_it != local_end; ++local_it) {
if (const K::Point_3 * local_point =
boost::get<K::Point_3>(&((*local_it)->first))) {
if (!comparePoints(*point, *local_point)) {
K::Segment_3 seg(*point, *local_point);
segments.insert(std::make_pair(seg, el));
out_point_found = true;
}
}
}
if (!out_point_found) {
TreeTypeHelper<Triangle<K>, K>::point_type a(
node_coordinates(0, 0), node_coordinates(1, 0),
node_coordinates(2, 0)),
b(node_coordinates(0, 1), node_coordinates(1, 1),
node_coordinates(2, 1)),
c(node_coordinates(0, 2), node_coordinates(1, 2),
node_coordinates(2, 2)),
d(node_coordinates(0, 3), node_coordinates(1, 3),
node_coordinates(2, 3));
K::Tetrahedron_3 tetra(a, b, c, d);
const K::Point_3 * inside_point = NULL;
if (tetra.has_on_bounded_side(query.source()) &&
!tetra.has_on_boundary(query.source()))
inside_point = &query.source();
else if (tetra.has_on_bounded_side(query.target()) &&
!tetra.has_on_boundary(query.target()))
inside_point = &query.target();
if (inside_point) {
K::Segment_3 seg(*inside_point, *point);
segments.insert(std::make_pair(seg, el));
}
}
delete local_tree;
}
}
}
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
#endif // __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_sphere_intersector.hh b/src/geometry/mesh_sphere_intersector.hh
index 7cac489cb..46c5e9f69 100644
--- a/src/geometry/mesh_sphere_intersector.hh
+++ b/src/geometry/mesh_sphere_intersector.hh
@@ -1,119 +1,119 @@
/**
* @file mesh_sphere_intersector.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jun 23 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Computation of mesh intersection with sphere(s)
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
#define __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
#include "aka_common.hh"
#include "mesh_geom_intersector.hh"
#include "mesh_geom_common.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
template <UInt dim, ElementType type>
class MeshSphereIntersector
: public MeshGeomIntersector<dim, type, Line_arc<cgal::Spherical>,
cgal::Spherical::Sphere_3, cgal::Spherical> {
using SK = cgal::Spherical;
using K = cgal::Cartesian;
/// Parent class type
typedef MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>
parent_type;
/// Result of intersection function type
typedef typename IntersectionTypeHelper<TreeTypeHelper<Triangle<K>, K>,
K::Segment_3>::intersection_type
result_type;
/// Pair of intersection points and element id
typedef std::pair<SK::Circular_arc_point_3, UInt> pair_type;
public:
/// Construct from mesh
explicit MeshSphereIntersector(Mesh & mesh);
/// Destructor
virtual ~MeshSphereIntersector();
public:
/// Construct the primitive tree object
virtual void constructData(GhostType ghost_type = _not_ghost);
/**
* @brief Computes the intersection of the mesh with a sphere
*
* @param query (sphere) to compute the intersections with the mesh
*/
virtual void computeIntersectionQuery(const SK::Sphere_3 & /*query*/) {
AKANTU_ERROR("This function is not implemented for spheres (It was "
- "to generic and has been replaced by "
- "computeMeshQueryIntersectionPoint");
+ "to generic and has been replaced by "
+ "computeMeshQueryIntersectionPoint");
}
/// Compute intersection points between the mesh primitives (segments) and a
/// query (surface in 3D or a curve in 2D), double intersection points for the
/// same primitives are not considered. A maximum is set to the number of
/// intersection nodes per element: 2 in 2D and 4 in 3D
virtual void computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query,
UInt nb_old_nodes);
/// Build the IGFEM mesh
virtual void
buildResultFromQueryList(const std::list<SK::Sphere_3> & /*query*/) {
AKANTU_ERROR("This function is no longer implemented to split "
- "geometrical operations and dedicated result "
- "construction");
+ "geometrical operations and dedicated result "
+ "construction");
}
/// Set the tolerance
void setToleranceIntersectionOnNode(UInt tol) {
this->tol_intersection_on_node = tol;
}
protected:
/// tolerance for which the intersection is considered on the mesh node
/// (relative to the segment lenght)
Real tol_intersection_on_node;
};
} // akantu
#include "mesh_sphere_intersector_tmpl.hh"
#endif // __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_sphere_intersector_tmpl.hh b/src/geometry/mesh_sphere_intersector_tmpl.hh
index f02b004c6..818132a63 100644
--- a/src/geometry/mesh_sphere_intersector_tmpl.hh
+++ b/src/geometry/mesh_sphere_intersector_tmpl.hh
@@ -1,195 +1,215 @@
/**
* @file mesh_sphere_intersector_tmpl.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jun 23 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Computation of mesh intersection with spheres
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
#define __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
#include "aka_common.hh"
#include "mesh_geom_common.hh"
-#include "tree_type_helper.hh"
#include "mesh_sphere_intersector.hh"
+#include "tree_type_helper.hh"
namespace akantu {
-template<UInt dim, ElementType type>
-MeshSphereIntersector<dim, type>::MeshSphereIntersector(Mesh & mesh):
- parent_type(mesh),
- tol_intersection_on_node(1e-10)
-{
+template <UInt dim, ElementType type>
+MeshSphereIntersector<dim, type>::MeshSphereIntersector(Mesh & mesh)
+ : parent_type(mesh), tol_intersection_on_node(1e-10) {
#if defined(AKANTU_IGFEM)
- if( (type == _triangle_3) || (type == _igfem_triangle_4) || (type == _igfem_triangle_5) ){
+ if ((type == _triangle_3) || (type == _igfem_triangle_4) ||
+ (type == _igfem_triangle_5)) {
const_cast<UInt &>(this->nb_seg_by_el) = 3;
} else {
AKANTU_ERROR("Not ready for mesh type " << type);
}
#else
- if( (type != _triangle_3) )
+ if ((type != _triangle_3))
AKANTU_ERROR("Not ready for mesh type " << type);
#endif
// initialize the intersection pointsss array with the spatial dimension
- this->intersection_points = new Array<Real>(0,dim);
- // A maximum is set to the number of intersection nodes per element to limit the size of new_node_per_elem: 2 in 2D and 4 in 3D
- this->new_node_per_elem = new Array<UInt>(0, 1 + 4 * (dim-1));
+ this->intersection_points = new Array<Real>(0, dim);
+ // A maximum is set to the number of intersection nodes per element to limit
+ // the size of new_node_per_elem: 2 in 2D and 4 in 3D
+ this->new_node_per_elem = new Array<UInt>(0, 1 + 4 * (dim - 1));
}
-template<UInt dim, ElementType type>
+template <UInt dim, ElementType type>
MeshSphereIntersector<dim, type>::~MeshSphereIntersector() {
delete this->new_node_per_elem;
delete this->intersection_points;
}
-template<UInt dim, ElementType type>
+template <UInt dim, ElementType type>
void MeshSphereIntersector<dim, type>::constructData(GhostType ghost_type) {
this->new_node_per_elem->resize(this->mesh.getNbElement(type, ghost_type));
this->new_node_per_elem->clear();
- MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>::constructData(ghost_type);
+ MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>::constructData(
+ ghost_type);
}
-template<UInt dim, ElementType type>
-void MeshSphereIntersector<dim, type>:: computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query,
- UInt nb_old_nodes) {
- /// function to replace computeIntersectionQuery in a more generic geometry module version
- // The newNodeEvent is not send from this method who only compute the intersection points
+template <UInt dim, ElementType type>
+void MeshSphereIntersector<dim, type>::computeMeshQueryIntersectionPoint(
+ const SK::Sphere_3 & query, UInt nb_old_nodes) {
+ /// function to replace computeIntersectionQuery in a more generic geometry
+ /// module version
+ // The newNodeEvent is not send from this method who only compute the
+ // intersection points
AKANTU_DEBUG_IN();
Array<Real> & nodes = this->mesh.getNodes();
UInt nb_node = nodes.size() + this->intersection_points->size();
// Tolerance for proximity checks should be defined by user
Real global_tolerance = Math::getTolerance();
Math::setTolerance(tol_intersection_on_node);
typedef boost::variant<pair_type> sk_inter_res;
TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::const_iterator
- it = this->factory.getPrimitiveList().begin(),
- end= this->factory.getPrimitiveList().end();
+ it = this->factory.getPrimitiveList().begin(),
+ end = this->factory.getPrimitiveList().end();
- for (; it != end ; ++it) { // loop on the primitives (segments)
+ for (; it != end; ++it) { // loop on the primitives (segments)
std::list<sk_inter_res> s_results;
CGAL::intersection(*it, query, std::back_inserter(s_results));
if (s_results.size() == 1) { // just one point
if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
if (pair->second == 1) { // not a point tangent to the sphere
// the intersection point written as a vector
Vector<Real> new_node(dim, 0.0);
cgal::Cartesian::Point_3 point(CGAL::to_double(pair->first.x()),
- CGAL::to_double(pair->first.y()),
- CGAL::to_double(pair->first.z()));
- for (UInt i = 0 ; i < dim ; i++) {
+ CGAL::to_double(pair->first.y()),
+ CGAL::to_double(pair->first.z()));
+ for (UInt i = 0; i < dim; i++) {
new_node(i) = point[i];
}
- /// boolean to decide wheter intersection point is on a standard node of the mesh or not
+ /// boolean to decide wheter intersection point is on a standard node
+ /// of the mesh or not
bool is_on_mesh = false;
- /// boolean to decide if this intersection point has been already computed for a neighbor element
- bool is_new = true;
-
- /// check if intersection point has already been computed
- UInt n = nb_old_nodes;
-
- // check if we already compute this intersection and add it as a node for a neighboor element of another type
- auto existing_node = nodes.begin(dim);
-
- for (; n < nodes.size() ; ++n) {// loop on the nodes from nb_old_nodes
- if (Math::are_vector_equal(dim, new_node.storage(), existing_node[n].storage())) {
- is_new = false;
- break;
- }
- }
- if(is_new){
- auto intersection_points_it = this->intersection_points->begin(dim);
- auto intersection_points_end = this->intersection_points->end(dim);
- for (; intersection_points_it != intersection_points_end ; ++intersection_points_it, ++n) {
- if (Math::are_vector_equal(dim, new_node.storage(), intersection_points_it->storage())) {
- is_new = false;
- break;
- }
- }
- }
-
- // get the initial and final points of the primitive (segment) and write them as vectors
- cgal::Cartesian::Point_3 source_cgal(CGAL::to_double(it->source().x()),
- CGAL::to_double(it->source().y()),
- CGAL::to_double(it->source().z()));
- cgal::Cartesian::Point_3 target_cgal(CGAL::to_double(it->target().x()),
- CGAL::to_double(it->target().y()),
- CGAL::to_double(it->target().z()));
- Vector<Real> source(dim), target(dim);
- for (UInt i = 0 ; i < dim ; i++) {
- source(i) = source_cgal[i];
- target(i) = target_cgal[i];
- }
-
- // Check if we are close from a node of the primitive (segment)
- if (Math::are_vector_equal(dim, source.storage(), new_node.storage()) ||
- Math::are_vector_equal(dim, target.storage(), new_node.storage())) {
- is_on_mesh = true;
- is_new = false;
- }
-
- if (is_new) {// if the intersection point is a new one add it to the list
- this->intersection_points->push_back(new_node);
- nb_node++;
- }
-
- // deduce the element id
- UInt element_id = it->id();
-
- // fill the new_node_per_elem array
- if (!is_on_mesh) { // if the node is not on a mesh node
- UInt & nb_new_nodes_per_el = (*this->new_node_per_elem)(element_id, 0);
- nb_new_nodes_per_el += 1;
- AKANTU_DEBUG_ASSERT(2 * nb_new_nodes_per_el < this->new_node_per_elem->getNbComponent(),
- "You might have to interface crossing the same material");
- (*this->new_node_per_elem)(element_id, (2 * nb_new_nodes_per_el) - 1) = n;
- (*this->new_node_per_elem)(element_id, 2 * nb_new_nodes_per_el) = it->segId();
- }
- }
+ /// boolean to decide if this intersection point has been already
+ /// computed for a neighbor element
+ bool is_new = true;
+
+ /// check if intersection point has already been computed
+ UInt n = nb_old_nodes;
+
+ // check if we already compute this intersection and add it as a node
+ // for a neighboor element of another type
+ auto existing_node = nodes.begin(dim);
+
+ for (; n < nodes.size(); ++n) { // loop on the nodes from nb_old_nodes
+ if (Math::are_vector_equal(dim, new_node.storage(),
+ existing_node[n].storage())) {
+ is_new = false;
+ break;
+ }
+ }
+ if (is_new) {
+ auto intersection_points_it = this->intersection_points->begin(dim);
+ auto intersection_points_end = this->intersection_points->end(dim);
+ for (; intersection_points_it != intersection_points_end;
+ ++intersection_points_it, ++n) {
+ if (Math::are_vector_equal(dim, new_node.storage(),
+ intersection_points_it->storage())) {
+ is_new = false;
+ break;
+ }
+ }
+ }
+
+ // get the initial and final points of the primitive (segment) and
+ // write them as vectors
+ cgal::Cartesian::Point_3 source_cgal(
+ CGAL::to_double(it->source().x()),
+ CGAL::to_double(it->source().y()),
+ CGAL::to_double(it->source().z()));
+ cgal::Cartesian::Point_3 target_cgal(
+ CGAL::to_double(it->target().x()),
+ CGAL::to_double(it->target().y()),
+ CGAL::to_double(it->target().z()));
+ Vector<Real> source(dim), target(dim);
+ for (UInt i = 0; i < dim; i++) {
+ source(i) = source_cgal[i];
+ target(i) = target_cgal[i];
+ }
+
+ // Check if we are close from a node of the primitive (segment)
+ if (Math::are_vector_equal(dim, source.storage(),
+ new_node.storage()) ||
+ Math::are_vector_equal(dim, target.storage(),
+ new_node.storage())) {
+ is_on_mesh = true;
+ is_new = false;
+ }
+
+ if (is_new) { // if the intersection point is a new one add it to the
+ // list
+ this->intersection_points->push_back(new_node);
+ nb_node++;
+ }
+
+ // deduce the element id
+ UInt element_id = it->id();
+
+ // fill the new_node_per_elem array
+ if (!is_on_mesh) { // if the node is not on a mesh node
+ UInt & nb_new_nodes_per_el =
+ (*this->new_node_per_elem)(element_id, 0);
+ nb_new_nodes_per_el += 1;
+ AKANTU_DEBUG_ASSERT(
+ 2 * nb_new_nodes_per_el <
+ this->new_node_per_elem->getNbComponent(),
+ "You might have to interface crossing the same material");
+ (*this->new_node_per_elem)(element_id,
+ (2 * nb_new_nodes_per_el) - 1) = n;
+ (*this->new_node_per_elem)(element_id, 2 * nb_new_nodes_per_el) =
+ it->segId();
+ }
+ }
}
}
}
Math::setTolerance(global_tolerance);
AKANTU_DEBUG_OUT();
}
} // akantu
#endif // __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/tree_type_helper.hh b/src/geometry/tree_type_helper.hh
index 633082d76..d43bdf549 100644
--- a/src/geometry/tree_type_helper.hh
+++ b/src/geometry/tree_type_helper.hh
@@ -1,112 +1,109 @@
/**
* @file tree_type_helper.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Thu Jan 14 2016
*
* @brief Converts element types of a mesh to CGAL primitive types
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TREE_TYPE_HELPER_HH__
#define __AKANTU_TREE_TYPE_HELPER_HH__
#include "aka_common.hh"
#include "line_arc.hh"
-#include "triangle.hh"
#include "tetrahedron.hh"
+#include "triangle.hh"
#include "aabb_primitive.hh"
#include "mesh_geom_common.hh"
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_tree.h>
namespace akantu {
-
+
/* -------------------------------------------------------------------------- */
/// Replacement class for algorithm that can't use the AABB tree types
-template<typename iterator>
-struct VoidTree {
+template <typename iterator> struct VoidTree {
VoidTree(const iterator & /*begin*/, const iterator & /*end*/) {}
};
/// Helper class used to ease the use of CGAL AABB tree algorithm
-template<class Primitive, class Kernel>
-struct TreeTypeHelper {
+template <class Primitive, class Kernel> struct TreeTypeHelper {
static const bool is_valid = false;
typedef Primitive primitive_type;
typedef typename std::list<primitive_type> container_type;
typedef typename container_type::iterator iterator;
typedef typename container_type::const_iterator const_iterator;
typedef typename CGAL::Point_3<Kernel> point_type;
typedef VoidTree<iterator> tree;
};
/// Helper class used to ease the use of intersections
-template<class TTHelper, class Query>
-struct IntersectionTypeHelper;
+template <class TTHelper, class Query> struct IntersectionTypeHelper;
/**
* Macro used to specialize TreeTypeHelper
* @param my_primitive associated primitive type
* @param my_query query_type
* @param my_kernel kernel type
*/
#define TREE_TYPE_HELPER_MACRO(my_primitive, my_query, my_kernel) \
template <> struct TreeTypeHelper<my_primitive<my_kernel>, my_kernel> { \
static const bool is_valid = true; \
typedef my_primitive<my_kernel> primitive_type; \
typedef my_primitive##_primitive aabb_primitive_type; \
typedef CGAL::Point_3<my_kernel> point_type; \
\
typedef std::list<primitive_type> container_type; \
typedef container_type::iterator iterator; \
typedef CGAL::AABB_traits<my_kernel, aabb_primitive_type> \
aabb_traits_type; \
typedef CGAL::AABB_tree<aabb_traits_type> tree; \
typedef tree::Primitive_id id_type; \
}; \
\
template <> \
struct IntersectionTypeHelper< \
TreeTypeHelper<my_primitive<my_kernel>, my_kernel>, my_query> { \
typedef boost::optional<TreeTypeHelper< \
my_primitive<my_kernel>, \
my_kernel>::tree::Intersection_and_primitive_id<my_query>::Type> \
intersection_type; \
}
TREE_TYPE_HELPER_MACRO(Triangle, cgal::Cartesian::Segment_3, cgal::Cartesian);
-//TREE_TYPE_HELPER_MACRO(Line_arc, cgal::Spherical::Sphere_3, cgal::Spherical);
+// TREE_TYPE_HELPER_MACRO(Line_arc, cgal::Spherical::Sphere_3, cgal::Spherical);
#undef TREE_TYPE_HELPER_MACRO
} // akantu
#endif // __AKANTU_TREE_TYPE_HELPER_HH__
diff --git a/src/io/dumper/dumpable.hh b/src/io/dumper/dumpable.hh
index 064ab647b..985e3b9f7 100644
--- a/src/io/dumper/dumpable.hh
+++ b/src/io/dumper/dumpable.hh
@@ -1,49 +1,48 @@
/**
* @file dumpable.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
* @date last modification: Tue Jan 06 2015
*
* @brief Interface for object who wants to dump themselves
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
-
#ifndef __AKANTU_DUMPABLE_HH__
#define __AKANTU_DUMPABLE_HH__
#ifdef AKANTU_USE_IOHELPER
-# include "dumpable_iohelper.hh"
+#include "dumpable_iohelper.hh"
#else
-# include "dumpable_dummy.hh"
-#endif //AKANTU_USE_IOHELPER
+#include "dumpable_dummy.hh"
+#endif // AKANTU_USE_IOHELPER
#endif /* __AKANTU_DUMPABLE_HH__ */
diff --git a/src/io/dumper/dumpable_dummy.hh b/src/io/dumper/dumpable_dummy.hh
index 3b6ca9686..0b9fb4694 100644
--- a/src/io/dumper/dumpable_dummy.hh
+++ b/src/io/dumper/dumpable_dummy.hh
@@ -1,252 +1,265 @@
/**
* @file dumpable_dummy.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
* @date last modification: Fri Aug 21 2015
*
* @brief Interface for object who wants to dump themselves
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPABLE_DUMMY_HH__
#define __AKANTU_DUMPABLE_DUMMY_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused"
namespace dumper {
class Field;
}
class DumperIOHelper;
class Mesh;
/* -------------------------------------------------------------------------- */
class Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- Dumpable() {};
- virtual ~Dumpable() { };
+ Dumpable(){};
+ virtual ~Dumpable(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- template<class T>
+ template <class T>
inline void registerDumper(const std::string & dumper_name,
- const std::string & file_name = "",
- const bool is_default = false) { }
+ const std::string & file_name = "",
+ const bool is_default = false) {}
void registerExternalDumper(DumperIOHelper * dumper,
const std::string & dumper_name,
- const bool is_default = false) { }
+ const bool is_default = false) {}
- void addDumpMesh(const Mesh & mesh,
- UInt spatial_dimension = _all_dimensions,
+ void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
- const ElementKind & element_kind = _ek_not_defined) {
- }
+ const ElementKind & element_kind = _ek_not_defined) {}
- void addDumpMeshToDumper(const std::string & dumper_name,
- const Mesh & mesh,
+ void addDumpMeshToDumper(const std::string & dumper_name, const Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
}
void addDumpFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) {
}
- void addDumpFilteredMeshToDumper(const std::string & dumper_name,
- const Mesh & mesh,
- const ElementTypeMapArray<UInt> & elements_filter,
- const Array<UInt> & nodes_filter,
- UInt spatial_dimension = _all_dimensions,
- const GhostType & ghost_type = _not_ghost,
- const ElementKind & element_kind = _ek_not_defined) {
- }
+ void addDumpFilteredMeshToDumper(
+ const std::string & dumper_name, const Mesh & mesh,
+ const ElementTypeMapArray<UInt> & elements_filter,
+ const Array<UInt> & nodes_filter,
+ UInt spatial_dimension = _all_dimensions,
+ const GhostType & ghost_type = _not_ghost,
+ const ElementKind & element_kind = _ek_not_defined) {}
- virtual void addDumpField(const std::string & field_id){
+ virtual void addDumpField(const std::string & field_id) {
AKANTU_TO_IMPLEMENT();
}
virtual void addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id){
+ const std::string & field_id) {
AKANTU_TO_IMPLEMENT();
}
virtual void addDumpFieldExternal(const std::string & field_id,
dumper::Field * field) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
virtual void addDumpFieldExternalToDumper(const std::string & dumper_name,
- const std::string & field_id,
- dumper::Field * field) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ const std::string & field_id,
+ dumper::Field * field) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- template<typename T>
+ template <typename T>
void addDumpFieldExternal(const std::string & field_id,
const Array<T> & field) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- template<typename T>
+ template <typename T>
void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const Array<T> & field) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- template<typename T>
- void addDumpFieldExternal(const std::string & field_id,
- const ElementTypeMapArray<T> & field,
- UInt spatial_dimension = _all_dimensions,
- const GhostType & ghost_type = _not_ghost,
- const ElementKind & element_kind = _ek_not_defined) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ template <typename T>
+ void
+ addDumpFieldExternal(const std::string & field_id,
+ const ElementTypeMapArray<T> & field,
+ UInt spatial_dimension = _all_dimensions,
+ const GhostType & ghost_type = _not_ghost,
+ const ElementKind & element_kind = _ek_not_defined) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- template<typename T>
- void addDumpFieldExternalToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const ElementTypeMapArray<T> & field,
- UInt spatial_dimension = _all_dimensions,
- const GhostType & ghost_type = _not_ghost,
- const ElementKind & element_kind = _ek_not_defined) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ template <typename T>
+ void addDumpFieldExternalToDumper(
+ const std::string & dumper_name, const std::string & field_id,
+ const ElementTypeMapArray<T> & field,
+ UInt spatial_dimension = _all_dimensions,
+ const GhostType & ghost_type = _not_ghost,
+ const ElementKind & element_kind = _ek_not_defined) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void removeDumpField(const std::string & field_id) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void removeDumpFieldFromDumper(const std::string & dumper_name,
- const std::string & field_id) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ const std::string & field_id) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void setDirecory(const std::string & directory) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void setBaseName(const std::string & basename) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- void setTextModeToDumper(const std::string & dumper_name){
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ void setTextModeToDumper(const std::string & dumper_name) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- void setTextModeToDumper(){
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ void setTextModeToDumper() {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
-
void dump() {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void dump(const std::string & dumper_name) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
void dump(UInt step) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- void dump(const std::string & dumper_name,
- UInt step) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ void dump(const std::string & dumper_name, UInt step) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- void dump(Real current_time,
- UInt step) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ void dump(Real current_time, UInt step) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- void dump(const std::string & dumper_name,
- Real current_time,
- UInt step) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ void dump(const std::string & dumper_name, Real current_time, UInt step) {
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
protected:
-
void internalAddDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field) {
- AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
protected:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
DumperIOHelper & getDumper() {
- AKANTU_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_ERROR("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- DumperIOHelper & getDumper(const std::string & dumper_name){
- AKANTU_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ DumperIOHelper & getDumper(const std::string & dumper_name) {
+ AKANTU_ERROR("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
- template<class T>
- T & getDumper(const std::string & dumper_name) {
- AKANTU_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ template <class T> T & getDumper(const std::string & dumper_name) {
+ AKANTU_ERROR("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
std::string getDefaultDumperName() {
- AKANTU_ERROR("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake.");
+ AKANTU_ERROR("No dumper activated at compilation, turn on "
+ "AKANTU_USE_IOHELPER in cmake.");
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
#pragma GCC diagnostic pop
} // akantu
#endif /* __AKANTU_DUMPABLE_DUMMY_HH__ */
diff --git a/src/io/dumper/dumpable_iohelper.hh b/src/io/dumper/dumpable_iohelper.hh
index 6c0c07a4a..e9252526f 100644
--- a/src/io/dumper/dumpable_iohelper.hh
+++ b/src/io/dumper/dumpable_iohelper.hh
@@ -1,196 +1,192 @@
/**
* @file dumpable_iohelper.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jan 06 2015
* @date last modification: Thu Nov 19 2015
*
* @brief Interface for object who wants to dump themselves
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_iohelper.hh"
/* -------------------------------------------------------------------------- */
#include <set>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPABLE_IOHELPER_HH__
#define __AKANTU_DUMPABLE_IOHELPER_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
Dumpable();
virtual ~Dumpable();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// create a new dumper (of templated type T) and register it under
/// dumper_name. file_name is used for construction of T. is default states if
/// this dumper is the default dumper.
- template<class T>
+ template <class T>
inline void registerDumper(const std::string & dumper_name,
const std::string & file_name = "",
const bool is_default = false);
/// register an externally created dumper
void registerExternalDumper(DumperIOHelper & dumper,
const std::string & dumper_name,
const bool is_default = false);
/// register a mesh to the default dumper
void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a mesh to the default identified by its name
- void addDumpMeshToDumper(const std::string & dumper_name,
- const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
+ void addDumpMeshToDumper(const std::string & dumper_name, const Mesh & mesh,
+ UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a filtered mesh as the default dumper
void addDumpFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a filtered mesh and provides a name
- void addDumpFilteredMeshToDumper(const std::string & dumper_name,
- const Mesh & mesh,
- const ElementTypeMapArray<UInt> & elements_filter,
- const Array<UInt> & nodes_filter,
- UInt spatial_dimension = _all_dimensions,
- const GhostType & ghost_type = _not_ghost,
- const ElementKind & element_kind = _ek_not_defined);
+ void addDumpFilteredMeshToDumper(
+ const std::string & dumper_name, const Mesh & mesh,
+ const ElementTypeMapArray<UInt> & elements_filter,
+ const Array<UInt> & nodes_filter,
+ UInt spatial_dimension = _all_dimensions,
+ const GhostType & ghost_type = _not_ghost,
+ const ElementKind & element_kind = _ek_not_defined);
/// to implement
virtual void addDumpField(const std::string & field_id);
/// to implement
virtual void addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id);
/// add a field
virtual void addDumpFieldExternal(const std::string & field_id,
dumper::Field * field);
virtual void addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field);
- template<typename T>
+ template <typename T>
inline void addDumpFieldExternal(const std::string & field_id,
const Array<T> & field);
- template<typename T>
+ template <typename T>
inline void addDumpFieldExternalToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const Array<T> & field);
- template<typename T>
- inline void addDumpFieldExternal(const std::string & field_id,
- const ElementTypeMapArray<T> & field,
- UInt spatial_dimension = _all_dimensions,
- const GhostType & ghost_type = _not_ghost,
- const ElementKind & element_kind = _ek_not_defined);
- template<typename T>
- inline void addDumpFieldExternalToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const ElementTypeMapArray<T> & field,
- UInt spatial_dimension = _all_dimensions,
- const GhostType & ghost_type = _not_ghost,
- const ElementKind & element_kind = _ek_not_defined);
+ const std::string & field_id,
+ const Array<T> & field);
+ template <typename T>
+ inline void
+ addDumpFieldExternal(const std::string & field_id,
+ const ElementTypeMapArray<T> & field,
+ UInt spatial_dimension = _all_dimensions,
+ const GhostType & ghost_type = _not_ghost,
+ const ElementKind & element_kind = _ek_not_defined);
+ template <typename T>
+ inline void addDumpFieldExternalToDumper(
+ const std::string & dumper_name, const std::string & field_id,
+ const ElementTypeMapArray<T> & field,
+ UInt spatial_dimension = _all_dimensions,
+ const GhostType & ghost_type = _not_ghost,
+ const ElementKind & element_kind = _ek_not_defined);
void removeDumpField(const std::string & field_id);
void removeDumpFieldFromDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldVector(const std::string & field_id);
virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensor(const std::string & field_id);
virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id);
void setDirectory(const std::string & directory);
void setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory);
void setBaseName(const std::string & basename);
void setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename);
void setTimeStepToDumper(Real time_step);
- void setTimeStepToDumper(const std::string & dumper_name,
- Real time_step);
-
+ void setTimeStepToDumper(const std::string & dumper_name, Real time_step);
void setTextModeToDumper(const std::string & dumper_name);
void setTextModeToDumper();
virtual void dump();
virtual void dump(UInt step);
virtual void dump(Real time, UInt step);
virtual void dump(const std::string & dumper_name);
virtual void dump(const std::string & dumper_name, UInt step);
virtual void dump(const std::string & dumper_name, Real time, UInt step);
-
public:
void internalAddDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
DumperIOHelper & getDumper();
DumperIOHelper & getDumper(const std::string & dumper_name);
- template<class T> T & getDumper(const std::string & dumper_name);
+ template <class T> T & getDumper(const std::string & dumper_name);
std::string getDefaultDumperName() const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
using DumperMap = std::map<std::string, DumperIOHelper *>;
using DumperSet = std::set<std::string>;
DumperMap dumpers;
std::string default_dumper;
};
} // akantu
#endif /* __AKANTU_DUMPABLE_IOHELPER_HH__ */
diff --git a/src/io/dumper/dumper_compute.hh b/src/io/dumper/dumper_compute.hh
index bb4ec952e..7af59b85c 100644
--- a/src/io/dumper/dumper_compute.hh
+++ b/src/io/dumper/dumper_compute.hh
@@ -1,270 +1,274 @@
/**
* @file dumper_compute.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Jan 19 2016
*
* @brief Field that map a function to another field
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_COMPUTE_HH__
#define __AKANTU_DUMPER_COMPUTE_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "dumper_field.hh"
#include "dumper_iohelper.hh"
#include "dumper_type_traits.hh"
-#include "dumper_field.hh"
#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
class ComputeFunctorInterface {
public:
virtual ~ComputeFunctorInterface() = default;
virtual UInt getDim() = 0;
virtual UInt getNbComponent(UInt old_nb_comp) = 0;
};
/* -------------------------------------------------------------------------- */
template <typename return_type>
class ComputeFunctorOutput : public ComputeFunctorInterface {
public:
ComputeFunctorOutput() = default;
~ComputeFunctorOutput() override = default;
};
/* -------------------------------------------------------------------------- */
template <typename input_type, typename return_type>
class ComputeFunctor : public ComputeFunctorOutput<return_type> {
public:
ComputeFunctor() = default;
~ComputeFunctor() override = default;
virtual return_type func(const input_type & d, Element global_index) = 0;
};
/* -------------------------------------------------------------------------- */
template <typename SubFieldCompute, typename _return_type>
class FieldCompute : public Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
using sub_iterator = typename SubFieldCompute::iterator;
using sub_types = typename SubFieldCompute::types;
using sub_return_type = typename sub_types::return_type;
using return_type = _return_type;
using data_type = typename sub_types::data_type;
- using types = TypeTraits<data_type, return_type, ElementTypeMapArray<data_type> >;
+ using types =
+ TypeTraits<data_type, return_type, ElementTypeMapArray<data_type>>;
class iterator {
public:
iterator(const sub_iterator & it,
ComputeFunctor<sub_return_type, return_type> & func)
: it(it), func(func) {}
bool operator!=(const iterator & it) const { return it.it != this->it; }
iterator operator++() {
++this->it;
return *this;
}
UInt currentGlobalIndex() { return this->it.currentGlobalIndex(); }
return_type operator*() { return func.func(*it, it.getCurrentElement()); }
Element getCurrentElement() { return this->it.getCurrentElement(); }
UInt element_type() { return this->it.element_type(); }
protected:
sub_iterator it;
ComputeFunctor<sub_return_type, return_type> & func;
};
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FieldCompute(SubFieldCompute & cont, ComputeFunctorInterface & func)
: sub_field(cont),
func(dynamic_cast<ComputeFunctor<sub_return_type, return_type> &>(
func)) {
this->checkHomogeneity();
};
~FieldCompute() override {
delete &(this->sub_field);
delete &(this->func);
}
void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) override {
dumper.addElemDataField(id, *this);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
iterator begin() { return iterator(sub_field.begin(), func); }
iterator end() { return iterator(sub_field.end(), func); }
UInt getDim() { return func.getDim(); }
UInt size() {
throw;
// return Functor::size();
return 0;
}
void checkHomogeneity() override { this->homogeneous = true; };
iohelper::DataType getDataType() {
return iohelper::getDataType<data_type>();
}
/// get the number of components of the hosted field
ElementTypeMap<UInt>
getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) override {
ElementTypeMap<UInt> nb_components;
const ElementTypeMap<UInt> & old_nb_components =
this->sub_field.getNbComponents(dim, ghost_type, kind);
ElementTypeMap<UInt>::type_iterator tit =
old_nb_components.firstType(dim, ghost_type, kind);
ElementTypeMap<UInt>::type_iterator end =
old_nb_components.lastType(dim, ghost_type, kind);
while (tit != end) {
UInt nb_comp = old_nb_components(*tit, ghost_type);
nb_components(*tit, ghost_type) = func.getNbComponent(nb_comp);
++tit;
}
return nb_components;
};
/// for connection to a FieldCompute
inline Field * connect(FieldComputeProxy & proxy) override;
/// for connection to a FieldCompute
ComputeFunctorInterface * connect(HomogenizerProxy & proxy) override;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
SubFieldCompute & sub_field;
ComputeFunctor<sub_return_type, return_type> & func;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class FieldComputeProxy {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FieldComputeProxy(ComputeFunctorInterface & func) : func(func){};
inline static Field * createFieldCompute(Field * field,
ComputeFunctorInterface & func) {
/// that looks fishy an object passed as a ref and destroyed at their end of
/// the function
FieldComputeProxy compute_proxy(func);
return field->connect(compute_proxy);
}
template <typename T> Field * connectToField(T * ptr) {
- if (dynamic_cast<ComputeFunctorOutput<Vector<Real> > *>(&func)) {
- return this->connectToFunctor<Vector<Real> >(ptr);
- } else if (dynamic_cast<ComputeFunctorOutput<Vector<UInt> > *>(&func)) {
- return this->connectToFunctor<Vector<UInt> >(ptr);
+ if (dynamic_cast<ComputeFunctorOutput<Vector<Real>> *>(&func)) {
+ return this->connectToFunctor<Vector<Real>>(ptr);
+ } else if (dynamic_cast<ComputeFunctorOutput<Vector<UInt>> *>(&func)) {
+ return this->connectToFunctor<Vector<UInt>>(ptr);
}
- else if (dynamic_cast<ComputeFunctorOutput<Matrix<UInt> > *>(&func)) {
- return this->connectToFunctor<Matrix<UInt> >(ptr);
+ else if (dynamic_cast<ComputeFunctorOutput<Matrix<UInt>> *>(&func)) {
+ return this->connectToFunctor<Matrix<UInt>>(ptr);
}
- else if (dynamic_cast<ComputeFunctorOutput<Matrix<Real> > *>(&func)) {
- return this->connectToFunctor<Matrix<Real> >(ptr);
+ else if (dynamic_cast<ComputeFunctorOutput<Matrix<Real>> *>(&func)) {
+ return this->connectToFunctor<Matrix<Real>>(ptr);
}
else
throw;
}
template <typename output, typename T> Field * connectToFunctor(T * ptr) {
auto * functor_ptr = new FieldCompute<T, output>(*ptr, func);
return functor_ptr;
}
template <typename output, typename SubFieldCompute, typename return_type1,
typename return_type2>
- Field * connectToFunctor(__attribute__((unused)) FieldCompute<
- FieldCompute<SubFieldCompute, return_type1>, return_type2> * ptr) {
+ Field *
+ connectToFunctor(__attribute__((unused))
+ FieldCompute<FieldCompute<SubFieldCompute, return_type1>,
+ return_type2> * ptr) {
throw; // return new FieldCompute<T,output>(*ptr,func);
return nullptr;
}
template <typename output, typename SubFieldCompute, typename return_type1,
typename return_type2, typename return_type3, typename return_type4>
- Field * connectToFunctor(__attribute__((unused)) FieldCompute<
- FieldCompute<FieldCompute<FieldCompute<SubFieldCompute, return_type1>,
- return_type2>,
- return_type3>,
- return_type4> * ptr) {
+ Field * connectToFunctor(
+ __attribute__((unused)) FieldCompute<
+ FieldCompute<FieldCompute<FieldCompute<SubFieldCompute, return_type1>,
+ return_type2>,
+ return_type3>,
+ return_type4> * ptr) {
throw; // return new FieldCompute<T,output>(*ptr,func);
return nullptr;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
ComputeFunctorInterface & func;
};
/* -------------------------------------------------------------------------- */
/// for connection to a FieldCompute
template <typename SubFieldCompute, typename return_type>
inline Field *
FieldCompute<SubFieldCompute, return_type>::connect(FieldComputeProxy & proxy) {
return proxy.connectToField(this);
}
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
} // akantu
#endif /* __AKANTU_DUMPER_COMPUTE_HH__ */
diff --git a/src/io/dumper/dumper_element_iterator.hh b/src/io/dumper/dumper_element_iterator.hh
index 0589840d9..24319d083 100644
--- a/src/io/dumper/dumper_element_iterator.hh
+++ b/src/io/dumper/dumper_element_iterator.hh
@@ -1,192 +1,178 @@
/**
* @file dumper_element_iterator.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Fri May 15 2015
*
* @brief Iterators for elemental fields
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__
#define __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__
/* -------------------------------------------------------------------------- */
#include "element.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template<class types, template <class> class final_iterator>
+template <class types, template <class> class final_iterator>
class element_iterator {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
using it_type = typename types::it_type;
using field_type = typename types::field_type;
using array_type = typename types::array_type;
using array_iterator = typename types::array_iterator;
using iterator = final_iterator<types>;
public:
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
element_iterator(const field_type & field,
const typename field_type::type_iterator & t_it,
const typename field_type::type_iterator & t_it_end,
const array_iterator & array_it,
const array_iterator & array_it_end,
const GhostType ghost_type = _not_ghost)
- : field(field),
- tit(t_it),
- tit_end(t_it_end),
- array_it(array_it),
- array_it_end(array_it_end),
- ghost_type(ghost_type) {
- }
+ : field(field), tit(t_it), tit_end(t_it_end), array_it(array_it),
+ array_it_end(array_it_end), ghost_type(ghost_type) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
bool operator!=(const iterator & it) const {
- return (ghost_type != it.ghost_type)
- || (tit != it.tit || (array_it != it.array_it));
+ return (ghost_type != it.ghost_type) ||
+ (tit != it.tit || (array_it != it.array_it));
}
iterator & operator++() {
++array_it;
- while(array_it == array_it_end && tit != tit_end) {
+ while (array_it == array_it_end && tit != tit_end) {
++tit;
- if(tit != tit_end) {
+ if (tit != tit_end) {
const array_type & vect = field(*tit, ghost_type);
UInt _nb_data_per_elem = getNbDataPerElem(*tit);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.size() * nb_component) / _nb_data_per_elem;
- array_it = vect.begin_reinterpret(_nb_data_per_elem,size);
- array_it_end = vect.end_reinterpret (_nb_data_per_elem,size);
+ array_it = vect.begin_reinterpret(_nb_data_per_elem, size);
+ array_it_end = vect.end_reinterpret(_nb_data_per_elem, size);
}
}
return *(static_cast<iterator *>(this));
};
ElementType getType() { return *tit; }
UInt element_type() { return getIOHelperType(*tit); }
- Element getCurrentElement(){
+ Element getCurrentElement() {
return Element{*tit, array_it.getCurrentIndex(), _not_ghost};
}
UInt getNbDataPerElem(const ElementType & type) const {
if (!nb_data_per_elem.exists(type, ghost_type))
- return field(type,ghost_type).getNbComponent();
-
- return nb_data_per_elem(type,ghost_type);
+ return field(type, ghost_type).getNbComponent();
+
+ return nb_data_per_elem(type, ghost_type);
}
- void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data){
+ void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) {
this->nb_data_per_elem = nb_data;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// the field to iterate on
const field_type & field;
/// field iterator
typename field_type::type_iterator tit;
/// field iterator end
typename field_type::type_iterator tit_end;
/// array iterator
array_iterator array_it;
/// internal iterator end
array_iterator array_it_end;
/// ghost type identification
const GhostType ghost_type;
/// number of data per element
ElementTypeMap<UInt> nb_data_per_elem;
-
};
/* -------------------------------------------------------------------------- */
-template<typename types>
+template <typename types>
class elemental_field_iterator
- : public element_iterator<types, elemental_field_iterator> {
+ : public element_iterator<types, elemental_field_iterator> {
public:
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
- using parent = element_iterator<types, ::akantu::dumper::elemental_field_iterator>;
+ using parent =
+ element_iterator<types, ::akantu::dumper::elemental_field_iterator>;
using it_type = typename types::it_type;
using return_type = typename types::return_type;
using field_type = typename types::field_type;
using array_iterator = typename types::array_iterator;
public:
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
elemental_field_iterator(const field_type & field,
const typename field_type::type_iterator & t_it,
const typename field_type::type_iterator & t_it_end,
const array_iterator & array_it,
const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost) :
- parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) { }
+ const GhostType ghost_type = _not_ghost)
+ : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
- return_type operator*(){
- return *this->array_it;
- }
+ return_type operator*() { return *this->array_it; }
private:
-
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
} // akantu
/* -------------------------------------------------------------------------- */
-
-
#endif /* __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__ */
diff --git a/src/io/dumper/dumper_element_partition.hh b/src/io/dumper/dumper_element_partition.hh
index d735814cb..3718e35e2 100644
--- a/src/io/dumper/dumper_element_partition.hh
+++ b/src/io/dumper/dumper_element_partition.hh
@@ -1,123 +1,118 @@
/**
* @file dumper_element_partition.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Jul 14 2015
*
* @brief ElementPartition field
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
#ifdef AKANTU_IGFEM
-# include "dumper_igfem_element_partition.hh"
+#include "dumper_igfem_element_partition.hh"
#endif
/* -------------------------------------------------------------------------- */
-template<class types>
+template <class types>
class element_partition_field_iterator
- : public element_iterator<types, element_partition_field_iterator> {
+ : public element_iterator<types, element_partition_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
- using parent = element_iterator<types, dumper::element_partition_field_iterator>;
+ using parent =
+ element_iterator<types, dumper::element_partition_field_iterator>;
using return_type =
typename SingleType<unsigned int, Vector, true>::return_type;
using array_iterator = typename types::array_iterator;
using field_type = typename types::field_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- element_partition_field_iterator(const field_type & field,
- const typename field_type::type_iterator & t_it,
- const typename field_type::type_iterator & t_it_end,
- const array_iterator & array_it,
- const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost) :
- parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {
+ element_partition_field_iterator(
+ const field_type & field, const typename field_type::type_iterator & t_it,
+ const typename field_type::type_iterator & t_it_end,
+ const array_iterator & array_it, const array_iterator & array_it_end,
+ const GhostType ghost_type = _not_ghost)
+ : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {
prank = Communicator::getStaticCommunicator().whoAmI();
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- return_type operator*() {
- return return_type(1, prank);
- }
+ return_type operator*() { return return_type(1, prank); }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
UInt prank;
};
-
/* -------------------------------------------------------------------------- */
-template<bool filtered = false>
-class ElementPartitionField :
- public GenericElementalField<SingleType<UInt,Vector,filtered>,
- element_partition_field_iterator> {
+template <bool filtered = false>
+class ElementPartitionField
+ : public GenericElementalField<SingleType<UInt, Vector, filtered>,
+ element_partition_field_iterator> {
public:
-
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
- using types = SingleType<UInt,Vector,filtered>;
+ using types = SingleType<UInt, Vector, filtered>;
using iterator = element_partition_field_iterator<types>;
- using parent = GenericElementalField<types,element_partition_field_iterator>;
+ using parent = GenericElementalField<types, element_partition_field_iterator>;
using field_type = typename types::field_type;
public:
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
ElementPartitionField(const field_type & field,
- UInt spatial_dimension = _all_dimensions,
- GhostType ghost_type = _not_ghost,
- ElementKind element_kind = _ek_not_defined) :
- parent(field, spatial_dimension, ghost_type, element_kind) {
+ UInt spatial_dimension = _all_dimensions,
+ GhostType ghost_type = _not_ghost,
+ ElementKind element_kind = _ek_not_defined)
+ : parent(field, spatial_dimension, ghost_type, element_kind) {
this->homogeneous = true;
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
UInt getDim() override { return 1; }
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
} // akantu
diff --git a/src/io/dumper/dumper_elemental_field.hh b/src/io/dumper/dumper_elemental_field.hh
index f327f070f..c62bf7b6c 100644
--- a/src/io/dumper/dumper_elemental_field.hh
+++ b/src/io/dumper/dumper_elemental_field.hh
@@ -1,80 +1,77 @@
/**
* @file dumper_elemental_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Mon Aug 17 2015
*
* @brief description of elemental fields
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_ELEMENTAL_FIELD_HH__
#define __AKANTU_DUMPER_ELEMENTAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "communicator.hh"
#include "dumper_field.hh"
#include "dumper_generic_elemental_field.hh"
#ifdef AKANTU_IGFEM
-# include "dumper_igfem_elemental_field.hh"
+#include "dumper_igfem_elemental_field.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-
-template<typename T, template <class> class ret = Vector,bool filtered = false>
+template <typename T, template <class> class ret = Vector,
+ bool filtered = false>
class ElementalField
- : public GenericElementalField<SingleType<T,ret,filtered>,
- elemental_field_iterator> {
+ : public GenericElementalField<SingleType<T, ret, filtered>,
+ elemental_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
- using types = SingleType<T,ret,filtered>;
+ using types = SingleType<T, ret, filtered>;
using field_type = typename types::field_type;
using iterator = elemental_field_iterator<types>;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ElementalField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
- ElementKind element_kind = _ek_not_defined) :
- GenericElementalField<types,elemental_field_iterator>(field,
- spatial_dimension,
- ghost_type,
- element_kind) { }
+ ElementKind element_kind = _ek_not_defined)
+ : GenericElementalField<types, elemental_field_iterator>(
+ field, spatial_dimension, ghost_type, element_kind) {}
};
/* -------------------------------------------------------------------------- */
-
__END_AKANTU_DUMPER__
} // akantu
#endif /* __AKANTU_DUMPER_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_filtered_connectivity.hh b/src/io/dumper/dumper_filtered_connectivity.hh
index b26f49c00..1dfe20e0d 100644
--- a/src/io/dumper/dumper_filtered_connectivity.hh
+++ b/src/io/dumper/dumper_filtered_connectivity.hh
@@ -1,151 +1,152 @@
/**
* @file dumper_filtered_connectivity.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Mon Aug 17 2015
*
* @brief FilteredConnectivities field
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "dumper_generic_elemental_field.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class types>
class filtered_connectivity_field_iterator
- : public element_iterator<types, filtered_connectivity_field_iterator> {
+ : public element_iterator<types, filtered_connectivity_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
- typedef element_iterator<types, dumper::filtered_connectivity_field_iterator> parent;
+ typedef element_iterator<types, dumper::filtered_connectivity_field_iterator>
+ parent;
using return_type = typename types::return_type;
using field_type = typename types::field_type;
using array_iterator = typename types::array_iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- filtered_connectivity_field_iterator(const field_type & field,
- const typename field_type::type_iterator & t_it,
- const typename field_type::type_iterator & t_it_end,
- const array_iterator & array_it,
- const array_iterator & array_it_end,
- const GhostType ghost_type = _not_ghost) :
- parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) { }
+ filtered_connectivity_field_iterator(
+ const field_type & field, const typename field_type::type_iterator & t_it,
+ const typename field_type::type_iterator & t_it_end,
+ const array_iterator & array_it, const array_iterator & array_it_end,
+ const GhostType ghost_type = _not_ghost)
+ : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- return_type operator*(){
+ return_type operator*() {
const Vector<UInt> & old_connect = *this->array_it;
Vector<UInt> new_connect(old_connect.size());
Array<UInt>::const_iterator<UInt> nodes_begin = nodal_filter->begin();
Array<UInt>::const_iterator<UInt> nodes_end = nodal_filter->end();
- for(UInt i(0); i<old_connect.size(); ++i) {
+ for (UInt i(0); i < old_connect.size(); ++i) {
Array<UInt>::const_iterator<UInt> new_id =
- std::find(nodes_begin, nodes_end, old_connect(i));
- if(new_id == nodes_end) AKANTU_EXCEPTION("Node not found in the filter!");
+ std::find(nodes_begin, nodes_end, old_connect(i));
+ if (new_id == nodes_end)
+ AKANTU_EXCEPTION("Node not found in the filter!");
new_connect(i) = new_id - nodes_begin;
}
return new_connect;
}
void setNodalFilter(const Array<UInt> & new_nodal_filter) {
nodal_filter = &new_nodal_filter;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const Array<UInt> * nodal_filter;
};
/* -------------------------------------------------------------------------- */
-class FilteredConnectivityField :
- public GenericElementalField<SingleType<UInt,Vector,true>,
- filtered_connectivity_field_iterator> {
+class FilteredConnectivityField
+ : public GenericElementalField<SingleType<UInt, Vector, true>,
+ filtered_connectivity_field_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
- typedef SingleType<UInt,Vector,true> types;
+ typedef SingleType<UInt, Vector, true> types;
using iterator = filtered_connectivity_field_iterator<types>;
using field_type = types::field_type;
- typedef GenericElementalField<types,filtered_connectivity_field_iterator> parent;
+ typedef GenericElementalField<types, filtered_connectivity_field_iterator>
+ parent;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
FilteredConnectivityField(const field_type & field,
const Array<UInt> & nodal_filter,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
- ElementKind element_kind = _ek_not_defined) :
- parent(field, spatial_dimension, ghost_type, element_kind),
- nodal_filter(nodal_filter) { }
+ ElementKind element_kind = _ek_not_defined)
+ : parent(field, spatial_dimension, ghost_type, element_kind),
+ nodal_filter(nodal_filter) {}
~FilteredConnectivityField() override {
// since the field is created in registerFilteredMesh it is destroyed here
delete const_cast<field_type *>(&this->field);
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
iterator begin() override {
iterator it = parent::begin();
it.setNodalFilter(nodal_filter);
return it;
}
iterator end() override {
iterator it = parent::end();
it.setNodalFilter(nodal_filter);
return it;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const Array<UInt> & nodal_filter;
};
-
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
} // akantu
/* -------------------------------------------------------------------------- */
diff --git a/src/io/dumper/dumper_generic_elemental_field.hh b/src/io/dumper/dumper_generic_elemental_field.hh
index d96b4209f..bf532fb86 100644
--- a/src/io/dumper/dumper_generic_elemental_field.hh
+++ b/src/io/dumper/dumper_generic_elemental_field.hh
@@ -1,224 +1,225 @@
/**
* @file dumper_generic_elemental_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Jan 19 2016
*
* @brief Generic interface for elemental fields
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__
#define __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
-#include "dumper_field.hh"
-#include "element_type_map_filter.hh"
#include "dumper_element_iterator.hh"
+#include "dumper_field.hh"
#include "dumper_homogenizing_field.hh"
+#include "element_type_map_filter.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class _types, template <class> class iterator_type>
class GenericElementalField : public Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
// check dumper_type_traits.hh for additional information over these types
using types = _types;
using data_type = typename types::data_type;
using it_type = typename types::it_type;
using field_type = typename types::field_type;
using array_type = typename types::array_type;
using array_iterator = typename types::array_iterator;
using field_type_iterator = typename field_type::type_iterator;
using iterator = iterator_type<types>;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
GenericElementalField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined)
: field(field), spatial_dimension(spatial_dimension),
ghost_type(ghost_type), element_kind(element_kind) {
this->checkHomogeneity();
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get the number of components of the hosted field
ElementTypeMap<UInt>
getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) override {
return this->field.getNbComponents(dim, ghost_type, kind);
};
/// return the size of the contained data: i.e. the number of elements ?
virtual UInt size() {
checkHomogeneity();
return this->nb_total_element;
}
/// return the iohelper datatype to be dumped
iohelper::DataType getDataType() {
return iohelper::getDataType<data_type>();
}
protected:
/// return the number of entries per element
UInt getNbDataPerElem(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
if (!nb_data_per_elem.exists(type, ghost_type))
return field(type, ghost_type).getNbComponent();
return nb_data_per_elem(type, this->ghost_type);
}
/// check if the same quantity of data for all element types
void checkHomogeneity() override;
public:
void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) override {
dumper.addElemDataField(id, *this);
};
/// for connection to a FieldCompute
inline Field * connect(FieldComputeProxy & proxy) override {
return proxy.connectToField(this);
}
/// for connection to a Homogenizer
inline ComputeFunctorInterface * connect(HomogenizerProxy & proxy) override {
return proxy.connectToField(this);
};
virtual iterator begin() {
field_type_iterator tit;
field_type_iterator end;
/// type iterators on the elemental field
tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
this->element_kind);
end = this->field.lastType(this->spatial_dimension, this->ghost_type,
this->element_kind);
/// skip all types without data
ElementType type = *tit;
for (; tit != end && this->field(*tit, this->ghost_type).size() == 0;
++tit) {
}
type = *tit;
if (tit == end)
return this->end();
/// getting information for the field of the given type
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data_per_elem = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.size() * nb_component) / nb_data_per_elem;
/// define element-wise iterator
array_iterator it = vect.begin_reinterpret(nb_data_per_elem, size);
array_iterator it_end = vect.end_reinterpret(nb_data_per_elem, size);
/// define data iterator
iterator rit =
iterator(this->field, tit, end, it, it_end, this->ghost_type);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
virtual iterator end() {
field_type_iterator tit;
field_type_iterator end;
tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
this->element_kind);
end = this->field.lastType(this->spatial_dimension, this->ghost_type,
this->element_kind);
ElementType type = *tit;
for (; tit != end; ++tit)
type = *tit;
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.size() * nb_component) / nb_data;
array_iterator it = vect.end_reinterpret(nb_data, size);
iterator rit = iterator(this->field, end, end, it, it, this->ghost_type);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
virtual UInt getDim() {
if (this->homogeneous) {
field_type_iterator tit = this->field.firstType(
this->spatial_dimension, this->ghost_type, this->element_kind);
return this->getNbDataPerElem(*tit);
}
throw;
return 0;
}
void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) override {
nb_data_per_elem = nb_data;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the ElementTypeMapArray embedded in the field
const field_type & field;
/// total number of elements
UInt nb_total_element;
/// the spatial dimension of the problem
UInt spatial_dimension;
/// whether this is a ghost field or not (for type selection)
GhostType ghost_type;
/// The element kind to operate on
ElementKind element_kind;
/// The number of data per element type
ElementTypeMap<UInt> nb_data_per_elem;
};
/* -------------------------------------------------------------------------- */
#include "dumper_generic_elemental_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
-__END_AKANTU_DUMPER__ } // akantu
+__END_AKANTU_DUMPER__
+} // akantu
#endif /* __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
index 35b74d555..80b6a524a 100644
--- a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
+++ b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
@@ -1,67 +1,69 @@
/**
* @file dumper_generic_elemental_field_tmpl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the template functions of the ElementalField
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-template<class types, template <class> class iterator>
-void GenericElementalField<types,iterator>::checkHomogeneity() {
+template <class types, template <class> class iterator>
+void GenericElementalField<types, iterator>::checkHomogeneity() {
using field_type_iterator = typename field_type::type_iterator;
using array_type = typename field_type::array_type;
field_type_iterator tit;
field_type_iterator end;
tit = field.firstType(spatial_dimension, ghost_type, element_kind);
end = field.lastType(spatial_dimension, ghost_type, element_kind);
this->nb_total_element = 0;
UInt nb_comp = 0;
bool homogen = true;
- if(tit != end) {
+ if (tit != end) {
nb_comp = this->field(*tit, ghost_type).getNbComponent();
- for(;tit != end; ++tit) {
+ for (; tit != end; ++tit) {
const array_type & vect = this->field(*tit, ghost_type);
UInt nb_element = vect.size();
UInt nb_comp_cur = vect.getNbComponent();
- if(homogen && nb_comp != nb_comp_cur) homogen = false;
+ if (homogen && nb_comp != nb_comp_cur)
+ homogen = false;
this->nb_total_element += nb_element;
// this->nb_data_per_elem(*tit,this->ghost_type) = nb_comp_cur;
}
- if(!homogen) nb_comp = 0;
+ if (!homogen)
+ nb_comp = 0;
}
this->homogeneous = homogen;
}
/* -------------------------------------------------------------------------- */
diff --git a/src/io/dumper/dumper_internal_material_field.hh b/src/io/dumper/dumper_internal_material_field.hh
index 94028416a..26924dda3 100644
--- a/src/io/dumper/dumper_internal_material_field.hh
+++ b/src/io/dumper/dumper_internal_material_field.hh
@@ -1,77 +1,73 @@
/**
* @file dumper_internal_material_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Sep 17 2015
*
* @brief description of material internal field
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH__
#define __AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_quadrature_point_iterator.hh"
#ifdef AKANTU_IGFEM
-# include "dumper_igfem_material_internal_field.hh"
+#include "dumper_igfem_material_internal_field.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template<typename T, bool filtered = false>
+template <typename T, bool filtered = false>
class InternalMaterialField
- : public GenericElementalField<SingleType<T,Vector,filtered>,
- quadrature_point_iterator> {
+ : public GenericElementalField<SingleType<T, Vector, filtered>,
+ quadrature_point_iterator> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
- using types = SingleType<T,Vector,filtered>;
- using parent = GenericElementalField<types,quadrature_point_iterator>;
+ using types = SingleType<T, Vector, filtered>;
+ using parent = GenericElementalField<types, quadrature_point_iterator>;
using field_type = typename types::field_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
InternalMaterialField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
- ElementKind element_kind = _ek_not_defined) :
- parent(field, spatial_dimension, ghost_type, element_kind){}
-
-
+ ElementKind element_kind = _ek_not_defined)
+ : parent(field, spatial_dimension, ghost_type, element_kind) {}
};
-
__END_AKANTU_DUMPER__
} // akantu
#endif /* __AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_iohelper.cc b/src/io/dumper/dumper_iohelper.cc
index 4024bf9ba..ce23d1089 100644
--- a/src/io/dumper/dumper_iohelper.cc
+++ b/src/io/dumper/dumper_iohelper.cc
@@ -1,305 +1,318 @@
/**
* @file dumper_iohelper.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
* @date last modification: Thu Sep 17 2015
*
* @brief implementation of DumperIOHelper
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <io_helper.hh>
-#include "dumper_iohelper.hh"
#include "dumper_elemental_field.hh"
-#include "dumper_nodal_field.hh"
#include "dumper_filtered_connectivity.hh"
+#include "dumper_iohelper.hh"
+#include "dumper_nodal_field.hh"
#include "dumper_variable.hh"
#include "mesh.hh"
#if defined(AKANTU_IGFEM)
#include "dumper_igfem_connectivity.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
DumperIOHelper::DumperIOHelper() = default;
/* -------------------------------------------------------------------------- */
DumperIOHelper::~DumperIOHelper() {
for (auto it = fields.begin(); it != fields.end(); ++it) {
delete it->second;
}
delete dumper;
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::setParallelContext(bool is_parallel) {
- UInt whoami = Communicator::getStaticCommunicator().whoAmI();
+ UInt whoami = Communicator::getStaticCommunicator().whoAmI();
UInt nb_proc = Communicator::getStaticCommunicator().getNbProc();
- if(is_parallel)
+ if (is_parallel)
dumper->setParallelContext(whoami, nb_proc);
else
dumper->setParallelContext(0, 1);
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::setDirectory(const std::string & directory) {
this->directory = directory;
dumper->setPrefix(directory);
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::setBaseName(const std::string & basename) {
filename = basename;
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::setTimeStep(Real time_step) {
- if(!time_activated)
+ if (!time_activated)
this->dumper->activateTimeDescFiles(time_step);
else
this->dumper->setTimeStep(time_step);
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::dump() {
try {
dumper->dump(filename, count);
} catch (iohelper::IOHelperException & e) {
- AKANTU_ERROR("I was not able to dump your data with a Dumper: " << e.what());
+ AKANTU_ERROR(
+ "I was not able to dump your data with a Dumper: " << e.what());
}
++count;
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::dump(UInt step) {
this->count = step;
this->dump();
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::dump(Real current_time, UInt step) {
this->dumper->setCurrentTime(current_time);
this->dump(step);
}
/* -------------------------------------------------------------------------- */
-void DumperIOHelper::registerMesh(const Mesh & mesh,
- UInt spatial_dimension,
- const GhostType & ghost_type,
- const ElementKind & element_kind) {
+void DumperIOHelper::registerMesh(const Mesh & mesh, UInt spatial_dimension,
+ const GhostType & ghost_type,
+ const ElementKind & element_kind) {
#if defined(AKANTU_IGFEM)
if (element_kind == _ek_igfem) {
registerField("connectivities",
- new dumper::IGFEMConnectivityField(mesh.getConnectivities(),
- spatial_dimension,
- ghost_type));
+ new dumper::IGFEMConnectivityField(
+ mesh.getConnectivities(), spatial_dimension, ghost_type));
} else
#endif
-
+
registerField("connectivities",
- new dumper::ElementalField<UInt>(mesh.getConnectivities(),
- spatial_dimension,
- ghost_type,
- element_kind));
+ new dumper::ElementalField<UInt>(mesh.getConnectivities(),
+ spatial_dimension,
+ ghost_type, element_kind));
- registerField("positions",
- new dumper::NodalField<Real>(mesh.getNodes()));
+ registerField("positions", new dumper::NodalField<Real>(mesh.getNodes()));
}
/* -------------------------------------------------------------------------- */
-void DumperIOHelper::registerFilteredMesh(const Mesh & mesh,
- const ElementTypeMapArray<UInt> & elements_filter,
- const Array<UInt> & nodes_filter,
- UInt spatial_dimension,
- const GhostType & ghost_type,
- const ElementKind & element_kind) {
+void DumperIOHelper::registerFilteredMesh(
+ const Mesh & mesh, const ElementTypeMapArray<UInt> & elements_filter,
+ const Array<UInt> & nodes_filter, UInt spatial_dimension,
+ const GhostType & ghost_type, const ElementKind & element_kind) {
auto * f_connectivities = new ElementTypeMapArrayFilter<UInt>(
mesh.getConnectivities(), elements_filter);
this->registerField("connectivities",
- new dumper::FilteredConnectivityField(*f_connectivities,
- nodes_filter,
- spatial_dimension,
- ghost_type,
- element_kind));
+ new dumper::FilteredConnectivityField(
+ *f_connectivities, nodes_filter, spatial_dimension,
+ ghost_type, element_kind));
- this->registerField("positions",new dumper::NodalField<Real,true>(
- mesh.getNodes(),
- 0,
- 0,
- &nodes_filter));
+ this->registerField("positions", new dumper::NodalField<Real, true>(
+ mesh.getNodes(), 0, 0, &nodes_filter));
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::registerField(const std::string & field_id,
dumper::Field * field) {
auto it = fields.find(field_id);
- if(it != fields.end()) {
- AKANTU_DEBUG_WARNING("The field " << field_id
- << " is already registered in this Dumper. Field ignored.");
+ if (it != fields.end()) {
+ AKANTU_DEBUG_WARNING(
+ "The field "
+ << field_id << " is already registered in this Dumper. Field ignored.");
return;
}
fields[field_id] = field;
field->registerToDumper(field_id, *dumper);
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::unRegisterField(const std::string & field_id) {
auto it = fields.find(field_id);
- if(it == fields.end()) {
- AKANTU_DEBUG_WARNING("The field " << field_id
- << " is not registered in this Dumper. Nothing to do.");
+ if (it == fields.end()) {
+ AKANTU_DEBUG_WARNING(
+ "The field " << field_id
+ << " is not registered in this Dumper. Nothing to do.");
return;
}
delete it->second;
fields.erase(it);
}
-
/* -------------------------------------------------------------------------- */
void DumperIOHelper::registerVariable(const std::string & variable_id,
dumper::VariableBase * variable) {
auto it = variables.find(variable_id);
- if(it != variables.end()) {
- AKANTU_DEBUG_WARNING("The Variable " << variable_id
- << " is already registered in this Dumper. Variable ignored.");
+ if (it != variables.end()) {
+ AKANTU_DEBUG_WARNING(
+ "The Variable "
+ << variable_id
+ << " is already registered in this Dumper. Variable ignored.");
return;
}
variables[variable_id] = variable;
variable->registerToDumper(variable_id, *dumper);
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::unRegisterVariable(const std::string & variable_id) {
auto it = variables.find(variable_id);
- if(it == variables.end()) {
- AKANTU_DEBUG_WARNING("The variable " << variable_id
- << " is not registered in this Dumper. Nothing to do.");
+ if (it == variables.end()) {
+ AKANTU_DEBUG_WARNING(
+ "The variable " << variable_id
+ << " is not registered in this Dumper. Nothing to do.");
return;
}
delete it->second;
variables.erase(it);
}
/* -------------------------------------------------------------------------- */
-template <ElementType type>
-iohelper::ElemType getIOHelperType() {
+template <ElementType type> iohelper::ElemType getIOHelperType() {
AKANTU_TO_IMPLEMENT();
return iohelper::MAX_ELEM_TYPE;
}
-template <>
-iohelper::ElemType getIOHelperType<_point_1>() { return iohelper::POINT_SET; }
-template <>
-iohelper::ElemType getIOHelperType<_segment_2>() { return iohelper::LINE1; }
-template <>
-iohelper::ElemType getIOHelperType<_segment_3>() { return iohelper::LINE2; }
+template <> iohelper::ElemType getIOHelperType<_point_1>() {
+ return iohelper::POINT_SET;
+}
+template <> iohelper::ElemType getIOHelperType<_segment_2>() {
+ return iohelper::LINE1;
+}
+template <> iohelper::ElemType getIOHelperType<_segment_3>() {
+ return iohelper::LINE2;
+}
-template <>
-iohelper::ElemType getIOHelperType<_triangle_3>() { return iohelper::TRIANGLE1; }
-template <>
-iohelper::ElemType getIOHelperType<_triangle_6>() { return iohelper::TRIANGLE2; }
+template <> iohelper::ElemType getIOHelperType<_triangle_3>() {
+ return iohelper::TRIANGLE1;
+}
+template <> iohelper::ElemType getIOHelperType<_triangle_6>() {
+ return iohelper::TRIANGLE2;
+}
-template <>
-iohelper::ElemType getIOHelperType<_quadrangle_4>() { return iohelper::QUAD1; }
-template <>
-iohelper::ElemType getIOHelperType<_quadrangle_8>() { return iohelper::QUAD2; }
+template <> iohelper::ElemType getIOHelperType<_quadrangle_4>() {
+ return iohelper::QUAD1;
+}
+template <> iohelper::ElemType getIOHelperType<_quadrangle_8>() {
+ return iohelper::QUAD2;
+}
-template <>
-iohelper::ElemType getIOHelperType<_tetrahedron_4>() { return iohelper::TETRA1; }
-template <>
-iohelper::ElemType getIOHelperType<_tetrahedron_10>() { return iohelper::TETRA2; }
+template <> iohelper::ElemType getIOHelperType<_tetrahedron_4>() {
+ return iohelper::TETRA1;
+}
+template <> iohelper::ElemType getIOHelperType<_tetrahedron_10>() {
+ return iohelper::TETRA2;
+}
-template <>
-iohelper::ElemType getIOHelperType<_hexahedron_8>() { return iohelper::HEX1; }
-template <>
-iohelper::ElemType getIOHelperType<_hexahedron_20>() { return iohelper::HEX2; }
+template <> iohelper::ElemType getIOHelperType<_hexahedron_8>() {
+ return iohelper::HEX1;
+}
+template <> iohelper::ElemType getIOHelperType<_hexahedron_20>() {
+ return iohelper::HEX2;
+}
-template <>
-iohelper::ElemType getIOHelperType<_pentahedron_6>() { return iohelper::PRISM1; }
-template <>
-iohelper::ElemType getIOHelperType<_pentahedron_15>() { return iohelper::PRISM2; }
+template <> iohelper::ElemType getIOHelperType<_pentahedron_6>() {
+ return iohelper::PRISM1;
+}
+template <> iohelper::ElemType getIOHelperType<_pentahedron_15>() {
+ return iohelper::PRISM2;
+}
#if defined(AKANTU_COHESIVE_ELEMENT)
-template <>
-iohelper::ElemType getIOHelperType<_cohesive_1d_2>() { return iohelper::COH1D2; }
-
-template <>
-iohelper::ElemType getIOHelperType<_cohesive_2d_4>() { return iohelper::COH2D4; }
-template <>
-iohelper::ElemType getIOHelperType<_cohesive_2d_6>() { return iohelper::COH2D6; }
-
-template <>
-iohelper::ElemType getIOHelperType<_cohesive_3d_6>() { return iohelper::COH3D6; }
-template <>
-iohelper::ElemType getIOHelperType<_cohesive_3d_12>() { return iohelper::COH3D12; }
-
-template <>
-iohelper::ElemType getIOHelperType<_cohesive_3d_8>() { return iohelper::COH3D8; }
-//template <>
-//iohelper::ElemType getIOHelperType<_cohesive_3d_16>() { return iohelper::COH3D16; }
+template <> iohelper::ElemType getIOHelperType<_cohesive_1d_2>() {
+ return iohelper::COH1D2;
+}
+
+template <> iohelper::ElemType getIOHelperType<_cohesive_2d_4>() {
+ return iohelper::COH2D4;
+}
+template <> iohelper::ElemType getIOHelperType<_cohesive_2d_6>() {
+ return iohelper::COH2D6;
+}
+
+template <> iohelper::ElemType getIOHelperType<_cohesive_3d_6>() {
+ return iohelper::COH3D6;
+}
+template <> iohelper::ElemType getIOHelperType<_cohesive_3d_12>() {
+ return iohelper::COH3D12;
+}
+
+template <> iohelper::ElemType getIOHelperType<_cohesive_3d_8>() {
+ return iohelper::COH3D8;
+}
+// template <>
+// iohelper::ElemType getIOHelperType<_cohesive_3d_16>() { return
+// iohelper::COH3D16; }
#endif
#if defined(AKANTU_STRUCTURAL_MECHANICS)
-template <>
-iohelper::ElemType getIOHelperType<_bernoulli_beam_2>() { return iohelper::BEAM2; }
-template <>
-iohelper::ElemType getIOHelperType<_bernoulli_beam_3>() { return iohelper::BEAM3; }
+template <> iohelper::ElemType getIOHelperType<_bernoulli_beam_2>() {
+ return iohelper::BEAM2;
+}
+template <> iohelper::ElemType getIOHelperType<_bernoulli_beam_3>() {
+ return iohelper::BEAM3;
+}
#endif
/* -------------------------------------------------------------------------- */
UInt getIOHelperType(ElementType type) {
UInt ioh_type = iohelper::MAX_ELEM_TYPE;
-#define GET_IOHELPER_TYPE(type) \
- ioh_type = getIOHelperType<type>();
+#define GET_IOHELPER_TYPE(type) ioh_type = getIOHelperType<type>();
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_IOHELPER_TYPE);
#undef GET_IOHELPER_TYPE
return ioh_type;
}
/* -------------------------------------------------------------------------- */
} // akantu
namespace iohelper {
- template<>
- DataType getDataType<akantu::NodeType>() { return _int; }
+template <> DataType getDataType<akantu::NodeType>() { return _int; }
}
diff --git a/src/io/dumper/dumper_iohelper.hh b/src/io/dumper/dumper_iohelper.hh
index b25b5fee7..862e79e98 100644
--- a/src/io/dumper/dumper_iohelper.hh
+++ b/src/io/dumper/dumper_iohelper.hh
@@ -1,158 +1,159 @@
/**
* @file dumper_iohelper.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
* @date last modification: Tue Jan 19 2016
*
* @brief Define the akantu dumper interface for IOhelper dumpers
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include "aka_array.hh"
#include "aka_common.hh"
#include "aka_types.hh"
-#include "aka_array.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_IOHELPER_HH__
#define __AKANTU_DUMPER_IOHELPER_HH__
/* -------------------------------------------------------------------------- */
namespace iohelper {
class Dumper;
}
namespace akantu {
UInt getIOHelperType(ElementType type);
namespace dumper {
-class Field;
-class VariableBase;
+ class Field;
+ class VariableBase;
}
class Mesh;
class DumperIOHelper {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DumperIOHelper();
virtual ~DumperIOHelper();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// register a given Mesh for the current dumper
virtual void registerMesh(const Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a filtered Mesh (provided filter lists) for the current dumper
virtual void
registerFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a Field object identified by name and provided by pointer
void registerField(const std::string & field_id, dumper::Field * field);
/// remove the Field identified by name from managed fields
void unRegisterField(const std::string & field_id);
/// register a VariableBase object identified by name and provided by pointer
void registerVariable(const std::string & variable_id,
dumper::VariableBase * variable);
/// remove a VariableBase identified by name from managed fields
void unRegisterVariable(const std::string & variable_id);
/// request dump: this calls IOHelper dump routine
virtual void dump();
/// request dump: this first set the current step and then calls IOHelper dump
/// routine
virtual void dump(UInt step);
/// request dump: this first set the current step and current time and then
/// calls IOHelper dump routine
virtual void dump(Real current_time, UInt step);
/// set the parallel context for IOHeper
virtual void setParallelContext(bool is_parallel);
/// set the directory where to generate the dumped files
virtual void setDirectory(const std::string & directory);
/// set the base name (needed by most IOHelper dumpers)
virtual void setBaseName(const std::string & basename);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// direct access to the iohelper::Dumper object
AKANTU_GET_MACRO(Dumper, *dumper, iohelper::Dumper &)
/// set the timestep of the iohelper::Dumper
void setTimeStep(Real time_step);
public:
/* ------------------------------------------------------------------------ */
/* Variable wrapper */
- template <typename T, bool is_scal = std::is_arithmetic<T>::value> class Variable;
+ template <typename T, bool is_scal = std::is_arithmetic<T>::value>
+ class Variable;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// internal iohelper::Dumper
iohelper::Dumper * dumper;
using Fields = std::map<std::string, dumper::Field *>;
- using Variables = std::map<std::string, dumper::VariableBase *> ;
+ using Variables = std::map<std::string, dumper::VariableBase *>;
/// list of registered fields to dump
Fields fields;
Variables variables;
/// dump counter
UInt count{0};
/// directory name
std::string directory;
/// filename prefix
std::string filename;
/// is time tracking activated in the dumper
bool time_activated{false};
};
} // akantu
#endif /* __AKANTU_DUMPER_IOHELPER_HH__ */
diff --git a/src/io/dumper/dumper_iohelper_paraview.cc b/src/io/dumper/dumper_iohelper_paraview.cc
index dd772f56b..4527586fa 100644
--- a/src/io/dumper/dumper_iohelper_paraview.cc
+++ b/src/io/dumper/dumper_iohelper_paraview.cc
@@ -1,67 +1,67 @@
/**
* @file dumper_paraview.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 26 2010
* @date last modification: Sun Oct 19 2014
*
* @brief implementations of DumperParaview
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "communicator.hh"
#include "dumper_iohelper_paraview.hh"
+#include "communicator.hh"
/* -------------------------------------------------------------------------- */
-#include <io_helper.hh>
#include <fstream>
+#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
namespace akantu {
DumperParaview::DumperParaview(const std::string & filename,
const std::string & directory, bool parallel)
: DumperIOHelper() {
iohelper::DumperParaview * dumper_para = new iohelper::DumperParaview();
dumper = dumper_para;
setBaseName(filename);
this->setParallelContext(parallel);
dumper_para->setMode(iohelper::BASE64);
dumper_para->setPrefix(directory);
dumper_para->init();
}
/* -------------------------------------------------------------------------- */
DumperParaview::~DumperParaview() = default;
/* -------------------------------------------------------------------------- */
void DumperParaview::setBaseName(const std::string & basename) {
DumperIOHelper::setBaseName(basename);
static_cast<iohelper::DumperParaview *>(dumper)->setVTUSubDirectory(filename +
"-VTU");
}
} // namespace akantu
diff --git a/src/io/dumper/dumper_iohelper_paraview.hh b/src/io/dumper/dumper_iohelper_paraview.hh
index eabc41a88..eac1bf120 100644
--- a/src/io/dumper/dumper_iohelper_paraview.hh
+++ b/src/io/dumper/dumper_iohelper_paraview.hh
@@ -1,74 +1,72 @@
/**
* @file dumper_paraview.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Dumper Paraview using IOHelper
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_PARAVIEW_HH__
#define __AKANTU_DUMPER_PARAVIEW_HH__
#include "dumper_iohelper.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class DumperParaview : public DumperIOHelper {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DumperParaview(const std::string & filename,
const std::string & directory = "./paraview",
bool parallel = true);
~DumperParaview() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
// void dump();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
void setBaseName(const std::string & basename) override;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
-
};
-
} // akantu
#endif /* __AKANTU_DUMPER_PARAVIEW_HH__ */
diff --git a/src/io/dumper/dumper_material_padders.hh b/src/io/dumper/dumper_material_padders.hh
index 16b10a77e..df66fb2cf 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,298 +1,289 @@
/**
* @file dumper_material_padders.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Fri Mar 27 2015
*
* @brief Material padders for plane stress/ plane strain
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
#define __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_padding_helper.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
class MaterialFunctor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- MaterialFunctor(const SolidMechanicsModel & model) :
- model(model),
- material_index(model.getMaterialByElement()),
- nb_data_per_element("nb_data_per_element", model.getID(), model.getMemoryID()),
- spatial_dimension(model.getSpatialDimension()){}
+ MaterialFunctor(const SolidMechanicsModel & model)
+ : model(model), material_index(model.getMaterialByElement()),
+ nb_data_per_element("nb_data_per_element", model.getID(),
+ model.getMemoryID()),
+ spatial_dimension(model.getSpatialDimension()) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
/// return the material from the global element index
const Material & getMaterialFromGlobalIndex(Element global_index) {
UInt index = global_index.element;
UInt material_id = material_index(global_index.type)(index);
const Material & material = model.getMaterial(material_id);
return material;
}
/// return the type of the element from global index
ElementType getElementTypeFromGlobalIndex(Element global_index) {
return global_index.type;
}
protected:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// all material padders probably need access to solid mechanics model
const SolidMechanicsModel & model;
/// they also need an access to the map from global ids to material id and
/// local ids
const ElementTypeMapArray<UInt> & material_index;
/// the number of data per element
const ElementTypeMapArray<UInt> nb_data_per_element;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
template <class T, class R>
class MaterialPadder : public MaterialFunctor,
public PadderGeneric<Vector<T>, R> {
public:
MaterialPadder(const SolidMechanicsModel & model) : MaterialFunctor(model) {}
};
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
-class StressPadder : public MaterialPadder<Real, Matrix<Real> > {
+class StressPadder : public MaterialPadder<Real, Matrix<Real>> {
public:
StressPadder(const SolidMechanicsModel & model)
- : MaterialPadder<Real, Matrix<Real> >(model) {
+ : MaterialPadder<Real, Matrix<Real>>(model) {
this->setPadding(3, 3);
}
inline Matrix<Real> func(const Vector<Real> & in,
Element global_element_id) override {
UInt nrows = spatial_dimension;
UInt ncols = in.size() / nrows;
UInt nb_data = in.size() / (nrows * nrows);
Matrix<Real> stress = this->pad(in, nrows, ncols, nb_data);
const Material & material =
this->getMaterialFromGlobalIndex(global_element_id);
bool plane_strain = true;
if (spatial_dimension == 2)
- plane_strain = !((bool) material.getParam("Plane_Stress"));
+ plane_strain = !((bool)material.getParam("Plane_Stress"));
if (plane_strain) {
Real nu = material.getParam("nu");
for (UInt d = 0; d < nb_data; ++d) {
stress(2, 2 + 3 * d) =
nu * (stress(0, 0 + 3 * d) + stress(1, 1 + 3 * d));
}
}
return stress;
}
UInt getDim() override { return 9; };
- UInt getNbComponent(UInt /*old_nb_comp*/) override {
- return this->getDim();
- };
+ UInt getNbComponent(UInt /*old_nb_comp*/) override { return this->getDim(); };
};
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
class StrainPadder : public MaterialFunctor,
- public PadderGeneric<Matrix<Real>, Matrix<Real> > {
+ public PadderGeneric<Matrix<Real>, Matrix<Real>> {
public:
StrainPadder(const SolidMechanicsModel & model) : MaterialFunctor(model) {
this->setPadding(3, 3);
}
inline Matrix<Real> func(const Matrix<Real> & in,
Element global_element_id) override {
UInt nrows = spatial_dimension;
UInt nb_data = in.size() / (nrows * nrows);
Matrix<Real> strain = this->pad(in, nb_data);
const Material & material =
this->getMaterialFromGlobalIndex(global_element_id);
bool plane_stress = material.getParam("Plane_Stress");
if (plane_stress) {
Real nu = material.getParam("nu");
for (UInt d = 0; d < nb_data; ++d) {
strain(2, 2 + 3 * d) =
nu / (nu - 1) * (strain(0, 0 + 3 * d) + strain(1, 1 + 3 * d));
}
}
return strain;
}
UInt getDim() override { return 9; };
- UInt getNbComponent(UInt /*old_nb_comp*/) override {
- return this->getDim();
- };
+ UInt getNbComponent(UInt /*old_nb_comp*/) override { return this->getDim(); };
};
/* -------------------------------------------------------------------------- */
template <bool green_strain>
class ComputeStrain : public MaterialFunctor,
- public ComputeFunctor<Vector<Real>, Matrix<Real> > {
+ public ComputeFunctor<Vector<Real>, Matrix<Real>> {
public:
ComputeStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) {}
- inline Matrix<Real> func(const Vector<Real> & in, Element /*global_element_id*/) override {
+ inline Matrix<Real> func(const Vector<Real> & in,
+ Element /*global_element_id*/) override {
UInt nrows = spatial_dimension;
UInt ncols = in.size() / nrows;
UInt nb_data = in.size() / (nrows * nrows);
Matrix<Real> ret_all_strain(nrows, ncols);
Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
Tensor3<Real> all_strain(ret_all_strain.storage(), nrows, nrows, nb_data);
for (UInt d = 0; d < nb_data; ++d) {
Matrix<Real> grad_u = all_grad_u(d);
Matrix<Real> strain = all_strain(d);
if (spatial_dimension == 2) {
if (green_strain)
Material::gradUToGreenStrain<2>(grad_u, strain);
else
Material::gradUToEpsilon<2>(grad_u, strain);
} else if (spatial_dimension == 3) {
if (green_strain)
Material::gradUToGreenStrain<3>(grad_u, strain);
else
Material::gradUToEpsilon<3>(grad_u, strain);
}
}
return ret_all_strain;
}
UInt getDim() override { return spatial_dimension * spatial_dimension; };
- UInt getNbComponent(UInt /*old_nb_comp*/) override {
- return this->getDim();
- };
+ UInt getNbComponent(UInt /*old_nb_comp*/) override { return this->getDim(); };
};
/* -------------------------------------------------------------------------- */
template <bool green_strain>
class ComputePrincipalStrain
: public MaterialFunctor,
- public ComputeFunctor<Vector<Real>, Matrix<Real> > {
+ public ComputeFunctor<Vector<Real>, Matrix<Real>> {
public:
ComputePrincipalStrain(const SolidMechanicsModel & model)
: MaterialFunctor(model) {}
inline Matrix<Real> func(const Vector<Real> & in,
Element /*global_element_id*/) override {
UInt nrows = spatial_dimension;
UInt nb_data = in.size() / (nrows * nrows);
Matrix<Real> ret_all_strain(nrows, nb_data);
Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
Matrix<Real> strain(nrows, nrows);
for (UInt d = 0; d < nb_data; ++d) {
Matrix<Real> grad_u = all_grad_u(d);
if (spatial_dimension == 2) {
if (green_strain)
Material::gradUToGreenStrain<2>(grad_u, strain);
else
Material::gradUToEpsilon<2>(grad_u, strain);
} else if (spatial_dimension == 3) {
if (green_strain)
Material::gradUToGreenStrain<3>(grad_u, strain);
else
Material::gradUToEpsilon<3>(grad_u, strain);
}
Vector<Real> principal_strain(ret_all_strain(d));
strain.eig(principal_strain);
}
return ret_all_strain;
}
UInt getDim() override { return spatial_dimension; };
- UInt getNbComponent(UInt /*old_nb_comp*/) override {
- return this->getDim();
- };
+ UInt getNbComponent(UInt /*old_nb_comp*/) override { return this->getDim(); };
};
/* -------------------------------------------------------------------------- */
class ComputeVonMisesStress
: public MaterialFunctor,
- public ComputeFunctor<Vector<Real>, Vector<Real> > {
+ public ComputeFunctor<Vector<Real>, Vector<Real>> {
public:
ComputeVonMisesStress(const SolidMechanicsModel & model)
: MaterialFunctor(model) {}
inline Vector<Real> func(const Vector<Real> & in,
Element /*global_element_id*/) override {
UInt nrows = spatial_dimension;
UInt nb_data = in.size() / (nrows * nrows);
Vector<Real> von_mises_stress(nb_data);
Matrix<Real> deviatoric_stress(3, 3);
for (UInt d = 0; d < nb_data; ++d) {
Matrix<Real> cauchy_stress(in.storage() + d * nrows * nrows, nrows,
nrows);
von_mises_stress(d) = Material::stressToVonMises(cauchy_stress);
}
return von_mises_stress;
}
UInt getDim() override { return 1; };
- UInt getNbComponent(UInt /*old_nb_comp*/) override {
- return this->getDim();
- };
+ UInt getNbComponent(UInt /*old_nb_comp*/) override { return this->getDim(); };
};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
} // akantu
#endif /* __AKANTU_DUMPER_MATERIAL_PADDERS_HH__ */
diff --git a/src/io/dumper/dumper_nodal_field.hh b/src/io/dumper/dumper_nodal_field.hh
index c894ce307..bda109fb0 100644
--- a/src/io/dumper/dumper_nodal_field.hh
+++ b/src/io/dumper/dumper_nodal_field.hh
@@ -1,250 +1,249 @@
/**
* @file dumper_nodal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Oct 26 2012
* @date last modification: Tue Jan 06 2015
*
* @brief Description of nodal fields
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_NODAL_FIELD_HH__
#define __AKANTU_DUMPER_NODAL_FIELD_HH__
#include "dumper_field.hh"
#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
// This represents a iohelper compatible field
-template<typename T, bool filtered = false,
- class Container = Array<T>, class Filter = Array<UInt> >
+template <typename T, bool filtered = false, class Container = Array<T>,
+ class Filter = Array<UInt>>
class NodalField;
/* -------------------------------------------------------------------------- */
-template<typename T, class Container, class Filter>
+template <typename T, class Container, class Filter>
class NodalField<T, false, Container, Filter> : public dumper::Field {
public:
/* ------------------------------------------------------------------------ */
/* Typedefs */
- /* ------------------------------------------------------------------------ */
-
+ /* ------------------------------------------------------------------------ */
+
/// associated iterator with any nodal field (non filetered)
- class iterator : public iohelper::iterator< T, iterator, Vector<T> > {
+ class iterator : public iohelper::iterator<T, iterator, Vector<T>> {
public:
iterator(T * vect, UInt offset, UInt n, UInt stride,
__attribute__((unused)) const UInt * filter = nullptr)
:
- internal_it(vect), offset(offset), n(n), stride(stride) {}
+ internal_it(vect),
+ offset(offset), n(n), stride(stride) {}
bool operator!=(const iterator & it) const override {
return internal_it != it.internal_it;
}
iterator & operator++() override {
internal_it += offset;
return *this;
};
Vector<T> operator*() override {
return Vector<T>(internal_it + stride, n);
};
private:
T * internal_it;
UInt offset, n, stride;
};
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
NodalField(const Container & field, UInt n = 0, UInt stride = 0,
__attribute__((unused)) const Filter * filter = nullptr)
:
- field(field), n(n), stride(stride), padding(0) {
+ field(field),
+ n(n), stride(stride), padding(0) {
AKANTU_DEBUG_ASSERT(filter == nullptr,
"Filter passed to unfiltered NodalField!");
- if(n == 0) { this->n = field.getNbComponent() - stride; }
+ if (n == 0) {
+ this->n = field.getNbComponent() - stride;
+ }
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) override {
dumper.addNodeDataField(id, *this);
}
inline iterator begin() {
return iterator(field.storage(), field.getNbComponent(), n, stride);
}
- inline iterator end () {
- return iterator(field.storage() + field.getNbComponent()*field.size(),
- field.getNbComponent(), n, stride);
+ inline iterator end() {
+ return iterator(field.storage() + field.getNbComponent() * field.size(),
+ field.getNbComponent(), n, stride);
}
bool isHomogeneous() override { return true; }
void checkHomogeneity() override { this->homogeneous = true; }
virtual UInt getDim() {
- if(this->padding) return this->padding;
- else return n;
+ if (this->padding)
+ return this->padding;
+ else
+ return n;
}
- void setPadding(UInt padding){this->padding = padding;}
+ void setPadding(UInt padding) { this->padding = padding; }
UInt size() { return field.size(); }
iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
private:
const Container & field;
UInt n, stride;
UInt padding;
};
-
-
/* -------------------------------------------------------------------------- */
-template<typename T, class Container, class Filter>
+template <typename T, class Container, class Filter>
class NodalField<T, true, Container, Filter> : public dumper::Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
- /* ------------------------------------------------------------------------ */
-
+ /* ------------------------------------------------------------------------ */
+
public:
- class iterator : public iohelper::iterator< T, iterator, Vector<T> > {
+ class iterator : public iohelper::iterator<T, iterator, Vector<T>> {
public:
- iterator(T * const vect, UInt _offset, UInt _n,
- UInt _stride, const UInt * filter) :
+ iterator(T * const vect, UInt _offset, UInt _n, UInt _stride,
+ const UInt * filter)
+ :
- internal_it(vect), offset(_offset), n(_n), stride(_stride),
- filter(filter) {}
+ internal_it(vect),
+ offset(_offset), n(_n), stride(_stride), filter(filter) {}
bool operator!=(const iterator & it) const override {
return filter != it.filter;
}
iterator & operator++() override {
++filter;
return *this;
}
Vector<T> operator*() override {
return Vector<T>(internal_it + *(filter)*offset + stride, n);
}
+
private:
T * const internal_it;
UInt offset, n, stride;
const UInt * filter;
};
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
- NodalField(const Container & _field,
- UInt _n = 0, UInt _stride = 0,
+ NodalField(const Container & _field, UInt _n = 0, UInt _stride = 0,
const Filter * filter = NULL)
- : field(_field), n(_n), stride(_stride), filter(filter), padding(0) {
+ : field(_field), n(_n), stride(_stride), filter(filter), padding(0) {
AKANTU_DEBUG_ASSERT(this->filter != nullptr,
"No filter passed to filtered NodalField!");
- AKANTU_DEBUG_ASSERT(this->filter->getNbComponent()==1,
- "Multi-component filter given to NodalField ("
- << this->filter->getNbComponent()
- << " components detected, sould be 1");
- if(n == 0) {
+ AKANTU_DEBUG_ASSERT(this->filter->getNbComponent() == 1,
+ "Multi-component filter given to NodalField ("
+ << this->filter->getNbComponent()
+ << " components detected, sould be 1");
+ if (n == 0) {
this->n = field.getNbComponent() - stride;
}
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) override {
dumper.addNodeDataField(id, *this);
}
inline iterator begin() {
- return iterator(field.storage(), field.getNbComponent(),
- n, stride, filter->storage());
+ return iterator(field.storage(), field.getNbComponent(), n, stride,
+ filter->storage());
}
inline iterator end() {
- return iterator(field.storage(), field.getNbComponent(),
- n, stride, filter->storage()+filter->size());
+ return iterator(field.storage(), field.getNbComponent(), n, stride,
+ filter->storage() + filter->size());
}
bool isHomogeneous() override { return true; }
void checkHomogeneity() override { this->homogeneous = true; }
virtual UInt getDim() {
- if(this->padding) return this->padding;
- else return n;
+ if (this->padding)
+ return this->padding;
+ else
+ return n;
}
- void setPadding(UInt padding){this->padding = padding;}
-
- UInt size() {
- return filter->size();
- }
+ void setPadding(UInt padding) { this->padding = padding; }
- iohelper::DataType getDataType() {
- return iohelper::getDataType<T>();
- }
+ UInt size() { return filter->size(); }
+ iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
+
private:
const Container & field;
UInt n, stride;
const Filter * filter;
UInt padding;
};
-
__END_AKANTU_DUMPER__
} // akantu
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_DUMPER_NODAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_padding_helper.hh b/src/io/dumper/dumper_padding_helper.hh
index f36ea33c3..5a9f75fc4 100644
--- a/src/io/dumper/dumper_padding_helper.hh
+++ b/src/io/dumper/dumper_padding_helper.hh
@@ -1,147 +1,132 @@
/**
* @file dumper_padding_helper.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Sun Oct 19 2014
*
* @brief Padding helper for field iterators
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_PADDING_HELPER_HH__
#define __AKANTU_DUMPER_PADDING_HELPER_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_compute.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
class PadderInterface {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- PadderInterface(){
+ PadderInterface() {
padding_m = 0;
padding_n = 0;
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
-
public:
-
-
- void setPadding(UInt m, UInt n = 0){
+ void setPadding(UInt m, UInt n = 0) {
padding_m = m;
padding_n = n;
}
- virtual UInt getPaddedDim(UInt nb_data) {
- return nb_data;
- }
-
+ virtual UInt getPaddedDim(UInt nb_data) { return nb_data; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
-
/// padding informations
UInt padding_n, padding_m;
};
/* -------------------------------------------------------------------------- */
-
-template<class input_type, class output_type>
-class PadderGeneric :
- public ComputeFunctor<input_type, output_type > , public PadderInterface {
+template <class input_type, class output_type>
+class PadderGeneric : public ComputeFunctor<input_type, output_type>,
+ public PadderInterface {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- PadderGeneric() : PadderInterface(){}
+ PadderGeneric() : PadderInterface() {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
-
public:
-
-
- inline output_type pad(const input_type & in,__attribute__((unused)) UInt nb_data) {
- return in; // trick due to the fact that IOHelper padds the vectors (avoid a copy of data)
+ inline output_type pad(const input_type & in,
+ __attribute__((unused)) UInt nb_data) {
+ return in; // trick due to the fact that IOHelper padds the vectors (avoid a
+ // copy of data)
}
-
};
/* -------------------------------------------------------------------------- */
-
-template<class T>
-class PadderGeneric<Vector<T>, Matrix<T> > :
- public ComputeFunctor<Vector<T>, Matrix<T> > , public PadderInterface {
+template <class T>
+class PadderGeneric<Vector<T>, Matrix<T>>
+ : public ComputeFunctor<Vector<T>, Matrix<T>>, public PadderInterface {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- inline Matrix<T> pad(const Vector<T> & _in,
- UInt nrows, UInt ncols,
+ inline Matrix<T> pad(const Vector<T> & _in, UInt nrows, UInt ncols,
UInt nb_data) {
Matrix<T> in(_in.storage(), nrows, ncols);
- if(padding_m <= nrows && padding_n*nb_data <= ncols)
+ if (padding_m <= nrows && padding_n * nb_data <= ncols)
return in;
else {
Matrix<T> ret(padding_m, padding_n * nb_data);
UInt nb_cols_per_data = in.cols() / nb_data;
for (UInt d = 0; d < nb_data; ++d)
for (UInt i = 0; i < in.rows(); ++i)
for (UInt j = 0; j < nb_cols_per_data; ++j)
ret(i, j + d * padding_n) = in(i, j + d * nb_cols_per_data);
return ret;
}
}
};
/* -------------------------------------------------------------------------- */
-
} // akantu
__END_AKANTU_DUMPER__
#endif /* __AKANTU_DUMPER_PADDING_HELPER_HH__ */
diff --git a/src/io/dumper/dumper_text.cc b/src/io/dumper/dumper_text.cc
index 98acb58da..ece87f179 100644
--- a/src/io/dumper/dumper_text.cc
+++ b/src/io/dumper/dumper_text.cc
@@ -1,113 +1,113 @@
/**
* @file dumper_text.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief implementation of text dumper
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <io_helper.hh>
#include "dumper_text.hh"
+#include "communicator.hh"
#include "dumper_nodal_field.hh"
#include "mesh.hh"
-#include "communicator.hh"
+#include <io_helper.hh>
namespace akantu {
/* -------------------------------------------------------------------------- */
DumperText::DumperText(const std::string & basename,
iohelper::TextDumpMode mode, bool parallel)
: DumperIOHelper() {
AKANTU_DEBUG_IN();
iohelper::DumperText * dumper_text = new iohelper::DumperText(mode);
this->dumper = dumper_text;
this->setBaseName(basename);
this->setParallelContext(parallel);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DumperText::registerMesh(const Mesh & mesh,
__attribute__((unused)) UInt spatial_dimension,
__attribute__((unused))
const GhostType & ghost_type,
__attribute__((unused))
const ElementKind & element_kind) {
registerField("position", new dumper::NodalField<Real>(mesh.getNodes()));
// in parallel we need node type
UInt nb_proc = mesh.getCommunicator().getNbProc();
if (nb_proc > 1) {
registerField("nodes_type",
new dumper::NodalField<NodeType>(mesh.getNodesType()));
}
}
/* -------------------------------------------------------------------------- */
void DumperText::registerFilteredMesh(
const Mesh & mesh,
__attribute__((unused)) const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
__attribute__((unused)) UInt spatial_dimension,
__attribute__((unused)) const GhostType & ghost_type,
__attribute__((unused)) const ElementKind & element_kind) {
registerField("position", new dumper::NodalField<Real, true>(
mesh.getNodes(), 0, 0, &nodes_filter));
// in parallel we need node type
UInt nb_proc = mesh.getCommunicator().getNbProc();
if (nb_proc > 1) {
registerField("nodes_type", new dumper::NodalField<NodeType, true>(
mesh.getNodesType(), 0, 0, &nodes_filter));
}
}
/* -------------------------------------------------------------------------- */
void DumperText::setBaseName(const std::string & basename) {
AKANTU_DEBUG_IN();
DumperIOHelper::setBaseName(basename);
static_cast<iohelper::DumperText *>(this->dumper)
->setDataSubDirectory(this->filename + "-DataFiles");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DumperText::setPrecision(UInt prec) {
AKANTU_DEBUG_IN();
static_cast<iohelper::DumperText *>(this->dumper)->setPrecision(prec);
AKANTU_DEBUG_OUT();
}
} // akantu
diff --git a/src/io/dumper/dumper_text.hh b/src/io/dumper/dumper_text.hh
index 7758e2e54..d8e253b31 100644
--- a/src/io/dumper/dumper_text.hh
+++ b/src/io/dumper/dumper_text.hh
@@ -1,89 +1,88 @@
/**
* @file dumper_text.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief to dump into a text file
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_iohelper.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_TEXT_HH__
#define __AKANTU_DUMPER_TEXT_HH__
/* -------------------------------------------------------------------------- */
#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
namespace akantu {
class DumperText : public DumperIOHelper {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
DumperText(const std::string & basename = "dumper_text",
- iohelper::TextDumpMode mode = iohelper::_tdm_space,
- bool parallel = true);
+ iohelper::TextDumpMode mode = iohelper::_tdm_space,
+ bool parallel = true);
~DumperText() override = default;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void
registerMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) override;
void registerFilteredMesh(
const Mesh & mesh, const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined) override;
void setBaseName(const std::string & basename) override;
private:
void registerNodeTypeField();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
void setPrecision(UInt prec);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
} // akantu
#endif /* __AKANTU_DUMPER_TEXT_HH__ */
diff --git a/src/io/dumper/dumper_type_traits.hh b/src/io/dumper/dumper_type_traits.hh
index 83e63954e..e2f8edf3c 100644
--- a/src/io/dumper/dumper_type_traits.hh
+++ b/src/io/dumper/dumper_type_traits.hh
@@ -1,99 +1,90 @@
/**
* @file dumper_type_traits.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Mon Sep 21 2015
*
* @brief Type traits for field properties
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_TYPE_TRAITS_HH__
#define __AKANTU_DUMPER_TYPE_TRAITS_HH__
/* -------------------------------------------------------------------------- */
#include "element_type_map.hh"
#include "element_type_map_filter.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-template <class data, class ret, class field>
-struct TypeTraits {
+template <class data, class ret, class field> struct TypeTraits {
//! the stored data (real, int, uint, ...)
using data_type = data;
//! the type returned by the operator *
using return_type = ret;
//! the field type (ElementTypeMap or ElementTypeMapFilter)
using field_type = field;
//! the type over which we iterate
using it_type = typename field_type::type;
//! the type of array (Array<T> or ArrayFilter<T>)
using array_type = typename field_type::array_type;
//! the iterator over the array
using array_iterator = typename array_type::const_vector_iterator;
};
/* -------------------------------------------------------------------------- */
// specialization for the case in which input and output types are the same
template <class T, template <class> class ret, bool filtered>
-struct SingleType
- : public TypeTraits<T,ret<T>,ElementTypeMapArray<T> >{
-
-};
+struct SingleType : public TypeTraits<T, ret<T>, ElementTypeMapArray<T>> {};
/* -------------------------------------------------------------------------- */
// same as before but for filtered data
template <class T, template <class> class ret>
-struct SingleType<T,ret,true> :
- public TypeTraits<T,ret<T>, ElementTypeMapArrayFilter<T> >{
-
-};
+struct SingleType<T, ret, true>
+ : public TypeTraits<T, ret<T>, ElementTypeMapArrayFilter<T>> {};
/* -------------------------------------------------------------------------- */
// specialization for the case in which input and output types are different
-template <class it_type, class data_type, template <class> class ret,
- bool filtered>
-struct DualType
- : public TypeTraits<data_type,ret<data_type>, ElementTypeMapArray<it_type> >{
-};
+template <class it_type, class data_type, template <class> class ret,
+ bool filtered>
+struct DualType : public TypeTraits<data_type, ret<data_type>,
+ ElementTypeMapArray<it_type>> {};
/* -------------------------------------------------------------------------- */
// same as before but for filtered data
-template <class it_type, class data_type,template <class> class ret>
-struct DualType<it_type,data_type,ret,true> :
- public TypeTraits<data_type,ret<data_type>, ElementTypeMapArrayFilter<it_type> >{
-
-};
+template <class it_type, class data_type, template <class> class ret>
+struct DualType<it_type, data_type, ret, true>
+ : public TypeTraits<data_type, ret<data_type>,
+ ElementTypeMapArrayFilter<it_type>> {};
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
} // akantu
/* -------------------------------------------------------------------------- */
-
#endif /* __AKANTU_DUMPER_TYPE_TRAITS_HH__ */
diff --git a/src/io/dumper/dumper_variable.hh b/src/io/dumper/dumper_variable.hh
index 770afb217..5d322273b 100644
--- a/src/io/dumper/dumper_variable.hh
+++ b/src/io/dumper/dumper_variable.hh
@@ -1,116 +1,119 @@
/**
* @file dumper_variable.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Tue Jun 04 2013
* @date last modification: Sun Oct 19 2014
*
* @brief template of variable
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include <type_traits>
-
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__
#define __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace dumper {
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
-/// Variable interface
-class VariableBase {
-public:
- VariableBase() = default;
- virtual ~VariableBase() = default;
- virtual void registerToDumper(const std::string & id,
- iohelper::Dumper & dumper) = 0;
-};
+ /// Variable interface
+ class VariableBase {
+ public:
+ VariableBase() = default;
+ virtual ~VariableBase() = default;
+ virtual void registerToDumper(const std::string & id,
+ iohelper::Dumper & dumper) = 0;
+ };
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
-template <typename T, bool is_scal = std::is_arithmetic<T>::value>
-class Variable : public VariableBase {
-public:
- Variable(const T & t) : vari(t) {}
+ template <typename T, bool is_scal = std::is_arithmetic<T>::value>
+ class Variable : public VariableBase {
+ public:
+ Variable(const T & t) : vari(t) {}
- void registerToDumper(const std::string & id,
- iohelper::Dumper & dumper) override {
- dumper.addVariable(id, *this);
- }
+ void registerToDumper(const std::string & id,
+ iohelper::Dumper & dumper) override {
+ dumper.addVariable(id, *this);
+ }
- const T & operator[](UInt i) const { return vari[i]; }
+ const T & operator[](UInt i) const { return vari[i]; }
- UInt getDim() { return vari.size(); }
- iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
+ UInt getDim() { return vari.size(); }
+ iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
-protected:
- const T & vari;
-};
+ protected:
+ const T & vari;
+ };
-/* -------------------------------------------------------------------------- */
-template <typename T> class Variable<Vector<T>, false> : public VariableBase {
-public:
- Variable(const Vector<T> & t) : vari(t) {}
+ /* --------------------------------------------------------------------------
+ */
+ template <typename T> class Variable<Vector<T>, false> : public VariableBase {
+ public:
+ Variable(const Vector<T> & t) : vari(t) {}
- void registerToDumper(const std::string & id,
- iohelper::Dumper & dumper) override {
- dumper.addVariable(id, *this);
- }
+ void registerToDumper(const std::string & id,
+ iohelper::Dumper & dumper) override {
+ dumper.addVariable(id, *this);
+ }
- const T & operator[](UInt i) const { return vari[i]; }
+ const T & operator[](UInt i) const { return vari[i]; }
- UInt getDim() { return vari.size(); }
- iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
+ UInt getDim() { return vari.size(); }
+ iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
-protected:
- const Vector<T> & vari;
-};
+ protected:
+ const Vector<T> & vari;
+ };
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
-template <typename T> class Variable<T, true> : public VariableBase {
-public:
- Variable(const T & t) : vari(t) {}
+ template <typename T> class Variable<T, true> : public VariableBase {
+ public:
+ Variable(const T & t) : vari(t) {}
- void registerToDumper(const std::string & id,
- iohelper::Dumper & dumper) override {
- dumper.addVariable(id, *this);
- }
+ void registerToDumper(const std::string & id,
+ iohelper::Dumper & dumper) override {
+ dumper.addVariable(id, *this);
+ }
- const T & operator[](__attribute__((unused)) UInt i) const { return vari; }
+ const T & operator[](__attribute__((unused)) UInt i) const { return vari; }
- UInt getDim() { return 1; }
- iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
+ UInt getDim() { return 1; }
+ iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
-protected:
- const T & vari;
-};
+ protected:
+ const T & vari;
+ };
} // namespace dumper
} // namespace akantu
#endif /* __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__ */
diff --git a/src/io/mesh_io/mesh_io_abaqus.cc b/src/io/mesh_io/mesh_io_abaqus.cc
index 5788b76db..a9f7714b4 100644
--- a/src/io/mesh_io/mesh_io_abaqus.cc
+++ b/src/io/mesh_io/mesh_io_abaqus.cc
@@ -1,475 +1,475 @@
/**
* @file mesh_io_abaqus.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Fri Dec 11 2015
*
* @brief read a mesh from an abaqus input file
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// std library header files
#include <fstream>
// akantu header files
#include "mesh.hh"
#include "mesh_io_abaqus.hh"
#include "mesh_utils.hh"
#include "element_group.hh"
#include "node_group.hh"
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined(__clang__) // test clang to be sure that when we test for gnu it
- // is only gnu
+// is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
#define GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION > 40600
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
/* -------------------------------------------------------------------------- */
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
MeshIOAbaqus::MeshIOAbaqus() = default;
/* -------------------------------------------------------------------------- */
MeshIOAbaqus::~MeshIOAbaqus() = default;
/* -------------------------------------------------------------------------- */
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace lbs = boost::spirit::qi::labels;
namespace phx = boost::phoenix;
/* -------------------------------------------------------------------------- */
void element_read(Mesh & mesh, const ElementType & type, UInt id,
const std::vector<Int> & conn,
const std::map<UInt, UInt> & nodes_mapping,
std::map<UInt, Element> & elements_mapping) {
Vector<UInt> tmp_conn(Mesh::getNbNodesPerElement(type));
AKANTU_DEBUG_ASSERT(conn.size() == tmp_conn.size(),
"The nodes in the Abaqus file have too many coordinates"
<< " for the mesh you try to fill.");
mesh.addConnectivityType(type);
Array<UInt> & connectivity = mesh.getConnectivity(type);
UInt i = 0;
for (auto it = conn.begin(); it != conn.end(); ++it) {
auto nit = nodes_mapping.find(*it);
AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
"There is an unknown node in the connectivity.");
tmp_conn[i++] = nit->second;
}
Element el{type, connectivity.size(), _not_ghost};
elements_mapping[id] = el;
connectivity.push_back(tmp_conn);
}
void node_read(Mesh & mesh, UInt id, const std::vector<Real> & pos,
std::map<UInt, UInt> & nodes_mapping) {
Vector<Real> tmp_pos(mesh.getSpatialDimension());
UInt i = 0;
for (auto it = pos.begin(); it != pos.end() || i < mesh.getSpatialDimension();
++it)
tmp_pos[i++] = *it;
nodes_mapping[id] = mesh.getNbNodes();
mesh.getNodes().push_back(tmp_pos);
}
/* ------------------------------------------------------------------------ */
void add_element_to_group(ElementGroup * el_grp, UInt element,
const std::map<UInt, Element> & elements_mapping) {
auto eit = elements_mapping.find(element);
AKANTU_DEBUG_ASSERT(eit != elements_mapping.end(),
"There is an unknown element ("
<< element << ") in the in the ELSET "
<< el_grp->getName() << ".");
el_grp->add(eit->second, true, false);
}
ElementGroup * element_group_create(Mesh & mesh, const ID & name) {
auto eg_it = mesh.element_group_find(name);
if (eg_it != mesh.element_group_end()) {
return eg_it->second;
} else {
return &mesh.createElementGroup(name, _all_dimensions);
}
}
NodeGroup * node_group_create(Mesh & mesh, const ID & name) {
auto ng_it = mesh.node_group_find(name);
if (ng_it != mesh.node_group_end()) {
return ng_it->second;
} else {
return &mesh.createNodeGroup(name, mesh.getSpatialDimension());
}
}
void add_node_to_group(NodeGroup * node_grp, UInt node,
const std::map<UInt, UInt> & nodes_mapping) {
auto nit = nodes_mapping.find(node);
AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
"There is an unknown node in the in the NSET "
<< node_grp->getName() << ".");
node_grp->add(nit->second, false);
}
void optimize_group(NodeGroup * grp) { grp->optimize(); }
void optimize_element_group(ElementGroup * grp) { grp->optimize(); }
/* -------------------------------------------------------------------------- */
template <class Iterator> struct AbaqusSkipper : qi::grammar<Iterator> {
AbaqusSkipper() : AbaqusSkipper::base_type(skip, "abaqus_skipper") {
/* clang-format off */
skip
= (ascii::space - spirit::eol)
| "**" >> *(qi::char_ - spirit::eol) >> spirit::eol
;
/* clang-format on */
}
qi::rule<Iterator> skip;
};
/* -------------------------------------------------------------------------- */
template <class Iterator, typename Skipper = AbaqusSkipper<Iterator>>
struct AbaqusMeshGrammar : qi::grammar<Iterator, void(), Skipper> {
public:
AbaqusMeshGrammar(Mesh & mesh)
: AbaqusMeshGrammar::base_type(start, "abaqus_mesh_reader"), mesh(mesh) {
/* clang-format off */
start
= *(
(qi::char_('*')
> ( (qi::no_case[ qi::lit("node output") ] > any_section)
| (qi::no_case[ qi::lit("element output") ] > any_section)
| (qi::no_case[ qi::lit("node") ] > nodes)
| (qi::no_case[ qi::lit("element") ] > elements)
| (qi::no_case[ qi::lit("heading") ] > header)
| (qi::no_case[ qi::lit("elset") ] > elements_set)
| (qi::no_case[ qi::lit("nset") ] > nodes_set)
| (qi::no_case[ qi::lit("material") ] > material)
| (keyword > any_section)
)
)
| spirit::eol
)
;
header
= spirit::eol
> *any_line
;
nodes
= *(qi::char_(',') >> option)
>> spirit::eol
>> *( (qi::int_
> node_position) [ phx::bind(&node_read,
phx::ref(mesh),
lbs::_1,
lbs::_2,
phx::ref(abaqus_nodes_to_akantu)) ]
>> spirit::eol
)
;
elements
= (
( qi::char_(',') >> qi::no_case[qi::lit("type")] >> '='
>> abaqus_element_type [ lbs::_a = lbs::_1 ]
)
^ *(qi::char_(',') >> option)
)
>> spirit::eol
>> *( (qi::int_
> connectivity) [ phx::bind(&element_read,
phx::ref(mesh),
lbs::_a,
lbs::_1,
lbs::_2,
phx::cref(abaqus_nodes_to_akantu),
phx::ref(abaqus_elements_to_akantu)) ]
>> spirit::eol
)
;
elements_set
= (
(
( qi::char_(',') >> qi::no_case[ qi::lit("elset") ] >> '='
>> value [ lbs::_a = phx::bind<ElementGroup *>(&element_group_create,
phx::ref(mesh),
lbs::_1) ]
)
^ *(qi::char_(',') >> option)
)
>> spirit::eol
>> qi::skip
(qi::char_(',') | qi::space)
[ +(qi::int_ [ phx::bind(&add_element_to_group,
lbs::_a,
lbs::_1,
phx::cref(abaqus_elements_to_akantu)
)
]
)
]
) [ phx::bind(&optimize_element_group, lbs::_a) ]
;
nodes_set
= (
(
( qi::char_(',')
>> qi::no_case[ qi::lit("nset") ] >> '='
>> value [ lbs::_a = phx::bind<NodeGroup *>(&node_group_create, phx::ref(mesh), lbs::_1) ]
)
^ *(qi::char_(',') >> option)
)
>> spirit::eol
>> qi::skip
(qi::char_(',') | qi::space)
[ +(qi::int_ [ phx::bind(&add_node_to_group,
lbs::_a,
lbs::_1,
phx::cref(abaqus_nodes_to_akantu)
)
]
)
]
) [ phx::bind(&optimize_group, lbs::_a) ]
;
material
= (
( qi::char_(',') >> qi::no_case[ qi::lit("name") ] >> '='
>> value [ phx::push_back(phx::ref(material_names), lbs::_1) ]
)
^ *(qi::char_(',') >> option)
) >> spirit::eol;
;
node_position
= +(qi::char_(',') > real [ phx::push_back(lbs::_val, lbs::_1) ])
;
connectivity
= +(qi::char_(',') > qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ])
;
any_section
= *(qi::char_(',') >> option) > spirit::eol
> *any_line
;
any_line
= *(qi::char_ - spirit::eol - qi::char_('*')) >> spirit::eol
;
keyword
= qi::lexeme[ +(qi::char_ - (qi::char_('*') | spirit::eol)) ]
;
option
= key > -( '=' >> value );
key
= qi::char_("a-zA-Z_") >> *(qi::char_("a-zA-Z_0-9") | qi::char_('-'))
;
value
= key.alias()
;
BOOST_SPIRIT_DEBUG_NODE(start);
abaqus_element_type.add
#if defined(AKANTU_STRUCTURAL_MECHANICS)
("BE21" , _bernoulli_beam_2)
("BE31" , _bernoulli_beam_3)
#endif
("T3D2" , _segment_2) // Gmsh generates this elements
("T3D3" , _segment_3) // Gmsh generates this elements
("CPE3" , _triangle_3)
("CPS3" , _triangle_3)
("DC2D3" , _triangle_3)
("CPE6" , _triangle_6)
("CPS6" , _triangle_6)
("DC2D6" , _triangle_6)
("CPE4" , _quadrangle_4)
("CPS4" , _quadrangle_4)
("DC2D4" , _quadrangle_4)
("CPE8" , _quadrangle_8)
("CPS8" , _quadrangle_8)
("DC2D8" , _quadrangle_8)
("C3D4" , _tetrahedron_4)
("DC3D4" , _tetrahedron_4)
("C3D8" , _hexahedron_8)
("C3D8R" , _hexahedron_8)
("DC3D8" , _hexahedron_8)
("C3D10" , _tetrahedron_10)
("DC3D10", _tetrahedron_10);
#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
#endif
start .name("abaqus-start-rule");
connectivity .name("abaqus-connectivity");
node_position .name("abaqus-nodes-position");
nodes .name("abaqus-nodes");
any_section .name("abaqus-any_section");
header .name("abaqus-header");
material .name("abaqus-material");
elements .name("abaqus-elements");
elements_set .name("abaqus-elements-set");
nodes_set .name("abaqus-nodes-set");
key .name("abaqus-key");
value .name("abaqus-value");
option .name("abaqus-option");
keyword .name("abaqus-keyword");
any_line .name("abaqus-any-line");
abaqus_element_type.name("abaqus-element-type");
/* clang-format on */
}
public:
AKANTU_GET_MACRO(MaterialNames, material_names,
const std::vector<std::string> &);
/* ------------------------------------------------------------------------ */
/* Rules */
/* ------------------------------------------------------------------------ */
private:
qi::rule<Iterator, void(), Skipper> start;
qi::rule<Iterator, std::vector<int>(), Skipper> connectivity;
qi::rule<Iterator, std::vector<Real>(), Skipper> node_position;
qi::rule<Iterator, void(), Skipper> nodes, any_section, header, material;
qi::rule<Iterator, void(), qi::locals<ElementType>, Skipper> elements;
qi::rule<Iterator, void(), qi::locals<ElementGroup *>, Skipper> elements_set;
qi::rule<Iterator, void(), qi::locals<NodeGroup *>, Skipper> nodes_set;
qi::rule<Iterator, std::string(), Skipper> key, value, option, keyword,
any_line;
qi::real_parser<Real, qi::real_policies<Real>> real;
qi::symbols<char, ElementType> abaqus_element_type;
/* ------------------------------------------------------------------------ */
/* Mambers */
/* ------------------------------------------------------------------------ */
private:
/// reference to the mesh to read
Mesh & mesh;
/// correspondance between the numbering of nodes in the abaqus file and in
/// the akantu mesh
std::map<UInt, UInt> abaqus_nodes_to_akantu;
/// correspondance between the element number in the abaqus file and the
/// Element in the akantu mesh
std::map<UInt, Element> abaqus_elements_to_akantu;
/// list of the material names
std::vector<std::string> material_names;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void MeshIOAbaqus::read(const std::string & filename, Mesh & mesh) {
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace lbs = boost::spirit::qi::labels;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
std::ifstream infile;
infile.open(filename.c_str());
if (!infile.good()) {
AKANTU_ERROR("Cannot open file " << filename);
}
std::string storage; // We will read the contents here.
infile.unsetf(std::ios::skipws); // No white space skipping!
std::copy(std::istream_iterator<char>(infile), std::istream_iterator<char>(),
std::back_inserter(storage));
using iterator_t = std::string::const_iterator;
using skipper = AbaqusSkipper<iterator_t>;
using grammar = AbaqusMeshGrammar<iterator_t, skipper>;
grammar g(mesh);
skipper ws;
iterator_t iter = storage.begin();
iterator_t end = storage.end();
qi::phrase_parse(iter, end, g, ws);
MeshAccessor mesh_accessor(mesh);
for (auto & mat_name : g.getMaterialNames()) {
auto eg_it = mesh.element_group_find(mat_name);
auto & eg = *eg_it->second;
if (eg_it != mesh.element_group_end()) {
for (auto & type : eg.elementTypes()) {
Array<std::string> & abaqus_material =
mesh_accessor.getData<std::string>("abaqus_material", type);
for (auto elem : eg.getElements(type)) {
abaqus_material(elem) = mat_name;
}
}
}
}
mesh_accessor.setNbGlobalNodes(mesh.getNodes().size());
MeshUtils::fillElementToSubElementsData(mesh);
}
} // namespace akantu
diff --git a/src/io/mesh_io/mesh_io_abaqus.hh b/src/io/mesh_io/mesh_io_abaqus.hh
index 0f6beec0a..5feea6314 100644
--- a/src/io/mesh_io/mesh_io_abaqus.hh
+++ b/src/io/mesh_io/mesh_io_abaqus.hh
@@ -1,60 +1,60 @@
/**
* @file mesh_io_abaqus.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 26 2010
* @date last modification: Tue Jun 30 2015
*
* @brief read a mesh from an abaqus input file
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh_io.hh"
#include "mesh_accessor.hh"
+#include "mesh_io.hh"
#ifndef __AKANTU_MESH_IO_ABAQUS_HH__
#define __AKANTU_MESH_IO_ABAQUS_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
class MeshIOAbaqus : public MeshIO {
public:
MeshIOAbaqus();
~MeshIOAbaqus() override;
/// read a mesh from the file
void read(const std::string & filename, Mesh & mesh) override;
/// write a mesh to a file
// virtual void write(const std::string & filename, const Mesh & mesh);
private:
/// correspondence between msh element types and akantu element types
std::map<std::string, ElementType> _abaqus_to_akantu_element_types;
};
} // akantu
#endif /* __AKANTU_MESH_IO_ABAQUS_HH__ */
diff --git a/src/io/mesh_io/mesh_io_diana.hh b/src/io/mesh_io/mesh_io_diana.hh
index 65004a5cc..a5bde0911 100644
--- a/src/io/mesh_io/mesh_io_diana.hh
+++ b/src/io/mesh_io/mesh_io_diana.hh
@@ -1,107 +1,109 @@
/**
* @file mesh_io_diana.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Nov 19 2015
*
* @brief diana mesh reader description
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_IO_DIANA_HH__
#define __AKANTU_MESH_IO_DIANA_HH__
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
/* -------------------------------------------------------------------------- */
namespace akantu {
class MeshIODiana : public MeshIO {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshIODiana();
~MeshIODiana() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// read a mesh from the file
void read(const std::string & filename, Mesh & mesh) override;
/// write a mesh to a file
void write(const std::string & filename, const Mesh & mesh) override;
private:
std::string readCoordinates(std::ifstream & infile, Mesh & mesh,
UInt & first_node_number);
std::string readElements(std::ifstream & infile, Mesh & mesh,
UInt first_node_number);
- std::string readGroups(std::ifstream & infile, Mesh & mesh, UInt first_node_number);
+ std::string readGroups(std::ifstream & infile, Mesh & mesh,
+ UInt first_node_number);
std::string readConnectivity(std::ifstream & infile, Mesh & mesh,
UInt first_node_number);
std::string readMaterialElement(std::ifstream & infile, Mesh & mesh);
std::string readMaterial(std::ifstream & infile,
const std::string & filename);
UInt readInterval(std::stringstream & line, std::set<UInt> & interval);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
std::map<std::string, ElementType> _diana_to_akantu_element_types;
std::map<std::string, std::string> _diana_to_akantu_mat_prop;
- /// order in witch element as to be read, akantu_node_order = _read_order[diana_node_order]
+ /// order in witch element as to be read, akantu_node_order =
+ /// _read_order[diana_node_order]
std::map<ElementType, UInt *> _read_order;
std::map<UInt, Element> diana_element_number_to_elements;
std::map<Element, UInt> akantu_number_to_diana_number;
};
} // akantu
#endif /* __AKANTU_MESH_IO_DIANA_HH__ */
diff --git a/src/io/mesh_io/mesh_io_msh.cc b/src/io/mesh_io/mesh_io_msh.cc
index 5576f5bf4..2f160815c 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,971 +1,972 @@
/**
* @file mesh_io_msh.cc
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Jan 21 2016
*
* @brief Read/Write for MSH files generated by gmsh
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -----------------------------------------------------------------------------
Version (Legacy) 1.0
$NOD
number-of-nodes
node-number x-coord y-coord z-coord
...
$ENDNOD
$ELM
number-of-elements
elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list
...
$ENDELM
-----------------------------------------------------------------------------
Version 2.1
$MeshFormat
version-number file-type data-size
$EndMeshFormat
$Nodes
number-of-nodes
node-number x-coord y-coord z-coord
...
$EndNodes
$Elements
number-of-elements
elm-number elm-type number-of-tags < tag > ... node-number-list
...
$EndElements
$PhysicalNames
number-of-names
physical-dimension physical-number "physical-name"
...
$EndPhysicalNames
$NodeData
number-of-string-tags
< "string-tag" >
...
number-of-real-tags
< real-tag >
...
number-of-integer-tags
< integer-tag >
...
node-number value ...
...
$EndNodeData
$ElementData
number-of-string-tags
< "string-tag" >
...
number-of-real-tags
< real-tag >
...
number-of-integer-tags
< integer-tag >
...
elm-number value ...
...
$EndElementData
$ElementNodeData
number-of-string-tags
< "string-tag" >
...
number-of-real-tags
< real-tag >
...
number-of-integer-tags
< integer-tag >
...
elm-number number-of-nodes-per-element value ...
...
$ElementEndNodeData
-----------------------------------------------------------------------------
elem-type
1: 2-node line.
2: 3-node triangle.
3: 4-node quadrangle.
4: 4-node tetrahedron.
5: 8-node hexahedron.
6: 6-node prism.
7: 5-node pyramid.
8: 3-node second order line
9: 6-node second order triangle
10: 9-node second order quadrangle
11: 10-node second order tetrahedron
12: 27-node second order hexahedron
13: 18-node second order prism
14: 14-node second order pyramid
15: 1-node point.
16: 8-node second order quadrangle
17: 20-node second order hexahedron
18: 15-node second order prism
19: 13-node second order pyramid
20: 9-node third order incomplete triangle
21: 10-node third order triangle
22: 12-node fourth order incomplete triangle
23: 15-node fourth order triangle
24: 15-node fifth order incomplete triangle
25: 21-node fifth order complete triangle
26: 4-node third order edge
27: 5-node fourth order edge
28: 6-node fifth order edge
29: 20-node third order tetrahedron
30: 35-node fourth order tetrahedron
31: 56-node fifth order tetrahedron
-------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// The boost spirit is a work on the way it does not compile so I kept the
// current code. The current code does not handle files generated on Windows
// <CRLF>
// #include <boost/config/warning_disable.hpp>
// #include <boost/spirit/include/qi.hpp>
// #include <boost/spirit/include/phoenix_core.hpp>
// #include <boost/spirit/include/phoenix_fusion.hpp>
// #include <boost/spirit/include/phoenix_object.hpp>
// #include <boost/spirit/include/phoenix_container.hpp>
// #include <boost/spirit/include/phoenix_operator.hpp>
// #include <boost/spirit/include/phoenix_bind.hpp>
// #include <boost/spirit/include/phoenix_stl.hpp>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/* Methods Implentations */
/* -------------------------------------------------------------------------- */
MeshIOMSH::MeshIOMSH() {
canReadSurface = true;
canReadExtendedData = true;
_msh_nodes_per_elem[_msh_not_defined] = 0;
_msh_nodes_per_elem[_msh_segment_2] = 2;
_msh_nodes_per_elem[_msh_triangle_3] = 3;
_msh_nodes_per_elem[_msh_quadrangle_4] = 4;
_msh_nodes_per_elem[_msh_tetrahedron_4] = 4;
_msh_nodes_per_elem[_msh_hexahedron_8] = 8;
_msh_nodes_per_elem[_msh_prism_1] = 6;
_msh_nodes_per_elem[_msh_pyramid_1] = 1;
_msh_nodes_per_elem[_msh_segment_3] = 3;
_msh_nodes_per_elem[_msh_triangle_6] = 6;
_msh_nodes_per_elem[_msh_quadrangle_9] = 9;
_msh_nodes_per_elem[_msh_tetrahedron_10] = 10;
_msh_nodes_per_elem[_msh_hexahedron_27] = 27;
_msh_nodes_per_elem[_msh_hexahedron_20] = 20;
_msh_nodes_per_elem[_msh_prism_18] = 18;
_msh_nodes_per_elem[_msh_prism_15] = 15;
_msh_nodes_per_elem[_msh_pyramid_14] = 14;
_msh_nodes_per_elem[_msh_point] = 1;
_msh_nodes_per_elem[_msh_quadrangle_8] = 8;
_msh_to_akantu_element_types[_msh_not_defined] = _not_defined;
_msh_to_akantu_element_types[_msh_segment_2] = _segment_2;
_msh_to_akantu_element_types[_msh_triangle_3] = _triangle_3;
_msh_to_akantu_element_types[_msh_quadrangle_4] = _quadrangle_4;
_msh_to_akantu_element_types[_msh_tetrahedron_4] = _tetrahedron_4;
_msh_to_akantu_element_types[_msh_hexahedron_8] = _hexahedron_8;
_msh_to_akantu_element_types[_msh_prism_1] = _pentahedron_6;
_msh_to_akantu_element_types[_msh_pyramid_1] = _not_defined;
_msh_to_akantu_element_types[_msh_segment_3] = _segment_3;
_msh_to_akantu_element_types[_msh_triangle_6] = _triangle_6;
_msh_to_akantu_element_types[_msh_quadrangle_9] = _not_defined;
_msh_to_akantu_element_types[_msh_tetrahedron_10] = _tetrahedron_10;
_msh_to_akantu_element_types[_msh_hexahedron_27] = _not_defined;
_msh_to_akantu_element_types[_msh_hexahedron_20] = _hexahedron_20;
_msh_to_akantu_element_types[_msh_prism_18] = _not_defined;
_msh_to_akantu_element_types[_msh_prism_15] = _pentahedron_15;
_msh_to_akantu_element_types[_msh_pyramid_14] = _not_defined;
_msh_to_akantu_element_types[_msh_point] = _point_1;
_msh_to_akantu_element_types[_msh_quadrangle_8] = _quadrangle_8;
_akantu_to_msh_element_types[_not_defined] = _msh_not_defined;
_akantu_to_msh_element_types[_segment_2] = _msh_segment_2;
_akantu_to_msh_element_types[_segment_3] = _msh_segment_3;
_akantu_to_msh_element_types[_triangle_3] = _msh_triangle_3;
_akantu_to_msh_element_types[_triangle_6] = _msh_triangle_6;
_akantu_to_msh_element_types[_tetrahedron_4] = _msh_tetrahedron_4;
_akantu_to_msh_element_types[_tetrahedron_10] = _msh_tetrahedron_10;
_akantu_to_msh_element_types[_quadrangle_4] = _msh_quadrangle_4;
_akantu_to_msh_element_types[_quadrangle_8] = _msh_quadrangle_8;
_akantu_to_msh_element_types[_hexahedron_8] = _msh_hexahedron_8;
_akantu_to_msh_element_types[_hexahedron_20] = _msh_hexahedron_20;
_akantu_to_msh_element_types[_pentahedron_6] = _msh_prism_1;
_akantu_to_msh_element_types[_pentahedron_15] = _msh_prism_15;
_akantu_to_msh_element_types[_point_1] = _msh_point;
#if defined(AKANTU_STRUCTURAL_MECHANICS)
_akantu_to_msh_element_types[_bernoulli_beam_2] = _msh_segment_2;
_akantu_to_msh_element_types[_bernoulli_beam_3] = _msh_segment_2;
- _akantu_to_msh_element_types[_discrete_kirchhoff_triangle_18] = _msh_triangle_3;
+ _akantu_to_msh_element_types[_discrete_kirchhoff_triangle_18] =
+ _msh_triangle_3;
#endif
std::map<ElementType, MSHElementType>::iterator it;
for (it = _akantu_to_msh_element_types.begin();
it != _akantu_to_msh_element_types.end(); ++it) {
UInt nb_nodes = _msh_nodes_per_elem[it->second];
std::vector<UInt> tmp(nb_nodes);
for (UInt i = 0; i < nb_nodes; ++i) {
tmp[i] = i;
}
switch (it->first) {
case _tetrahedron_10:
tmp[8] = 9;
tmp[9] = 8;
break;
case _pentahedron_6:
tmp[0] = 2;
tmp[1] = 0;
tmp[2] = 1;
tmp[3] = 5;
tmp[4] = 3;
tmp[5] = 4;
break;
case _pentahedron_15:
tmp[0] = 2;
tmp[1] = 0;
tmp[2] = 1;
tmp[3] = 5;
tmp[4] = 3;
tmp[5] = 4;
tmp[6] = 8;
tmp[8] = 11;
tmp[9] = 6;
tmp[10] = 9;
tmp[11] = 10;
tmp[12] = 14;
tmp[14] = 12;
break;
case _hexahedron_20:
tmp[9] = 11;
tmp[10] = 12;
tmp[11] = 9;
tmp[12] = 13;
tmp[13] = 10;
tmp[17] = 19;
tmp[18] = 17;
tmp[19] = 18;
break;
default:
// nothing to change
break;
}
_read_order[it->first] = tmp;
}
}
/* -------------------------------------------------------------------------- */
MeshIOMSH::~MeshIOMSH() = default;
/* -------------------------------------------------------------------------- */
/* Spirit stuff */
/* -------------------------------------------------------------------------- */
// namespace _parser {
// namespace spirit = ::boost::spirit;
// namespace qi = ::boost::spirit::qi;
// namespace ascii = ::boost::spirit::ascii;
// namespace lbs = ::boost::spirit::qi::labels;
// namespace phx = ::boost::phoenix;
// /* ------------------------------------------------------------------------
// */
// /* Lazy functors */
// /* ------------------------------------------------------------------------
// */
// struct _Element {
// int index;
// std::vector<int> tags;
// std::vector<int> connectivity;
// ElementType type;
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_get_nb_nodes_ {
// template <class elem_type> struct result { typedef int type; };
// template <class elem_type> bool operator()(elem_type et) {
// return MeshIOMSH::_msh_nodes_per_elem[et];
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_element_ {
// template <class id_t, class tags_t, class elem_type, class conn_t>
// struct result {
// typedef _Element type;
// };
// template <class id_t, class tags_t, class elem_type, class conn_t>
// _Element operator()(id_t id, const elem_type & et, const tags_t & t,
// const conn_t & c) {
// _Element tmp_el;
// tmp_el.index = id;
// tmp_el.tags = t;
// tmp_el.connectivity = c;
// tmp_el.type = et;
// return tmp_el;
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_check_value_ {
// template <class T> struct result { typedef void type; };
// template <class T> void operator()(T v1, T v2) {
// if (v1 != v2) {
// AKANTU_EXCEPTION("The msh parser expected a "
// << v2 << " in the header bug got a " << v1);
// }
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_node_read_ {
// template <class Mesh, class ID, class V, class size, class Map>
// struct result {
// typedef bool type;
// };
// template <class Mesh, class ID, class V, class size, class Map>
// bool operator()(Mesh & mesh, const ID & id, const V & pos, size max,
// Map & nodes_mapping) const {
// Vector<Real> tmp_pos(mesh.getSpatialDimension());
// UInt i = 0;
// for (typename V::const_iterator it = pos.begin();
// it != pos.end() || i < mesh.getSpatialDimension(); ++it)
// tmp_pos[i++] = *it;
// nodes_mapping[id] = mesh.getNbNodes();
// mesh.getNodes().push_back(tmp_pos);
// return (mesh.getNbNodes() < UInt(max));
// }
// };
// /* ------------------------------------------------------------------------
// */
// struct lazy_element_read_ {
// template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
// struct result {
// typedef bool type;
// };
// template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
// bool operator()(Mesh & mesh, const EL & element, size max,
// const NodeMap & nodes_mapping,
// ElemMap & elements_mapping) const {
// Vector<UInt> tmp_conn(Mesh::getNbNodesPerElement(element.type));
// AKANTU_DEBUG_ASSERT(element.connectivity.size() == tmp_conn.size(),
// "The element "
// << element.index
// << "in the MSH file has too many nodes.");
// mesh.addConnectivityType(element.type);
// Array<UInt> & connectivity = mesh.getConnectivity(element.type);
// UInt i = 0;
// for (std::vector<int>::const_iterator it =
// element.connectivity.begin();
// it != element.connectivity.end(); ++it) {
// typename NodeMap::const_iterator nit = nodes_mapping.find(*it);
// AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
// "There is an unknown node in the connectivity.");
// tmp_conn[i++] = nit->second;
// }
// ::akantu::Element el(element.type, connectivity.size());
// elements_mapping[element.index] = el;
// connectivity.push_back(tmp_conn);
// for (UInt i = 0; i < element.tags.size(); ++i) {
// std::stringstream tag_sstr;
// tag_sstr << "tag_" << i;
// Array<UInt> * data =
// mesh.template getDataPointer<UInt>(tag_sstr.str(), element.type,
// _not_ghost);
// data->push_back(element.tags[i]);
// }
// return (mesh.getNbElement() < UInt(max));
// }
// };
// /* ------------------------------------------------------------------------
// */
// template <class Iterator, typename Skipper = ascii::space_type>
// struct MshMeshGrammar : qi::grammar<Iterator, void(), Skipper> {
// public:
// MshMeshGrammar(Mesh & mesh)
// : MshMeshGrammar::base_type(start, "msh_mesh_reader"), mesh(mesh) {
// phx::function<lazy_element_> lazy_element;
// phx::function<lazy_get_nb_nodes_> lazy_get_nb_nodes;
// phx::function<lazy_check_value_> lazy_check_value;
// phx::function<lazy_node_read_> lazy_node_read;
// phx::function<lazy_element_read_> lazy_element_read;
// clang-format off
// start
// = *( known_section | unknown_section
// )
// ;
// known_section
// = qi::char_("$")
// >> sections [ lbs::_a = lbs::_1 ]
// >> qi::lazy(*lbs::_a)
// >> qi::lit("$End")
// //>> qi::lit(phx::ref(lbs::_a))
// ;
// unknown_section
// = qi::char_("$")
// >> qi::char_("") [ lbs::_a = lbs::_1 ]
// >> ignore_section
// >> qi::lit("$End")
// >> qi::lit(phx::val(lbs::_a))
// ;
// mesh_format // version followed by 0 or 1 for ascii or binary
// = version >> (
// ( qi::char_("0")
// >> qi::int_ [ lazy_check_value(lbs::_1, 8) ]
// )
// | ( qi::char_("1")
// >> qi::int_ [ lazy_check_value(lbs::_1, 8) ]
// >> qi::dword [ lazy_check_value(lbs::_1, 1) ]
// )
// )
// ;
// nodes
// = nodes_
// ;
// nodes_
// = qi::int_ [ lbs::_a = lbs::_1 ]
// > *(
// ( qi::int_ >> position ) [ lazy_node_read(phx::ref(mesh),
// lbs::_1,
// phx::cref(lbs::_2),
// lbs::_a,
// phx::ref(this->msh_nodes_to_akantu)) ]
// )
// ;
// element
// = elements_
// ;
// elements_
// = qi::int_ [ lbs::_a = lbs::_1 ]
// > qi::repeat(phx::ref(lbs::_a))[ element [ lazy_element_read(phx::ref(mesh),
// lbs::_1,
// phx::cref(lbs::_a),
// phx::cref(this->msh_nodes_to_akantu),
// phx::ref(this->msh_elemt_to_akantu)) ]]
// ;
// ignore_section
// = *(qi::char_ - qi::char_('$'))
// ;
// interpolation_scheme = ignore_section;
// element_data = ignore_section;
// node_data = ignore_section;
// version
// = qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ]
// >> *( qi::char_(".") >> qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ] )
// ;
// position
// = real [ phx::push_back(lbs::_val, lbs::_1) ]
// > real [ phx::push_back(lbs::_val, lbs::_1) ]
// > real [ phx::push_back(lbs::_val, lbs::_1) ]
// ;
// tags
// = qi::int_ [ lbs::_a = lbs::_1 ]
// > qi::repeat(phx::val(lbs::_a))[ qi::int_ [ phx::push_back(lbs::_val,
// lbs::_1) ] ]
// ;
// element
// = ( qi::int_ [ lbs::_a = lbs::_1 ]
// > msh_element_type [ lbs::_b = lazy_get_nb_nodes(lbs::_1) ]
// > tags [ lbs::_c = lbs::_1 ]
// > connectivity(lbs::_a) [ lbs::_d = lbs::_1 ]
// ) [ lbs::_val = lazy_element(lbs::_a,
// phx::cref(lbs::_b),
// phx::cref(lbs::_c),
// phx::cref(lbs::_d)) ]
// ;
// connectivity
// = qi::repeat(lbs::_r1)[ qi::int_ [ phx::push_back(lbs::_val,
// lbs::_1) ] ]
// ;
// sections.add
// ("MeshFormat", &mesh_format)
// ("Nodes", &nodes)
// ("Elements", &elements)
// ("PhysicalNames", &physical_names)
// ("InterpolationScheme", &interpolation_scheme)
// ("ElementData", &element_data)
// ("NodeData", &node_data);
// msh_element_type.add
// ("0" , _not_defined )
// ("1" , _segment_2 )
// ("2" , _triangle_3 )
// ("3" , _quadrangle_4 )
// ("4" , _tetrahedron_4 )
// ("5" , _hexahedron_8 )
// ("6" , _pentahedron_6 )
// ("7" , _not_defined )
// ("8" , _segment_3 )
// ("9" , _triangle_6 )
// ("10", _not_defined )
// ("11", _tetrahedron_10)
// ("12", _not_defined )
// ("13", _not_defined )
// ("14", _hexahedron_20 )
// ("15", _pentahedron_15)
// ("16", _not_defined )
// ("17", _point_1 )
// ("18", _quadrangle_8 );
// mesh_format .name("MeshFormat" );
// nodes .name("Nodes" );
// elements .name("Elements" );
// physical_names .name("PhysicalNames" );
// interpolation_scheme.name("InterpolationScheme");
// element_data .name("ElementData" );
// node_data .name("NodeData" );
// clang-format on
// }
// /* ----------------------------------------------------------------------
// */
// /* Rules */
// /* ----------------------------------------------------------------------
// */
// private:
// qi::symbols<char, ElementType> msh_element_type;
// qi::symbols<char, qi::rule<Iterator, void(), Skipper> *> sections;
// qi::rule<Iterator, void(), Skipper> start;
// qi::rule<Iterator, void(), Skipper, qi::locals<std::string> >
// unknown_section;
// qi::rule<Iterator, void(), Skipper, qi::locals<qi::rule<Iterator,
// Skipper> *> > known_section;
// qi::rule<Iterator, void(), Skipper> mesh_format, nodes, elements,
// physical_names, ignore_section,
// interpolation_scheme, element_data, node_data, any_line;
// qi::rule<Iterator, void(), Skipper, qi::locals<int> > nodes_;
// qi::rule<Iterator, void(), Skipper, qi::locals< int, int, vector<int>,
// vector<int> > > elements_;
// qi::rule<Iterator, std::vector<int>(), Skipper> version;
// qi::rule<Iterator, _Element(), Skipper, qi::locals<ElementType> >
// element;
// qi::rule<Iterator, std::vector<int>(), Skipper, qi::locals<int> > tags;
// qi::rule<Iterator, std::vector<int>(int), Skipper> connectivity;
// qi::rule<Iterator, std::vector<Real>(), Skipper> position;
// qi::real_parser<Real, qi::real_policies<Real> > real;
// /* ----------------------------------------------------------------------
// */
// /* Members */
// /* ----------------------------------------------------------------------
// */
// private:
// /// reference to the mesh to read
// Mesh & mesh;
// /// correspondance between the numbering of nodes in the abaqus file and
// in
// /// the akantu mesh
// std::map<UInt, UInt> msh_nodes_to_akantu;
// /// correspondance between the element number in the abaqus file and the
// /// Element in the akantu mesh
// std::map<UInt, Element> msh_elemt_to_akantu;
// };
// }
// /* --------------------------------------------------------------------------
// */
// void MeshIOAbaqus::read(const std::string& filename, Mesh& mesh) {
// namespace qi = boost::spirit::qi;
// namespace ascii = boost::spirit::ascii;
// std::ifstream infile;
// infile.open(filename.c_str());
// if(!infile.good()) {
// AKANTU_ERROR("Cannot open file " << filename);
// }
// std::string storage; // We will read the contents here.
// infile.unsetf(std::ios::skipws); // No white space skipping!
// std::copy(std::istream_iterator<char>(infile),
// std::istream_iterator<char>(),
// std::back_inserter(storage));
// typedef std::string::const_iterator iterator_t;
// typedef ascii::space_type skipper;
// typedef _parser::MshMeshGrammar<iterator_t, skipper> grammar;
// grammar g(mesh);
// skipper ws;
// iterator_t iter = storage.begin();
// iterator_t end = storage.end();
// qi::phrase_parse(iter, end, g, ws);
// this->setNbGlobalNodes(mesh, mesh.getNodes().size());
// MeshUtils::fillElementToSubElementsData(mesh);
// }
static void my_getline(std::ifstream & infile, std::string & str) {
std::string tmp_str;
std::getline(infile, tmp_str);
str = trim(tmp_str);
}
/* -------------------------------------------------------------------------- */
void MeshIOMSH::read(const std::string & filename, Mesh & mesh) {
MeshAccessor mesh_accessor(mesh);
std::ifstream infile;
infile.open(filename.c_str());
std::string line;
UInt first_node_number = std::numeric_limits<UInt>::max(),
last_node_number = 0, file_format = 1, current_line = 0;
bool has_physical_names = false;
if (!infile.good()) {
AKANTU_EXCEPTION("Cannot open file " << filename);
}
while (infile.good()) {
my_getline(infile, line);
current_line++;
/// read the header
if (line == "$MeshFormat") {
my_getline(infile, line); /// the format line
std::stringstream sstr(line);
std::string version;
sstr >> version;
Int format;
sstr >> format;
if (format != 0)
AKANTU_ERROR("This reader can only read ASCII files.");
my_getline(infile, line); /// the end of block line
current_line += 2;
file_format = 2;
}
/// read the physical names
if (line == "$PhysicalNames") {
has_physical_names = true;
my_getline(infile, line); /// the format line
std::stringstream sstr(line);
UInt num_of_phys_names;
sstr >> num_of_phys_names;
for (UInt k(0); k < num_of_phys_names; k++) {
my_getline(infile, line);
std::stringstream sstr_phys_name(line);
UInt phys_name_id;
UInt phys_dim;
sstr_phys_name >> phys_dim >> phys_name_id;
std::size_t b = line.find('\"');
std::size_t e = line.rfind('\"');
std::string phys_name = line.substr(b + 1, e - b - 1);
phys_name_map[phys_name_id] = phys_name;
}
}
/// read all nodes
if (line == "$Nodes" || line == "$NOD") {
UInt nb_nodes;
my_getline(infile, line);
std::stringstream sstr(line);
sstr >> nb_nodes;
current_line++;
Array<Real> & nodes = mesh_accessor.getNodes();
nodes.resize(nb_nodes);
mesh_accessor.setNbGlobalNodes(nb_nodes);
UInt index;
Real coord[3];
UInt spatial_dimension = nodes.getNbComponent();
/// for each node, read the coordinates
for (UInt i = 0; i < nb_nodes; ++i) {
UInt offset = i * spatial_dimension;
my_getline(infile, line);
std::stringstream sstr_node(line);
sstr_node >> index >> coord[0] >> coord[1] >> coord[2];
current_line++;
first_node_number = std::min(first_node_number, index);
last_node_number = std::max(last_node_number, index);
/// read the coordinates
for (UInt j = 0; j < spatial_dimension; ++j)
nodes.storage()[offset + j] = coord[j];
}
my_getline(infile, line); /// the end of block line
}
/// read all elements
if (line == "$Elements" || line == "$ELM") {
UInt nb_elements;
std::vector<UInt> read_order;
my_getline(infile, line);
std::stringstream sstr(line);
sstr >> nb_elements;
current_line++;
Int index;
UInt msh_type;
ElementType akantu_type, akantu_type_old = _not_defined;
Array<UInt> * connectivity = nullptr;
UInt node_per_element = 0;
for (UInt i = 0; i < nb_elements; ++i) {
my_getline(infile, line);
std::stringstream sstr_elem(line);
current_line++;
sstr_elem >> index;
sstr_elem >> msh_type;
/// get the connectivity vector depending on the element type
akantu_type =
this->_msh_to_akantu_element_types[(MSHElementType)msh_type];
if (akantu_type == _not_defined) {
AKANTU_DEBUG_WARNING("Unsuported element kind "
<< msh_type << " at line " << current_line);
continue;
}
if (akantu_type != akantu_type_old) {
connectivity = &mesh_accessor.getConnectivity(akantu_type);
// connectivity->resize(0);
node_per_element = connectivity->getNbComponent();
akantu_type_old = akantu_type;
read_order = this->_read_order[akantu_type];
}
/// read tags informations
if (file_format == 2) {
UInt nb_tags;
sstr_elem >> nb_tags;
for (UInt j = 0; j < nb_tags; ++j) {
Int tag;
sstr_elem >> tag;
std::stringstream sstr_tag_name;
sstr_tag_name << "tag_" << j;
Array<UInt> & data = mesh.getDataPointer<UInt>(
sstr_tag_name.str(), akantu_type, _not_ghost);
data.push_back(tag);
}
} else if (file_format == 1) {
Int tag;
sstr_elem >> tag; // reg-phys
std::string tag_name = "tag_0";
Array<UInt> * data =
&mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
data->push_back(tag);
sstr_elem >> tag; // reg-elem
tag_name = "tag_1";
data = &mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
data->push_back(tag);
sstr_elem >> tag; // number-of-nodes
}
Vector<UInt> local_connect(node_per_element);
for (UInt j = 0; j < node_per_element; ++j) {
UInt node_index;
sstr_elem >> node_index;
AKANTU_DEBUG_ASSERT(node_index <= last_node_number,
"Node number not in range : line "
<< current_line);
node_index -= first_node_number;
local_connect(read_order[j]) = node_index;
}
connectivity->push_back(local_connect);
}
my_getline(infile, line); /// the end of block line
}
if ((line[0] == '$') && (line.find("End") == std::string::npos)) {
AKANTU_DEBUG_WARNING("Unsuported block_kind " << line << " at line "
<< current_line);
}
}
// mesh.updateTypesOffsets(_not_ghost);
infile.close();
this->constructPhysicalNames("tag_0", mesh);
if (has_physical_names)
mesh.createGroupsFromMeshData<std::string>("physical_names");
MeshUtils::fillElementToSubElementsData(mesh);
}
/* -------------------------------------------------------------------------- */
void MeshIOMSH::write(const std::string & filename, const Mesh & mesh) {
std::ofstream outfile;
const Array<Real> & nodes = mesh.getNodes();
outfile.open(filename.c_str());
outfile << "$MeshFormat" << std::endl;
outfile << "2.1 0 8" << std::endl;
outfile << "$EndMeshFormat" << std::endl;
outfile << std::setprecision(std::numeric_limits<Real>::digits10);
outfile << "$Nodes" << std::endl;
outfile << nodes.size() << std::endl;
outfile << std::uppercase;
for (UInt i = 0; i < nodes.size(); ++i) {
Int offset = i * nodes.getNbComponent();
outfile << i + 1;
for (UInt j = 0; j < nodes.getNbComponent(); ++j) {
outfile << " " << nodes.storage()[offset + j];
}
for (UInt p = nodes.getNbComponent(); p < 3; ++p)
outfile << " " << 0.;
outfile << std::endl;
;
}
outfile << std::nouppercase;
outfile << "$EndNodes" << std::endl;
;
outfile << "$Elements" << std::endl;
;
Int nb_elements = 0;
for (auto && type :
mesh.elementTypes(_all_dimensions, _not_ghost, _ek_not_defined)) {
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
nb_elements += connectivity.size();
}
outfile << nb_elements << std::endl;
UInt element_idx = 1;
for (auto && type :
mesh.elementTypes(_all_dimensions, _not_ghost, _ek_not_defined)) {
const auto & connectivity = mesh.getConnectivity(type, _not_ghost);
UInt * tag[2] = {nullptr, nullptr};
if (mesh.hasData<UInt>("tag_0", type, _not_ghost)) {
const auto & data_tag_0 = mesh.getData<UInt>("tag_0", type, _not_ghost);
tag[0] = data_tag_0.storage();
}
if (mesh.hasData<UInt>("tag_1", type, _not_ghost)) {
const auto & data_tag_1 = mesh.getData<UInt>("tag_1", type, _not_ghost);
tag[1] = data_tag_1.storage();
}
for (UInt i = 0; i < connectivity.size(); ++i) {
UInt offset = i * connectivity.getNbComponent();
outfile << element_idx << " " << _akantu_to_msh_element_types[type]
<< " 2";
/// \todo write the real data in the file
for (UInt t = 0; t < 2; ++t)
if (tag[t])
outfile << " " << tag[t][i];
else
outfile << " 0";
for (UInt j = 0; j < connectivity.getNbComponent(); ++j) {
outfile << " " << connectivity.storage()[offset + j] + 1;
}
outfile << std::endl;
element_idx++;
}
}
outfile << "$EndElements" << std::endl;
;
outfile.close();
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/io/mesh_io/mesh_io_msh.hh b/src/io/mesh_io/mesh_io_msh.hh
index 7c905705b..70c52f4c4 100644
--- a/src/io/mesh_io/mesh_io_msh.hh
+++ b/src/io/mesh_io/mesh_io_msh.hh
@@ -1,115 +1,110 @@
/**
* @file mesh_io_msh.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Mon Dec 07 2015
*
* @brief Read/Write for MSH files
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_IO_MSH_HH__
#define __AKANTU_MESH_IO_MSH_HH__
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class MeshIOMSH : public MeshIO {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MeshIOMSH();
~MeshIOMSH() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// read a mesh from the file
void read(const std::string & filename, Mesh & mesh) override;
/// write a mesh to a file
void write(const std::string & filename, const Mesh & mesh) override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// MSH element types
enum MSHElementType {
- _msh_not_defined = 0,
- _msh_segment_2 = 1, // 2-node line.
- _msh_triangle_3 = 2, // 3-node triangle.
- _msh_quadrangle_4 = 3, // 4-node quadrangle.
- _msh_tetrahedron_4 = 4, // 4-node tetrahedron.
- _msh_hexahedron_8 = 5, // 8-node hexahedron.
- _msh_prism_1 = 6, // 6-node prism.
- _msh_pyramid_1 = 7, // 5-node pyramid.
- _msh_segment_3 = 8, // 3-node second order line
- _msh_triangle_6 = 9, // 6-node second order triangle
- _msh_quadrangle_9 = 10, // 9-node second order quadrangle
- _msh_tetrahedron_10 = 11, // 10-node second order tetrahedron
- _msh_hexahedron_27 = 12, // 27-node second order hexahedron
- _msh_prism_18 = 13, // 18-node second order prism
- _msh_pyramid_14 = 14, // 14-node second order pyramid
- _msh_point = 15, // 1-node point.
- _msh_quadrangle_8 = 16, // 8-node second order quadrangle
- _msh_hexahedron_20 = 17, // 20-node second order hexahedron
- _msh_prism_15 = 18 // 15-node second order prism
+ _msh_not_defined = 0,
+ _msh_segment_2 = 1, // 2-node line.
+ _msh_triangle_3 = 2, // 3-node triangle.
+ _msh_quadrangle_4 = 3, // 4-node quadrangle.
+ _msh_tetrahedron_4 = 4, // 4-node tetrahedron.
+ _msh_hexahedron_8 = 5, // 8-node hexahedron.
+ _msh_prism_1 = 6, // 6-node prism.
+ _msh_pyramid_1 = 7, // 5-node pyramid.
+ _msh_segment_3 = 8, // 3-node second order line
+ _msh_triangle_6 = 9, // 6-node second order triangle
+ _msh_quadrangle_9 = 10, // 9-node second order quadrangle
+ _msh_tetrahedron_10 = 11, // 10-node second order tetrahedron
+ _msh_hexahedron_27 = 12, // 27-node second order hexahedron
+ _msh_prism_18 = 13, // 18-node second order prism
+ _msh_pyramid_14 = 14, // 14-node second order pyramid
+ _msh_point = 15, // 1-node point.
+ _msh_quadrangle_8 = 16, // 8-node second order quadrangle
+ _msh_hexahedron_20 = 17, // 20-node second order hexahedron
+ _msh_prism_15 = 18 // 15-node second order prism
};
#define MAX_NUMBER_OF_NODE_PER_ELEMENT 10 // tetrahedron of second order
/// order in witch element as to be read
- std::map< ElementType, std::vector<UInt> > _read_order;
+ std::map<ElementType, std::vector<UInt>> _read_order;
/// number of nodes per msh element
std::map<MSHElementType, UInt> _msh_nodes_per_elem;
/// correspondence between msh element types and akantu element types
std::map<MSHElementType, ElementType> _msh_to_akantu_element_types;
/// correspondence between akantu element types and msh element types
std::map<ElementType, MSHElementType> _akantu_to_msh_element_types;
};
-
} // akantu
#endif /* __AKANTU_MESH_IO_MSH_HH__ */
diff --git a/src/io/parser/algebraic_parser.hh b/src/io/parser/algebraic_parser.hh
index be4102241..da97a2380 100644
--- a/src/io/parser/algebraic_parser.hh
+++ b/src/io/parser/algebraic_parser.hh
@@ -1,513 +1,512 @@
/**
* @file algebraic_parser.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Wed Nov 11 2015
*
* @brief algebraic_parser definition of the grammar
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
// Boost
#include <boost/config/warning_disable.hpp>
-#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
+#include <boost/spirit/include/qi.hpp>
/* -------------------------------------------------------------------------- */
-
#ifndef __AKANTU_ALGEBRAIC_PARSER_HH__
#define __AKANTU_ALGEBRAIC_PARSER_HH__
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace lbs = boost::spirit::qi::labels;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
namespace akantu {
namespace parser {
struct algebraic_error_handler_ {
template <typename, typename, typename> struct result {
using type = void;
};
template <typename Iterator>
void operator()(qi::info const & what, Iterator err_pos,
Iterator last) const {
AKANTU_EXCEPTION(
"Error! Expecting "
<< what // what failed?
<< " here: \""
<< std::string(err_pos, last) // iterators to error-pos, end
<< "\"");
}
};
static Real my_min(Real a, Real b) { return std::min(a, b); }
static Real my_max(Real a, Real b) { return std::max(a, b); }
static Real my_pow(Real a, Real b) { return std::pow(a, b); }
static Real eval_param(const ID & a, const ParserSection & section) {
return section.getParameter(a, _ppsc_current_and_parent_scope);
}
static Real unary_func(Real (*func)(Real), Real a) { return func(a); }
static Real binary_func(Real (*func)(Real, Real), Real a, Real b) {
return func(a, b);
}
template <class Iterator, typename Skipper = spirit::unused_type>
struct AlgebraicGrammar : qi::grammar<Iterator, Real(), Skipper> {
AlgebraicGrammar(const ParserSection & section)
: AlgebraicGrammar::base_type(start, "algebraic_grammar"),
section(section) {
// phx::function<lazy_pow_> lazy_pow;
// phx::function<lazy_unary_func_> lazy_unary_func;
// phx::function<lazy_binary_func_> lazy_binary_func;
// phx::function<lazy_eval_param_> lazy_eval_param;
/* clang-format off */
start
= expr.alias()
;
expr
= term [ lbs::_val = lbs::_1 ]
>> *( ('+' > term [ lbs::_val += lbs::_1 ])
| ('-' > term [ lbs::_val -= lbs::_1 ])
)
;
term
= factor [ lbs::_val = lbs::_1 ]
>> *( ('*' > factor [ lbs::_val *= lbs::_1 ])
| ('/' > factor [ lbs::_val /= lbs::_1 ])
)
;
factor
= number [ lbs::_val = lbs::_1 ]
>> *("**" > number [ lbs::_val = phx::bind(&my_pow, lbs::_val, lbs::_1) ])
;
number
= real [ lbs::_val = lbs::_1 ]
| ('-' > number [ lbs::_val = -lbs::_1 ])
| ('+' > number [ lbs::_val = lbs::_1 ])
| constant [ lbs::_val = lbs::_1 ]
| function [ lbs::_val = lbs::_1 ]
| ('(' > expr > ')') [ lbs::_val = lbs::_1 ]
| variable [ lbs::_val = lbs::_1 ]
;
function
= (qi::no_case[unary_function]
> '('
> expr
> ')') [ lbs::_val = phx::bind(&unary_func, lbs::_1, lbs::_2) ]
| (qi::no_case[binary_function]
> '(' >> expr
> ',' >> expr
> ')') [ lbs::_val = phx::bind(&binary_func ,lbs::_1, lbs::_2, lbs::_3) ]
;
variable
= key [ lbs::_val = phx::bind(&eval_param, lbs::_1, section) ]
;
key
= qi::no_skip[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")] // coming from the InputFileGrammar
;
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#ifndef M_E
# define M_E 2.7182818284590452354
#endif
constant.add
("pi", M_PI)
("e", M_E);
unary_function.add
("abs" , &std::abs )
("acos" , &std::acos )
("asin" , &std::asin )
("atan" , &std::atan )
("ceil" , &std::ceil )
("cos" , &std::cos )
("cosh" , &std::cosh )
("exp" , &std::exp )
("floor" , &std::floor )
("log10" , &std::log10 )
("log" , &std::log )
("sin" , &std::sin )
("sinh" , &std::sinh )
("sqrt" , &std::sqrt )
("tan" , &std::tan )
("tanh" , &std::tanh )
("acosh" , &std::acosh )
("asinh" , &std::asinh )
("atanh" , &std::atanh )
("exp2" , &std::exp2 )
("expm1" , &std::expm1 )
("log1p" , &std::log1p )
("log2" , &std::log2 )
("erf" , &std::erf )
("erfc" , &std::erfc )
("lgamma", &std::lgamma)
("tgamma", &std::tgamma)
("trunc" , &std::trunc )
("round" , &std::round )
// ("crbt" , &std::crbt )
;
binary_function.add
("pow" , &std::pow )
("min" , &parser::my_min)
("max" , &parser::my_max)
("atan2", &std::atan2 )
("fmod" , &std::fmod )
("hypot", &std::hypot )
;
#if !defined(AKANTU_NDEBUG)
phx::function<algebraic_error_handler_> const error_handler = algebraic_error_handler_();
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
#endif
expr .name("expression");
term .name("term");
factor .name("factor");
number .name("numerical-value");
variable.name("variable");
function.name("function");
constant.name("constants-list");
unary_function.name("unary-functions-list");
binary_function.name("binary-functions-list");
#if !defined AKANTU_NDEBUG
if(AKANTU_DEBUG_TEST(dblDebug)) {
qi::debug(expr);
qi::debug(term);
qi::debug(factor);
qi::debug(number);
qi::debug(variable);
qi::debug(function);
}
#endif
}
/* clang-format on */
private:
qi::rule<Iterator, Real(), Skipper> start;
qi::rule<Iterator, Real(), Skipper> expr;
qi::rule<Iterator, Real(), Skipper> term;
qi::rule<Iterator, Real(), Skipper> factor;
qi::rule<Iterator, Real(), Skipper> number;
qi::rule<Iterator, Real(), Skipper> variable;
qi::rule<Iterator, Real(), Skipper> function;
qi::rule<Iterator, std::string(), Skipper> key;
- qi::real_parser<Real, qi::real_policies<Real> > real;
+ qi::real_parser<Real, qi::real_policies<Real>> real;
qi::symbols<char, Real> constant;
qi::symbols<char, Real (*)(Real)> unary_function;
qi::symbols<char, Real (*)(Real, Real)> binary_function;
const ParserSection & section;
};
/* ---------------------------------------------------------------------- */
/* Vector Parser */
/* ---------------------------------------------------------------------- */
struct parsable_vector {
operator Vector<Real>() {
Vector<Real> tmp(_cells.size());
auto it = _cells.begin();
for (UInt i = 0; it != _cells.end(); ++it, ++i)
tmp(i) = *it;
return tmp;
}
std::vector<Real> _cells;
};
inline std::ostream & operator<<(std::ostream & stream,
const parsable_vector & pv) {
stream << "pv[";
auto it = pv._cells.begin();
if (it != pv._cells.end()) {
stream << *it;
for (++it; it != pv._cells.end(); ++it)
stream << ", " << *it;
}
stream << "]";
return stream;
}
struct parsable_matrix {
operator Matrix<Real>() {
size_t cols = 0;
auto it_rows = _cells.begin();
for (; it_rows != _cells.end(); ++it_rows)
cols = std::max(cols, it_rows->_cells.size());
Matrix<Real> tmp(_cells.size(), _cells[0]._cells.size(), 0.);
it_rows = _cells.begin();
for (UInt i = 0; it_rows != _cells.end(); ++it_rows, ++i) {
auto it_cols = it_rows->_cells.begin();
for (UInt j = 0; it_cols != it_rows->_cells.end(); ++it_cols, ++j) {
tmp(i, j) = *it_cols;
}
}
return tmp;
}
std::vector<parsable_vector> _cells;
};
inline std::ostream & operator<<(std::ostream & stream,
const parsable_matrix & pm) {
stream << "pm[";
auto it = pm._cells.begin();
if (it != pm._cells.end()) {
stream << *it;
for (++it; it != pm._cells.end(); ++it)
stream << ", " << *it;
}
stream << "]";
return stream;
}
/* ---------------------------------------------------------------------- */
template <typename T1, typename T2>
static void cont_add(T1 & cont, T2 & value) {
cont._cells.push_back(value);
}
/* ---------------------------------------------------------------------- */
template <class Iterator, typename Skipper = spirit::unused_type>
struct VectorGrammar : qi::grammar<Iterator, parsable_vector(), Skipper> {
VectorGrammar(const ParserSection & section)
: VectorGrammar::base_type(start, "vector_algebraic_grammar"),
number(section) {
start = '[' > vector > ']';
vector =
(number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
lbs::_1)] >>
*(',' >> number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
lbs::_1)]))[lbs::_val = lbs::_a];
#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
phx::function<algebraic_error_handler_> const error_handler =
algebraic_error_handler_();
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
#endif
start.name("start");
vector.name("vector");
number.name("value");
#if !defined AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDebug)) {
qi::debug(start);
qi::debug(vector);
}
#endif
}
private:
qi::rule<Iterator, parsable_vector(), Skipper> start;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper>
vector;
qi::rule<Iterator, Real(), Skipper> value;
AlgebraicGrammar<Iterator, Skipper> number;
};
/* ---------------------------------------------------------------------- */
static inline bool vector_eval(const ID & a, const ParserSection & section,
- parsable_vector & result) {
+ parsable_vector & result) {
std::string value = section.getParameter(a, _ppsc_current_and_parent_scope);
std::string::const_iterator b = value.begin();
std::string::const_iterator e = value.end();
parser::VectorGrammar<std::string::const_iterator, qi::space_type> grammar(
section);
return qi::phrase_parse(b, e, grammar, qi::space, result);
}
/* ---------------------------------------------------------------------- */
template <class Iterator, typename Skipper = spirit::unused_type>
struct MatrixGrammar : qi::grammar<Iterator, parsable_matrix(), Skipper> {
MatrixGrammar(const ParserSection & section)
: MatrixGrammar::base_type(start, "matrix_algebraic_grammar"),
vector(section) {
start = '[' >> matrix >> ']';
matrix =
(rows[phx::bind(&cont_add<parsable_matrix, parsable_vector>, lbs::_a,
lbs::_1)] >>
*(',' >> rows[phx::bind(&cont_add<parsable_matrix, parsable_vector>,
lbs::_a, lbs::_1)]))[lbs::_val = lbs::_a];
rows = eval_vector | vector;
eval_vector = (key[lbs::_pass = phx::bind(&vector_eval, lbs::_1, section,
lbs::_a)])[lbs::_val = lbs::_a];
key = qi::char_("a-zA-Z_") >>
*qi::char_("a-zA-Z_0-9") // coming from the InputFileGrammar
;
#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
phx::function<algebraic_error_handler_> const error_handler =
algebraic_error_handler_();
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
#endif
start.name("matrix");
matrix.name("all_rows");
rows.name("rows");
vector.name("vector");
eval_vector.name("eval_vector");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDebug)) {
qi::debug(start);
qi::debug(matrix);
qi::debug(rows);
qi::debug(eval_vector);
qi::debug(key);
}
#endif
}
private:
qi::rule<Iterator, parsable_matrix(), Skipper> start;
qi::rule<Iterator, parsable_matrix(), qi::locals<parsable_matrix>, Skipper>
matrix;
qi::rule<Iterator, parsable_vector(), Skipper> rows;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper>
eval_vector;
qi::rule<Iterator, std::string(), Skipper> key;
VectorGrammar<Iterator, Skipper> vector;
};
/* ---------------------------------------------------------------------- */
/* Randon Generator */
/* ---------------------------------------------------------------------- */
struct ParsableRandomGenerator {
ParsableRandomGenerator(
Real base = Real(),
const RandomDistributionType & type = _rdt_not_defined,
const parsable_vector & parameters = parsable_vector())
: base(base), type(type), parameters(parameters) {}
Real base;
RandomDistributionType type;
parsable_vector parameters;
};
inline std::ostream & operator<<(std::ostream & stream,
const ParsableRandomGenerator & prg) {
stream << "prg[" << prg.base << " " << UInt(prg.type) << " "
<< prg.parameters << "]";
return stream;
}
/* ---------------------------------------------------------------------- */
template <class Iterator, typename Skipper = spirit::unused_type>
struct RandomGeneratorGrammar
: qi::grammar<Iterator, ParsableRandomGenerator(), Skipper> {
RandomGeneratorGrammar(const ParserSection & section)
: RandomGeneratorGrammar::base_type(start, "random_generator_grammar"),
number(section) {
start = generator.alias();
generator =
qi::hold[distribution[lbs::_val = lbs::_1]] |
number[lbs::_val = phx::construct<ParsableRandomGenerator>(lbs::_1)];
distribution = (number >> generator_type >> '[' >> generator_params >>
']')[lbs::_val = phx::construct<ParsableRandomGenerator>(
lbs::_1, lbs::_2, lbs::_3)];
generator_params =
(number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
lbs::_1)] >>
*(',' > number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
lbs::_1)]))[lbs::_val = lbs::_a];
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD(r, data, elem) \
(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem)), \
AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem)))
generator_type.add BOOST_PP_SEQ_FOR_EACH(
AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD, _,
AKANTU_RANDOM_DISTRIBUTION_TYPES);
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD
#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
phx::function<algebraic_error_handler_> const error_handler =
algebraic_error_handler_();
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
#endif
start.name("random-generator");
generator.name("random-generator");
distribution.name("random-distribution");
generator_type.name("generator-type");
generator_params.name("generator-parameters");
number.name("number");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDebug)) {
qi::debug(generator);
qi::debug(distribution);
qi::debug(generator_params);
}
#endif
}
private:
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> start;
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> generator;
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> distribution;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper>
generator_params;
AlgebraicGrammar<Iterator, Skipper> number;
qi::symbols<char, RandomDistributionType> generator_type;
};
}
}
#endif /* __AKANTU_ALGEBRAIC_PARSER_HH__ */
diff --git a/src/io/parser/cppargparse/cppargparse.cc b/src/io/parser/cppargparse/cppargparse.cc
index bb1c85158..5c3280299 100644
--- a/src/io/parser/cppargparse/cppargparse.cc
+++ b/src/io/parser/cppargparse/cppargparse.cc
@@ -1,523 +1,523 @@
/**
* @file cppargparse.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
* @date last modification: Wed Nov 11 2015
*
* @brief implementation of the ArgumentParser
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "cppargparse.hh"
#include <cstdlib>
#include <cstring>
#include <libgen.h>
-#include <iostream>
+#include <algorithm>
#include <iomanip>
-#include <string>
+#include <iostream>
#include <queue>
#include <sstream>
-#include <algorithm>
+#include <string>
#include <exception>
#include <stdexcept>
#include <string.h>
namespace cppargparse {
/* -------------------------------------------------------------------------- */
static inline std::string to_upper(const std::string & str) {
std::string lstr = str;
std::transform(lstr.begin(), lstr.end(), lstr.begin(),
(int (*)(int))std::toupper);
return lstr;
}
/* -------------------------------------------------------------------------- */
/* ArgumentParser */
/* -------------------------------------------------------------------------- */
ArgumentParser::ArgumentParser() {
this->addArgument("-h;--help", "show this help message and exit", 0, _boolean,
false, true);
}
/* -------------------------------------------------------------------------- */
ArgumentParser::~ArgumentParser() {
for (auto it = arguments.begin(); it != arguments.end(); ++it) {
delete it->second;
}
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::setParallelContext(int prank, int psize) {
this->prank = prank;
this->psize = psize;
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::_exit(const std::string & msg, int status) {
if (prank == 0) {
if (msg != "") {
std::cerr << msg << std::endl;
std::cerr << std::endl;
}
this->print_help(std::cerr);
}
if (external_exit)
(*external_exit)(status);
else {
exit(status);
}
}
/* -------------------------------------------------------------------------- */
const ArgumentParser::Argument & ArgumentParser::
operator[](const std::string & name) const {
auto it = success_parsed.find(name);
if (it != success_parsed.end()) {
return *(it->second);
} else {
throw std::range_error("No argument named \'" + name +
"\' was found in the parsed argument," +
" make sur to specify it \'required\'" +
" or to give it a default value");
}
}
/* -------------------------------------------------------------------------- */
bool ArgumentParser::has(const std::string & name) const {
return (success_parsed.find(name) != success_parsed.end());
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::addArgument(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type) {
_addArgument(name_or_flag, help, nargs, type);
}
/* -------------------------------------------------------------------------- */
ArgumentParser::_Argument &
ArgumentParser::_addArgument(const std::string & name, const std::string & help,
int nargs, ArgumentType type) {
_Argument * arg = nullptr;
switch (type) {
case _string: {
arg = new ArgumentStorage<std::string>();
break;
}
case _float: {
arg = new ArgumentStorage<double>();
break;
}
case _integer: {
arg = new ArgumentStorage<int>();
break;
}
case _boolean: {
arg = new ArgumentStorage<bool>();
break;
}
}
arg->help = help;
arg->nargs = nargs;
arg->type = type;
std::stringstream sstr(name);
std::string item;
std::vector<std::string> tmp_keys;
while (std::getline(sstr, item, ';')) {
tmp_keys.push_back(item);
}
int long_key = -1;
int short_key = -1;
bool problem = (tmp_keys.size() > 2) || (name == "");
for (auto it = tmp_keys.begin(); it != tmp_keys.end(); ++it) {
if (it->find("--") == 0) {
problem |= (long_key != -1);
long_key = it - tmp_keys.begin();
} else if (it->find("-") == 0) {
problem |= (long_key != -1);
short_key = it - tmp_keys.begin();
}
}
problem |= ((tmp_keys.size() == 2) && (long_key == -1 || short_key == -1));
if (problem) {
delete arg;
throw std::invalid_argument("Synthax of name or flags is not correct. "
"Possible synthax are \'-f\', \'-f;--foo\', "
"\'--foo\', \'bar\'");
}
if (long_key != -1) {
arg->name = tmp_keys[long_key];
arg->name.erase(0, 2);
} else if (short_key != -1) {
arg->name = tmp_keys[short_key];
arg->name.erase(0, 1);
} else {
arg->name = tmp_keys[0];
pos_args.push_back(arg);
arg->required = (nargs != _one_if_possible);
arg->is_positional = true;
}
arguments[arg->name] = arg;
if (!arg->is_positional) {
if (short_key != -1) {
std::string key = tmp_keys[short_key];
key_args[key] = arg;
arg->keys.push_back(key);
}
if (long_key != -1) {
std::string key = tmp_keys[long_key];
key_args[key] = arg;
arg->keys.push_back(key);
}
}
return *arg;
}
#if not HAVE_STRDUP
static char * strdup(const char * str) {
size_t len = strlen(str);
auto * x = (char *)malloc(len + 1); /* 1 for the null terminator */
- if(!x)
- return nullptr; /* malloc could not allocate memory */
- memcpy(x,str,len+1); /* copy the string into the new buffer */
+ if (!x)
+ return nullptr; /* malloc could not allocate memory */
+ memcpy(x, str, len + 1); /* copy the string into the new buffer */
return x;
}
#endif
/* -------------------------------------------------------------------------- */
void ArgumentParser::parse(int & argc, char **& argv, int flags,
bool parse_help) {
bool stop_in_not_parsed = flags & _stop_on_not_parsed;
bool remove_parsed = flags & _remove_parsed;
std::vector<std::string> argvs;
argvs.reserve(argc);
for (int i = 0; i < argc; ++i) {
argvs.emplace_back(argv[i]);
}
unsigned int current_position = 0;
if (this->program_name == "" && argc > 0) {
std::string prog = argvs[current_position];
const char * c_prog = prog.c_str();
char * c_prog_tmp = strdup(c_prog);
std::string base_prog(basename(c_prog_tmp));
this->program_name = base_prog;
std::free(c_prog_tmp);
}
std::queue<_Argument *> positional_queue;
for (auto it = pos_args.begin(); it != pos_args.end(); ++it)
positional_queue.push(*it);
std::vector<int> argvs_to_remove;
++current_position; // consume argv[0]
while (current_position < argvs.size()) {
std::string arg = argvs[current_position];
++current_position;
auto key_it = key_args.find(arg);
bool is_positional = false;
_Argument * argument_ptr = nullptr;
if (key_it == key_args.end()) {
if (positional_queue.empty()) {
if (stop_in_not_parsed)
this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
continue;
} else {
argument_ptr = positional_queue.front();
is_positional = true;
--current_position;
}
} else {
argument_ptr = key_it->second;
}
if (remove_parsed && !is_positional && argument_ptr->name != "help") {
argvs_to_remove.push_back(current_position - 1);
}
_Argument & argument = *argument_ptr;
unsigned int min_nb_val = 0, max_nb_val = 0;
switch (argument.nargs) {
case _one_if_possible:
max_nb_val = 1;
break; // "?"
case _at_least_one:
min_nb_val = 1; // "+"
- /* FALLTHRU */
- /* [[fallthrough]]; un-comment when compiler will get it*/
+ /* FALLTHRU */
+ /* [[fallthrough]]; un-comment when compiler will get it*/
case _any:
max_nb_val = argc - current_position;
break; // "*"
default:
min_nb_val = max_nb_val = argument.nargs; // "N"
}
std::vector<std::string> values;
unsigned int arg_consumed = 0;
if (max_nb_val <= (argc - current_position)) {
for (; arg_consumed < max_nb_val; ++arg_consumed) {
std::string v = argvs[current_position];
++current_position;
bool is_key = key_args.find(v) != key_args.end();
bool is_good_type = checkType(argument.type, v);
if (!is_key && is_good_type) {
values.push_back(v);
if (remove_parsed)
argvs_to_remove.push_back(current_position - 1);
} else {
// unconsume not parsed argument for optional
if (!is_positional || is_key)
--current_position;
break;
}
}
}
if (arg_consumed < min_nb_val) {
if (!is_positional) {
this->_exit("Not enought values for the argument " + argument.name +
" where provided",
EXIT_FAILURE);
} else {
if (stop_in_not_parsed)
this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
}
} else {
if (is_positional)
positional_queue.pop();
if (!argument.parsed) {
success_parsed[argument.name] = &argument;
argument.parsed = true;
if ((argument.nargs == _one_if_possible || argument.nargs == 0) &&
arg_consumed == 0) {
if (argument.has_const)
argument.setToConst();
else if (argument.has_default)
argument.setToDefault();
} else {
argument.setValues(values);
}
} else {
this->_exit("Argument " + argument.name +
" already present in the list of argument",
EXIT_FAILURE);
}
}
}
for (auto ait = arguments.begin(); ait != arguments.end(); ++ait) {
_Argument & argument = *(ait->second);
if (!argument.parsed) {
if (argument.has_default) {
argument.setToDefault();
success_parsed[argument.name] = &argument;
}
if (argument.required) {
this->_exit("Argument " + argument.name + " required but not given!",
EXIT_FAILURE);
}
}
}
// removing the parsed argument if remove_parsed is true
if (argvs_to_remove.size()) {
std::vector<int>::const_iterator next_to_remove = argvs_to_remove.begin();
for (int i = 0, c = 0; i < argc; ++i) {
if (next_to_remove == argvs_to_remove.end() || i != *next_to_remove) {
argv[c] = argv[i];
++c;
} else {
if (next_to_remove != argvs_to_remove.end())
++next_to_remove;
}
}
argc -= argvs_to_remove.size();
}
this->argc = &argc;
this->argv = &argv;
if (this->arguments["help"]->parsed && parse_help) {
this->_exit();
}
}
/* -------------------------------------------------------------------------- */
bool ArgumentParser::checkType(ArgumentType type,
const std::string & value) const {
std::stringstream sstr(value);
switch (type) {
case _string: {
std::string s;
sstr >> s;
break;
}
case _float: {
double d;
sstr >> d;
break;
}
case _integer: {
int i;
sstr >> i;
break;
}
case _boolean: {
bool b;
sstr >> b;
break;
}
}
return (sstr.fail() == false);
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::printself(std::ostream & stream) const {
for (auto it = success_parsed.begin(); it != success_parsed.end(); ++it) {
const Argument & argument = *(it->second);
argument.printself(stream);
stream << std::endl;
}
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::print_usage(std::ostream & stream) const {
stream << "Usage: " << this->program_name;
// print shorten usage
for (auto it = arguments.begin(); it != arguments.end(); ++it) {
const _Argument & argument = *(it->second);
if (!argument.is_positional) {
if (!argument.required)
stream << " [";
stream << argument.keys[0];
this->print_usage_nargs(stream, argument);
if (!argument.required)
stream << "]";
}
}
for (auto it = pos_args.begin(); it != pos_args.end(); ++it) {
const _Argument & argument = **it;
this->print_usage_nargs(stream, argument);
}
stream << std::endl;
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::print_usage_nargs(std::ostream & stream,
const _Argument & argument) const {
std::string u_name = to_upper(argument.name);
switch (argument.nargs) {
case _one_if_possible:
stream << " [" << u_name << "]";
break;
case _at_least_one:
stream << " " << u_name;
- /* FALLTHRU */
- /* [[fallthrough]]; un-comment when compiler will get it */
+ /* FALLTHRU */
+ /* [[fallthrough]]; un-comment when compiler will get it */
case _any:
stream << " [" << u_name << " ...]";
break;
default:
for (int i = 0; i < argument.nargs; ++i) {
stream << " " << u_name;
}
}
}
void ArgumentParser::print_help(std::ostream & stream) const {
this->print_usage(stream);
if (!pos_args.empty()) {
stream << std::endl;
stream << "positional arguments:" << std::endl;
for (auto it = pos_args.begin(); it != pos_args.end(); ++it) {
const _Argument & argument = **it;
this->print_help_argument(stream, argument);
}
}
if (!key_args.empty()) {
stream << std::endl;
stream << "optional arguments:" << std::endl;
for (auto it = arguments.begin(); it != arguments.end(); ++it) {
const _Argument & argument = *(it->second);
if (!argument.is_positional) {
this->print_help_argument(stream, argument);
}
}
}
}
void ArgumentParser::print_help_argument(std::ostream & stream,
const _Argument & argument) const {
std::string key("");
if (argument.is_positional)
key = argument.name;
else {
std::stringstream sstr;
for (unsigned int i = 0; i < argument.keys.size(); ++i) {
if (i != 0)
sstr << ", ";
sstr << argument.keys[i];
this->print_usage_nargs(sstr, argument);
}
key = sstr.str();
}
stream << " " << std::left << std::setw(15) << key << " " << argument.help;
argument.printDefault(stream);
stream << std::endl;
}
}
diff --git a/src/io/parser/cppargparse/cppargparse.hh b/src/io/parser/cppargparse/cppargparse.hh
index 353d3c857..4a89f4c54 100644
--- a/src/io/parser/cppargparse/cppargparse.hh
+++ b/src/io/parser/cppargparse/cppargparse.hh
@@ -1,201 +1,200 @@
/**
* @file cppargparse.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
* @date last modification: Tue Dec 08 2015
*
* @brief Get the commandline options and store them as short, long and others
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <iostream>
#include <map>
#include <string>
-#include <iostream>
#include <vector>
#ifndef __CPPARGPARSE_HH__
#define __CPPARGPARSE_HH__
/* -------------------------------------------------------------------------- */
namespace cppargparse {
/// define the types of the arguments
enum ArgumentType { _string, _integer, _float, _boolean };
/// Defines how many arguments to expect
enum ArgumentNargs { _one_if_possible = -1, _at_least_one = -2, _any = -3 };
/// Flags for the parse function of ArgumentParser
enum ParseFlags {
_no_flags = 0x0, ///< Default behavior
_stop_on_not_parsed = 0x1, ///< Stop on unknown arguments
_remove_parsed = 0x2 ///< Remove parsed arguments from argc argv
};
/// Helps to combine parse flags
inline ParseFlags operator|(const ParseFlags & a, const ParseFlags & b) {
auto tmp = ParseFlags(int(a) | int(b));
return tmp;
}
/* -------------------------------------------------------------------------- */
/**
* ArgumentParser is a class that mimics the Python argparse module
*/
class ArgumentParser {
public:
/// public definition of an argument
class Argument {
public:
Argument() : name(std::string()) {}
virtual ~Argument() = default;
virtual void printself(std::ostream & stream) const = 0;
template <class T> operator T() const;
std::string name;
};
/// constructor
ArgumentParser();
/// destroy everything
~ArgumentParser();
/// add an argument with a description
void addArgument(const std::string & name_or_flag, const std::string & help,
int nargs = 1, ArgumentType type = _string);
/// add an argument with an help and a default value
template <class T>
void addArgument(const std::string & name_or_flag, const std::string & help,
int nargs, ArgumentType type, T def);
/// add an argument with an help and a default + const value
template <class T>
void addArgument(const std::string & name_or_flag, const std::string & help,
int nargs, ArgumentType type, T def, T cons);
/// parse argc, argv
void parse(int & argc, char **& argv, int flags = _stop_on_not_parsed,
bool parse_help = true);
/// get the last argc parsed
int & getArgC() { return *(this->argc); }
/// get the last argv parsed
- char** & getArgV() { return *(this->argv); }
+ char **& getArgV() { return *(this->argv); }
/// print the content in the stream
void printself(std::ostream & stream) const;
/// print the help text
void print_help(std::ostream & stream = std::cout) const;
/// print the usage text
void print_usage(std::ostream & stream = std::cout) const;
/// set an external function to replace the exit function from the stdlib
void setExternalExitFunction(void (*external_exit)(int)) {
this->external_exit = external_exit;
}
/// accessor for a registered argument that was parsed, throw an exception if
/// the argument does not exist or was not set (parsed or default value)
const Argument & operator[](const std::string & name) const;
/// is the argument present
bool has(const std::string &) const;
/// set the parallel context to avoid multiple help messages in
/// multiproc/thread cases
void setParallelContext(int prank, int psize);
public:
-
/// Internal class describing the arguments
struct _Argument;
/// Stores that value of an argument
- template<class T> class ArgumentStorage;
+ template <class T> class ArgumentStorage;
private:
/// Internal function to be used by the public addArgument
_Argument & _addArgument(const std::string & name_or_flag,
const std::string & description, int nargs,
ArgumentType type);
void _exit(const std::string & msg = "", int status = 0);
bool checkType(ArgumentType type, const std::string & value) const;
/// function to help to print help
void print_usage_nargs(std::ostream & stream,
const _Argument & argument) const;
/// function to help to print help
void print_help_argument(std::ostream & stream,
const _Argument & argument) const;
private:
/// public arguments storage
using Arguments = std::map<std::string, Argument *>;
/// internal arguments storage
using _Arguments = std::map<std::string, _Argument *>;
/// association key argument
using ArgumentKeyMap = std::map<std::string, _Argument *>;
/// position arguments
using PositionalArgument = std::vector<_Argument *>;
/// internal storage of arguments declared by the user
_Arguments arguments;
/// list of arguments successfully parsed
Arguments success_parsed;
/// keys associated to arguments
ArgumentKeyMap key_args;
/// positional arguments
PositionalArgument pos_args;
/// program name
std::string program_name;
/// exit function to use
void (*external_exit)(int){nullptr};
/// Parallel context, rank and size of communicator
int prank{0}, psize{1};
/// The last argc parsed (those are the modified version after parse)
int * argc;
/// The last argv parsed (those are the modified version after parse)
char *** argv;
};
}
inline std::ostream & operator<<(std::ostream & stream,
const cppargparse::ArgumentParser & argparse) {
argparse.printself(stream);
return stream;
}
#endif /* __CPPARGPARSE_HH__ */
#include "cppargparse_tmpl.hh"
diff --git a/src/io/parser/cppargparse/cppargparse_tmpl.hh b/src/io/parser/cppargparse/cppargparse_tmpl.hh
index 68192782a..c12727656 100644
--- a/src/io/parser/cppargparse/cppargparse_tmpl.hh
+++ b/src/io/parser/cppargparse/cppargparse_tmpl.hh
@@ -1,240 +1,240 @@
/**
* @file cppargparse_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
* @date last modification: Tue Dec 08 2015
*
* @brief Implementation of the templated part of the commandline argument
* parser
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <stdexcept>
#include <sstream>
+#include <stdexcept>
#ifndef __CPPARGPARSE_TMPL_HH__
#define __CPPARGPARSE_TMPL_HH__
namespace cppargparse {
/* -------------------------------------------------------------------------- */
/* Argument */
/* -------------------------------------------------------------------------- */
/// internal description of arguments
struct ArgumentParser::_Argument : public Argument {
_Argument() : Argument(), help(std::string()) {}
~_Argument() override = default;
void setValues(std::vector<std::string> & values) {
for (auto it = values.begin(); it != values.end(); ++it) {
this->addValue(*it);
}
}
virtual void addValue(std::string & value) = 0;
virtual void setToDefault() = 0;
virtual void setToConst() = 0;
std::ostream & printDefault(std::ostream & stream) const {
stream << std::boolalpha;
if (has_default) {
stream << " (default: ";
this->_printDefault(stream);
stream << ")";
}
if (has_const) {
stream << " (const: ";
this->_printConst(stream);
stream << ")";
}
return stream;
}
virtual std::ostream & _printDefault(std::ostream & stream) const = 0;
virtual std::ostream & _printConst(std::ostream & stream) const = 0;
std::string help;
int nargs{1};
ArgumentType type{_string};
bool required{false};
bool parsed{false};
bool has_default{false};
bool has_const{false};
std::vector<std::string> keys;
bool is_positional{false};
};
/* -------------------------------------------------------------------------- */
/// typed storage of the arguments
template <class T>
class ArgumentParser::ArgumentStorage : public ArgumentParser::_Argument {
public:
ArgumentStorage() : _default(T()), _const(T()), values(std::vector<T>()) {}
void addValue(std::string & value) override {
std::stringstream sstr(value);
T t;
sstr >> t;
values.push_back(t);
}
void setToDefault() override {
values.clear();
values.push_back(_default);
}
void setToConst() override {
values.clear();
values.push_back(_const);
}
void printself(std::ostream & stream) const override {
stream << this->name << " =";
stream << std::boolalpha; // for boolean
for (auto vit = this->values.begin(); vit != this->values.end(); ++vit) {
stream << " " << *vit;
}
}
std::ostream & _printDefault(std::ostream & stream) const override {
stream << _default;
return stream;
}
std::ostream & _printConst(std::ostream & stream) const override {
stream << _const;
return stream;
}
T _default;
T _const;
std::vector<T> values;
};
/* -------------------------------------------------------------------------- */
template <>
inline void
ArgumentParser::ArgumentStorage<std::string>::addValue(std::string & value) {
values.push_back(value);
}
template <class T> struct is_vector {
enum { value = false };
};
-template <class T> struct is_vector<std::vector<T> > {
+template <class T> struct is_vector<std::vector<T>> {
enum { value = true };
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_vector = cppargparse::is_vector<T>::value>
struct cast_helper {
static T cast(const ArgumentParser::Argument & arg) {
const auto & _arg =
dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg);
if (_arg.values.size() == 1) {
return _arg.values[0];
} else {
throw std::length_error("Not enougth or too many argument where passed "
"for the command line argument: " +
arg.name);
}
}
};
template <class T> struct cast_helper<T, true> {
static T cast(const ArgumentParser::Argument & arg) {
const auto & _arg =
dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg);
return _arg.values;
}
};
/* -------------------------------------------------------------------------- */
template <class T> ArgumentParser::Argument::operator T() const {
return cast_helper<T>::cast(*this);
}
template <> inline ArgumentParser::Argument::operator const char *() const {
return cast_helper<std::string>::cast(*this).c_str();
}
template <> inline ArgumentParser::Argument::operator unsigned int() const {
return cast_helper<int>::cast(*this);
}
template <class T>
void ArgumentParser::addArgument(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, T def) {
_Argument & arg = _addArgument(name_or_flag, help, nargs, type);
dynamic_cast<ArgumentStorage<T> &>(arg)._default = def;
arg.has_default = true;
}
template <class T>
void ArgumentParser::addArgument(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, T def, T cons) {
_Argument & arg = _addArgument(name_or_flag, help, nargs, type);
dynamic_cast<ArgumentStorage<T> &>(arg)._default = def;
arg.has_default = true;
dynamic_cast<ArgumentStorage<T> &>(arg)._const = cons;
arg.has_const = true;
}
/* -------------------------------------------------------------------------- */
template <>
inline void
ArgumentParser::addArgument<const char *>(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, const char * def) {
this->addArgument<std::string>(name_or_flag, help, nargs, type, def);
}
template <>
inline void
ArgumentParser::addArgument<unsigned int>(const std::string & name_or_flag,
const std::string & help, int nargs,
ArgumentType type, unsigned int def) {
this->addArgument<int>(name_or_flag, help, nargs, type, def);
}
/* -------------------------------------------------------------------------- */
template <>
inline void ArgumentParser::addArgument<const char *>(
const std::string & name_or_flag, const std::string & help, int nargs,
ArgumentType type, const char * def, const char * cons) {
this->addArgument<std::string>(name_or_flag, help, nargs, type, def, cons);
}
template <>
inline void ArgumentParser::addArgument<unsigned int>(
const std::string & name_or_flag, const std::string & help, int nargs,
ArgumentType type, unsigned int def, unsigned int cons) {
this->addArgument<int>(name_or_flag, help, nargs, type, def, cons);
}
}
#endif /* __AKANTU_CPPARGPARSE_TMPL_HH__ */
diff --git a/src/io/parser/input_file_parser.hh b/src/io/parser/input_file_parser.hh
index 201f9a9b9..3826abca1 100644
--- a/src/io/parser/input_file_parser.hh
+++ b/src/io/parser/input_file_parser.hh
@@ -1,270 +1,268 @@
/**
* @file input_file_parser.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Tue May 19 2015
*
* @brief Grammar definition for the input files
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// Boost
/* -------------------------------------------------------------------------- */
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/variant/recursive_variant.hpp>
#ifndef __AKANTU_INPUT_FILE_PARSER_HH__
#define __AKANTU_INPUT_FILE_PARSER_HH__
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace lbs = boost::spirit::qi::labels;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
namespace akantu {
namespace parser {
struct error_handler_ {
template <typename, typename, typename, typename> struct result {
using type = void;
};
template <typename Iterator>
void operator()(qi::info const & what, Iterator err_pos, Iterator /*first*/,
Iterator /*last*/) const {
spirit::classic::file_position pos = err_pos.get_position();
AKANTU_EXCEPTION("Parse error [ "
<< "Expecting " << what << " instead of \"" << *err_pos
<< "\" ]"
<< " in file " << pos.file << " line " << pos.line
<< " column " << pos.column << std::endl
<< "'" << err_pos.get_currentline() << "'" << std::endl
<< std::setw(pos.column) << " "
<< "^- here");
}
private:
};
- static ParserSection &
- create_subsection(const ParserType & type, const boost::optional<std::string> & opt_name,
- const boost::optional<std::string> & opt_option,
- ParserSection & sect) {
+ static ParserSection & create_subsection(
+ const ParserType & type, const boost::optional<std::string> & opt_name,
+ const boost::optional<std::string> & opt_option, ParserSection & sect) {
std::string option = "";
if (opt_option)
option = *opt_option;
static size_t id = 12;
std::string name = "anonymous_" + std::to_string(id++);
if (opt_name)
name = *opt_name;
-
ParserSection sect_tmp(name, type, option, sect);
return sect.addSubSection(sect_tmp);
}
template <typename Iter>
static bool create_parameter(boost::iterator_range<Iter> & rng,
std::string & value, ParserSection & sect) {
try {
std::string name(rng.begin(), rng.end());
name = trim(name);
spirit::classic::file_position pos = rng.begin().get_position();
ParserParameter param_tmp(name, value, sect);
param_tmp.setDebugInfo(pos.file, pos.line, pos.column);
sect.addParameter(param_tmp);
} catch (debug::Exception & e) {
return false;
}
return true;
}
static std::string concatenate(const std::string & t1,
const std::string & t2) {
return (t1 + t2);
}
/* ---------------------------------------------------------------------- */
/* Grammars definitions */
/* ---------------------------------------------------------------------- */
template <class Iterator>
struct InputFileGrammar
: qi::grammar<Iterator, void(), typename Skipper<Iterator>::type> {
InputFileGrammar(ParserSection * sect)
: InputFileGrammar::base_type(start, "input_file_grammar"),
parent_section(sect) {
/* clang-format off */
start
= mini_section(parent_section)
;
mini_section
= *(
entry (lbs::_r1)
| section(lbs::_r1)
)
;
entry
= (
qi::raw[key]
>> '='
> value
) [ lbs::_pass = phx::bind(&create_parameter<Iterator>,
lbs::_1,
lbs::_2,
*lbs::_r1) ]
;
section
= (
qi::no_case[section_type]
> qi::lexeme
[
-section_name
> -section_option
]
) [ lbs::_a = &phx::bind(&create_subsection,
lbs::_1,
phx::at_c<0>(lbs::_2),
phx::at_c<1>(lbs::_2),
*lbs::_r1) ]
> '['
> mini_section(lbs::_a)
> ']'
;
section_name
= qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")
;
section_option
= (+ascii::space >> section_name) [ lbs::_val = lbs::_2 ]
;
key
= qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")
;
value
= (
mono_line_value [ lbs::_a = phx::bind(&concatenate, lbs::_a, lbs::_1) ]
> *(
'\\' > mono_line_value [ lbs::_a = phx::bind(&concatenate, lbs::_a, lbs::_1) ]
)
) [ lbs::_val = lbs::_a ]
;
mono_line_value
= qi::lexeme
[
+(qi::char_ - (qi::char_('=') | spirit::eol | '#' | ';' | '\\'))
]
;
skipper
= ascii::space
| "#" >> *(qi::char_ - spirit::eol)
;
/* clang-format on */
#define AKANTU_SECTION_TYPE_ADD(r, data, elem) \
(BOOST_PP_STRINGIZE(elem), BOOST_PP_CAT(ParserType::_, elem))
section_type.add BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_ADD, _,
AKANTU_SECTION_TYPES);
#undef AKANTU_SECTION_TYPE_ADD
#if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
phx::function<error_handler_> const error_handler = error_handler_();
qi::on_error<qi::fail>(start,
error_handler(lbs::_4, lbs::_3, lbs::_1, lbs::_2));
#endif
section.name("section");
section_name.name("section-name");
section_option.name("section-option");
mini_section.name("section-content");
entry.name("parameter");
key.name("parameter-name");
value.name("parameter-value");
section_type.name("section-types-list");
mono_line_value.name("mono-line-value");
#if !defined AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDebug)) {
// qi::debug(section);
qi::debug(section_name);
qi::debug(section_option);
// qi::debug(mini_section);
// qi::debug(entry);
qi::debug(key);
qi::debug(value);
qi::debug(mono_line_value);
}
#endif
}
const std::string & getErrorMessage() const { return error_message; };
using skipper_type = typename Skipper<Iterator>::type;
skipper_type skipper;
private:
std::string error_message;
qi::rule<Iterator, void(ParserSection *), skipper_type> mini_section;
qi::rule<Iterator, void(ParserSection *), qi::locals<ParserSection *>,
skipper_type>
section;
qi::rule<Iterator, void(), skipper_type> start;
qi::rule<Iterator, std::string()> section_name;
qi::rule<Iterator, std::string()> section_option;
qi::rule<Iterator, void(ParserSection *), skipper_type> entry;
qi::rule<Iterator, std::string(), skipper_type> key;
qi::rule<Iterator, std::string(), qi::locals<std::string>, skipper_type>
value;
qi::rule<Iterator, std::string(), skipper_type> mono_line_value;
qi::symbols<char, ParserType> section_type;
ParserSection * parent_section;
};
}
} // akantu
#endif /* __AKANTU_INPUT_FILE_PARSER_HH__ */
diff --git a/src/io/parser/parameter_registry.cc b/src/io/parser/parameter_registry.cc
index 3f70068a8..1e63f3127 100644
--- a/src/io/parser/parameter_registry.cc
+++ b/src/io/parser/parameter_registry.cc
@@ -1,153 +1,154 @@
/**
* @file parameter_registry.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Thu Nov 19 2015
*
* @brief Parameter Registry and derived classes implementation
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <utility>
#include "parameter_registry.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
Parameter::Parameter() : name(""), description("") {}
/* -------------------------------------------------------------------------- */
Parameter::Parameter(std::string name, std::string description,
ParameterAccessType param_type)
: name(std::move(name)), description(std::move(description)),
param_type(param_type) {}
/* -------------------------------------------------------------------------- */
bool Parameter::isWritable() const { return param_type & _pat_writable; }
/* -------------------------------------------------------------------------- */
bool Parameter::isReadable() const { return param_type & _pat_readable; }
/* -------------------------------------------------------------------------- */
bool Parameter::isInternal() const { return param_type & _pat_internal; }
/* -------------------------------------------------------------------------- */
bool Parameter::isParsable() const { return param_type & _pat_parsable; }
/* -------------------------------------------------------------------------- */
void Parameter::setAccessType(ParameterAccessType ptype) {
this->param_type = ptype;
}
/* -------------------------------------------------------------------------- */
void Parameter::printself(std::ostream & stream) const {
stream << " ";
if (isInternal())
stream << "iii";
else {
if (isReadable())
stream << "r";
else
stream << "-";
if (isWritable())
stream << "w";
else
stream << "-";
if (isParsable())
stream << "p";
else
stream << "-";
}
stream << " ";
std::stringstream sstr;
sstr << name;
UInt width = std::max(int(10 - sstr.str().length()), 0);
sstr.width(width);
if (description != "") {
sstr << " [" << description << "]";
}
stream << sstr.str();
width = std::max(int(50 - sstr.str().length()), 0);
stream.width(width);
stream << " : ";
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
ParameterRegistry::ParameterRegistry() = default;
/* -------------------------------------------------------------------------- */
ParameterRegistry::~ParameterRegistry() {
std::map<std::string, Parameter *>::iterator it, end;
for (it = params.begin(); it != params.end(); ++it) {
delete it->second;
it->second = NULL;
}
this->params.clear();
}
/* -------------------------------------------------------------------------- */
void ParameterRegistry::printself(std::ostream & stream, int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
Parameters::const_iterator it;
for (it = params.begin(); it != params.end(); ++it) {
stream << space;
it->second->printself(stream);
}
SubRegisteries::const_iterator sub_it;
- for (sub_it = sub_registries.begin(); sub_it != sub_registries.end(); ++sub_it) {
+ for (sub_it = sub_registries.begin(); sub_it != sub_registries.end();
+ ++sub_it) {
stream << space << "Registry [" << std::endl;
sub_it->second->printself(stream, indent + 1);
stream << space << "]";
}
}
/* -------------------------------------------------------------------------- */
void ParameterRegistry::registerSubRegistry(const ID & id,
ParameterRegistry & registry) {
sub_registries[id] = &registry;
}
/* -------------------------------------------------------------------------- */
void ParameterRegistry::setParameterAccessType(const std::string & name,
ParameterAccessType ptype) {
auto it = params.find(name);
if (it == params.end())
AKANTU_CUSTOM_EXCEPTION(debug::ParameterUnexistingException(name, *this));
Parameter & param = *(it->second);
param.setAccessType(ptype);
}
} // akantu
diff --git a/src/io/parser/parameter_registry.hh b/src/io/parser/parameter_registry.hh
index 76f9e4d7e..af649bdc8 100644
--- a/src/io/parser/parameter_registry.hh
+++ b/src/io/parser/parameter_registry.hh
@@ -1,217 +1,222 @@
/**
* @file parameter_registry.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Aug 09 2012
* @date last modification: Thu Dec 17 2015
*
* @brief Interface of the parameter registry
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "parser.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PARAMETER_REGISTRY_HH__
#define __AKANTU_PARAMETER_REGISTRY_HH__
namespace akantu {
class ParserParameter;
}
namespace akantu {
/* -------------------------------------------------------------------------- */
/// Defines the access modes of parsable parameters
enum ParameterAccessType {
_pat_internal = 0x0001,
_pat_writable = 0x0010,
_pat_readable = 0x0100,
_pat_modifiable = 0x0110, //<_pat_readable | _pat_writable,
_pat_parsable = 0x1000,
_pat_parsmod = 0x1110 //< _pat_parsable | _pat_modifiable
};
/// Bit-wise operator between access modes
inline ParameterAccessType operator|(const ParameterAccessType & a,
const ParameterAccessType & b) {
auto tmp = ParameterAccessType(UInt(a) | UInt(b));
return tmp;
}
/* -------------------------------------------------------------------------- */
template <typename T> class ParameterTyped;
/**
* Interface for the Parameter
*/
class Parameter {
public:
Parameter();
Parameter(std::string name, std::string description,
ParameterAccessType param_type);
virtual ~Parameter() = default;
/* ------------------------------------------------------------------------ */
bool isInternal() const;
bool isWritable() const;
bool isReadable() const;
bool isParsable() const;
void setAccessType(ParameterAccessType ptype);
/* ------------------------------------------------------------------------ */
template <typename T, typename V> void set(const V & value);
virtual void setAuto(const ParserParameter & param);
template <typename T> T & get();
template <typename T> const T & get() const;
virtual inline operator Real() const { throw std::bad_cast(); };
template <typename T> inline operator T() const;
/* ------------------------------------------------------------------------ */
virtual void printself(std::ostream & stream) const;
- virtual const std::type_info& type() const = 0;
+ virtual const std::type_info & type() const = 0;
+
protected:
/// Returns const instance of templated sub-class ParameterTyped
template <typename T> const ParameterTyped<T> & getParameterTyped() const;
/// Returns instance of templated sub-class ParameterTyped
template <typename T> ParameterTyped<T> & getParameterTyped();
protected:
/// Name of parameter
std::string name;
+
private:
/// Description of parameter
std::string description;
/// Type of access
ParameterAccessType param_type{_pat_internal};
};
/* -------------------------------------------------------------------------- */
/* Typed Parameter */
/* -------------------------------------------------------------------------- */
/**
* Type parameter transfering a ParserParameter (string: string) to a typed
* parameter in the memory of the p
*/
template <typename T> class ParameterTyped : public Parameter {
public:
ParameterTyped(std::string name, std::string description,
ParameterAccessType param_type, T & param);
/* ------------------------------------------------------------------------ */
template <typename V> void setTyped(const V & value);
void setAuto(const ParserParameter & param) override;
T & getTyped();
const T & getTyped() const;
void printself(std::ostream & stream) const override;
inline operator Real() const override;
- inline const std::type_info& type() const override { return typeid(T); }
+ inline const std::type_info & type() const override { return typeid(T); }
+
private:
/// Value of parameter
T & param;
};
/* -------------------------------------------------------------------------- */
/* Parsable Interface */
/* -------------------------------------------------------------------------- */
/// Defines interface for classes to manipulate parsable parameters
class ParameterRegistry {
public:
ParameterRegistry();
virtual ~ParameterRegistry();
/* ------------------------------------------------------------------------ */
/// Add parameter to the params map
template <typename T>
void registerParam(std::string name, T & variable, ParameterAccessType type,
const std::string & description = "");
/// Add parameter to the params map (with default value)
template <typename T>
void registerParam(std::string name, T & variable, const T & default_value,
ParameterAccessType type,
const std::string & description = "");
/*------------------------------------------------------------------------- */
protected:
void registerSubRegistry(const ID & id, ParameterRegistry & registry);
/* ------------------------------------------------------------------------ */
public:
/// Set value to a parameter (with possible different type)
template <typename T, typename V>
void setMixed(const std::string & name, const V & value);
/// Set value to a parameter
template <typename T> void set(const std::string & name, const T & value);
/// Get value of a parameter
inline const Parameter & get(const std::string & name) const;
std::vector<ID> listParameters() const {
std::vector<ID> params;
- for(auto & pair : this->params) params.push_back(pair.first);
+ for (auto & pair : this->params)
+ params.push_back(pair.first);
return params;
}
std::vector<ID> listSubRegisteries() const {
std::vector<ID> subs;
- for(auto & pair : this->sub_registries) subs.push_back(pair.first);
+ for (auto & pair : this->sub_registries)
+ subs.push_back(pair.first);
return subs;
}
protected:
template <typename T> T & get_(const std::string & name);
protected:
void setParameterAccessType(const std::string & name,
ParameterAccessType ptype);
/* ------------------------------------------------------------------------ */
virtual void printself(std::ostream & stream, int indent) const;
protected:
/// Parameters map
using Parameters = std::map<std::string, Parameter *>;
Parameters params;
/// list of sub-registries
using SubRegisteries = std::map<std::string, ParameterRegistry *>;
SubRegisteries sub_registries;
/// should accessor check in sub registries
bool consisder_sub{true};
};
} // akantu
#include "parameter_registry_tmpl.hh"
#endif /* __AKANTU_PARAMETER_REGISTRY_HH__ */
diff --git a/src/io/parser/parser.cc b/src/io/parser/parser.cc
index d9d116db2..b21c0db0f 100644
--- a/src/io/parser/parser.cc
+++ b/src/io/parser/parser.cc
@@ -1,98 +1,101 @@
/**
* @file parser.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Wed Jan 13 2016
*
* @brief implementation of the parser
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// STL
#include <fstream>
#include <iomanip>
#include <map>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "parser.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
ParserSection::~ParserSection() { this->clean(); }
/* -------------------------------------------------------------------------- */
ParserParameter & ParserSection::addParameter(const ParserParameter & param) {
if (parameters.find(param.getName()) != parameters.end())
AKANTU_EXCEPTION("The parameter \"" + param.getName() +
"\" is already defined in this section");
- return (parameters.insert(std::pair<std::string, ParserParameter>(
- param.getName(), param)).first->second);
+ return (parameters
+ .insert(std::pair<std::string, ParserParameter>(param.getName(),
+ param))
+ .first->second);
}
/* -------------------------------------------------------------------------- */
ParserSection & ParserSection::addSubSection(const ParserSection & section) {
return ((sub_sections_by_type.insert(std::pair<ParserType, ParserSection>(
- section.getType(), section)))->second);
+ section.getType(), section)))
+ ->second);
}
/* -------------------------------------------------------------------------- */
std::string Parser::getLastParsedFile() const { return last_parsed_file; }
/* -------------------------------------------------------------------------- */
void ParserSection::printself(std::ostream & stream,
unsigned int indent) const {
std::string space;
std::string ind = AKANTU_INDENT;
for (unsigned int i = 0; i < indent; i++, space += ind)
;
stream << space << "Section(" << this->type << ") " << this->name
<< (option != "" ? (" " + option) : "") << " [" << std::endl;
if (!this->parameters.empty()) {
stream << space << ind << "Parameters [" << std::endl;
auto pit = this->parameters.begin();
for (; pit != this->parameters.end(); ++pit) {
stream << space << ind << " + ";
pit->second.printself(stream);
stream << std::endl;
}
stream << space << ind << "]" << std::endl;
}
if (!this->sub_sections_by_type.empty()) {
stream << space << ind << "Subsections [" << std::endl;
auto sit = this->sub_sections_by_type.begin();
for (; sit != this->sub_sections_by_type.end(); ++sit)
sit->second.printself(stream, indent + 2);
stream << std::endl;
stream << space << ind << "]" << std::endl;
}
stream << space << "]" << std::endl;
}
} // akantu
diff --git a/src/io/parser/parser_grammar_tmpl.hh b/src/io/parser/parser_grammar_tmpl.hh
index fa7fd7191..9174f2529 100644
--- a/src/io/parser/parser_grammar_tmpl.hh
+++ b/src/io/parser/parser_grammar_tmpl.hh
@@ -1,81 +1,81 @@
/**
* @file parser_grammar_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 11 2015
*
* @brief implementation of the templated part of ParsableParam Parsable and
* ParsableParamTyped
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
//#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/classic_position_iterator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
-#include <boost/spirit/include/classic_position_iterator.hpp>
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_PARSER_GRAMMAR_TMPL_HH
#define AKANTU_PARSER_GRAMMAR_TMPL_HH
namespace akantu {
namespace qi = boost::spirit::qi;
-
/* -------------------------------------------------------------------------- */
template <class T, class Grammar>
T Parser::parseType(const std::string & value, Grammar & grammar) {
using boost::spirit::ascii::space;
std::string::const_iterator b = value.begin();
std::string::const_iterator e = value.end();
T resultat = T();
bool res = false;
try {
res = qi::phrase_parse(b, e, grammar, space, resultat);
- } catch(debug::Exception & ex) {
- AKANTU_EXCEPTION("Could not parse '" << value << "' as a "
- << debug::demangle(typeid(T).name()) << ", an unknown error append '"
- << ex.what());
+ } catch (debug::Exception & ex) {
+ AKANTU_EXCEPTION("Could not parse '"
+ << value << "' as a " << debug::demangle(typeid(T).name())
+ << ", an unknown error append '" << ex.what());
}
- if(!res || (b != e)) {
- AKANTU_EXCEPTION("Could not parse '" << value << "' as a "
- << debug::demangle(typeid(T).name()) << ", an unknown error append '"
- << std::string(value.begin(), b) << "<HERE>" << std::string(b, e) << "'");
+ if (!res || (b != e)) {
+ AKANTU_EXCEPTION("Could not parse '"
+ << value << "' as a " << debug::demangle(typeid(T).name())
+ << ", an unknown error append '"
+ << std::string(value.begin(), b) << "<HERE>"
+ << std::string(b, e) << "'");
}
return resultat;
}
namespace parser {
- template<class Iterator>
- struct Skipper {
+ template <class Iterator> struct Skipper {
using type = qi::rule<Iterator, void()>;
};
}
} // akantu
-#endif //AKANTU_PARSER_GRAMMAR_TMPL_HH
+#endif // AKANTU_PARSER_GRAMMAR_TMPL_HH
diff --git a/src/io/parser/parser_input_files.cc b/src/io/parser/parser_input_files.cc
index 77a18ded7..06d388c56 100644
--- a/src/io/parser/parser_input_files.cc
+++ b/src/io/parser/parser_input_files.cc
@@ -1,117 +1,119 @@
/**
* @file parser_input_files.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 11 2015
* @date last modification: Wed Jan 13 2016
*
* @brief implementation of the parser
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
+#elif defined(__clang__) // test clang to be sure that when we test for gnu it
+ // is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
-# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-# if GCC_VERSION > 40600
-# pragma GCC diagnostic push
-# endif
-# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#define GCC_VERSION \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION > 40600
+#pragma GCC diagnostic push
+#endif
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "parser_grammar_tmpl.hh"
/* -------------------------------------------------------------------------- */
#include "input_file_parser.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
void Parser::parse(const std::string & filename) {
this->clean();
std::ifstream input(filename.c_str());
if (!input.good()) {
AKANTU_EXCEPTION("Could not open file " << filename << "!");
}
input.unsetf(std::ios::skipws);
// wrap istream into iterator
spirit::istream_iterator fwd_begin(input);
spirit::istream_iterator fwd_end;
// wrap forward iterator with position iterator, to record the position
using pos_iterator_type =
spirit::classic::position_iterator2<spirit::istream_iterator>;
pos_iterator_type position_begin(fwd_begin, fwd_end, filename);
pos_iterator_type position_end;
// parse
parser::InputFileGrammar<pos_iterator_type> ag(this);
bool result = qi::phrase_parse(position_begin, position_end, ag, ag.skipper);
if (!result || position_begin != position_end) {
spirit::classic::file_position pos = position_begin.get_position();
AKANTU_EXCEPTION("Parse error [ "
<< ag.getErrorMessage() << " ]"
<< " in file " << filename << " line " << pos.line
<< " column " << pos.column << std::endl
<< "'" << position_begin.get_currentline() << "'"
<< std::endl
<< std::setw(pos.column) << " "
<< "^- here");
}
try {
bool permissive = getParameter("permissive_parser", _ppsc_current_scope);
permissive_parser = permissive;
AKANTU_DEBUG_INFO("Parser switched permissive mode to "
<< std::boolalpha << permissive_parser);
} catch (debug::Exception & e) {
}
last_parsed_file = filename;
input.close();
}
} // akantu
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
+#elif defined(__clang__) // test clang to be sure that when we test for gnu it
+ // is only gnu
#elif defined(__GNUG__)
-# if GCC_VERSION > 40600
-# pragma GCC diagnostic pop
-# else
-# pragma GCC diagnostic warning "-Wunused-local-typedefs"
-# endif
+#if GCC_VERSION > 40600
+#pragma GCC diagnostic pop
+#else
+#pragma GCC diagnostic warning "-Wunused-local-typedefs"
+#endif
#endif
-
diff --git a/src/io/parser/parser_random.cc b/src/io/parser/parser_random.cc
index 43e79f1f1..40b05fe81 100644
--- a/src/io/parser/parser_random.cc
+++ b/src/io/parser/parser_random.cc
@@ -1,109 +1,109 @@
/**
* @file parser_random.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Mon Dec 07 2015
*
* @brief implementation of the parser
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined(__clang__) // test clang to be sure that when we test for gnu it
- // is only gnu
+// is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
#define GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION > 40600
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "parser_grammar_tmpl.hh"
/* -------------------------------------------------------------------------- */
#include "algebraic_parser.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
RandomParameter<Real>
Parser::parseRandomParameter(const std::string & value,
const ParserSection & section) {
using boost::spirit::ascii::space_type;
parser::RandomGeneratorGrammar<std::string::const_iterator, space_type>
grammar(section);
grammar.name("random_grammar");
parser::ParsableRandomGenerator rg =
Parser::parseType<parser::ParsableRandomGenerator>(value, grammar);
Vector<Real> params = rg.parameters;
switch (rg.type) {
case _rdt_not_defined:
return RandomParameter<Real>(rg.base,
std::uniform_real_distribution<Real>(0, 0));
case _rdt_uniform:
return RandomParameter<Real>(
rg.base, std::uniform_real_distribution<Real>(params(0), params(1)));
case _rdt_exponential:
return RandomParameter<Real>(
rg.base, std::exponential_distribution<Real>(params(0)));
case _rdt_gamma:
return RandomParameter<Real>(
rg.base, std::gamma_distribution<Real>(params(0), params(1)));
case _rdt_weibull:
return RandomParameter<Real>(
rg.base, std::weibull_distribution<Real>(params(1), params(0)));
case _rdt_extreme_value:
return RandomParameter<Real>(
rg.base, std::extreme_value_distribution<Real>(params(0), params(1)));
case _rdt_normal:
return RandomParameter<Real>(
rg.base, std::normal_distribution<Real>(params(0), params(1)));
case _rdt_lognormal:
return RandomParameter<Real>(
rg.base, std::lognormal_distribution<Real>(params(0), params(1)));
case _rdt_chi_squared:
return RandomParameter<Real>(
rg.base, std::chi_squared_distribution<Real>(params(0)));
case _rdt_cauchy:
return RandomParameter<Real>(
rg.base, std::cauchy_distribution<Real>(params(0), params(1)));
case _rdt_fisher_f:
return RandomParameter<Real>(
rg.base, std::fisher_f_distribution<Real>(params(0), params(1)));
case _rdt_student_t:
return RandomParameter<Real>(rg.base,
std::student_t_distribution<Real>(params(0)));
default:
AKANTU_EXCEPTION("This is an unknown random distribution in the parser");
}
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/io/parser/parser_real.cc b/src/io/parser/parser_real.cc
index c232530fd..423307831 100644
--- a/src/io/parser/parser_real.cc
+++ b/src/io/parser/parser_real.cc
@@ -1,59 +1,63 @@
/**
* @file parser_real.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Wed Nov 11 2015
*
* @brief implementation of the parser
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
+#elif defined(__clang__) // test clang to be sure that when we test for gnu it
+ // is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
-# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-# if GCC_VERSION > 40600
-# pragma GCC diagnostic push
-# endif
-# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#define GCC_VERSION \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION > 40600
+#pragma GCC diagnostic push
+#endif
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "parser_grammar_tmpl.hh"
/* -------------------------------------------------------------------------- */
#include "algebraic_parser.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
-Real Parser::parseReal(const std::string & value, const ParserSection & section) {
+Real Parser::parseReal(const std::string & value,
+ const ParserSection & section) {
using boost::spirit::ascii::space_type;
- parser::AlgebraicGrammar<std::string::const_iterator, space_type> grammar(section);
+ parser::AlgebraicGrammar<std::string::const_iterator, space_type> grammar(
+ section);
grammar.name("algebraic_grammar");
return Parser::parseType<Real>(value, grammar);
}
} // akantu
diff --git a/src/io/parser/parser_types.cc b/src/io/parser/parser_types.cc
index ff6565216..34bde6424 100644
--- a/src/io/parser/parser_types.cc
+++ b/src/io/parser/parser_types.cc
@@ -1,69 +1,75 @@
/**
* @file parser_types.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Wed Nov 11 2015
*
* @brief implementation of the parser
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
+#elif defined(__clang__) // test clang to be sure that when we test for gnu it
+ // is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
-# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-# if GCC_VERSION > 40600
-# pragma GCC diagnostic push
-# endif
-# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#define GCC_VERSION \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION > 40600
+#pragma GCC diagnostic push
+#endif
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "parser_grammar_tmpl.hh"
/* -------------------------------------------------------------------------- */
#include "algebraic_parser.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
-Vector<Real> Parser::parseVector(const std::string & value, const ParserSection & section) {
+Vector<Real> Parser::parseVector(const std::string & value,
+ const ParserSection & section) {
using boost::spirit::ascii::space_type;
- parser::VectorGrammar<std::string::const_iterator, space_type> grammar(section);
+ parser::VectorGrammar<std::string::const_iterator, space_type> grammar(
+ section);
grammar.name("vector_grammar");
return Parser::parseType<parser::parsable_vector>(value, grammar);
}
/* -------------------------------------------------------------------------- */
-Matrix<Real> Parser::parseMatrix(const std::string & value, const ParserSection & section) {
+Matrix<Real> Parser::parseMatrix(const std::string & value,
+ const ParserSection & section) {
using boost::spirit::ascii::space_type;
- parser::MatrixGrammar<std::string::const_iterator, space_type> grammar(section);
+ parser::MatrixGrammar<std::string::const_iterator, space_type> grammar(
+ section);
grammar.name("matrix_grammar");
return Parser::parseType<parser::parsable_matrix>(value, grammar);
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/mesh/element_group.cc b/src/mesh/element_group.cc
index a25adebfb..9f0158d7a 100644
--- a/src/mesh/element_group.cc
+++ b/src/mesh/element_group.cc
@@ -1,202 +1,203 @@
/**
* @file element_group.cc
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Tue Aug 18 2015
*
- * @brief Stores information relevent to the notion of domain boundary and surfaces.
+ * @brief Stores information relevent to the notion of domain boundary and
+ * surfaces.
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <sstream>
-#include <algorithm>
-#include <iterator>
-#include "mesh.hh"
-#include "group_manager.hh"
-#include "group_manager_inline_impl.cc"
+#include "aka_csr.hh"
#include "dumpable.hh"
#include "dumpable_inline_impl.hh"
-#include "aka_csr.hh"
+#include "group_manager.hh"
+#include "group_manager_inline_impl.cc"
+#include "mesh.hh"
#include "mesh_utils.hh"
+#include <algorithm>
+#include <iterator>
+#include <sstream>
#include "element_group.hh"
#if defined(AKANTU_USE_IOHELPER)
-# include "dumper_iohelper_paraview.hh"
+#include "dumper_iohelper_paraview.hh"
#endif
namespace akantu {
/* -------------------------------------------------------------------------- */
-ElementGroup::ElementGroup(const std::string & group_name,
- const Mesh & mesh,
- NodeGroup & node_group,
- UInt dimension,
- const std::string & id,
- const MemoryID & mem_id) :
- Memory(id, mem_id),
- mesh(mesh),
- name(group_name),
- elements("elements", id, mem_id),
- node_group(node_group),
- dimension(dimension) {
+ElementGroup::ElementGroup(const std::string & group_name, const Mesh & mesh,
+ NodeGroup & node_group, UInt dimension,
+ const std::string & id, const MemoryID & mem_id)
+ : Memory(id, mem_id), mesh(mesh), name(group_name),
+ elements("elements", id, mem_id), node_group(node_group),
+ dimension(dimension) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_USE_IOHELPER)
- this->registerDumper<DumperParaview>("paraview_" + group_name, group_name, true);
+ this->registerDumper<DumperParaview>("paraview_" + group_name, group_name,
+ true);
this->addDumpFilteredMesh(mesh, elements, node_group.getNodes(), dimension);
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void ElementGroup::empty() {
- elements.free();
-}
+void ElementGroup::empty() { elements.free(); }
/* -------------------------------------------------------------------------- */
void ElementGroup::append(const ElementGroup & other_group) {
AKANTU_DEBUG_IN();
node_group.append(other_group.node_group);
/// loop on all element types in all dimensions
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- type_iterator it = other_group.firstType(_all_dimensions,
- ghost_type,
- _ek_not_defined);
- type_iterator last = other_group.lastType(_all_dimensions,
- ghost_type,
- _ek_not_defined);
+ type_iterator it =
+ other_group.firstType(_all_dimensions, ghost_type, _ek_not_defined);
+ type_iterator last =
+ other_group.lastType(_all_dimensions, ghost_type, _ek_not_defined);
for (; it != last; ++it) {
ElementType type = *it;
- const Array<UInt> & other_elem_list = other_group.elements(type, ghost_type);
+ const Array<UInt> & other_elem_list =
+ other_group.elements(type, ghost_type);
UInt nb_other_elem = other_elem_list.size();
Array<UInt> * elem_list;
UInt nb_elem = 0;
/// create current type if doesn't exists, otherwise get information
if (elements.exists(type, ghost_type)) {
elem_list = &elements(type, ghost_type);
nb_elem = elem_list->size();
- }
- else {
+ } else {
elem_list = &(elements.alloc(0, 1, type, ghost_type));
}
/// append new elements to current list
elem_list->resize(nb_elem + nb_other_elem);
- std::copy(other_elem_list.begin(),
- other_elem_list.end(),
+ std::copy(other_elem_list.begin(), other_elem_list.end(),
elem_list->begin() + nb_elem);
/// remove duplicates
std::sort(elem_list->begin(), elem_list->end());
- Array<UInt>::iterator<> end = std::unique(elem_list->begin(), elem_list->end());
+ Array<UInt>::iterator<> end =
+ std::unique(elem_list->begin(), elem_list->end());
elem_list->resize(end - elem_list->begin());
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::printself(std::ostream & stream, int indent) const {
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << space << "ElementGroup [" << std::endl;
- stream << space << " + name: " << name << std::endl;
+ stream << space << " + name: " << name << std::endl;
stream << space << " + dimension: " << dimension << std::endl;
elements.printself(stream, indent + 1);
node_group.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void ElementGroup::optimize() {
// increasing the locality of data when iterating on the element of a group
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- ElementList::type_iterator it = elements.firstType(_all_dimensions, ghost_type);
- ElementList::type_iterator last = elements.lastType(_all_dimensions, ghost_type);
+ ElementList::type_iterator it =
+ elements.firstType(_all_dimensions, ghost_type);
+ ElementList::type_iterator last =
+ elements.lastType(_all_dimensions, ghost_type);
for (; it != last; ++it) {
Array<UInt> & els = elements(*it, ghost_type);
std::sort(els.begin(), els.end());
Array<UInt>::iterator<> end = std::unique(els.begin(), els.end());
els.resize(end - els.begin());
}
}
node_group.optimize();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::fillFromNodeGroup() {
CSR<Element> node_to_elem;
MeshUtils::buildNode2Elements(this->mesh, node_to_elem, this->dimension);
std::set<Element> seen;
- Array<UInt>::const_iterator<> itn = this->node_group.begin();
+ Array<UInt>::const_iterator<> itn = this->node_group.begin();
Array<UInt>::const_iterator<> endn = this->node_group.end();
- for (;itn != endn; ++itn) {
+ for (; itn != endn; ++itn) {
CSR<Element>::iterator ite = node_to_elem.begin(*itn);
CSR<Element>::iterator ende = node_to_elem.end(*itn);
- for (;ite != ende; ++ite) {
+ for (; ite != ende; ++ite) {
const Element & elem = *ite;
- if(this->dimension != _all_dimensions && this->dimension != Mesh::getSpatialDimension(elem.type)) continue;
- if(seen.find(elem) != seen.end()) continue;
+ if (this->dimension != _all_dimensions &&
+ this->dimension != Mesh::getSpatialDimension(elem.type))
+ continue;
+ if (seen.find(elem) != seen.end())
+ continue;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(elem.type);
- Array<UInt>::const_iterator< Vector<UInt> > conn_it =
- this->mesh.getConnectivity(elem.type, elem.ghost_type).begin(nb_nodes_per_element);
+ Array<UInt>::const_iterator<Vector<UInt>> conn_it =
+ this->mesh.getConnectivity(elem.type, elem.ghost_type)
+ .begin(nb_nodes_per_element);
const Vector<UInt> & conn = conn_it[elem.element];
UInt count = 0;
for (UInt n = 0; n < conn.size(); ++n) {
- count += (this->node_group.getNodes().find(conn(n)) != UInt(-1) ? 1 : 0);
+ count +=
+ (this->node_group.getNodes().find(conn(n)) != UInt(-1) ? 1 : 0);
}
- if(count == nb_nodes_per_element) this->add(elem);
+ if (count == nb_nodes_per_element)
+ this->add(elem);
seen.insert(elem);
}
}
this->optimize();
}
/* -------------------------------------------------------------------------- */
-
} // akantu
diff --git a/src/mesh/group_manager.cc b/src/mesh/group_manager.cc
index 7989e8404..a18c02007 100644
--- a/src/mesh/group_manager.cc
+++ b/src/mesh/group_manager.cc
@@ -1,1042 +1,1040 @@
/**
* @file group_manager.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@gmail.com>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Mon Aug 17 2015
*
* @brief Stores information about ElementGroup and NodeGroup
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "group_manager.hh"
#include "aka_csr.hh"
#include "data_accessor.hh"
#include "element_group.hh"
#include "element_synchronizer.hh"
#include "mesh.hh"
#include "mesh_accessor.hh"
#include "mesh_utils.hh"
#include "node_group.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <iterator>
#include <list>
#include <numeric>
#include <queue>
#include <sstream>
#include <utility>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
GroupManager::GroupManager(const Mesh & mesh, const ID & id,
const MemoryID & mem_id)
: id(id), memory_id(mem_id), mesh(mesh) {
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
GroupManager::~GroupManager() {
auto eit = element_groups.begin();
auto eend = element_groups.end();
for (; eit != eend; ++eit)
delete (eit->second);
auto nit = node_groups.begin();
auto nend = node_groups.end();
for (; nit != nend; ++nit)
delete (nit->second);
}
/* -------------------------------------------------------------------------- */
NodeGroup & GroupManager::createNodeGroup(const std::string & group_name,
bool replace_group) {
AKANTU_DEBUG_IN();
auto it = node_groups.find(group_name);
if (it != node_groups.end()) {
if (replace_group) {
it->second->empty();
AKANTU_DEBUG_OUT();
return *(it->second);
} else
AKANTU_EXCEPTION(
"Trying to create a node group that already exists:" << group_name);
}
std::stringstream sstr;
sstr << this->id << ":" << group_name << "_node_group";
NodeGroup * node_group =
new NodeGroup(group_name, mesh, sstr.str(), memory_id);
node_groups[group_name] = node_group;
AKANTU_DEBUG_OUT();
return *node_group;
}
/* -------------------------------------------------------------------------- */
template <typename T>
NodeGroup &
GroupManager::createFilteredNodeGroup(const std::string & group_name,
const NodeGroup & source_node_group,
T & filter) {
AKANTU_DEBUG_IN();
NodeGroup & node_group = this->createNodeGroup(group_name);
node_group.append(source_node_group);
if (T::type == FilterFunctor::_node_filter_functor) {
node_group.applyNodeFilter(filter);
} else {
AKANTU_ERROR("ElementFilter cannot be applied to NodeGroup yet."
- << " Needs to be implemented.");
+ << " Needs to be implemented.");
}
AKANTU_DEBUG_OUT();
return node_group;
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyNodeGroup(const std::string & group_name) {
AKANTU_DEBUG_IN();
auto nit = node_groups.find(group_name);
auto nend = node_groups.end();
if (nit != nend) {
delete (nit->second);
node_groups.erase(nit);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
UInt dimension,
bool replace_group) {
AKANTU_DEBUG_IN();
NodeGroup & new_node_group =
createNodeGroup(group_name + "_nodes", replace_group);
auto it = element_groups.find(group_name);
if (it != element_groups.end()) {
if (replace_group) {
it->second->empty();
AKANTU_DEBUG_OUT();
return *(it->second);
} else
AKANTU_EXCEPTION("Trying to create a element group that already exists:"
<< group_name);
}
std::stringstream sstr;
sstr << this->id << ":" << group_name << "_element_group";
ElementGroup * element_group = new ElementGroup(
group_name, mesh, new_node_group, dimension, sstr.str(), memory_id);
std::stringstream sstr_nodes;
sstr_nodes << group_name << "_nodes";
node_groups[sstr_nodes.str()] = &new_node_group;
element_groups[group_name] = element_group;
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyElementGroup(const std::string & group_name,
bool destroy_node_group) {
AKANTU_DEBUG_IN();
auto eit = element_groups.find(group_name);
auto eend = element_groups.end();
if (eit != eend) {
if (destroy_node_group)
destroyNodeGroup(eit->second->getNodeGroup().getName());
delete (eit->second);
element_groups.erase(eit);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyAllElementGroups(bool destroy_node_groups) {
AKANTU_DEBUG_IN();
auto eit = element_groups.begin();
auto eend = element_groups.end();
for (; eit != eend; ++eit) {
if (destroy_node_groups)
destroyNodeGroup(eit->second->getNodeGroup().getName());
delete (eit->second);
}
element_groups.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
UInt dimension,
NodeGroup & node_group) {
AKANTU_DEBUG_IN();
if (element_groups.find(group_name) != element_groups.end())
AKANTU_EXCEPTION(
"Trying to create a element group that already exists:" << group_name);
ElementGroup * element_group =
new ElementGroup(group_name, mesh, node_group, dimension,
id + ":" + group_name + "_element_group", memory_id);
element_groups[group_name] = element_group;
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
template <typename T>
ElementGroup & GroupManager::createFilteredElementGroup(
const std::string & group_name, UInt dimension,
const NodeGroup & node_group, T & filter) {
AKANTU_DEBUG_IN();
ElementGroup * element_group = nullptr;
if (T::type == FilterFunctor::_node_filter_functor) {
NodeGroup & filtered_node_group = this->createFilteredNodeGroup(
group_name + "_nodes", node_group, filter);
element_group =
&(this->createElementGroup(group_name, dimension, filtered_node_group));
} else if (T::type == FilterFunctor::_element_filter_functor) {
AKANTU_ERROR(
"Cannot handle an ElementFilter yet. Needs to be implemented.");
}
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
class ClusterSynchronizer : public DataAccessor<Element> {
using DistantIDs = std::set<std::pair<UInt, UInt>>;
public:
ClusterSynchronizer(GroupManager & group_manager, UInt element_dimension,
std::string cluster_name_prefix,
ElementTypeMapArray<UInt> & element_to_fragment,
const ElementSynchronizer & element_synchronizer,
UInt nb_cluster)
: group_manager(group_manager), element_dimension(element_dimension),
cluster_name_prefix(std::move(cluster_name_prefix)),
element_to_fragment(element_to_fragment),
element_synchronizer(element_synchronizer), nb_cluster(nb_cluster) {}
UInt synchronize() {
Communicator & comm = Communicator::getStaticCommunicator();
UInt rank = comm.whoAmI();
UInt nb_proc = comm.getNbProc();
/// find starting index to renumber local clusters
Array<UInt> nb_cluster_per_proc(nb_proc);
nb_cluster_per_proc(rank) = nb_cluster;
comm.allGather(nb_cluster_per_proc);
starting_index = std::accumulate(nb_cluster_per_proc.begin(),
nb_cluster_per_proc.begin() + rank, 0);
UInt global_nb_fragment =
std::accumulate(nb_cluster_per_proc.begin() + rank,
nb_cluster_per_proc.end(), starting_index);
/// create the local to distant cluster pairs with neighbors
element_synchronizer.synchronizeOnce(*this, _gst_gm_clusters);
/// count total number of pairs
Array<int> nb_pairs(nb_proc); // This is potentially a bug for more than
// 2**31 pairs, but due to a all gatherv after
// it must be int to match MPI interfaces
nb_pairs(rank) = distant_ids.size();
comm.allGather(nb_pairs);
UInt total_nb_pairs = std::accumulate(nb_pairs.begin(), nb_pairs.end(), 0);
/// generate pairs global array
UInt local_pair_index =
std::accumulate(nb_pairs.storage(), nb_pairs.storage() + rank, 0);
Array<UInt> total_pairs(total_nb_pairs, 2);
for (auto & ids : distant_ids) {
total_pairs(local_pair_index, 0) = ids.first;
total_pairs(local_pair_index, 1) = ids.second;
++local_pair_index;
}
/// communicate pairs to all processors
nb_pairs *= 2;
comm.allGatherV(total_pairs, nb_pairs);
/// renumber clusters
/// generate fragment list
std::vector<std::set<UInt>> global_clusters;
UInt total_nb_cluster = 0;
Array<bool> is_fragment_in_cluster(global_nb_fragment, 1, false);
std::queue<UInt> fragment_check_list;
while (total_pairs.size() != 0) {
/// create a new cluster
++total_nb_cluster;
global_clusters.resize(total_nb_cluster);
std::set<UInt> & current_cluster = global_clusters[total_nb_cluster - 1];
UInt first_fragment = total_pairs(0, 0);
UInt second_fragment = total_pairs(0, 1);
total_pairs.erase(0);
fragment_check_list.push(first_fragment);
fragment_check_list.push(second_fragment);
while (!fragment_check_list.empty()) {
UInt current_fragment = fragment_check_list.front();
- UInt * total_pairs_end =
- total_pairs.storage() + total_pairs.size() * 2;
+ UInt * total_pairs_end = total_pairs.storage() + total_pairs.size() * 2;
UInt * fragment_found =
std::find(total_pairs.storage(), total_pairs_end, current_fragment);
if (fragment_found != total_pairs_end) {
UInt position = fragment_found - total_pairs.storage();
UInt pair = position / 2;
UInt other_index = (position + 1) % 2;
fragment_check_list.push(total_pairs(pair, other_index));
total_pairs.erase(pair);
} else {
fragment_check_list.pop();
current_cluster.insert(current_fragment);
is_fragment_in_cluster(current_fragment) = true;
}
}
}
/// add to FragmentToCluster all local fragments
for (UInt c = 0; c < global_nb_fragment; ++c) {
if (!is_fragment_in_cluster(c)) {
++total_nb_cluster;
global_clusters.resize(total_nb_cluster);
std::set<UInt> & current_cluster =
global_clusters[total_nb_cluster - 1];
current_cluster.insert(c);
}
}
/// reorganize element groups to match global clusters
for (UInt c = 0; c < global_clusters.size(); ++c) {
/// create new element group corresponding to current cluster
std::stringstream sstr;
sstr << cluster_name_prefix << "_" << c;
ElementGroup & cluster =
group_manager.createElementGroup(sstr.str(), element_dimension, true);
auto it = global_clusters[c].begin();
auto end = global_clusters[c].end();
/// append to current element group all fragments that belong to
/// the same cluster if they exist
for (; it != end; ++it) {
Int local_index = *it - starting_index;
if (local_index < 0 || local_index >= Int(nb_cluster))
continue;
std::stringstream tmp_sstr;
tmp_sstr << "tmp_" << cluster_name_prefix << "_" << local_index;
auto eg_it = group_manager.element_group_find(tmp_sstr.str());
AKANTU_DEBUG_ASSERT(eg_it != group_manager.element_group_end(),
"Temporary fragment \"" << tmp_sstr.str()
<< "\" not found");
cluster.append(*(eg_it->second));
group_manager.destroyElementGroup(tmp_sstr.str(), true);
}
}
return total_nb_cluster;
}
private:
/// functions for parallel communications
inline UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const override {
if (tag == _gst_gm_clusters)
return elements.size() * sizeof(UInt);
return 0;
}
inline void packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const override {
if (tag != _gst_gm_clusters)
return;
Array<Element>::const_iterator<> el_it = elements.begin();
Array<Element>::const_iterator<> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
const Element & el = *el_it;
/// for each element pack its global cluster index
buffer << element_to_fragment(el.type, el.ghost_type)(el.element) +
starting_index;
}
}
inline void unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) override {
if (tag != _gst_gm_clusters)
return;
Array<Element>::const_iterator<> el_it = elements.begin();
Array<Element>::const_iterator<> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
UInt distant_cluster;
buffer >> distant_cluster;
const Element & el = *el_it;
UInt local_cluster =
element_to_fragment(el.type, el.ghost_type)(el.element) +
starting_index;
distant_ids.insert(std::make_pair(local_cluster, distant_cluster));
}
}
private:
GroupManager & group_manager;
UInt element_dimension;
std::string cluster_name_prefix;
ElementTypeMapArray<UInt> & element_to_fragment;
const ElementSynchronizer & element_synchronizer;
UInt nb_cluster;
DistantIDs distant_ids;
UInt starting_index;
};
/* -------------------------------------------------------------------------- */
/// \todo this function doesn't work in 1D
UInt GroupManager::createBoundaryGroupFromGeometry() {
UInt spatial_dimension = mesh.getSpatialDimension();
return createClusters(spatial_dimension - 1, "boundary");
}
/* -------------------------------------------------------------------------- */
UInt GroupManager::createClusters(
UInt element_dimension, Mesh & mesh_facets, std::string cluster_name_prefix,
const GroupManager::ClusteringFilter & filter) {
return createClusters(element_dimension, std::move(cluster_name_prefix),
filter, mesh_facets);
}
/* -------------------------------------------------------------------------- */
UInt GroupManager::createClusters(
UInt element_dimension, std::string cluster_name_prefix,
const GroupManager::ClusteringFilter & filter) {
std::unique_ptr<Mesh> mesh_facets;
if (!mesh_facets && element_dimension > 0) {
MeshAccessor mesh_accessor(const_cast<Mesh &>(mesh));
mesh_facets = std::make_unique<Mesh>(mesh.getSpatialDimension(),
mesh_accessor.getNodesSharedPtr(),
"mesh_facets_for_clusters");
mesh_facets->defineMeshParent(mesh);
MeshUtils::buildAllFacets(mesh, *mesh_facets, element_dimension,
element_dimension - 1);
}
return createClusters(element_dimension, std::move(cluster_name_prefix),
filter, *mesh_facets);
}
/* -------------------------------------------------------------------------- */
//// \todo if needed element list construction can be optimized by
//// templating the filter class
UInt GroupManager::createClusters(UInt element_dimension,
const std::string & cluster_name_prefix,
const GroupManager::ClusteringFilter & filter,
Mesh & mesh_facets) {
AKANTU_DEBUG_IN();
UInt nb_proc = mesh.getCommunicator().getNbProc();
std::string tmp_cluster_name_prefix = cluster_name_prefix;
ElementTypeMapArray<UInt> * element_to_fragment = nullptr;
if (nb_proc > 1 && mesh.isDistributed()) {
element_to_fragment =
new ElementTypeMapArray<UInt>("element_to_fragment", id, memory_id);
element_to_fragment->initialize(
mesh, _nb_component = 1, _spatial_dimension = element_dimension,
_element_kind = _ek_not_defined, _with_nb_element = true);
// mesh.initElementTypeMapArray(*element_to_fragment, 1, element_dimension,
// false, _ek_not_defined, true);
tmp_cluster_name_prefix = "tmp_" + tmp_cluster_name_prefix;
}
ElementTypeMapArray<bool> seen_elements("seen_elements", id, memory_id);
seen_elements.initialize(mesh, _spatial_dimension = element_dimension,
_element_kind = _ek_not_defined,
_with_nb_element = true);
// mesh.initElementTypeMapArray(seen_elements, 1, element_dimension, false,
// _ek_not_defined, true);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Element el;
el.ghost_type = ghost_type;
Mesh::type_iterator type_it =
mesh.firstType(element_dimension, ghost_type, _ek_not_defined);
Mesh::type_iterator type_end =
mesh.lastType(element_dimension, ghost_type, _ek_not_defined);
for (; type_it != type_end; ++type_it) {
el.type = *type_it;
UInt nb_element = mesh.getNbElement(*type_it, ghost_type);
Array<bool> & seen_elements_array = seen_elements(el.type, ghost_type);
for (UInt e = 0; e < nb_element; ++e) {
el.element = e;
if (!filter(el))
seen_elements_array(e) = true;
}
}
}
Array<bool> checked_node(mesh.getNbNodes(), 1, false);
UInt nb_cluster = 0;
/// keep looping until all elements are seen
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Element uns_el;
uns_el.ghost_type = ghost_type;
Mesh::type_iterator type_it =
mesh.firstType(element_dimension, ghost_type, _ek_not_defined);
Mesh::type_iterator type_end =
mesh.lastType(element_dimension, ghost_type, _ek_not_defined);
for (; type_it != type_end; ++type_it) {
uns_el.type = *type_it;
Array<bool> & seen_elements_vec =
seen_elements(uns_el.type, uns_el.ghost_type);
for (UInt e = 0; e < seen_elements_vec.size(); ++e) {
// skip elements that have been already seen
if (seen_elements_vec(e) == true)
continue;
// set current element
uns_el.element = e;
seen_elements_vec(e) = true;
/// create a new cluster
std::stringstream sstr;
sstr << tmp_cluster_name_prefix << "_" << nb_cluster;
ElementGroup & cluster =
createElementGroup(sstr.str(), element_dimension, true);
++nb_cluster;
// point element are cluster by themself
if (element_dimension == 0) {
cluster.add(uns_el);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(uns_el.type);
Vector<UInt> connect =
mesh.getConnectivity(uns_el.type, uns_el.ghost_type)
.begin(nb_nodes_per_element)[uns_el.element];
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
/// add element's nodes to the cluster
UInt node = connect[n];
if (!checked_node(node)) {
cluster.addNode(node);
checked_node(node) = true;
}
}
continue;
}
std::queue<Element> element_to_add;
element_to_add.push(uns_el);
/// keep looping until current cluster is complete (no more
/// connected elements)
while (!element_to_add.empty()) {
/// take first element and erase it in the queue
Element el = element_to_add.front();
element_to_add.pop();
/// if parallel, store cluster index per element
if (nb_proc > 1 && mesh.isDistributed())
(*element_to_fragment)(el.type, el.ghost_type)(el.element) =
nb_cluster - 1;
/// add current element to the cluster
cluster.add(el);
const Array<Element> & element_to_facet =
mesh_facets.getSubelementToElement(el.type, el.ghost_type);
UInt nb_facet_per_element = element_to_facet.getNbComponent();
for (UInt f = 0; f < nb_facet_per_element; ++f) {
const Element & facet = element_to_facet(el.element, f);
if (facet == ElementNull)
continue;
const std::vector<Element> & connected_elements =
mesh_facets.getElementToSubelement(
facet.type, facet.ghost_type)(facet.element);
for (UInt elem = 0; elem < connected_elements.size(); ++elem) {
const Element & check_el = connected_elements[elem];
// check if this element has to be skipped
if (check_el == ElementNull || check_el == el)
continue;
Array<bool> & seen_elements_vec_current =
seen_elements(check_el.type, check_el.ghost_type);
if (seen_elements_vec_current(check_el.element) == false) {
seen_elements_vec_current(check_el.element) = true;
element_to_add.push(check_el);
}
}
}
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
Vector<UInt> connect = mesh.getConnectivity(el.type, el.ghost_type)
.begin(nb_nodes_per_element)[el.element];
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
/// add element's nodes to the cluster
UInt node = connect[n];
if (!checked_node(node)) {
cluster.addNode(node, false);
checked_node(node) = true;
}
}
}
}
}
}
if (nb_proc > 1 && mesh.isDistributed()) {
ClusterSynchronizer cluster_synchronizer(
*this, element_dimension, cluster_name_prefix, *element_to_fragment,
this->mesh.getElementSynchronizer(), nb_cluster);
nb_cluster = cluster_synchronizer.synchronize();
delete element_to_fragment;
}
if (mesh.isDistributed())
this->synchronizeGroupNames();
AKANTU_DEBUG_OUT();
return nb_cluster;
}
/* -------------------------------------------------------------------------- */
template <typename T>
void GroupManager::createGroupsFromMeshData(const std::string & dataset_name) {
std::set<std::string> group_names;
const ElementTypeMapArray<T> & datas = mesh.getData<T>(dataset_name);
- using type_iterator =
- typename ElementTypeMapArray<T>::type_iterator;
+ using type_iterator = typename ElementTypeMapArray<T>::type_iterator;
std::map<std::string, UInt> group_dim;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
type_iterator type_it = datas.firstType(_all_dimensions, *gt);
type_iterator type_end = datas.lastType(_all_dimensions, *gt);
for (; type_it != type_end; ++type_it) {
const Array<T> & dataset = datas(*type_it, *gt);
UInt nb_element = mesh.getNbElement(*type_it, *gt);
AKANTU_DEBUG_ASSERT(dataset.size() == nb_element,
"Not the same number of elements ("
<< *type_it << ":" << *gt
<< ") in the map from MeshData ("
<< dataset.size() << ") " << dataset_name
<< " and in the mesh (" << nb_element << ")!");
for (UInt e(0); e < nb_element; ++e) {
std::stringstream sstr;
sstr << dataset(e);
std::string gname = sstr.str();
group_names.insert(gname);
auto it = group_dim.find(gname);
if (it == group_dim.end()) {
group_dim[gname] = mesh.getSpatialDimension(*type_it);
} else {
it->second = std::max(it->second, mesh.getSpatialDimension(*type_it));
}
}
}
}
auto git = group_names.begin();
auto gend = group_names.end();
for (; git != gend; ++git)
createElementGroup(*git, group_dim[*git]);
if (mesh.isDistributed())
this->synchronizeGroupNames();
Element el;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
el.ghost_type = *gt;
type_iterator type_it = datas.firstType(_all_dimensions, *gt);
type_iterator type_end = datas.lastType(_all_dimensions, *gt);
for (; type_it != type_end; ++type_it) {
el.type = *type_it;
const Array<T> & dataset = datas(*type_it, *gt);
UInt nb_element = mesh.getNbElement(*type_it, *gt);
AKANTU_DEBUG_ASSERT(dataset.size() == nb_element,
"Not the same number of elements in the map from "
"MeshData and in the mesh!");
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(el.type);
Array<UInt>::const_iterator<Vector<UInt>> cit =
mesh.getConnectivity(*type_it, *gt).begin(nb_nodes_per_element);
for (UInt e(0); e < nb_element; ++e, ++cit) {
el.element = e;
std::stringstream sstr;
sstr << dataset(e);
ElementGroup & group = getElementGroup(sstr.str());
group.add(el, false, false);
const Vector<UInt> & connect = *cit;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connect[n];
group.addNode(node, false);
}
}
}
}
git = group_names.begin();
for (; git != gend; ++git) {
getElementGroup(*git).optimize();
}
}
template void GroupManager::createGroupsFromMeshData<std::string>(
const std::string & dataset_name);
template void
GroupManager::createGroupsFromMeshData<UInt>(const std::string & dataset_name);
/* -------------------------------------------------------------------------- */
void GroupManager::createElementGroupFromNodeGroup(
const std::string & name, const std::string & node_group_name,
UInt dimension) {
NodeGroup & node_group = getNodeGroup(node_group_name);
ElementGroup & group = createElementGroup(name, dimension, node_group);
group.fillFromNodeGroup();
}
/* -------------------------------------------------------------------------- */
void GroupManager::printself(std::ostream & stream, int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "GroupManager [" << std::endl;
std::set<std::string> node_group_seen;
for (auto it(element_group_begin()); it != element_group_end(); ++it) {
it->second->printself(stream, indent + 1);
node_group_seen.insert(it->second->getNodeGroup().getName());
}
for (auto it(node_group_begin()); it != node_group_end(); ++it) {
if (node_group_seen.find(it->second->getName()) == node_group_seen.end())
it->second->printself(stream, indent + 1);
}
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
UInt GroupManager::getNbElementGroups(UInt dimension) const {
if (dimension == _all_dimensions)
return element_groups.size();
auto it = element_groups.begin();
auto end = element_groups.end();
UInt count = 0;
for (; it != end; ++it)
count += (it->second->getDimension() == dimension);
return count;
}
/* -------------------------------------------------------------------------- */
void GroupManager::checkAndAddGroups(CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
UInt nb_node_group;
buffer >> nb_node_group;
AKANTU_DEBUG_INFO("Received " << nb_node_group << " node group names");
for (UInt ng = 0; ng < nb_node_group; ++ng) {
std::string node_group_name;
buffer >> node_group_name;
if (node_groups.find(node_group_name) == node_groups.end()) {
this->createNodeGroup(node_group_name);
}
AKANTU_DEBUG_INFO("Received node goup name: " << node_group_name);
}
UInt nb_element_group;
buffer >> nb_element_group;
AKANTU_DEBUG_INFO("Received " << nb_element_group << " element group names");
for (UInt eg = 0; eg < nb_element_group; ++eg) {
std::string element_group_name;
buffer >> element_group_name;
std::string node_group_name;
buffer >> node_group_name;
UInt dim;
buffer >> dim;
AKANTU_DEBUG_INFO("Received element group name: "
<< element_group_name << " corresponding to a "
<< Int(dim) << "D group with node group "
<< node_group_name);
NodeGroup & node_group = *node_groups[node_group_name];
if (element_groups.find(element_group_name) == element_groups.end()) {
this->createElementGroup(element_group_name, dim, node_group);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::fillBufferWithGroupNames(
DynamicCommunicationBuffer & comm_buffer) const {
AKANTU_DEBUG_IN();
// packing node group names;
UInt nb_groups = this->node_groups.size();
comm_buffer << nb_groups;
AKANTU_DEBUG_INFO("Sending " << nb_groups << " node group names");
auto nnames_it = node_groups.begin();
auto nnames_end = node_groups.end();
for (; nnames_it != nnames_end; ++nnames_it) {
std::string node_group_name = nnames_it->first;
comm_buffer << node_group_name;
AKANTU_DEBUG_INFO("Sending node goupe name: " << node_group_name);
}
// packing element group names with there associated node group name
nb_groups = this->element_groups.size();
comm_buffer << nb_groups;
AKANTU_DEBUG_INFO("Sending " << nb_groups << " element group names");
auto gnames_it = this->element_groups.begin();
auto gnames_end = this->element_groups.end();
for (; gnames_it != gnames_end; ++gnames_it) {
ElementGroup & element_group = *(gnames_it->second);
std::string element_group_name = gnames_it->first;
std::string node_group_name = element_group.getNodeGroup().getName();
UInt dim = element_group.getDimension();
comm_buffer << element_group_name;
comm_buffer << node_group_name;
comm_buffer << dim;
AKANTU_DEBUG_INFO("Sending element group name: "
<< element_group_name << " corresponding to a "
<< Int(dim) << "D group with the node group "
<< node_group_name);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::synchronizeGroupNames() {
AKANTU_DEBUG_IN();
const Communicator & comm = mesh.getCommunicator();
Int nb_proc = comm.getNbProc();
Int my_rank = comm.whoAmI();
if (nb_proc == 1)
return;
if (my_rank == 0) {
for (Int p = 1; p < nb_proc; ++p) {
CommunicationStatus status;
comm.probe<char>(p, p, status);
AKANTU_DEBUG_INFO("Got " << printMemorySize<char>(status.size())
<< " from proc " << p);
CommunicationBuffer recv_buffer(status.size());
comm.receive(recv_buffer, p, p);
this->checkAndAddGroups(recv_buffer);
}
DynamicCommunicationBuffer comm_buffer;
this->fillBufferWithGroupNames(comm_buffer);
UInt buffer_size = comm_buffer.size();
comm.broadcast(buffer_size, 0);
AKANTU_DEBUG_INFO("Initiating broadcast with "
<< printMemorySize<char>(comm_buffer.size()));
comm.broadcast(comm_buffer, 0);
} else {
DynamicCommunicationBuffer comm_buffer;
this->fillBufferWithGroupNames(comm_buffer);
AKANTU_DEBUG_INFO("Sending " << printMemorySize<char>(comm_buffer.size())
<< " to proc " << 0);
comm.send(comm_buffer, 0, my_rank);
UInt buffer_size = 0;
comm.broadcast(buffer_size, 0);
AKANTU_DEBUG_INFO("Receiving broadcast with "
<< printMemorySize<char>(comm_buffer.size()));
CommunicationBuffer recv_buffer(buffer_size);
comm.broadcast(recv_buffer, 0);
this->checkAndAddGroups(recv_buffer);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
const ElementGroup &
GroupManager::getElementGroup(const std::string & name) const {
auto it = element_group_find(name);
if (it == element_group_end()) {
AKANTU_EXCEPTION("There are no element groups named "
<< name << " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::getElementGroup(const std::string & name) {
auto it = element_group_find(name);
if (it == element_group_end()) {
AKANTU_EXCEPTION("There are no element groups named "
<< name << " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
const NodeGroup & GroupManager::getNodeGroup(const std::string & name) const {
auto it = node_group_find(name);
if (it == node_group_end()) {
AKANTU_EXCEPTION("There are no node groups named "
<< name << " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
NodeGroup & GroupManager::getNodeGroup(const std::string & name) {
auto it = node_group_find(name);
if (it == node_group_end()) {
AKANTU_EXCEPTION("There are no node groups named "
<< name << " associated to the group manager: " << id);
}
return *(it->second);
}
} // namespace akantu
diff --git a/src/mesh/group_manager.hh b/src/mesh/group_manager.hh
index 1a203623a..56998407b 100644
--- a/src/mesh/group_manager.hh
+++ b/src/mesh/group_manager.hh
@@ -1,317 +1,316 @@
/**
* @file group_manager.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@gmail.com>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Mon Nov 16 2015
*
* @brief Stores information relevent to the notion of element and nodes
*groups.
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_GROUP_MANAGER_HH__
#define __AKANTU_GROUP_MANAGER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
#include <set>
/* -------------------------------------------------------------------------- */
namespace akantu {
class ElementGroup;
class NodeGroup;
class Mesh;
class Element;
class ElementSynchronizer;
template <bool> class CommunicationBufferTemplated;
namespace dumper {
class Field;
}
} // namespace akantu
namespace akantu {
/* -------------------------------------------------------------------------- */
class GroupManager {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
private:
-
#ifdef SWIGPYTHON
public:
using ElementGroups = std::map<std::string, ElementGroup *>;
using NodeGroups = std::map<std::string, NodeGroup *>;
private:
#else
using ElementGroups = std::map<std::string, ElementGroup *>;
using NodeGroups = std::map<std::string, NodeGroup *>;
#endif
public:
using GroupManagerTypeSet = std::set<ElementType>;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
GroupManager(const Mesh & mesh, const ID & id = "group_manager",
const MemoryID & memory_id = 0);
virtual ~GroupManager();
/* ------------------------------------------------------------------------ */
/* Groups iterators */
/* ------------------------------------------------------------------------ */
public:
using node_group_iterator = NodeGroups::iterator;
using element_group_iterator = ElementGroups::iterator;
using const_node_group_iterator = NodeGroups::const_iterator;
using const_element_group_iterator = ElementGroups::const_iterator;
#ifndef SWIG
#define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(group_type, function, \
param_in, param_out) \
inline BOOST_PP_CAT(BOOST_PP_CAT(const_, group_type), _iterator) \
BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) const { \
return BOOST_PP_CAT(group_type, s).function(param_out); \
}; \
\
inline BOOST_PP_CAT(group_type, _iterator) \
BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) { \
return BOOST_PP_CAT(group_type, s).function(param_out); \
}
#define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(group_type, function) \
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION( \
group_type, function, BOOST_PP_EMPTY(), BOOST_PP_EMPTY())
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, begin);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, end);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, begin);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, end);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(element_group, find,
const std::string & name, name);
AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(node_group, find,
const std::string & name, name);
#endif
/* ------------------------------------------------------------------------ */
/* Clustering filter */
/* ------------------------------------------------------------------------ */
public:
class ClusteringFilter {
public:
virtual bool operator()(const Element &) const { return true; }
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// create an empty node group
NodeGroup & createNodeGroup(const std::string & group_name,
bool replace_group = false);
/// create a node group from another node group but filtered
template <typename T>
NodeGroup & createFilteredNodeGroup(const std::string & group_name,
const NodeGroup & node_group, T & filter);
/// destroy a node group
void destroyNodeGroup(const std::string & group_name);
/// create an element group and the associated node group
ElementGroup & createElementGroup(const std::string & group_name,
UInt dimension = _all_dimensions,
bool replace_group = false);
/// create an element group from another element group but filtered
template <typename T>
ElementGroup &
createFilteredElementGroup(const std::string & group_name, UInt dimension,
const NodeGroup & node_group, T & filter);
/// destroy an element group and the associated node group
void destroyElementGroup(const std::string & group_name,
bool destroy_node_group = false);
/// destroy all element groups and the associated node groups
void destroyAllElementGroups(bool destroy_node_groups = false);
/// create a element group using an existing node group
ElementGroup & createElementGroup(const std::string & group_name,
UInt dimension, NodeGroup & node_group);
/// create groups based on values stored in a given mesh data
template <typename T>
void createGroupsFromMeshData(const std::string & dataset_name);
/// create boundaries group by a clustering algorithm \todo extend to parallel
UInt createBoundaryGroupFromGeometry();
/// create element clusters for a given dimension
UInt createClusters(UInt element_dimension, Mesh & mesh_facets,
std::string cluster_name_prefix = "cluster",
const ClusteringFilter & filter = ClusteringFilter());
/// create element clusters for a given dimension
UInt createClusters(UInt element_dimension,
std::string cluster_name_prefix = "cluster",
const ClusteringFilter & filter = ClusteringFilter());
private:
/// create element clusters for a given dimension
UInt createClusters(UInt element_dimension,
const std::string & cluster_name_prefix,
const ClusteringFilter & filter, Mesh & mesh_facets);
public:
/// Create an ElementGroup based on a NodeGroup
void createElementGroupFromNodeGroup(const std::string & name,
const std::string & node_group,
UInt dimension = _all_dimensions);
virtual void printself(std::ostream & stream, int indent = 0) const;
/// this function insure that the group names are present on all processors
/// /!\ it is a SMP call
void synchronizeGroupNames();
/// register an elemental field to the given group name (overloading for
/// ElementalPartionField)
#ifndef SWIG
template <typename T, template <bool> class dump_type>
dumper::Field * createElementalField(
const ElementTypeMapArray<T> & field, const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
/// register an elemental field to the given group name (overloading for
/// ElementalField)
template <typename T, template <class> class ret_type,
template <class, template <class> class, bool> class dump_type>
dumper::Field * createElementalField(
const ElementTypeMapArray<T> & field, const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
/// register an elemental field to the given group name (overloading for
/// MaterialInternalField)
template <typename T,
/// type of InternalMaterialField
template <typename, bool filtered> class dump_type>
dumper::Field * createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem);
template <typename type, bool flag, template <class, bool> class ftype>
dumper::Field * createNodalField(const ftype<type, flag> * field,
const std::string & group_name,
UInt padding_size = 0);
template <typename type, bool flag, template <class, bool> class ftype>
dumper::Field * createStridedNodalField(const ftype<type, flag> * field,
const std::string & group_name,
UInt size, UInt stride,
UInt padding_size);
protected:
/// fill a buffer with all the group names
void fillBufferWithGroupNames(
CommunicationBufferTemplated<false> & comm_buffer) const;
/// take a buffer and create the missing groups localy
void checkAndAddGroups(CommunicationBufferTemplated<true> & buffer);
/// register an elemental field to the given group name
template <class dump_type, typename field_type>
inline dumper::Field *
createElementalField(const field_type & field, const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
const ElementTypeMap<UInt> & nb_data_per_elem);
/// register an elemental field to the given group name
template <class dump_type, typename field_type>
inline dumper::Field *
createElementalFilteredField(const field_type & field,
const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem);
#endif
/* ------------------------------------------------------------------------ */
/* Accessor */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(ElementGroups, element_groups, const ElementGroups &);
const ElementGroup & getElementGroup(const std::string & name) const;
const NodeGroup & getNodeGroup(const std::string & name) const;
ElementGroup & getElementGroup(const std::string & name);
NodeGroup & getNodeGroup(const std::string & name);
UInt getNbElementGroups(UInt dimension = _all_dimensions) const;
UInt getNbNodeGroups() { return node_groups.size(); };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id to create element and node groups
ID id;
/// memory_id to create element and node groups
MemoryID memory_id;
/// list of the node groups managed
NodeGroups node_groups;
/// list of the element groups managed
ElementGroups element_groups;
/// Mesh to which the element belongs
const Mesh & mesh;
};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const GroupManager & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AKANTU_GROUP_MANAGER_HH__ */
diff --git a/src/mesh/group_manager_inline_impl.cc b/src/mesh/group_manager_inline_impl.cc
index 437abda2b..9629a5279 100644
--- a/src/mesh/group_manager_inline_impl.cc
+++ b/src/mesh/group_manager_inline_impl.cc
@@ -1,205 +1,205 @@
/**
* @file group_manager_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Tue Dec 08 2015
*
* @brief Stores information relevent to the notion of domain boundary and
* surfaces.
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_field.hh"
#include "element_group.hh"
#include "element_type_map_filter.hh"
#ifdef AKANTU_USE_IOHELPER
#include "dumper_nodal_field.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename T, template <bool> class dump_type>
dumper::Field * GroupManager::createElementalField(
const ElementTypeMapArray<T> & field, const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem) {
const ElementTypeMapArray<T> * field_ptr = &field;
if (field_ptr == nullptr)
return nullptr;
if (group_name == "all")
return this->createElementalField<dump_type<false>>(
field, group_name, spatial_dimension, kind, nb_data_per_elem);
else
return this->createElementalFilteredField<dump_type<true>>(
field, group_name, spatial_dimension, kind, nb_data_per_elem);
}
/* -------------------------------------------------------------------------- */
template <typename T, template <class> class T2,
template <class, template <class> class, bool> class dump_type>
dumper::Field * GroupManager::createElementalField(
const ElementTypeMapArray<T> & field, const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem) {
const ElementTypeMapArray<T> * field_ptr = &field;
if (field_ptr == nullptr)
return nullptr;
if (group_name == "all")
return this->createElementalField<dump_type<T, T2, false>>(
field, group_name, spatial_dimension, kind, nb_data_per_elem);
else
return this->createElementalFilteredField<dump_type<T, T2, true>>(
field, group_name, spatial_dimension, kind, nb_data_per_elem);
}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename T2, bool filtered>
class dump_type> ///< type of InternalMaterialField
dumper::Field *
GroupManager::createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem) {
const ElementTypeMapArray<T> * field_ptr = &field;
if (field_ptr == nullptr)
return nullptr;
if (group_name == "all")
return this->createElementalField<dump_type<T, false>>(
field, group_name, spatial_dimension, kind, nb_data_per_elem);
else
return this->createElementalFilteredField<dump_type<T, true>>(
field, group_name, spatial_dimension, kind, nb_data_per_elem);
}
/* -------------------------------------------------------------------------- */
template <typename dump_type, typename field_type>
dumper::Field * GroupManager::createElementalField(
const field_type & field, const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
const ElementTypeMap<UInt> & nb_data_per_elem) {
const field_type * field_ptr = &field;
if (field_ptr == nullptr)
return nullptr;
if (group_name != "all")
throw;
dumper::Field * dumper =
new dump_type(field, spatial_dimension, _not_ghost, kind);
dumper->setNbDataPerElem(nb_data_per_elem);
return dumper;
}
/* -------------------------------------------------------------------------- */
template <typename dump_type, typename field_type>
dumper::Field * GroupManager::createElementalFilteredField(
const field_type & field, const std::string & group_name,
UInt spatial_dimension, const ElementKind & kind,
ElementTypeMap<UInt> nb_data_per_elem) {
const field_type * field_ptr = &field;
if (field_ptr == nullptr)
return nullptr;
if (group_name == "all")
throw;
using T = typename field_type::type;
ElementGroup & group = this->getElementGroup(group_name);
UInt dim = group.getDimension();
if (dim != spatial_dimension)
throw;
const ElementTypeMapArray<UInt> & elemental_filter = group.getElements();
auto * filtered = new ElementTypeMapArrayFilter<T>(field, elemental_filter,
nb_data_per_elem);
dumper::Field * dumper = new dump_type(*filtered, dim, _not_ghost, kind);
dumper->setNbDataPerElem(nb_data_per_elem);
return dumper;
}
/* -------------------------------------------------------------------------- */
template <typename type, bool flag, template <class, bool> class ftype>
dumper::Field * GroupManager::createNodalField(const ftype<type, flag> * field,
const std::string & group_name,
UInt padding_size) {
if (field == nullptr)
return nullptr;
if (group_name == "all") {
using DumpType = typename dumper::NodalField<type, false>;
auto * dumper = new DumpType(*field, 0, 0, nullptr);
dumper->setPadding(padding_size);
return dumper;
} else {
ElementGroup & group = this->getElementGroup(group_name);
const Array<UInt> * nodal_filter = &(group.getNodes());
using DumpType = typename dumper::NodalField<type, true>;
auto * dumper = new DumpType(*field, 0, 0, nodal_filter);
dumper->setPadding(padding_size);
return dumper;
}
return nullptr;
}
/* -------------------------------------------------------------------------- */
template <typename type, bool flag, template <class, bool> class ftype>
dumper::Field *
GroupManager::createStridedNodalField(const ftype<type, flag> * field,
const std::string & group_name, UInt size,
UInt stride, UInt padding_size) {
if (field == NULL)
return nullptr;
if (group_name == "all") {
- using DumpType= typename dumper::NodalField<type, false>;
+ using DumpType = typename dumper::NodalField<type, false>;
auto * dumper = new DumpType(*field, size, stride, NULL);
dumper->setPadding(padding_size);
return dumper;
} else {
ElementGroup & group = this->getElementGroup(group_name);
const Array<UInt> * nodal_filter = &(group.getNodes());
- using DumpType = typename dumper::NodalField<type, true> ;
+ using DumpType = typename dumper::NodalField<type, true>;
auto * dumper = new DumpType(*field, size, stride, nodal_filter);
dumper->setPadding(padding_size);
return dumper;
}
return nullptr;
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
#endif
diff --git a/src/mesh/mesh.cc b/src/mesh/mesh.cc
index 88c7d1050..bb13d8b62 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,571 +1,570 @@
/**
* @file mesh.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Jan 22 2016
*
* @brief class handling meshes
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_config.hh"
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
#include "group_manager_inline_impl.cc"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_iterators.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include "communicator.hh"
#include "element_synchronizer.hh"
#include "facet_synchronizer.hh"
#include "mesh_utils_distribution.hh"
#include "node_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
#include "dumper_field.hh"
#include "dumper_internal_material_field.hh"
#endif
/* -------------------------------------------------------------------------- */
#include <limits>
#include <sstream>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id,
Communicator & communicator)
: Memory(id, memory_id),
GroupManager(*this, id + ":group_manager", memory_id),
nodes_type(0, 1, id + ":nodes_type"),
connectivities("connectivities", id, memory_id),
ghosts_counters("ghosts_counters", id, memory_id),
normals("normals", id, memory_id), spatial_dimension(spatial_dimension),
lower_bounds(spatial_dimension, 0.), upper_bounds(spatial_dimension, 0.),
size(spatial_dimension, 0.), local_lower_bounds(spatial_dimension, 0.),
local_upper_bounds(spatial_dimension, 0.),
mesh_data("mesh_data", id, memory_id), communicator(&communicator) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension, Communicator & communicator, const ID & id,
const MemoryID & memory_id)
: Mesh(spatial_dimension, id, memory_id, communicator) {
AKANTU_DEBUG_IN();
this->nodes =
std::make_shared<Array<Real>>(0, spatial_dimension, id + ":coordinates");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id)
: Mesh(spatial_dimension, Communicator::getStaticCommunicator(), id,
memory_id) {}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension, const std::shared_ptr<Array<Real>> & nodes,
const ID & id, const MemoryID & memory_id)
: Mesh(spatial_dimension, id, memory_id,
Communicator::getStaticCommunicator()) {
this->nodes = nodes;
this->nb_global_nodes = this->nodes->size();
this->nodes_to_elements.resize(nodes->size());
for (auto & node_set : nodes_to_elements) {
node_set = std::make_unique<std::set<Element>>();
}
this->computeBoundingBox();
}
/* -------------------------------------------------------------------------- */
void Mesh::getBarycenters(Array<Real> & barycenter, const ElementType & type,
const GhostType & ghost_type) const {
barycenter.resize(getNbElement(type, ghost_type));
for (auto && data : enumerate(make_view(barycenter, spatial_dimension))) {
getBarycenter(Element{type, UInt(std::get<0>(data)), ghost_type},
std::get<1>(data));
}
}
/* -------------------------------------------------------------------------- */
Mesh & Mesh::initMeshFacets(const ID & id) {
AKANTU_DEBUG_IN();
if (!mesh_facets) {
mesh_facets = std::make_unique<Mesh>(spatial_dimension, this->nodes,
getID() + ":" + id, getMemoryID());
mesh_facets->mesh_parent = this;
mesh_facets->is_mesh_facets = true;
MeshUtils::buildAllFacets(*this, *mesh_facets, 0);
if (mesh.isDistributed()) {
mesh_facets->is_distributed = true;
mesh_facets->element_synchronizer = std::make_unique<FacetSynchronizer>(
*mesh_facets, mesh.getElementSynchronizer());
}
/// transfers the the mesh physical names to the mesh facets
if (not this->hasData("physical_names")) {
AKANTU_DEBUG_OUT();
return *mesh_facets;
}
if (not mesh_facets->hasData("physical_names")) {
mesh_facets->registerData<std::string>("physical_names");
}
auto & mesh_phys_data = this->getData<std::string>("physical_names");
auto & phys_data = mesh_facets->getData<std::string>("physical_names");
phys_data.initialize(*mesh_facets,
_spatial_dimension = spatial_dimension - 1,
_with_nb_element = true);
ElementTypeMapArray<Real> barycenters(getID(), "temporary_barycenters");
barycenters.initialize(*mesh_facets, _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension - 1,
_with_nb_element = true);
for (auto && ghost_type : ghost_types) {
- for (auto && type : barycenters.elementTypes(
- spatial_dimension - 1, ghost_type)) {
+ for (auto && type :
+ barycenters.elementTypes(spatial_dimension - 1, ghost_type)) {
mesh_facets->getBarycenters(barycenters(type, ghost_type), type,
ghost_type);
}
}
for_each_element(
mesh,
[&](auto && element) {
Vector<Real> barycenter(spatial_dimension);
mesh.getBarycenter(element, barycenter);
auto norm_barycenter = barycenter.norm();
auto tolerance = Math::getTolerance();
if (norm_barycenter > tolerance)
tolerance *= norm_barycenter;
const auto & element_to_facet = mesh_facets->getElementToSubelement(
element.type, element.ghost_type);
Vector<Real> barycenter_facet(spatial_dimension);
auto range =
enumerate(make_view(barycenters(element.type, element.ghost_type),
spatial_dimension));
#ifndef AKANTU_NDEBUG
auto min_dist = std::numeric_limits<Real>::max();
#endif
// this is a spacial search coded the most inefficient way.
auto facet =
std::find_if(range.begin(), range.end(), [&](auto && data) {
auto facet = std::get<0>(data);
if (element_to_facet(facet)[1] == ElementNull)
return false;
auto norm_distance = barycenter.distance(std::get<1>(data));
#ifndef AKANTU_NDEBUG
min_dist = std::min(min_dist, norm_distance);
#endif
return (norm_distance < tolerance);
});
if (facet == range.end()) {
AKANTU_DEBUG_INFO("The element "
<< element
<< " did not find its associated facet in the "
"mesh_facets! Try to decrease math tolerance. "
"The closest element was at a distance of "
<< min_dist);
return;
}
// set physical name
phys_data(Element{element.type, UInt(std::get<0>(*facet)),
element.ghost_type}) = mesh_phys_data(element);
},
_spatial_dimension = spatial_dimension - 1);
mesh_facets->createGroupsFromMeshData<std::string>("physical_names");
}
AKANTU_DEBUG_OUT();
return *mesh_facets;
}
/* -------------------------------------------------------------------------- */
void Mesh::defineMeshParent(const Mesh & mesh) {
AKANTU_DEBUG_IN();
this->mesh_parent = &mesh;
this->is_mesh_facets = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh::~Mesh() = default;
/* -------------------------------------------------------------------------- */
void Mesh::read(const std::string & filename, const MeshIOType & mesh_io_type) {
MeshIO mesh_io;
mesh_io.read(filename, *this, mesh_io_type);
type_iterator it =
this->firstType(spatial_dimension, _not_ghost, _ek_not_defined);
type_iterator last =
this->lastType(spatial_dimension, _not_ghost, _ek_not_defined);
if (it == last)
AKANTU_EXCEPTION(
"The mesh contained in the file "
<< filename << " does not seem to be of the good dimension."
<< " No element of dimension " << spatial_dimension << " where read.");
this->nb_global_nodes = this->nodes->size();
this->computeBoundingBox();
this->nodes_to_elements.resize(nodes->size());
for (auto & node_set : nodes_to_elements) {
node_set = std::make_unique<std::set<Element>>();
}
}
/* -------------------------------------------------------------------------- */
void Mesh::write(const std::string & filename,
const MeshIOType & mesh_io_type) {
MeshIO mesh_io;
mesh_io.write(filename, *this, mesh_io_type);
}
/* -------------------------------------------------------------------------- */
void Mesh::printself(std::ostream & stream, int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "Mesh [" << std::endl;
stream << space << " + id : " << getID() << std::endl;
stream << space << " + spatial dimension : " << this->spatial_dimension
<< std::endl;
stream << space << " + nodes [" << std::endl;
nodes->printself(stream, indent + 2);
stream << space << " + connectivities [" << std::endl;
connectivities.printself(stream, indent + 2);
stream << space << " ]" << std::endl;
GroupManager::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void Mesh::computeBoundingBox() {
AKANTU_DEBUG_IN();
for (UInt k = 0; k < spatial_dimension; ++k) {
local_lower_bounds(k) = std::numeric_limits<double>::max();
local_upper_bounds(k) = -std::numeric_limits<double>::max();
}
for (UInt i = 0; i < nodes->size(); ++i) {
// if(!isPureGhostNode(i))
for (UInt k = 0; k < spatial_dimension; ++k) {
local_lower_bounds(k) = std::min(local_lower_bounds[k], (*nodes)(i, k));
local_upper_bounds(k) = std::max(local_upper_bounds[k], (*nodes)(i, k));
}
}
if (this->is_distributed) {
Matrix<Real> reduce_bounds(spatial_dimension, 2);
for (UInt k = 0; k < spatial_dimension; ++k) {
reduce_bounds(k, 0) = local_lower_bounds(k);
reduce_bounds(k, 1) = -local_upper_bounds(k);
}
communicator->allReduce(reduce_bounds, SynchronizerOperation::_min);
for (UInt k = 0; k < spatial_dimension; ++k) {
lower_bounds(k) = reduce_bounds(k, 0);
upper_bounds(k) = -reduce_bounds(k, 1);
}
} else {
this->lower_bounds = this->local_lower_bounds;
this->upper_bounds = this->local_upper_bounds;
}
size = upper_bounds - lower_bounds;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Mesh::initNormals() {
normals.initialize(*this, _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension,
_element_kind = _ek_not_defined);
}
/* -------------------------------------------------------------------------- */
void Mesh::getGlobalConnectivity(
ElementTypeMapArray<UInt> & global_connectivity) {
AKANTU_DEBUG_IN();
for (auto && ghost_type : ghost_types) {
for (auto type :
- global_connectivity.elementTypes(_spatial_dimension = _all_dimensions,
- _element_kind = _ek_not_defined,
- _ghost_type = ghost_type)) {
+ global_connectivity.elementTypes(_spatial_dimension = _all_dimensions,
+ _element_kind = _ek_not_defined, _ghost_type = ghost_type)) {
if (not connectivities.exists(type, ghost_type))
continue;
auto & local_conn = connectivities(type, ghost_type);
auto & g_connectivity = global_connectivity(type, ghost_type);
UInt nb_nodes = local_conn.size() * local_conn.getNbComponent();
if (not nodes_global_ids && is_mesh_facets) {
std::transform(
local_conn.begin_reinterpret(nb_nodes),
local_conn.end_reinterpret(nb_nodes),
g_connectivity.begin_reinterpret(nb_nodes),
[& node_ids = *mesh_parent->nodes_global_ids](UInt l)->UInt {
return node_ids(l);
});
} else {
std::transform(local_conn.begin_reinterpret(nb_nodes),
local_conn.end_reinterpret(nb_nodes),
g_connectivity.begin_reinterpret(nb_nodes),
[& node_ids = *nodes_global_ids](UInt l)->UInt {
return node_ids(l);
});
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Mesh::getGroupDumper(const std::string & dumper_name,
const std::string & group_name) {
if (group_name == "all")
return this->getDumper(dumper_name);
else
return element_groups[group_name]->getDumper(dumper_name);
}
/* -------------------------------------------------------------------------- */
template <typename T>
ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<T> & arrays,
const ElementKind & element_kind) {
ElementTypeMap<UInt> nb_data_per_elem;
for (auto type : elementTypes(spatial_dimension, _not_ghost, element_kind)) {
UInt nb_elements = this->getNbElement(type);
auto & array = arrays(type);
nb_data_per_elem(type) = array.getNbComponent() * array.size();
nb_data_per_elem(type) /= nb_elements;
}
return nb_data_per_elem;
}
/* -------------------------------------------------------------------------- */
template ElementTypeMap<UInt>
Mesh::getNbDataPerElem(ElementTypeMapArray<Real> & array,
const ElementKind & element_kind);
template ElementTypeMap<UInt>
Mesh::getNbDataPerElem(ElementTypeMapArray<UInt> & array,
const ElementKind & element_kind);
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
template <typename T>
dumper::Field *
Mesh::createFieldFromAttachedData(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind) {
dumper::Field * field = nullptr;
ElementTypeMapArray<T> * internal = nullptr;
try {
internal = &(this->getData<T>(field_id));
} catch (...) {
return nullptr;
}
ElementTypeMap<UInt> nb_data_per_elem =
this->getNbDataPerElem(*internal, element_kind);
field = this->createElementalField<T, dumper::InternalMaterialField>(
*internal, group_name, this->spatial_dimension, element_kind,
nb_data_per_elem);
return field;
}
template dumper::Field *
Mesh::createFieldFromAttachedData<Real>(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind);
template dumper::Field *
Mesh::createFieldFromAttachedData<UInt>(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind);
#endif
/* -------------------------------------------------------------------------- */
void Mesh::distribute() {
this->distribute(Communicator::getStaticCommunicator());
}
/* -------------------------------------------------------------------------- */
void Mesh::distribute(Communicator & communicator) {
AKANTU_DEBUG_ASSERT(is_distributed == false,
"This mesh is already distribute");
this->communicator = &communicator;
this->element_synchronizer = std::make_unique<ElementSynchronizer>(
*this, this->getID() + ":element_synchronizer", this->getMemoryID(),
true);
this->node_synchronizer = std::make_unique<NodeSynchronizer>(
*this, this->getID() + ":node_synchronizer", this->getMemoryID(), true);
Int psize = this->communicator->getNbProc();
#ifdef AKANTU_USE_SCOTCH
Int prank = this->communicator->whoAmI();
if (prank == 0) {
MeshPartitionScotch partition(*this, spatial_dimension);
partition.partitionate(psize);
MeshUtilsDistribution::distributeMeshCentralized(*this, 0, partition);
} else {
MeshUtilsDistribution::distributeMeshCentralized(*this, 0);
}
#else
if (!(psize == 1)) {
AKANTU_ERROR("Cannot distribute a mesh without a partitioning tool");
}
#endif
this->is_distributed = true;
this->computeBoundingBox();
}
/* -------------------------------------------------------------------------- */
void Mesh::getAssociatedElements(const Array<UInt> & node_list,
Array<Element> & elements) {
for (const auto & node : node_list)
for (const auto & element : *nodes_to_elements[node])
elements.push_back(element);
}
/* -------------------------------------------------------------------------- */
void Mesh::fillNodesToElements() {
Element e;
UInt nb_nodes = nodes->size();
for (UInt n = 0; n < nb_nodes; ++n) {
if (this->nodes_to_elements[n])
this->nodes_to_elements[n]->clear();
else
this->nodes_to_elements[n] = std::make_unique<std::set<Element>>();
}
for (auto ghost_type : ghost_types) {
e.ghost_type = ghost_type;
for (const auto & type :
elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
e.type = type;
UInt nb_element = this->getNbElement(type, ghost_type);
Array<UInt>::const_iterator<Vector<UInt>> conn_it =
connectivities(type, ghost_type)
.begin(Mesh::getNbNodesPerElement(type));
for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
e.element = el;
const Vector<UInt> & conn = *conn_it;
for (UInt n = 0; n < conn.size(); ++n)
nodes_to_elements[conn(n)]->insert(e);
}
}
}
}
/* -------------------------------------------------------------------------- */
void Mesh::eraseElements(const Array<Element> & elements) {
ElementTypeMap<UInt> last_element;
RemovedElementsEvent event(*this);
auto & remove_list = event.getList();
auto & new_numbering = event.getNewNumbering();
for (auto && el : elements) {
if (el.ghost_type != _not_ghost) {
auto & count = ghosts_counters(el);
--count;
if (count > 0)
continue;
}
remove_list.push_back(el);
if (not last_element.exists(el.type, el.ghost_type)) {
UInt nb_element = mesh.getNbElement(el.type, el.ghost_type);
last_element(nb_element - 1, el.type, el.ghost_type);
auto & numbering =
new_numbering.alloc(nb_element, 1, el.type, el.ghost_type);
for (auto && pair : enumerate(numbering)) {
std::get<1>(pair) = std::get<0>(pair);
}
}
UInt & pos = last_element(el.type, el.ghost_type);
auto & numbering = new_numbering(el.type, el.ghost_type);
numbering(el.element) = UInt(-1);
numbering(pos) = el.element;
--pos;
}
this->sendEvent(event);
}
} // namespace akantu
diff --git a/src/mesh/mesh_data.cc b/src/mesh/mesh_data.cc
index f669598df..88022e988 100644
--- a/src/mesh/mesh_data.cc
+++ b/src/mesh/mesh_data.cc
@@ -1,49 +1,48 @@
/**
* @file mesh_data.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri Apr 13 2012
* @date last modification: Sun Oct 19 2014
*
* @brief Stores generic data loaded from the mesh file
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
-#include "mesh.hh"
#include "mesh_data.hh"
+#include "mesh.hh"
namespace akantu {
-MeshData::MeshData(const ID & _id, const ID & parent_id, const MemoryID & mem_id)
- : Memory(parent_id + ":" + _id, mem_id) {
-}
+MeshData::MeshData(const ID & _id, const ID & parent_id,
+ const MemoryID & mem_id)
+ : Memory(parent_id + ":" + _id, mem_id) {}
MeshData::~MeshData() {
ElementalDataMap::iterator it, end;
- for(it = elemental_data.begin(); it != elemental_data.end(); ++it) {
+ for (it = elemental_data.begin(); it != elemental_data.end(); ++it) {
delete it->second;
}
}
} // akantu
-
diff --git a/src/mesh/mesh_data_tmpl.hh b/src/mesh/mesh_data_tmpl.hh
index 99c7103ca..6cd581045 100644
--- a/src/mesh/mesh_data_tmpl.hh
+++ b/src/mesh/mesh_data_tmpl.hh
@@ -1,276 +1,275 @@
/**
* @file mesh_data_tmpl.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
* @date last modification: Thu Nov 05 2015
*
* @brief Stores generic data loaded from the mesh file
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_data.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_DATA_TMPL_HH__
#define __AKANTU_MESH_DATA_TMPL_HH__
namespace akantu {
#define MESH_DATA_GET_TYPE(r, data, type) \
template <> \
inline MeshDataTypeCode \
MeshData::getTypeCode<BOOST_PP_TUPLE_ELEM(2, 1, type)>() const { \
return BOOST_PP_TUPLE_ELEM(2, 0, type); \
}
/* -------------------------------------------------------------------------- */
// get the type of the data stored in elemental_data
template <typename T> inline MeshDataTypeCode MeshData::getTypeCode() const {
AKANTU_ERROR("Type " << debug::demangle(typeid(T).name())
- << "not implemented by MeshData.");
+ << "not implemented by MeshData.");
}
/* -------------------------------------------------------------------------- */
BOOST_PP_SEQ_FOR_EACH(MESH_DATA_GET_TYPE, void, AKANTU_MESH_DATA_TYPES)
#undef MESH_DATA_GET_TYPE
inline MeshDataTypeCode MeshData::getTypeCode(const ID & name) const {
auto it = typecode_map.find(name);
if (it == typecode_map.end())
AKANTU_EXCEPTION("No dataset named " << name << " found.");
return it->second;
}
/* -------------------------------------------------------------------------- */
// Register new elemental data templated (and alloc data) with check if the
// name is new
template <typename T> void MeshData::registerElementalData(const ID & name) {
auto it = elemental_data.find(name);
if (it == elemental_data.end()) {
allocElementalData<T>(name);
} else {
AKANTU_DEBUG_INFO("Data named " << name << " already registered.");
}
}
/* -------------------------------------------------------------------------- */
- // Register new elemental data of a given MeshDataTypeCode with check if the
- // name is new
+// Register new elemental data of a given MeshDataTypeCode with check if the
+// name is new
#define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem): { \
registerElementalData<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(name); \
break; \
}
inline void MeshData::registerElementalData(const ID & name,
MeshDataTypeCode type) {
switch (type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, name,
AKANTU_MESH_DATA_TYPES)
default:
AKANTU_ERROR("Type " << type << "not implemented by MeshData.");
}
}
#undef AKANTU_MESH_DATA_CASE_MACRO
/* -------------------------------------------------------------------------- */
/// Register new elemental data (and alloc data)
template <typename T>
ElementTypeMapArray<T> * MeshData::allocElementalData(const ID & name) {
auto * dataset = new ElementTypeMapArray<T>(name, id, memory_id);
elemental_data[name] = dataset;
typecode_map[name] = getTypeCode<T>();
return dataset;
}
/* -------------------------------------------------------------------------- */
template <typename T>
const ElementTypeMapArray<T> &
MeshData::getElementalData(const ID & name) const {
auto it = elemental_data.find(name);
if (it == elemental_data.end())
AKANTU_EXCEPTION("No dataset named " << name << " found.");
return dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second));
}
/* -------------------------------------------------------------------------- */
// Get an existing elemental data
template <typename T>
ElementTypeMapArray<T> & MeshData::getElementalData(const ID & name) {
auto it = elemental_data.find(name);
if (it == elemental_data.end())
AKANTU_EXCEPTION("No dataset named " << name << " found.");
return dynamic_cast<ElementTypeMapArray<T> &>(*(it->second));
}
/* -------------------------------------------------------------------------- */
template <typename T>
bool MeshData::hasDataArray(const ID & name, const ElementType & elem_type,
const GhostType & ghost_type) const {
auto it = elemental_data.find(name);
if (it == elemental_data.end())
return false;
auto & elem_map = dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second));
return elem_map.exists(elem_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline bool MeshData::hasData(const ID & name) const {
auto it = elemental_data.find(name);
return (it != elemental_data.end());
}
/* -------------------------------------------------------------------------- */
template <typename T>
const Array<T> &
MeshData::getElementalDataArray(const ID & name, const ElementType & elem_type,
const GhostType & ghost_type) const {
auto it = elemental_data.find(name);
if (it == elemental_data.end()) {
AKANTU_EXCEPTION("Data named " << name
<< " not registered for type: " << elem_type
<< " - ghost_type:" << ghost_type << "!");
}
return dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second))(
elem_type, ghost_type);
}
template <typename T>
Array<T> & MeshData::getElementalDataArray(const ID & name,
const ElementType & elem_type,
const GhostType & ghost_type) {
auto it = elemental_data.find(name);
if (it == elemental_data.end()) {
AKANTU_EXCEPTION("Data named " << name
<< " not registered for type: " << elem_type
<< " - ghost_type:" << ghost_type << "!");
}
return dynamic_cast<ElementTypeMapArray<T> &>(*(it->second))(elem_type,
ghost_type);
}
/* -------------------------------------------------------------------------- */
// Get an elemental data array, if it does not exist: allocate it
template <typename T>
Array<T> & MeshData::getElementalDataArrayAlloc(const ID & name,
const ElementType & elem_type,
const GhostType & ghost_type,
UInt nb_component) {
auto it = elemental_data.find(name);
ElementTypeMapArray<T> * dataset;
if (it == elemental_data.end()) {
dataset = allocElementalData<T>(name);
} else {
dataset = dynamic_cast<ElementTypeMapArray<T> *>(it->second);
}
AKANTU_DEBUG_ASSERT(
getTypeCode<T>() == typecode_map.find(name)->second,
"Function getElementalDataArrayAlloc called with the wrong type!");
if (!(dataset->exists(elem_type, ghost_type))) {
dataset->alloc(0, nb_component, elem_type, ghost_type);
}
return (*dataset)(elem_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
#define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem): { \
nb_comp = getNbComponentTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>( \
name, el_type, ghost_type); \
break; \
}
inline UInt MeshData::getNbComponent(const ID & name,
const ElementType & el_type,
const GhostType & ghost_type) const {
auto it = typecode_map.find(name);
UInt nb_comp(0);
if (it == typecode_map.end()) {
AKANTU_EXCEPTION("Could not determine the type held in dataset "
<< name << " for type: " << el_type
<< " - ghost_type:" << ghost_type << ".");
}
MeshDataTypeCode type = it->second;
switch (type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, name,
AKANTU_MESH_DATA_TYPES)
default:
AKANTU_ERROR(
"Could not call the correct instance of getNbComponentTemplated.");
break;
}
return nb_comp;
}
#undef AKANTU_MESH_DATA_CASE_MACRO
/* -------------------------------------------------------------------------- */
template <typename T>
inline UInt
MeshData::getNbComponentTemplated(const ID & name, const ElementType & el_type,
const GhostType & ghost_type) const {
return getElementalDataArray<T>(name, el_type, ghost_type).getNbComponent();
}
/* -------------------------------------------------------------------------- */
// get the names of the data stored in elemental_data
#define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem): { \
ElementTypeMapArray<BOOST_PP_TUPLE_ELEM(2, 1, elem)> * dataset; \
dataset = \
dynamic_cast<ElementTypeMapArray<BOOST_PP_TUPLE_ELEM(2, 1, elem)> *>( \
it->second); \
exists = dataset->exists(el_type, ghost_type); \
break; \
}
inline void MeshData::getTagNames(StringVector & tags,
const ElementType & el_type,
const GhostType & ghost_type) const {
tags.clear();
bool exists(false);
auto it = elemental_data.begin();
auto it_end = elemental_data.end();
for (; it != it_end; ++it) {
MeshDataTypeCode type = getTypeCode(it->first);
switch (type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, ,
AKANTU_MESH_DATA_TYPES)
default:
- AKANTU_ERROR(
- "Could not determine the proper type to (dynamic-)cast.");
+ AKANTU_ERROR("Could not determine the proper type to (dynamic-)cast.");
break;
}
if (exists) {
tags.push_back(it->first);
}
}
}
#undef AKANTU_MESH_DATA_CASE_MACRO
/* -------------------------------------------------------------------------- */
} // namespace akantu
#endif /* __AKANTU_MESH_DATA_TMPL_HH__ */
diff --git a/src/mesh/mesh_events.hh b/src/mesh/mesh_events.hh
index 684de1e56..53f8f0d9a 100644
--- a/src/mesh/mesh_events.hh
+++ b/src/mesh/mesh_events.hh
@@ -1,199 +1,198 @@
/**
* @file mesh_events.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Feb 20 2015
* @date last modification: Mon Dec 07 2015
*
* @brief Classes corresponding to mesh events type
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <utility>
#include "aka_array.hh"
#include "element.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_EVENTS_HH__
#define __AKANTU_MESH_EVENTS_HH__
-
namespace akantu {
/// akantu::MeshEvent is the base event for meshes
template <class Entity> class MeshEvent {
public:
virtual ~MeshEvent() = default;
/// Get the list of entity modified by the event nodes or elements
const Array<Entity> & getList() const { return list; }
/// Get the list of entity modified by the event nodes or elements
Array<Entity> & getList() { return list; }
protected:
Array<Entity> list;
};
class Mesh;
/// akantu::MeshEvent related to new nodes in the mesh
class NewNodesEvent : public MeshEvent<UInt> {
public:
~NewNodesEvent() override = default;
};
/// akantu::MeshEvent related to nodes removed from the mesh
class RemovedNodesEvent : public MeshEvent<UInt> {
public:
~RemovedNodesEvent() override = default;
inline RemovedNodesEvent(const Mesh & mesh);
/// Get the new numbering following suppression of nodes from nodes arrays
AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, Array<UInt> &);
/// Get the new numbering following suppression of nodes from nodes arrays
AKANTU_GET_MACRO(NewNumbering, new_numbering, const Array<UInt> &);
private:
Array<UInt> new_numbering;
};
/// akantu::MeshEvent related to new elements in the mesh
class NewElementsEvent : public MeshEvent<Element> {
public:
~NewElementsEvent() override = default;
};
/// akantu::MeshEvent related to elements removed from the mesh
class RemovedElementsEvent : public MeshEvent<Element> {
public:
~RemovedElementsEvent() override = default;
inline RemovedElementsEvent(const Mesh & mesh,
const ID & new_numbering_id = "new_numbering");
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO(NewNumbering, new_numbering,
const ElementTypeMapArray<UInt> &);
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering,
ElementTypeMapArray<UInt> &);
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, UInt);
/// Get the new numbering following suppression of elements from elements
/// arrays
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, UInt);
protected:
ElementTypeMapArray<UInt> new_numbering;
};
/// akantu::MeshEvent for element that changed in some sort, can be seen as a
/// combination of removed and added elements
class ChangedElementsEvent : public RemovedElementsEvent {
public:
~ChangedElementsEvent() override = default;
inline ChangedElementsEvent(
const Mesh & mesh, ID new_numbering_id = "changed_event:new_numbering")
: RemovedElementsEvent(mesh, std::move(new_numbering_id)){};
AKANTU_GET_MACRO(ListOld, list, const Array<Element> &);
AKANTU_GET_MACRO_NOT_CONST(ListOld, list, Array<Element> &);
AKANTU_GET_MACRO(ListNew, new_list, const Array<Element> &);
AKANTU_GET_MACRO_NOT_CONST(ListNew, new_list, Array<Element> &);
protected:
Array<Element> new_list;
};
/* -------------------------------------------------------------------------- */
class MeshEventHandler {
public:
virtual ~MeshEventHandler() = default;
/* ------------------------------------------------------------------------ */
/* Internal code */
/* ------------------------------------------------------------------------ */
private:
/// send a akantu::NewNodesEvent
inline void sendEvent(const NewNodesEvent & event) {
onNodesAdded(event.getList(), event);
}
/// send a akantu::RemovedNodesEvent
inline void sendEvent(const RemovedNodesEvent & event) {
onNodesRemoved(event.getList(), event.getNewNumbering(), event);
}
/// send a akantu::NewElementsEvent
inline void sendEvent(const NewElementsEvent & event) {
onElementsAdded(event.getList(), event);
}
/// send a akantu::RemovedElementsEvent
inline void sendEvent(const RemovedElementsEvent & event) {
onElementsRemoved(event.getList(), event.getNewNumbering(), event);
}
/// send a akantu::ChangedElementsEvent
inline void sendEvent(const ChangedElementsEvent & event) {
onElementsChanged(event.getListOld(), event.getListNew(),
event.getNewNumbering(), event);
}
template <class EventHandler> friend class EventHandlerManager;
/* ------------------------------------------------------------------------ */
/* Interface */
/* ------------------------------------------------------------------------ */
public:
/// function to implement to react on akantu::NewNodesEvent
virtual void onNodesAdded(const Array<UInt> & /*nodes_list*/,
const NewNodesEvent & /*event*/) {
AKANTU_TO_IMPLEMENT();
}
/// function to implement to react on akantu::RemovedNodesEvent
virtual void onNodesRemoved(const Array<UInt> & /*nodes_list*/,
const Array<UInt> & /*new_numbering*/,
const RemovedNodesEvent & /*event*/) {
AKANTU_TO_IMPLEMENT();
}
/// function to implement to react on akantu::NewElementsEvent
virtual void onElementsAdded(const Array<Element> & /*elements_list*/,
const NewElementsEvent & /*event*/) {
AKANTU_TO_IMPLEMENT();
}
/// function to implement to react on akantu::RemovedElementsEvent
virtual void
onElementsRemoved(const Array<Element> & /*elements_list*/,
const ElementTypeMapArray<UInt> & /*new_numbering*/,
const RemovedElementsEvent & /*event*/) {
AKANTU_TO_IMPLEMENT();
}
/// function to implement to react on akantu::ChangedElementsEvent
virtual void
onElementsChanged(const Array<Element> & /*old_elements_list*/,
const Array<Element> & /*new_elements_list*/,
const ElementTypeMapArray<UInt> & /*new_numbering*/,
const ChangedElementsEvent & /*event*/) {
AKANTU_TO_IMPLEMENT();
}
};
} // akantu
#endif /* __AKANTU_MESH_EVENTS_HH__ */
diff --git a/src/mesh/mesh_filter.hh b/src/mesh/mesh_filter.hh
index 213325536..59420e63d 100644
--- a/src/mesh/mesh_filter.hh
+++ b/src/mesh/mesh_filter.hh
@@ -1,75 +1,73 @@
/**
* @file mesh_filter.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Dec 18 2015
*
* @brief the class representing the meshes
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_FILTER_HH__
#define __AKANTU_MESH_FILTER_HH__
/* -------------------------------------------------------------------------- */
#include "element.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/* Filter Functors */
/* -------------------------------------------------------------------------- */
/// struct for the possible filter functors
struct FilterFunctor {
enum Type { _node_filter_functor, _element_filter_functor };
};
/// class (functor) for the node filter
class NodeFilterFunctor : public FilterFunctor {
public:
- bool operator()(__attribute__((unused)) UInt node) {
- AKANTU_TO_IMPLEMENT();
- }
+ bool operator()(__attribute__((unused)) UInt node) { AKANTU_TO_IMPLEMENT(); }
public:
static const Type type = _node_filter_functor;
};
/// class (functor) for the element filter
class ElementFilterFunctor : public FilterFunctor {
public:
bool operator()(__attribute__((unused)) const Element & element) {
AKANTU_TO_IMPLEMENT();
}
public:
static const Type type = _element_filter_functor;
};
} // akantu
#endif /* __AKANTU_MESH_FILTER_HH__ */
diff --git a/src/mesh/mesh_inline_impl.cc b/src/mesh/mesh_inline_impl.cc
index e78c5748c..fd19d3982 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,641 +1,637 @@
/**
* @file mesh_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Thu Jan 21 2016
*
* @brief Implementation of the inline functions of the mesh class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh.hh"
#include "aka_iterators.hh"
#include "element_class.hh"
+#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_INLINE_IMPL_CC__
#define __AKANTU_MESH_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
inline ElementKind Element::kind() const { return Mesh::getKind(type); }
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <typename... pack>
Mesh::ElementTypesIteratorHelper Mesh::elementTypes(pack &&... _pack) const {
return connectivities.elementTypes(_pack...);
}
/* -------------------------------------------------------------------------- */
inline RemovedNodesEvent::RemovedNodesEvent(const Mesh & mesh)
: new_numbering(mesh.getNbNodes(), 1, "new_numbering") {}
/* -------------------------------------------------------------------------- */
inline RemovedElementsEvent::RemovedElementsEvent(const Mesh & mesh,
const ID & new_numbering_id)
: new_numbering(new_numbering_id, mesh.getID(), mesh.getMemoryID()) {}
/* -------------------------------------------------------------------------- */
template <>
inline void Mesh::sendEvent<NewElementsEvent>(NewElementsEvent & event) {
this->nodes_to_elements.resize(nodes->size());
for (const auto & elem : event.getList()) {
const Array<UInt> & conn = connectivities(elem.type, elem.ghost_type);
UInt nb_nodes_per_elem = this->getNbNodesPerElement(elem.type);
for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
UInt node = conn(elem.element, n);
if (not nodes_to_elements[node])
nodes_to_elements[node] = std::make_unique<std::set<Element>>();
nodes_to_elements[node]->insert(elem);
}
}
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template <> inline void Mesh::sendEvent<NewNodesEvent>(NewNodesEvent & event) {
this->computeBoundingBox();
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template <>
inline void
Mesh::sendEvent<RemovedElementsEvent>(RemovedElementsEvent & event) {
this->connectivities.onElementsRemoved(event.getNewNumbering());
this->fillNodesToElements();
this->computeBoundingBox();
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template <>
inline void Mesh::sendEvent<RemovedNodesEvent>(RemovedNodesEvent & event) {
const auto & new_numbering = event.getNewNumbering();
this->removeNodesFromArray(*nodes, new_numbering);
if (nodes_global_ids)
this->removeNodesFromArray(*nodes_global_ids, new_numbering);
if (nodes_type.size() != 0)
this->removeNodesFromArray(nodes_type, new_numbering);
if (not nodes_to_elements.empty()) {
std::vector<std::unique_ptr<std::set<Element>>> tmp(
nodes_to_elements.size());
auto it = nodes_to_elements.begin();
UInt new_nb_nodes = 0;
for (auto new_i : new_numbering) {
if (new_i != UInt(-1)) {
tmp[new_i] = std::move(*it);
++new_nb_nodes;
}
++it;
}
tmp.resize(new_nb_nodes);
std::move(tmp.begin(), tmp.end(), nodes_to_elements.begin());
}
computeBoundingBox();
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Mesh::removeNodesFromArray(Array<T> & vect,
const Array<UInt> & new_numbering) {
Array<T> tmp(vect.size(), vect.getNbComponent());
UInt nb_component = vect.getNbComponent();
UInt new_nb_nodes = 0;
for (UInt i = 0; i < new_numbering.size(); ++i) {
UInt new_i = new_numbering(i);
if (new_i != UInt(-1)) {
T * to_copy = vect.storage() + i * nb_component;
std::uninitialized_copy(to_copy, to_copy + nb_component,
tmp.storage() + new_i * nb_component);
++new_nb_nodes;
}
}
tmp.resize(new_nb_nodes);
vect.copy(tmp);
}
/* -------------------------------------------------------------------------- */
inline Array<UInt> & Mesh::getNodesGlobalIdsPointer() {
AKANTU_DEBUG_IN();
if (not nodes_global_ids) {
nodes_global_ids = std::make_unique<Array<UInt>>(
nodes->size(), 1, getID() + ":nodes_global_ids");
for (auto && global_ids : enumerate(*nodes_global_ids)) {
std::get<1>(global_ids) = std::get<0>(global_ids);
}
}
AKANTU_DEBUG_OUT();
return *nodes_global_ids;
}
/* -------------------------------------------------------------------------- */
inline Array<NodeType> & Mesh::getNodesTypePointer() {
AKANTU_DEBUG_IN();
if (nodes_type.size() == 0) {
nodes_type.resize(nodes->size());
nodes_type.set(_nt_normal);
}
AKANTU_DEBUG_OUT();
return nodes_type;
}
/* -------------------------------------------------------------------------- */
inline Array<UInt> &
Mesh::getConnectivityPointer(const ElementType & type,
const GhostType & ghost_type) {
if (connectivities.exists(type, ghost_type))
return connectivities(type, ghost_type);
if (ghost_type != _not_ghost) {
ghosts_counters.alloc(0, 1, type, ghost_type, 1);
}
AKANTU_DEBUG_INFO("The connectivity vector for the type " << type
<< " created");
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
return connectivities.alloc(0, nb_nodes_per_element, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline Array<std::vector<Element>> &
Mesh::getElementToSubelementPointer(const ElementType & type,
const GhostType & ghost_type) {
return getDataPointer<std::vector<Element>>("element_to_subelement", type,
ghost_type, 1, true);
}
/* -------------------------------------------------------------------------- */
inline Array<Element> &
Mesh::getSubelementToElementPointer(const ElementType & type,
const GhostType & ghost_type) {
auto & array = getDataPointer<Element>(
"subelement_to_element", type, ghost_type, getNbFacetsPerElement(type),
true, is_mesh_facets);
array.set(ElementNull);
return array;
}
/* -------------------------------------------------------------------------- */
-inline const auto &
-Mesh::getElementToSubelement() const {
+inline const auto & Mesh::getElementToSubelement() const {
return getData<std::vector<Element>>("element_to_subelement");
}
/* -------------------------------------------------------------------------- */
inline const auto &
Mesh::getElementToSubelement(const ElementType & type,
const GhostType & ghost_type) const {
return getData<std::vector<Element>>("element_to_subelement", type,
ghost_type);
}
/* -------------------------------------------------------------------------- */
-inline auto &
-Mesh::getElementToSubelement(const ElementType & type,
- const GhostType & ghost_type) {
+inline auto & Mesh::getElementToSubelement(const ElementType & type,
+ const GhostType & ghost_type) {
return getData<std::vector<Element>>("element_to_subelement", type,
ghost_type);
}
/* -------------------------------------------------------------------------- */
inline const auto &
Mesh::getSubelementToElement(const ElementType & type,
const GhostType & ghost_type) const {
return getData<Element>("subelement_to_element", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
-inline auto &
-Mesh::getSubelementToElement(const ElementType & type,
- const GhostType & ghost_type) {
+inline auto & Mesh::getSubelementToElement(const ElementType & type,
+ const GhostType & ghost_type) {
return getData<Element>("subelement_to_element", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline Array<T> &
Mesh::getDataPointer(const ID & data_name, const ElementType & el_type,
const GhostType & ghost_type, UInt nb_component,
bool size_to_nb_element, bool resize_with_parent) {
Array<T> & tmp = mesh_data.getElementalDataArrayAlloc<T>(
data_name, el_type, ghost_type, nb_component);
if (size_to_nb_element) {
if (resize_with_parent)
tmp.resize(mesh_parent->getNbElement(el_type, ghost_type));
else
tmp.resize(this->getNbElement(el_type, ghost_type));
} else {
tmp.resize(0);
}
return tmp;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline bool Mesh::hasData(const ID & data_name, const ElementType & el_type,
const GhostType & ghost_type) const {
return mesh_data.hasDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline const Array<T> & Mesh::getData(const ID & data_name,
const ElementType & el_type,
const GhostType & ghost_type) const {
return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline Array<T> & Mesh::getData(const ID & data_name,
const ElementType & el_type,
const GhostType & ghost_type) {
return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::hasData(const ID & data_name) const {
return mesh_data.hasData(data_name);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline const ElementTypeMapArray<T> &
Mesh::getData(const ID & data_name) const {
return mesh_data.getElementalData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline ElementTypeMapArray<T> & Mesh::getData(const ID & data_name) {
return mesh_data.getElementalData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline ElementTypeMapArray<T> & Mesh::registerData(const ID & data_name) {
this->mesh_data.registerElementalData<T>(data_name);
return this->getData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbElement(const ElementType & type,
const GhostType & ghost_type) const {
try {
const Array<UInt> & conn = connectivities(type, ghost_type);
return conn.size();
} catch (...) {
return 0;
}
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbElement(const UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & kind) const {
AKANTU_DEBUG_ASSERT(spatial_dimension <= 3 || spatial_dimension == UInt(-1),
"spatial_dimension is " << spatial_dimension
<< " and is greater than 3 !");
UInt nb_element = 0;
for (auto type : elementTypes(spatial_dimension, ghost_type, kind))
nb_element += getNbElement(type, ghost_type);
return nb_element;
}
/* -------------------------------------------------------------------------- */
inline void Mesh::getBarycenter(UInt element, const ElementType & type,
Real * barycenter, GhostType ghost_type) const {
UInt * conn_val = getConnectivity(type, ghost_type).storage();
UInt nb_nodes_per_element = getNbNodesPerElement(type);
auto * local_coord = new Real[spatial_dimension * nb_nodes_per_element];
UInt offset = element * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
memcpy(local_coord + n * spatial_dimension,
nodes->storage() + conn_val[offset + n] * spatial_dimension,
spatial_dimension * sizeof(Real));
}
Math::barycenter(local_coord, nb_nodes_per_element, spatial_dimension,
barycenter);
delete[] local_coord;
}
/* -------------------------------------------------------------------------- */
inline void Mesh::getBarycenter(const Element & element,
Vector<Real> & barycenter) const {
getBarycenter(element.element, element.type, barycenter.storage(),
element.ghost_type);
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbNodesPerElement(const ElementType & type) {
UInt nb_nodes_per_element = 0;
#define GET_NB_NODES_PER_ELEMENT(type) \
nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_NODES_PER_ELEMENT);
#undef GET_NB_NODES_PER_ELEMENT
return nb_nodes_per_element;
}
/* -------------------------------------------------------------------------- */
inline ElementType Mesh::getP1ElementType(const ElementType & type) {
ElementType p1_type = _not_defined;
#define GET_P1_TYPE(type) p1_type = ElementClass<type>::getP1ElementType()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_P1_TYPE);
#undef GET_P1_TYPE
return p1_type;
}
/* -------------------------------------------------------------------------- */
inline ElementKind Mesh::getKind(const ElementType & type) {
ElementKind kind = _ek_not_defined;
#define GET_KIND(type) kind = ElementClass<type>::getKind()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_KIND);
#undef GET_KIND
return kind;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getSpatialDimension(const ElementType & type) {
UInt spatial_dimension = 0;
#define GET_SPATIAL_DIMENSION(type) \
spatial_dimension = ElementClass<type>::getSpatialDimension()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SPATIAL_DIMENSION);
#undef GET_SPATIAL_DIMENSION
return spatial_dimension;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbFacetTypes(const ElementType & type,
__attribute__((unused)) UInt t) {
UInt nb = 0;
#define GET_NB_FACET_TYPE(type) nb = ElementClass<type>::getNbFacetTypes()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET_TYPE);
#undef GET_NB_FACET_TYPE
return nb;
}
/* -------------------------------------------------------------------------- */
inline constexpr auto Mesh::getFacetType(const ElementType & type, UInt t) {
#define GET_FACET_TYPE(type) return ElementClass<type>::getFacetType(t);
AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(GET_FACET_TYPE);
#undef GET_FACET_TYPE
return _not_defined;
}
/* -------------------------------------------------------------------------- */
inline constexpr auto Mesh::getAllFacetTypes(const ElementType & type) {
-#define GET_FACET_TYPE(type) \
- return ElementClass<type>::getFacetTypes();
+#define GET_FACET_TYPE(type) return ElementClass<type>::getFacetTypes();
AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(GET_FACET_TYPE);
#undef GET_FACET_TYPE
return ElementClass<_not_defined>::getFacetTypes();
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbFacetsPerElement(const ElementType & type) {
AKANTU_DEBUG_IN();
UInt n_facet = 0;
#define GET_NB_FACET(type) n_facet = ElementClass<type>::getNbFacetsPerElement()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
#undef GET_NB_FACET
AKANTU_DEBUG_OUT();
return n_facet;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbFacetsPerElement(const ElementType & type, UInt t) {
AKANTU_DEBUG_IN();
UInt n_facet = 0;
#define GET_NB_FACET(type) \
n_facet = ElementClass<type>::getNbFacetsPerElement(t)
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
#undef GET_NB_FACET
AKANTU_DEBUG_OUT();
return n_facet;
}
/* -------------------------------------------------------------------------- */
inline auto Mesh::getFacetLocalConnectivity(const ElementType & type, UInt t) {
AKANTU_DEBUG_IN();
#define GET_FACET_CON(type) \
AKANTU_DEBUG_OUT(); \
return ElementClass<type>::getFacetLocalConnectivityPerElement(t)
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_CON);
#undef GET_FACET_CON
AKANTU_DEBUG_OUT();
return ElementClass<_not_defined>::getFacetLocalConnectivityPerElement(0);
// This avoid a compilation warning but will certainly
// also cause a segfault if reached
}
/* -------------------------------------------------------------------------- */
inline auto Mesh::getFacetConnectivity(const Element & element, UInt t) const {
AKANTU_DEBUG_IN();
Matrix<const UInt> local_facets(getFacetLocalConnectivity(element.type, t));
Matrix<UInt> facets(local_facets.rows(), local_facets.cols());
const Array<UInt> & conn = connectivities(element.type, element.ghost_type);
for (UInt f = 0; f < facets.rows(); ++f) {
for (UInt n = 0; n < facets.cols(); ++n) {
facets(f, n) = conn(element.element, local_facets(f, n));
}
}
AKANTU_DEBUG_OUT();
return facets;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Mesh::extractNodalValuesFromElement(
const Array<T> & nodal_values, T * local_coord, UInt * connectivity,
UInt n_nodes, UInt nb_degree_of_freedom) const {
for (UInt n = 0; n < n_nodes; ++n) {
memcpy(local_coord + n * nb_degree_of_freedom,
nodal_values.storage() + connectivity[n] * nb_degree_of_freedom,
nb_degree_of_freedom * sizeof(T));
}
}
/* -------------------------------------------------------------------------- */
inline void Mesh::addConnectivityType(const ElementType & type,
const GhostType & ghost_type) {
getConnectivityPointer(type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isPureGhostNode(UInt n) const {
return nodes_type.size() ? (nodes_type(n) == _nt_pure_gost) : false;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isLocalOrMasterNode(UInt n) const {
return nodes_type.size()
? (nodes_type(n) == _nt_master) || (nodes_type(n) == _nt_normal)
: true;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isLocalNode(UInt n) const {
return nodes_type.size() ? nodes_type(n) == _nt_normal : true;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isMasterNode(UInt n) const {
return nodes_type.size() ? nodes_type(n) == _nt_master : false;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isSlaveNode(UInt n) const {
return nodes_type.size() ? nodes_type(n) >= 0 : false;
}
/* -------------------------------------------------------------------------- */
inline NodeType Mesh::getNodeType(UInt local_id) const {
return nodes_type.size() ? nodes_type(local_id) : _nt_normal;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNodeGlobalId(UInt local_id) const {
return nodes_global_ids ? (*nodes_global_ids)(local_id) : local_id;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNodeLocalId(UInt global_id) const {
AKANTU_DEBUG_ASSERT(nodes_global_ids != nullptr,
"The global ids are note set.");
return nodes_global_ids->find(global_id);
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbGlobalNodes() const {
return nodes_global_ids ? nb_global_nodes : nodes->size();
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbNodesPerElementList(const Array<Element> & elements) {
UInt nb_nodes_per_element = 0;
UInt nb_nodes = 0;
ElementType current_element_type = _not_defined;
Array<Element>::const_iterator<Element> el_it = elements.begin();
Array<Element>::const_iterator<Element> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
const Element & el = *el_it;
if (el.type != current_element_type) {
current_element_type = el.type;
nb_nodes_per_element = Mesh::getNbNodesPerElement(current_element_type);
}
nb_nodes += nb_nodes_per_element;
}
return nb_nodes;
}
/* -------------------------------------------------------------------------- */
inline Mesh & Mesh::getMeshFacets() {
if (!this->mesh_facets)
AKANTU_SILENT_EXCEPTION(
"No facet mesh is defined yet! check the buildFacets functions");
return *this->mesh_facets;
}
/* -------------------------------------------------------------------------- */
inline const Mesh & Mesh::getMeshFacets() const {
if (!this->mesh_facets)
AKANTU_SILENT_EXCEPTION(
"No facet mesh is defined yet! check the buildFacets functions");
return *this->mesh_facets;
}
/* -------------------------------------------------------------------------- */
inline const Mesh & Mesh::getMeshParent() const {
if (!this->mesh_parent)
AKANTU_SILENT_EXCEPTION(
"No parent mesh is defined! This is only valid in a mesh_facets");
return *this->mesh_parent;
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
#endif /* __AKANTU_MESH_INLINE_IMPL_CC__ */
diff --git a/src/mesh/node_group.hh b/src/mesh/node_group.hh
index 40a2361b2..8eb5f5d51 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,142 +1,132 @@
/**
* @file node_group.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Dec 08 2015
*
* @brief Node group definition
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
#include "aka_array.hh"
+#include "aka_common.hh"
#include "aka_memory.hh"
-#include "mesh_filter.hh"
#include "dumpable.hh"
+#include "mesh_filter.hh"
/* -------------------------------------------------------------------------- */
-
-
#ifndef __AKANTU_NODE_GROUP_HH__
#define __AKANTU_NODE_GROUP_HH__
namespace akantu {
class NodeGroup : public Memory, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- NodeGroup(const std::string & name,
- const Mesh & mesh,
+ NodeGroup(const std::string & name, const Mesh & mesh,
const std::string & id = "node_group",
const MemoryID & memory_id = 0);
~NodeGroup() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
using const_node_iterator = Array<UInt>::const_iterator<UInt>;
/// empty the node group
void empty();
/// iterator to the beginning of the node group
inline const_node_iterator begin() const;
/// iterator to the end of the node group
inline const_node_iterator end() const;
/// add a node and give the local position through an iterator
inline const_node_iterator add(UInt node, bool check_for_duplicate = true);
/// remove a node
inline void remove(UInt node);
#ifndef SWIG
- inline decltype(auto) find(UInt node) const {
- return node_group.find(node);
- }
+ inline decltype(auto) find(UInt node) const { return node_group.find(node); }
#endif
/// remove duplicated nodes
void optimize();
/// append a group to current one
void append(const NodeGroup & other_group);
/// apply a filter on current node group
- template <typename T>
- void applyNodeFilter(T & filter);
+ template <typename T> void applyNodeFilter(T & filter);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
AKANTU_GET_MACRO_NOT_CONST(Nodes, node_group, Array<UInt> &);
AKANTU_GET_MACRO(Nodes, node_group, const Array<UInt> &);
AKANTU_GET_MACRO(Name, name, const std::string &);
/// give the number of nodes in the current group
inline UInt size() const;
- UInt * storage(){return node_group.storage();};
-
+ UInt * storage() { return node_group.storage(); };
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// name of the group
std::string name;
/// list of nodes in the group
Array<UInt> & node_group;
/// reference to the mesh in question
- //const Mesh & mesh;
+ // const Mesh & mesh;
};
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const NodeGroup & _this)
-{
+inline std::ostream & operator<<(std::ostream & stream,
+ const NodeGroup & _this) {
_this.printself(stream);
return stream;
}
} // akantu
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "node_group_inline_impl.cc"
-
-
#endif /* __AKANTU_NODE_GROUP_HH__ */
diff --git a/src/mesh/node_group_inline_impl.cc b/src/mesh/node_group_inline_impl.cc
index 3587b776a..c165570f9 100644
--- a/src/mesh/node_group_inline_impl.cc
+++ b/src/mesh/node_group_inline_impl.cc
@@ -1,102 +1,99 @@
/**
* @file node_group_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Dec 08 2015
*
* @brief Node group inline function definitions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::begin() const {
return node_group.begin();
}
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::end() const {
return node_group.end();
}
/* -------------------------------------------------------------------------- */
-inline NodeGroup::const_node_iterator NodeGroup::add(UInt node, bool check_for_duplicate) {
- if(check_for_duplicate) {
+inline NodeGroup::const_node_iterator NodeGroup::add(UInt node,
+ bool check_for_duplicate) {
+ if (check_for_duplicate) {
const_node_iterator it = std::find(begin(), end(), node);
- if(it == node_group.end()) {
+ if (it == node_group.end()) {
node_group.push_back(node);
return (node_group.end() - 1);
}
return it;
} else {
node_group.push_back(node);
return (node_group.end() - 1);
}
}
/* -------------------------------------------------------------------------- */
inline void NodeGroup::remove(UInt node) {
Array<UInt>::iterator<> it = this->node_group.begin();
Array<UInt>::iterator<> end = this->node_group.end();
AKANTU_DEBUG_ASSERT(it != end, "The node group is empty!!");
for (; it != node_group.end(); ++it) {
- if (*it == node) {
+ if (*it == node) {
it = node_group.erase(it);
}
}
AKANTU_DEBUG_ASSERT(it != end, "The node was not found!");
}
/* -------------------------------------------------------------------------- */
-inline UInt NodeGroup::size() const {
- return node_group.size();
-}
+inline UInt NodeGroup::size() const { return node_group.size(); }
/* -------------------------------------------------------------------------- */
struct FilterFunctor;
-template <typename T>
-void NodeGroup::applyNodeFilter(T & filter) {
+template <typename T> void NodeGroup::applyNodeFilter(T & filter) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(T::type == FilterFunctor::_node_filter_functor,
- "NodeFilter can only apply node filter functor");
+ "NodeFilter can only apply node filter functor");
Array<UInt>::iterator<> it = this->node_group.begin();
for (; it != node_group.end(); ++it) {
/// filter == true -> keep node
- if (!filter(*it)) {
+ if (!filter(*it)) {
it = node_group.erase(it);
}
}
AKANTU_DEBUG_OUT();
}
-
} // akantu
diff --git a/src/mesh_utils/cohesive_element_inserter.hh b/src/mesh_utils/cohesive_element_inserter.hh
index fa446a31b..faa0481e3 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,193 +1,192 @@
/**
* @file cohesive_element_inserter.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Dec 04 2013
* @date last modification: Fri Oct 02 2015
*
* @brief Cohesive element inserter
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "data_accessor.hh"
#include "mesh_utils.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
#include <numeric>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
#define __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
namespace akantu {
class GlobalIdsUpdater;
class FacetSynchronizer;
} // akantu
namespace akantu {
class CohesiveElementInserter : public DataAccessor<Element>, public Parsable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
CohesiveElementInserter(Mesh & mesh,
const ID & id = "cohesive_element_inserter");
~CohesiveElementInserter() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// set range limitation for intrinsic cohesive element insertion
void setLimit(SpacialDirection axis, Real first_limit, Real second_limit);
/// insert intrinsic cohesive elements in a predefined range
UInt insertIntrinsicElements();
/// insert extrinsic cohesive elements (returns the number of new
/// cohesive elements)
UInt insertElements(bool only_double_facets = false);
/// limit check facets to match given insertion limits
void limitCheckFacets();
protected:
/// init parallel variables
void initParallel(ElementSynchronizer & element_synchronizer);
void parseSection(const ParserSection & section) override;
protected:
/// internal version of limitCheckFacets
void limitCheckFacets(ElementTypeMapArray<bool> & check_facets);
/// update facet insertion arrays after facets doubling
void updateInsertionFacets();
/// update nodes type and global ids for parallel simulations
/// (locally, within each processor)
UInt updateGlobalIDs(NewNodesEvent & node_event);
/// synchronize the global ids among the processors in parallel simulations
void synchronizeGlobalIDs(NewNodesEvent & node_event);
/// update nodes type
void updateNodesType(Mesh & mesh, NewNodesEvent & node_event);
/// functions for parallel communications
inline UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) override;
template <bool pack_mode>
inline void
packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
const Array<Element> & elements) const;
template <bool pack_mode>
inline void
packUnpackGroupedInsertionData(CommunicationBuffer & buffer,
const Array<Element> & elements) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_NOT_CONST(InsertionFacetsByElement, insertion_facets,
ElementTypeMapArray<bool> &);
AKANTU_GET_MACRO(InsertionFacetsByElement, insertion_facets,
const ElementTypeMapArray<bool> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InsertionFacets, insertion_facets, bool);
AKANTU_GET_MACRO(CheckFacets, check_facets,
const ElementTypeMapArray<bool> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(CheckFacets, check_facets, bool);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(CheckFacets, check_facets, bool);
AKANTU_GET_MACRO(MeshFacets, mesh_facets, const Mesh &);
AKANTU_GET_MACRO_NOT_CONST(MeshFacets, mesh_facets, Mesh &);
AKANTU_SET_MACRO(IsExtrinsic, is_extrinsic, bool);
-
public:
friend class SolidMechanicsModelCohesive;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// object id
ID id;
/// main mesh where to insert cohesive elements
Mesh & mesh;
/// mesh containing facets
Mesh & mesh_facets;
/// list of facets where to insert elements
ElementTypeMapArray<bool> insertion_facets;
/// limits for element insertion
Matrix<Real> insertion_limits;
/// list of groups to consider for insertion, ignored if empty
std::vector<ID> physical_groups;
/// vector containing facets in which extrinsic cohesive elements can be
/// inserted
ElementTypeMapArray<bool> check_facets;
/// global connectivity ids updater
std::unique_ptr<GlobalIdsUpdater> global_ids_updater;
/// is this inserter used in extrinsic
bool is_extrinsic{false};
};
class CohesiveNewNodesEvent : public NewNodesEvent {
public:
CohesiveNewNodesEvent() = default;
~CohesiveNewNodesEvent() override = default;
AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
private:
Array<UInt> old_nodes;
};
} // akantu
#include "cohesive_element_inserter_inline_impl.cc"
#endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__ */
diff --git a/src/mesh_utils/cohesive_element_inserter_inline_impl.cc b/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
index 03dba562a..65255ff86 100644
--- a/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
+++ b/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
@@ -1,103 +1,105 @@
/**
* @file cohesive_element_inserter_inline_impl.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief Cohesive element inserter inline functions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "cohesive_element_inserter.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__
#define __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
-inline UInt CohesiveElementInserter::getNbData(const Array<Element> & elements,
- const SynchronizationTag & tag) const {
+inline UInt
+CohesiveElementInserter::getNbData(const Array<Element> & elements,
+ const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
if (tag == _gst_ce_groups) {
size = elements.size() * (sizeof(bool) + sizeof(unsigned int));
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
-inline void CohesiveElementInserter::packData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- const SynchronizationTag & tag) const {
+inline void
+CohesiveElementInserter::packData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
if (tag == _gst_ce_groups)
packUnpackGroupedInsertionData<true>(buffer, elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-inline void CohesiveElementInserter::unpackData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- const SynchronizationTag & tag) {
+inline void
+CohesiveElementInserter::unpackData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
if (tag == _gst_ce_groups)
packUnpackGroupedInsertionData<false>(buffer, elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool pack_mode>
inline void CohesiveElementInserter::packUnpackGroupedInsertionData(
CommunicationBuffer & buffer, const Array<Element> & elements) const {
AKANTU_DEBUG_IN();
auto current_element_type = _not_defined;
auto current_ghost_type = _casper;
- auto & physical_names =
- mesh_facets.registerData<UInt>("physical_names");
+ auto & physical_names = mesh_facets.registerData<UInt>("physical_names");
Array<bool> * vect = nullptr;
Array<UInt> * vect2 = nullptr;
for (const auto & el : elements) {
if (el.type != current_element_type ||
el.ghost_type != current_ghost_type) {
current_element_type = el.type;
current_ghost_type = el.ghost_type;
vect =
&const_cast<Array<bool> &>(insertion_facets(el.type, el.ghost_type));
vect2 = &(physical_names(el.type, el.ghost_type));
}
Vector<bool> data(vect->storage() + el.element, 1);
Vector<unsigned int> data2(vect2->storage() + el.element, 1);
if (pack_mode) {
buffer << data;
buffer << data2;
} else {
buffer >> data;
buffer >> data2;
}
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
#endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__ */
diff --git a/src/mesh_utils/global_ids_updater.cc b/src/mesh_utils/global_ids_updater.cc
index 1d71b41d4..bd3ae404d 100644
--- a/src/mesh_utils/global_ids_updater.cc
+++ b/src/mesh_utils/global_ids_updater.cc
@@ -1,57 +1,57 @@
/**
* @file global_ids_updater.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Apr 13 2012
* @date last modification: Fri Oct 02 2015
*
* @brief Functions of the GlobalIdsUpdater
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "global_ids_updater.hh"
-#include "mesh_utils.hh"
#include "element_synchronizer.hh"
+#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
-
namespace akantu {
UInt GlobalIdsUpdater::updateGlobalIDs(UInt old_nb_nodes) {
UInt total_nb_new_nodes = this->updateGlobalIDsLocally(old_nb_nodes);
this->synchronizeGlobalIDs();
return total_nb_new_nodes;
}
UInt GlobalIdsUpdater::updateGlobalIDsLocally(UInt old_nb_nodes) {
- UInt total_nb_new_nodes = MeshUtils::updateLocalMasterGlobalConnectivity(mesh, old_nb_nodes);
+ UInt total_nb_new_nodes =
+ MeshUtils::updateLocalMasterGlobalConnectivity(mesh, old_nb_nodes);
return total_nb_new_nodes;
}
void GlobalIdsUpdater::synchronizeGlobalIDs() {
this->synchronizer.synchronizeOnce(*this, _gst_giu_global_conn);
}
} // akantu
diff --git a/src/mesh_utils/global_ids_updater.hh b/src/mesh_utils/global_ids_updater.hh
index 05395b879..bc2b6199a 100644
--- a/src/mesh_utils/global_ids_updater.hh
+++ b/src/mesh_utils/global_ids_updater.hh
@@ -1,100 +1,100 @@
/**
* @file global_ids_updater.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Oct 02 2015
*
* @brief Class that updates the global ids of new nodes that are
* inserted in the mesh. The functions in this class must be called
* after updating the node types
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_GLOBAL_IDS_UPDATER_HH__
#define __AKANTU_GLOBAL_IDS_UPDATER_HH__
/* -------------------------------------------------------------------------- */
#include "data_accessor.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class ElementSynchronizer;
-} // akantu
+} // akantu
namespace akantu {
class GlobalIdsUpdater : public DataAccessor<Element> {
public:
GlobalIdsUpdater(Mesh & mesh, ElementSynchronizer & synchronizer)
: mesh(mesh), synchronizer(synchronizer) {}
/// function to update and synchronize the global connectivity of
/// new inserted nodes. It must be called after updating the node
/// types. (It calls in sequence the functions
/// updateGlobalIDsLocally and synchronizeGlobalIDs)
UInt updateGlobalIDs(UInt old_nb_nodes);
/// function to update the global connectivity (only locally) of new
/// inserted nodes. It must be called after updating the node types.
UInt updateGlobalIDsLocally(UInt old_nb_nodes);
/// function to synchronize the global connectivity of new inserted
/// nodes among the processors. It must be called after updating the
/// node types.
void synchronizeGlobalIDs();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) override;
/* ------------------------------------------------------------------------ */
template <bool pack_mode>
inline void
packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
const Array<Element> & elements) const;
/* ------------------------------------------------------------------------ */
/* Members */
/* ------------------------------------------------------------------------ */
private:
/// Reference to the mesh to update
Mesh & mesh;
/// distributed synchronizer to communicate the connectivity
ElementSynchronizer & synchronizer;
};
-} // akantu
+} // akantu
#include "global_ids_updater_inline_impl.cc"
#endif /* __AKANTU_GLOBAL_IDS_UPDATER_HH__ */
diff --git a/src/mesh_utils/mesh_partition.cc b/src/mesh_utils/mesh_partition.cc
index 48bb235fe..d7a27e34f 100644
--- a/src/mesh_utils/mesh_partition.cc
+++ b/src/mesh_utils/mesh_partition.cc
@@ -1,434 +1,434 @@
/**
* @file mesh_partition.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Aug 17 2010
* @date last modification: Fri Jan 22 2016
*
* @brief implementation of common part of all partitioner
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_partition.hh"
#include "aka_iterators.hh"
#include "aka_types.hh"
#include "mesh_accessor.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <numeric>
#include <unordered_map>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
MeshPartition::MeshPartition(const Mesh & mesh, UInt spatial_dimension,
const ID & id, const MemoryID & memory_id)
: Memory(id, memory_id), mesh(mesh), spatial_dimension(spatial_dimension),
partitions("partition", id, memory_id),
ghost_partitions("ghost_partition", id, memory_id),
ghost_partitions_offset("ghost_partition_offset", id, memory_id),
saved_connectivity("saved_connectivity", id, memory_id) {
AKANTU_DEBUG_IN();
UInt nb_total_element = 0;
for (auto && type :
mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
linearized_offsets.push_back(std::make_pair(type, nb_total_element));
nb_total_element += mesh.getConnectivity(type).size();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MeshPartition::~MeshPartition() = default;
/* -------------------------------------------------------------------------- */
UInt MeshPartition::linearized(const Element & element) {
auto it =
std::find_if(linearized_offsets.begin(), linearized_offsets.end(),
[&element](auto & a) { return a.first == element.type; });
AKANTU_DEBUG_ASSERT(it != linearized_offsets.end(),
"A bug might be crawling around this corner...");
return (it->second + element.element);
}
/* -------------------------------------------------------------------------- */
Element MeshPartition::unlinearized(UInt lin_element) {
ElementType type{_not_defined};
UInt offset{0};
for (auto & pair : linearized_offsets) {
if (lin_element < pair.second)
continue;
std::tie(type, offset) = pair;
}
return Element{type, lin_element - offset, _not_ghost};
}
/* -------------------------------------------------------------------------- */
/**
* TODO this function should most probably be rewritten in a more modern way
* conversion in c++ of the GENDUALMETIS (mesh.c) function wrote by George in
* Metis (University of Minnesota)
*/
void MeshPartition::buildDualGraph(Array<Int> & dxadj, Array<Int> & dadjncy,
Array<Int> & edge_loads,
const EdgeLoadFunctor & edge_load_func) {
AKANTU_DEBUG_IN();
std::map<ElementType, std::tuple<const Array<UInt> *, UInt, UInt>>
connectivities;
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_total_element{0};
for (auto & type :
mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
auto type_p1 = mesh.getP1ElementType(type);
auto nb_nodes_per_element_p1 = mesh.getNbNodesPerElement(type_p1);
auto magic_number = mesh.getNbNodesPerElement(mesh.getFacetType(type_p1));
const auto & conn = mesh.getConnectivity(type, _not_ghost);
- connectivities[type] = std::make_tuple(
- &conn, nb_nodes_per_element_p1, magic_number);
+ connectivities[type] =
+ std::make_tuple(&conn, nb_nodes_per_element_p1, magic_number);
nb_total_element += conn.size();
}
CSR<Element> node_to_elem;
MeshUtils::buildNode2Elements(mesh, node_to_elem);
dxadj.resize(nb_total_element + 1);
/// initialize the dxadj array
auto dxadj_it = dxadj.begin();
for (auto & pair : connectivities) {
const auto & connectivity = *std::get<0>(pair.second);
auto nb_nodes_per_element_p1 = std::get<1>(pair.second);
std::fill_n(dxadj_it, connectivity.size(), nb_nodes_per_element_p1);
dxadj_it += connectivity.size();
}
/// convert the dxadj_val array in a csr one
for (UInt i = 1; i < nb_total_element; ++i)
dxadj(i) += dxadj(i - 1);
for (UInt i = nb_total_element; i > 0; --i)
dxadj(i) = dxadj(i - 1);
dxadj(0) = 0;
dadjncy.resize(2 * dxadj(nb_total_element));
edge_loads.resize(2 * dxadj(nb_total_element));
/// weight map to determine adjacency
std::unordered_map<UInt, UInt> weight_map;
for (auto & pair : connectivities) {
auto type = pair.first;
const auto & connectivity = *std::get<0>(pair.second);
auto nb_nodes_per_element = std::get<1>(pair.second);
auto magic_number = std::get<2>(pair.second);
Element element{type, 0, _not_ghost};
for (const auto & conn :
make_view(connectivity, connectivity.getNbComponent())) {
auto linearized_el = linearized(element);
/// fill the weight map
for (UInt n : arange(nb_nodes_per_element)) {
auto && node = conn(n);
for (auto k = node_to_elem.rbegin(node); k != node_to_elem.rend(node);
--k) {
auto & current_element = *k;
auto current_el = linearized(current_element);
AKANTU_DEBUG_ASSERT(current_el != UInt(-1),
"Linearized element not found");
if (current_el <= linearized_el)
break;
auto weight_map_insert =
weight_map.insert(std::make_pair(current_el, 1));
if (not weight_map_insert.second)
(weight_map_insert.first->second)++;
}
}
/// each element with a weight of the size of a facet are adjacent
for (auto & weight_pair : weight_map) {
auto & adjacent_el = weight_pair.first;
auto magic = weight_pair.second;
if (magic != magic_number)
continue;
#if defined(AKANTU_COHESIVE_ELEMENT)
/// Patch in order to prevent neighboring cohesive elements
/// from detecting each other
auto adjacent_element = unlinearized(adjacent_el);
auto el_kind = element.kind();
auto adjacent_el_kind = adjacent_element.kind();
if (el_kind == adjacent_el_kind && el_kind == _ek_cohesive)
continue;
#endif
UInt index_adj = dxadj(adjacent_el)++;
UInt index_lin = dxadj(linearized_el)++;
dadjncy(index_lin) = adjacent_el;
dadjncy(index_adj) = linearized_el;
}
element.element++;
weight_map.clear();
}
}
Int k_start = 0, linerized_el = 0, j = 0;
for (auto & pair : connectivities) {
const auto & connectivity = *std::get<0>(pair.second);
auto nb_nodes_per_element_p1 = std::get<1>(pair.second);
auto nb_element = connectivity.size();
for (UInt el = 0; el < nb_element; ++el, ++linerized_el) {
for (Int k = k_start; k < dxadj(linerized_el); ++k, ++j)
dadjncy(j) = dadjncy(k);
dxadj(linerized_el) = j;
k_start += nb_nodes_per_element_p1;
}
}
for (UInt i = nb_total_element; i > 0; --i)
dxadj(i) = dxadj(i - 1);
dxadj(0) = 0;
UInt adj = 0;
for (UInt i = 0; i < nb_total_element; ++i) {
UInt nb_adj = dxadj(i + 1) - dxadj(i);
for (UInt j = 0; j < nb_adj; ++j, ++adj) {
Int el_adj_id = dadjncy(dxadj(i) + j);
Element el = unlinearized(i);
Element el_adj = unlinearized(el_adj_id);
Int load = edge_load_func(el, el_adj);
edge_loads(adj) = load;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartition::fillPartitionInformation(
const Mesh & mesh, const Int * linearized_partitions) {
AKANTU_DEBUG_IN();
CSR<Element> node_to_elem;
MeshUtils::buildNode2Elements(mesh, node_to_elem);
UInt linearized_el = 0;
for (auto & type :
mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
partitions.alloc(nb_element, 1, type, _not_ghost);
auto & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
ghost_part_csr.resizeRows(nb_element);
ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
ghost_partitions.alloc(0, 1, type, _ghost);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
UInt part = linearized_partitions[linearized_el];
partitions(type, _not_ghost)(el) = part;
std::list<UInt> list_adj_part;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity.storage()[el * nb_nodes_per_element + n];
CSR<Element>::iterator ne;
for (ne = node_to_elem.begin(node); ne != node_to_elem.end(node);
++ne) {
const Element & adj_element = *ne;
UInt adj_el = linearized(adj_element);
UInt adj_part = linearized_partitions[adj_el];
if (part != adj_part) {
list_adj_part.push_back(adj_part);
}
}
}
list_adj_part.sort();
list_adj_part.unique();
for (auto & adj_part : list_adj_part) {
ghost_part_csr.getRows().push_back(adj_part);
ghost_part_csr.rowOffset(el)++;
ghost_partitions(type, _ghost).push_back(adj_part);
ghost_partitions_offset(type, _ghost)(el)++;
}
}
ghost_part_csr.countToCSR();
/// convert the ghost_partitions_offset array in an offset array
Array<UInt> & ghost_partitions_offset_ptr =
ghost_partitions_offset(type, _ghost);
for (UInt i = 1; i < nb_element; ++i)
ghost_partitions_offset_ptr(i) += ghost_partitions_offset_ptr(i - 1);
for (UInt i = nb_element; i > 0; --i)
ghost_partitions_offset_ptr(i) = ghost_partitions_offset_ptr(i - 1);
ghost_partitions_offset_ptr(0) = 0;
}
// All Facets
for (Int sp = spatial_dimension - 1; sp >= 0; --sp) {
for (auto & type : mesh.elementTypes(sp, _not_ghost, _ek_not_defined)) {
UInt nb_element = mesh.getNbElement(type);
partitions.alloc(nb_element, 1, type, _not_ghost);
AKANTU_DEBUG_INFO("Allocating partitions for " << type);
auto & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
ghost_part_csr.resizeRows(nb_element);
ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
ghost_partitions.alloc(0, 1, type, _ghost);
AKANTU_DEBUG_INFO("Allocating ghost_partitions for " << type);
const Array<std::vector<Element>> & elem_to_subelem =
mesh.getElementToSubelement(type, _not_ghost);
for (UInt i(0); i < mesh.getNbElement(type, _not_ghost);
++i) { // Facet loop
const std::vector<Element> & adjacent_elems = elem_to_subelem(i);
if (!adjacent_elems.empty()) {
Element min_elem{_max_element_type, std::numeric_limits<UInt>::max(),
*ghost_type_t::end()};
UInt min_part(std::numeric_limits<UInt>::max());
std::set<UInt> adjacent_parts;
for (UInt j(0); j < adjacent_elems.size(); ++j) {
UInt adjacent_elem_id = adjacent_elems[j].element;
UInt adjacent_elem_part =
partitions(adjacent_elems[j].type,
adjacent_elems[j].ghost_type)(adjacent_elem_id);
if (adjacent_elem_part < min_part) {
min_part = adjacent_elem_part;
min_elem = adjacent_elems[j];
}
adjacent_parts.insert(adjacent_elem_part);
}
partitions(type, _not_ghost)(i) = min_part;
auto git = ghost_partitions_csr(min_elem.type, _not_ghost)
.begin(min_elem.element);
auto gend = ghost_partitions_csr(min_elem.type, _not_ghost)
.end(min_elem.element);
for (; git != gend; ++git) {
adjacent_parts.insert(min_part);
}
adjacent_parts.erase(min_part);
for (auto & part : adjacent_parts) {
ghost_part_csr.getRows().push_back(part);
ghost_part_csr.rowOffset(i)++;
ghost_partitions(type, _ghost).push_back(part);
}
ghost_partitions_offset(type, _ghost)(i + 1) =
ghost_partitions_offset(type, _ghost)(i + 1) +
adjacent_elems.size();
} else {
partitions(type, _not_ghost)(i) = 0;
}
}
ghost_part_csr.countToCSR();
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartition::tweakConnectivity(const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
if (pairs.size() == 0)
return;
Mesh::type_iterator it =
mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
Mesh::type_iterator end =
mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
for (; it != end; ++it) {
ElementType type = *it;
Array<UInt> & conn =
const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
UInt nb_nodes_per_element = conn.getNbComponent();
UInt nb_element = conn.size();
Array<UInt> & saved_conn = saved_connectivity.alloc(
nb_element, nb_nodes_per_element, type, _not_ghost);
saved_conn.copy(conn);
for (UInt i = 0; i < pairs.size(); ++i) {
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
if (pairs(i, 1) == conn(el, n))
conn(el, n) = pairs(i, 0);
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartition::restoreConnectivity() {
AKANTU_DEBUG_IN();
MeshAccessor mesh_accessor(const_cast<Mesh &>(mesh));
for (auto && type : saved_connectivity.elementTypes(
spatial_dimension, _not_ghost, _ek_not_defined)) {
auto & conn = mesh_accessor.getConnectivity(type, _not_ghost);
auto & saved_conn = saved_connectivity(type, _not_ghost);
conn.copy(saved_conn);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
bool MeshPartition::hasPartitions(const ElementType & type,
const GhostType & ghost_type) {
return partitions.exists(type, ghost_type);
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
index 6e87f6869..78d5990bb 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
@@ -1,141 +1,141 @@
/**
* @file mesh_partition_mesh_data.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri May 03 2013
* @date last modification: Wed Nov 11 2015
*
* @brief implementation of the MeshPartitionMeshData class
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "mesh_partition_mesh_data.hh"
#if !defined(AKANTU_NDEBUG)
#include <set>
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
MeshPartitionMeshData::MeshPartitionMeshData(const Mesh & mesh,
UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id)
: MeshPartition(mesh, spatial_dimension, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MeshPartitionMeshData::MeshPartitionMeshData(
const Mesh & mesh, const ElementTypeMapArray<UInt> & mapping,
UInt spatial_dimension, const ID & id, const MemoryID & memory_id)
: MeshPartition(mesh, spatial_dimension, id, memory_id),
partition_mapping(&mapping) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::partitionate(UInt nb_part,
__attribute__((unused))
const EdgeLoadFunctor & edge_load_func,
const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
tweakConnectivity(pairs);
nb_partitions = nb_part;
GhostType ghost_type = _not_ghost;
UInt spatial_dimension = mesh.getSpatialDimension();
Mesh::type_iterator it =
mesh.firstType(spatial_dimension, ghost_type, _ek_not_defined);
Mesh::type_iterator end =
mesh.lastType(spatial_dimension, ghost_type, _ek_not_defined);
UInt linearized_el = 0;
UInt nb_elements = mesh.getNbElement(mesh.getSpatialDimension(), ghost_type);
auto * partition_list = new Int[nb_elements];
#if !defined(AKANTU_NDEBUG)
std::set<UInt> partitions;
#endif
for (; it != end; ++it) {
ElementType type = *it;
const Array<UInt> & partition_array =
(*partition_mapping)(type, ghost_type);
- Array<UInt>::const_iterator<Vector<UInt> > p_it = partition_array.begin(1);
- Array<UInt>::const_iterator<Vector<UInt> > p_end = partition_array.end(1);
+ Array<UInt>::const_iterator<Vector<UInt>> p_it = partition_array.begin(1);
+ Array<UInt>::const_iterator<Vector<UInt>> p_end = partition_array.end(1);
AKANTU_DEBUG_ASSERT(UInt(p_end - p_it) ==
mesh.getNbElement(type, ghost_type),
"The partition mapping does not have the right number "
<< "of entries for type " << type
<< " and ghost type " << ghost_type << "."
<< " Tags=" << p_end - p_it
<< " Mesh=" << mesh.getNbElement(type, ghost_type));
for (; p_it != p_end; ++p_it, ++linearized_el) {
partition_list[linearized_el] = (*p_it)(0);
#if !defined(AKANTU_NDEBUG)
partitions.insert((*p_it)(0));
#endif
}
}
#if !defined(AKANTU_NDEBUG)
AKANTU_DEBUG_ASSERT(partitions.size() == nb_part,
"The number of real partitions does not match with the "
"number of asked partitions");
#endif
fillPartitionInformation(mesh, partition_list);
delete[] partition_list;
restoreConnectivity();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::reorder() { AKANTU_TO_IMPLEMENT(); }
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::setPartitionMapping(
const ElementTypeMapArray<UInt> & mapping) {
partition_mapping = &mapping;
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::setPartitionMappingFromMeshData(
const std::string & data_name) {
partition_mapping = &(mesh.getData<UInt>(data_name));
}
} // akantu
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
index a8f44b91a..d2405af38 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
@@ -1,98 +1,94 @@
/**
* @file mesh_partition_mesh_data.hh
*
* @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief mesh partitioning based on data provided in the mesh
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_PARTITION_MESH_DATA_HH__
#define __AKANTU_MESH_PARTITION_MESH_DATA_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_partition.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class MeshPartitionMeshData : public MeshPartition {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MeshPartitionMeshData(const Mesh & mesh, UInt spatial_dimension,
const ID & id = "MeshPartitionerMeshData",
const MemoryID & memory_id = 0);
MeshPartitionMeshData(const Mesh & mesh,
const ElementTypeMapArray<UInt> & mapping,
UInt spatial_dimension,
const ID & id = "MeshPartitionerMeshData",
const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void
partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
const Array<UInt> & pairs = Array<UInt>()) override;
void reorder() override;
void setPartitionMapping(const ElementTypeMapArray<UInt> & mapping);
void setPartitionMappingFromMeshData(const std::string & data_name);
- private:
-
+private:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
const ElementTypeMapArray<UInt> * partition_mapping;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-
} // akantu
#endif /* __AKANTU_MESH_PARTITION_MESH_DATA_HH__ */
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
index 1721808e0..9d0cd28f1 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
@@ -1,481 +1,479 @@
/**
* @file mesh_partition_scotch.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Jan 22 2016
*
* @brief implementation of the MeshPartitionScotch class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_partition_scotch.hh"
#include "aka_common.hh"
#include "aka_random_generator.hh"
#include "aka_static_if.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <cstdio>
#include <fstream>
/* -------------------------------------------------------------------------- */
#if !defined(AKANTU_USE_PTSCOTCH)
#ifndef AKANTU_SCOTCH_NO_EXTERN
extern "C" {
#endif // AKANTU_SCOTCH_NO_EXTERN
#include <scotch.h>
#ifndef AKANTU_SCOTCH_NO_EXTERN
}
#endif // AKANTU_SCOTCH_NO_EXTERN
#else // AKANTU_USE_PTSCOTCH
#include <ptscotch.h>
#endif // AKANTU_USE_PTSCOTCH
namespace akantu {
namespace {
constexpr int scotch_version = int(SCOTCH_VERSION);
}
/* -------------------------------------------------------------------------- */
MeshPartitionScotch::MeshPartitionScotch(const Mesh & mesh,
UInt spatial_dimension, const ID & id,
const MemoryID & memory_id)
: MeshPartition(mesh, spatial_dimension, id, memory_id) {
AKANTU_DEBUG_IN();
// check if the akantu types and Scotch one are consistent
static_assert(
sizeof(Int) == sizeof(SCOTCH_Num),
"The integer type of Akantu does not match the one from Scotch");
static_if(aka::bool_constant_v<scotch_version >= 6>)
.then([](auto && y) { SCOTCH_randomSeed(y); })
- .else_([](auto && y) {
- srandom(y);
- })(std::forward<UInt>(RandomGenerator<UInt>::seed()));
+ .else_([](auto && y) { srandom(y); })(
+ std::forward<UInt>(RandomGenerator<UInt>::seed()));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
static SCOTCH_Mesh * createMesh(const Mesh & mesh) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes = mesh.getNbNodes();
UInt total_nb_element = 0;
UInt nb_edge = 0;
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator end = mesh.lastType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
total_nb_element += nb_element;
nb_edge += nb_element * nb_nodes_per_element;
}
SCOTCH_Num vnodbas = 0;
SCOTCH_Num vnodnbr = nb_nodes;
SCOTCH_Num velmbas = vnodnbr;
SCOTCH_Num velmnbr = total_nb_element;
auto * verttab = new SCOTCH_Num[vnodnbr + velmnbr + 1];
SCOTCH_Num * vendtab = verttab + 1;
SCOTCH_Num * velotab = nullptr;
SCOTCH_Num * vnlotab = nullptr;
SCOTCH_Num * vlbltab = nullptr;
memset(verttab, 0, (vnodnbr + velmnbr + 1) * sizeof(SCOTCH_Num));
it = mesh.firstType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
if (Mesh::getSpatialDimension(type) != spatial_dimension)
continue;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
/// count number of occurrence of each node
for (UInt el = 0; el < nb_element; ++el) {
UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
verttab[*(conn_val++)]++;
}
}
}
/// convert the occurrence array in a csr one
for (UInt i = 1; i < nb_nodes; ++i)
verttab[i] += verttab[i - 1];
for (UInt i = nb_nodes; i > 0; --i)
verttab[i] = verttab[i - 1];
verttab[0] = 0;
/// rearrange element to get the node-element list
SCOTCH_Num edgenbr = verttab[vnodnbr] + nb_edge;
auto * edgetab = new SCOTCH_Num[edgenbr];
UInt linearized_el = 0;
it = mesh.firstType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n)
edgetab[verttab[*(conn_val++)]++] = linearized_el + velmbas;
}
}
for (UInt i = nb_nodes; i > 0; --i)
verttab[i] = verttab[i - 1];
verttab[0] = 0;
SCOTCH_Num * verttab_tmp = verttab + vnodnbr + 1;
SCOTCH_Num * edgetab_tmp = edgetab + verttab[vnodnbr];
it = mesh.firstType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
for (UInt el = 0; el < nb_element; ++el) {
*verttab_tmp = *(verttab_tmp - 1) + nb_nodes_per_element;
verttab_tmp++;
UInt * conn = connectivity.storage() + el * nb_nodes_per_element;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
*(edgetab_tmp++) = *(conn++) + vnodbas;
}
}
}
auto * meshptr = new SCOTCH_Mesh;
SCOTCH_meshInit(meshptr);
SCOTCH_meshBuild(meshptr, velmbas, vnodbas, velmnbr, vnodnbr, verttab,
vendtab, velotab, vnlotab, vlbltab, edgenbr, edgetab);
/// Check the mesh
AKANTU_DEBUG_ASSERT(SCOTCH_meshCheck(meshptr) == 0,
"Scotch mesh is not consistent");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save initial graph
FILE * fmesh = fopen("ScotchMesh.msh", "w");
SCOTCH_meshSave(meshptr, fmesh);
fclose(fmesh);
/// write geometry file
std::ofstream fgeominit;
fgeominit.open("ScotchMesh.xyz");
fgeominit << spatial_dimension << std::endl << nb_nodes << std::endl;
const Array<Real> & nodes = mesh.getNodes();
Real * nodes_val = nodes.storage();
for (UInt i = 0; i < nb_nodes; ++i) {
fgeominit << i << " ";
for (UInt s = 0; s < spatial_dimension; ++s)
fgeominit << *(nodes_val++) << " ";
fgeominit << std::endl;
;
}
fgeominit.close();
}
#endif
AKANTU_DEBUG_OUT();
return meshptr;
}
/* -------------------------------------------------------------------------- */
static void destroyMesh(SCOTCH_Mesh * meshptr) {
AKANTU_DEBUG_IN();
SCOTCH_Num velmbas, vnodbas, vnodnbr, velmnbr, *verttab, *vendtab, *velotab,
*vnlotab, *vlbltab, edgenbr, *edgetab, degrptr;
SCOTCH_meshData(meshptr, &velmbas, &vnodbas, &velmnbr, &vnodnbr, &verttab,
&vendtab, &velotab, &vnlotab, &vlbltab, &edgenbr, &edgetab,
&degrptr);
delete[] verttab;
delete[] edgetab;
SCOTCH_meshExit(meshptr);
delete meshptr;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionScotch::partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func,
const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
nb_partitions = nb_part;
tweakConnectivity(pairs);
AKANTU_DEBUG_INFO("Partitioning the mesh " << mesh.getID() << " in "
<< nb_part << " parts.");
Array<Int> dxadj;
Array<Int> dadjncy;
Array<Int> edge_loads;
buildDualGraph(dxadj, dadjncy, edge_loads, edge_load_func);
/// variables that will hold our structures in scotch format
SCOTCH_Graph scotch_graph;
SCOTCH_Strat scotch_strat;
/// description number and arrays for struct mesh for scotch
SCOTCH_Num baseval = 0; // base numbering for element and
// nodes (0 -> C , 1 -> fortran)
SCOTCH_Num vertnbr = dxadj.size() - 1; // number of vertexes
SCOTCH_Num * parttab; // array of partitions
SCOTCH_Num edgenbr = dxadj(vertnbr); // twice the number of "edges"
//(an "edge" bounds two nodes)
SCOTCH_Num * verttab = dxadj.storage(); // array of start indices in edgetab
SCOTCH_Num * vendtab = nullptr; // array of after-last indices in edgetab
SCOTCH_Num * velotab = nullptr; // integer load associated with
// every vertex ( optional )
SCOTCH_Num * edlotab = edge_loads.storage(); // integer load associated with
// every edge ( optional )
SCOTCH_Num * edgetab = dadjncy.storage(); // adjacency array of every vertex
SCOTCH_Num * vlbltab = nullptr; // vertex label array (optional)
/// Allocate space for Scotch arrays
parttab = new SCOTCH_Num[vertnbr];
/// Initialize the strategy structure
SCOTCH_stratInit(&scotch_strat);
/// Initialize the graph structure
SCOTCH_graphInit(&scotch_graph);
/// Build the graph from the adjacency arrays
SCOTCH_graphBuild(&scotch_graph, baseval, vertnbr, verttab, vendtab, velotab,
vlbltab, edgenbr, edgetab, edlotab);
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save initial graph
FILE * fgraphinit = fopen("GraphIniFile.grf", "w");
SCOTCH_graphSave(&scotch_graph, fgraphinit);
fclose(fgraphinit);
/// write geometry file
std::ofstream fgeominit;
fgeominit.open("GeomIniFile.xyz");
fgeominit << spatial_dimension << std::endl << vertnbr << std::endl;
const Array<Real> & nodes = mesh.getNodes();
Mesh::type_iterator f_it =
mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
Mesh::type_iterator f_end =
mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
- auto nodes_it =
- nodes.begin(spatial_dimension);
+ auto nodes_it = nodes.begin(spatial_dimension);
UInt out_linerized_el = 0;
for (; f_it != f_end; ++f_it) {
ElementType type = *f_it;
UInt nb_element = mesh.getNbElement(*f_it);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Vector<Real> mid(spatial_dimension);
for (UInt el = 0; el < nb_element; ++el) {
mid.set(0.);
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity.storage()[nb_nodes_per_element * el + n];
mid += Vector<Real>(nodes_it[node]);
}
mid /= nb_nodes_per_element;
fgeominit << out_linerized_el++ << " ";
for (UInt s = 0; s < spatial_dimension; ++s)
fgeominit << mid[s] << " ";
fgeominit << std::endl;
;
}
}
fgeominit.close();
}
#endif
/// Check the graph
AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
"Graph to partition is not consistent");
/// Partition the mesh
SCOTCH_graphPart(&scotch_graph, nb_part, &scotch_strat, parttab);
/// Check the graph
AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
"Partitioned graph is not consistent");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save the partitioned graph
FILE * fgraph = fopen("GraphFile.grf", "w");
SCOTCH_graphSave(&scotch_graph, fgraph);
fclose(fgraph);
/// save the partition map
std::ofstream fmap;
fmap.open("MapFile.map");
fmap << vertnbr << std::endl;
for (Int i = 0; i < vertnbr; i++)
fmap << i << " " << parttab[i] << std::endl;
fmap.close();
}
#endif
/// free the scotch data structures
SCOTCH_stratExit(&scotch_strat);
SCOTCH_graphFree(&scotch_graph);
SCOTCH_graphExit(&scotch_graph);
fillPartitionInformation(mesh, parttab);
delete[] parttab;
restoreConnectivity();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionScotch::reorder() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Reordering the mesh " << mesh.getID());
SCOTCH_Mesh * scotch_mesh = createMesh(mesh);
UInt nb_nodes = mesh.getNbNodes();
SCOTCH_Strat scotch_strat;
// SCOTCH_Ordering scotch_order;
auto * permtab = new SCOTCH_Num[nb_nodes];
SCOTCH_Num * peritab = nullptr;
SCOTCH_Num cblknbr = 0;
SCOTCH_Num * rangtab = nullptr;
SCOTCH_Num * treetab = nullptr;
/// Initialize the strategy structure
SCOTCH_stratInit(&scotch_strat);
SCOTCH_Graph scotch_graph;
SCOTCH_graphInit(&scotch_graph);
SCOTCH_meshGraph(scotch_mesh, &scotch_graph);
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
FILE * fgraphinit = fopen("ScotchMesh.grf", "w");
SCOTCH_graphSave(&scotch_graph, fgraphinit);
fclose(fgraphinit);
}
#endif
/// Check the graph
// AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
// "Mesh to Graph is not consistent");
SCOTCH_graphOrder(&scotch_graph, &scotch_strat, permtab, peritab, &cblknbr,
rangtab, treetab);
SCOTCH_graphExit(&scotch_graph);
SCOTCH_stratExit(&scotch_strat);
destroyMesh(scotch_mesh);
/// Renumbering
UInt spatial_dimension = mesh.getSpatialDimension();
for (UInt g = _not_ghost; g <= _ghost; ++g) {
auto gt = (GhostType)g;
Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, gt);
for (; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type, gt);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, gt);
UInt * conn = connectivity.storage();
for (UInt el = 0; el < nb_element * nb_nodes_per_element; ++el, ++conn) {
*conn = permtab[*conn];
}
}
}
/// \todo think of a in-place way to do it
auto * new_coordinates = new Real[spatial_dimension * nb_nodes];
Real * old_coordinates = mesh.getNodes().storage();
for (UInt i = 0; i < nb_nodes; ++i) {
memcpy(new_coordinates + permtab[i] * spatial_dimension,
old_coordinates + i * spatial_dimension,
spatial_dimension * sizeof(Real));
}
memcpy(old_coordinates, new_coordinates,
nb_nodes * spatial_dimension * sizeof(Real));
delete[] new_coordinates;
delete[] permtab;
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
index e96865878..2dc3e385b 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
@@ -1,81 +1,78 @@
/**
* @file mesh_partition_scotch.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief mesh partitioning based on libScotch
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_PARTITION_SCOTCH_HH__
#define __AKANTU_MESH_PARTITION_SCOTCH_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_partition.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class MeshPartitionScotch : public MeshPartition {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MeshPartitionScotch(const Mesh & mesh, UInt spatial_dimension,
- const ID & id = "mesh_partition_scotch",
- const MemoryID & memory_id = 0);
+ const ID & id = "mesh_partition_scotch",
+ const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void
partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
const Array<UInt> & pairs = Array<UInt>()) override;
void reorder() override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
-
};
} // akantu
#endif /* __AKANTU_MESH_PARTITION_SCOTCH_HH__ */
diff --git a/src/mesh_utils/mesh_utils.cc b/src/mesh_utils/mesh_utils.cc
index 97b0dcceb..7883e4a37 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2091 +1,2091 @@
/**
* @file mesh_utils.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Aug 20 2010
* @date last modification: Fri Jan 22 2016
*
* @brief All mesh utils necessary for various tasks
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_utils.hh"
#include "element_synchronizer.hh"
#include "fe_engine.hh"
#include "mesh_accessor.hh"
/* -------------------------------------------------------------------------- */
#include <limits>
#include <numeric>
#include <queue>
#include <set>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
void MeshUtils::buildNode2Elements(const Mesh & mesh,
CSR<Element> & node_to_elem,
UInt spatial_dimension) {
AKANTU_DEBUG_IN();
if (spatial_dimension == _all_dimensions)
spatial_dimension = mesh.getSpatialDimension();
/// count number of occurrence of each node
UInt nb_nodes = mesh.getNbNodes();
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
// AKANTU_DEBUG_ASSERT(
// mesh.firstType(spatial_dimension) != mesh.lastType(spatial_dimension),
// "Some elements must be found in right dimension to compute facets!");
for (auto && ghost_type : ghost_types) {
for (auto && type :
mesh.elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
UInt nb_element = mesh.getNbElement(type, ghost_type);
auto conn_it = mesh.getConnectivity(type, ghost_type)
.begin(Mesh::getNbNodesPerElement(type));
for (UInt el = 0; el < nb_element; ++el, ++conn_it)
for (UInt n = 0; n < conn_it->size(); ++n)
++node_to_elem.rowOffset((*conn_it)(n));
}
}
node_to_elem.countToCSR();
node_to_elem.resizeCols();
/// rearrange element to get the node-element list
Element e;
node_to_elem.beginInsertions();
for (auto && ghost_type : ghost_types) {
e.ghost_type = ghost_type;
for (auto && type :
mesh.elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
e.type = type;
UInt nb_element = mesh.getNbElement(type, ghost_type);
- auto conn_it = mesh.getConnectivity(type, ghost_type).begin(
- Mesh::getNbNodesPerElement(type));
+ auto conn_it = mesh.getConnectivity(type, ghost_type)
+ .begin(Mesh::getNbNodesPerElement(type));
for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
e.element = el;
for (UInt n = 0; n < conn_it->size(); ++n)
node_to_elem.insertInRow((*conn_it)(n), e);
}
}
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildNode2ElementsElementTypeMap(const Mesh & mesh,
CSR<UInt> & node_to_elem,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_elements = mesh.getConnectivity(type, ghost_type).size();
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
/// count number of occurrence of each node
for (UInt el = 0; el < nb_elements; ++el) {
UInt el_offset = el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n)
++node_to_elem.rowOffset(conn_val[el_offset + n]);
}
/// convert the occurrence array in a csr one
node_to_elem.countToCSR();
node_to_elem.resizeCols();
node_to_elem.beginInsertions();
/// save the element index in the node-element list
for (UInt el = 0; el < nb_elements; ++el) {
UInt el_offset = el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
node_to_elem.insertInRow(conn_val[el_offset + n], el);
}
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildFacets(Mesh & mesh) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh.lastType(spatial_dimension - 1, gt_facet);
for (; it != end; ++it) {
mesh.getConnectivity(*it, *gt).resize(0);
// \todo inform the mesh event handler
}
}
buildFacetsDimension(mesh, mesh, true, spatial_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
UInt to_dimension) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
buildAllFacets(mesh, mesh_facets, spatial_dimension, to_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
UInt from_dimension, UInt to_dimension) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(
mesh_facets.isMeshFacets(),
"The mesh_facets should be initialized with initMeshFacets");
/// generate facets
buildFacetsDimension(mesh, mesh_facets, false, from_dimension);
/// copy nodes type
MeshAccessor mesh_accessor_facets(mesh_facets);
mesh_accessor_facets.getNodesType().copy(mesh.getNodesType());
/// sort facets and generate sub-facets
for (UInt i = from_dimension - 1; i > to_dimension; --i) {
buildFacetsDimension(mesh_facets, mesh_facets, false, i);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildFacetsDimension(const Mesh & mesh, Mesh & mesh_facets,
bool boundary_only, UInt dimension) {
AKANTU_DEBUG_IN();
// save the current parent of mesh_facets and set it temporarly to mesh since
// mesh is the one containing the elements for which mesh_facets has the
// sub-elements
// example: if the function is called with mesh = mesh_facets
const Mesh * mesh_facets_parent = nullptr;
try {
mesh_facets_parent = &mesh_facets.getMeshParent();
} catch (...) {
}
mesh_facets.defineMeshParent(mesh);
MeshAccessor mesh_accessor(mesh_facets);
UInt spatial_dimension = mesh.getSpatialDimension();
const Array<Real> & mesh_facets_nodes = mesh_facets.getNodes();
const auto mesh_facets_nodes_it = mesh_facets_nodes.begin(spatial_dimension);
CSR<Element> node_to_elem;
buildNode2Elements(mesh, node_to_elem, dimension);
Array<UInt> counter;
std::vector<Element> connected_elements;
// init the SubelementToElement data to improve performance
for (auto && ghost_type : ghost_types) {
for (auto && type : mesh.elementTypes(dimension, ghost_type)) {
mesh_accessor.getSubelementToElement(type, ghost_type);
auto facet_types = mesh.getAllFacetTypes(type);
for (auto && ft : arange(facet_types.size())) {
auto facet_type = facet_types(ft);
mesh_accessor.getElementToSubelement(facet_type, ghost_type);
mesh_accessor.getConnectivity(facet_type, ghost_type);
}
}
}
const ElementSynchronizer * synchronizer = nullptr;
if (mesh.isDistributed()) {
synchronizer = &(mesh.getElementSynchronizer());
}
Element current_element;
for (auto && ghost_type : ghost_types) {
GhostType facet_ghost_type = ghost_type;
current_element.ghost_type = ghost_type;
for (auto && type : mesh.elementTypes(dimension, ghost_type)) {
auto facet_types = mesh.getAllFacetTypes(type);
current_element.type = type;
for (auto && ft : arange(facet_types.size())) {
auto facet_type = facet_types(ft);
auto nb_element = mesh.getNbElement(type, ghost_type);
auto element_to_subelement =
&mesh_facets.getElementToSubelement(facet_type, ghost_type);
auto connectivity_facets =
&mesh_facets.getConnectivity(facet_type, ghost_type);
auto nb_facet_per_element = mesh.getNbFacetsPerElement(type, ft);
const auto & element_connectivity =
mesh.getConnectivity(type, ghost_type);
Matrix<const UInt> facet_local_connectivity(
mesh.getFacetLocalConnectivity(type, ft));
auto nb_nodes_per_facet = connectivity_facets->getNbComponent();
Vector<UInt> facet(nb_nodes_per_facet);
for (UInt el = 0; el < nb_element; ++el) {
current_element.element = el;
for (UInt f = 0; f < nb_facet_per_element; ++f) {
for (UInt n = 0; n < nb_nodes_per_facet; ++n)
facet(n) =
element_connectivity(el, facet_local_connectivity(f, n));
UInt first_node_nb_elements = node_to_elem.getNbCols(facet(0));
counter.resize(first_node_nb_elements);
counter.clear();
// loop over the other nodes to search intersecting elements,
// which are the elements that share another node with the
// starting element after first_node
UInt local_el = 0;
auto first_node_elements = node_to_elem.begin(facet(0));
auto first_node_elements_end = node_to_elem.end(facet(0));
for (; first_node_elements != first_node_elements_end;
++first_node_elements, ++local_el) {
for (UInt n = 1; n < nb_nodes_per_facet; ++n) {
auto node_elements_begin = node_to_elem.begin(facet(n));
auto node_elements_end = node_to_elem.end(facet(n));
counter(local_el) +=
std::count(node_elements_begin, node_elements_end,
*first_node_elements);
}
}
// counting the number of elements connected to the facets and
// taking the minimum element number, because the facet should
// be inserted just once
UInt nb_element_connected_to_facet = 0;
Element minimum_el = ElementNull;
connected_elements.clear();
for (UInt el_f = 0; el_f < first_node_nb_elements; el_f++) {
Element real_el = node_to_elem(facet(0), el_f);
if (not(counter(el_f) == nb_nodes_per_facet - 1))
continue;
++nb_element_connected_to_facet;
minimum_el = std::min(minimum_el, real_el);
connected_elements.push_back(real_el);
}
if (minimum_el != current_element)
continue;
bool full_ghost_facet = false;
UInt n = 0;
while (n < nb_nodes_per_facet && mesh.isPureGhostNode(facet(n)))
++n;
if (n == nb_nodes_per_facet)
full_ghost_facet = true;
if (full_ghost_facet)
continue;
if (boundary_only and nb_element_connected_to_facet != 1)
continue;
std::vector<Element> elements;
// build elements_on_facets: linearized_el must come first
// in order to store the facet in the correct direction
// and avoid to invert the sign in the normal computation
elements.push_back(current_element);
if (nb_element_connected_to_facet == 1) { /// boundary facet
elements.push_back(ElementNull);
} else if (nb_element_connected_to_facet == 2) { /// internal facet
elements.push_back(connected_elements[1]);
/// check if facet is in between ghost and normal
/// elements: if it's the case, the facet is either
/// ghost or not ghost. The criterion to decide this
/// is arbitrary. It was chosen to check the processor
/// id (prank) of the two neighboring elements. If
/// prank of the ghost element is lower than prank of
/// the normal one, the facet is not ghost, otherwise
/// it's ghost
GhostType gt[2] = {_not_ghost, _not_ghost};
for (UInt el = 0; el < connected_elements.size(); ++el)
gt[el] = connected_elements[el].ghost_type;
if (gt[0] != gt[1] and
(gt[0] == _not_ghost or gt[1] == _not_ghost)) {
UInt prank[2];
for (UInt el = 0; el < 2; ++el) {
prank[el] = synchronizer->getRank(connected_elements[el]);
}
// ugly trick from Marco detected :P
bool ghost_one = (gt[0] != _ghost);
if (prank[ghost_one] > prank[!ghost_one])
facet_ghost_type = _not_ghost;
else
facet_ghost_type = _ghost;
connectivity_facets =
&mesh_facets.getConnectivity(facet_type, facet_ghost_type);
element_to_subelement = &mesh_facets.getElementToSubelement(
facet_type, facet_ghost_type);
}
} else { /// facet of facet
for (UInt i = 1; i < nb_element_connected_to_facet; ++i) {
elements.push_back(connected_elements[i]);
}
}
element_to_subelement->push_back(elements);
connectivity_facets->push_back(facet);
/// current facet index
UInt current_facet = connectivity_facets->size() - 1;
/// loop on every element connected to current facet and
/// insert current facet in the first free spot of the
/// subelement_to_element vector
for (UInt elem = 0; elem < elements.size(); ++elem) {
Element loc_el = elements[elem];
if (loc_el.type == _not_defined)
continue;
Array<Element> & subelement_to_element =
mesh_facets.getSubelementToElement(loc_el.type,
loc_el.ghost_type);
UInt nb_facet_per_loc_element =
subelement_to_element.getNbComponent();
for (UInt f_in = 0; f_in < nb_facet_per_loc_element; ++f_in) {
auto & el = subelement_to_element(loc_el.element, f_in);
if (el.type != _not_defined)
continue;
el.type = facet_type;
el.element = current_facet;
el.ghost_type = facet_ghost_type;
break;
}
}
/// reset connectivity in case a facet was found in
/// between ghost and normal elements
if (facet_ghost_type != ghost_type) {
facet_ghost_type = ghost_type;
connectivity_facets =
&mesh_accessor.getConnectivity(facet_type, facet_ghost_type);
element_to_subelement = &mesh_accessor.getElementToSubelement(
facet_type, facet_ghost_type);
}
}
}
}
}
}
// restore the parent of mesh_facet
if (mesh_facets_parent)
mesh_facets.defineMeshParent(*mesh_facets_parent);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::renumberMeshNodes(Mesh & mesh,
Array<UInt> & local_connectivities,
UInt nb_local_element, UInt nb_ghost_element,
ElementType type,
Array<UInt> & old_nodes_numbers) {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
std::map<UInt, UInt> renumbering_map;
for (UInt i = 0; i < old_nodes_numbers.size(); ++i) {
renumbering_map[old_nodes_numbers(i)] = i;
}
/// renumber the nodes
renumberNodesInConnectivity(local_connectivities,
(nb_local_element + nb_ghost_element) *
nb_nodes_per_element,
renumbering_map);
old_nodes_numbers.resize(renumbering_map.size());
for (auto & renumber_pair : renumbering_map) {
old_nodes_numbers(renumber_pair.second) = renumber_pair.first;
}
renumbering_map.clear();
MeshAccessor mesh_accessor(mesh);
/// copy the renumbered connectivity to the right place
auto & local_conn = mesh_accessor.getConnectivity(type);
local_conn.resize(nb_local_element);
memcpy(local_conn.storage(), local_connectivities.storage(),
nb_local_element * nb_nodes_per_element * sizeof(UInt));
auto & ghost_conn = mesh_accessor.getConnectivity(type, _ghost);
ghost_conn.resize(nb_ghost_element);
std::memcpy(ghost_conn.storage(),
local_connectivities.storage() +
nb_local_element * nb_nodes_per_element,
nb_ghost_element * nb_nodes_per_element * sizeof(UInt));
auto & ghost_counter = mesh_accessor.getGhostsCounters(type, _ghost);
ghost_counter.resize(nb_ghost_element, 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::renumberNodesInConnectivity(
Array<UInt> & list_nodes, UInt nb_nodes,
std::map<UInt, UInt> & renumbering_map) {
AKANTU_DEBUG_IN();
UInt * connectivity = list_nodes.storage();
UInt new_node_num = renumbering_map.size();
for (UInt n = 0; n < nb_nodes; ++n, ++connectivity) {
UInt & node = *connectivity;
auto it = renumbering_map.find(node);
if (it == renumbering_map.end()) {
UInt old_node = node;
renumbering_map[old_node] = new_node_num;
node = new_node_num;
++new_node_num;
} else {
node = it->second;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::purifyMesh(Mesh & mesh) {
AKANTU_DEBUG_IN();
std::map<UInt, UInt> renumbering_map;
RemovedNodesEvent remove_nodes(mesh);
Array<UInt> & nodes_removed = remove_nodes.getList();
for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
auto ghost_type = (GhostType)gt;
Mesh::type_iterator it =
mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
Mesh::type_iterator end =
mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
for (; it != end; ++it) {
ElementType type(*it);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
UInt nb_element(connectivity.size());
renumberNodesInConnectivity(
connectivity, nb_element * nb_nodes_per_element, renumbering_map);
}
}
Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
std::fill(new_numbering.begin(), new_numbering.end(), UInt(-1));
auto it = renumbering_map.begin();
auto end = renumbering_map.end();
for (; it != end; ++it) {
new_numbering(it->first) = it->second;
}
for (UInt i = 0; i < new_numbering.size(); ++i) {
if (new_numbering(i) == UInt(-1))
nodes_removed.push_back(i);
}
mesh.sendEvent(remove_nodes);
AKANTU_DEBUG_OUT();
}
#if defined(AKANTU_COHESIVE_ELEMENT)
/* -------------------------------------------------------------------------- */
UInt MeshUtils::insertCohesiveElements(
Mesh & mesh, Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion,
Array<UInt> & doubled_nodes, Array<Element> & new_elements,
bool only_double_facets) {
UInt spatial_dimension = mesh.getSpatialDimension();
UInt elements_to_insert = updateFacetToDouble(mesh_facets, facet_insertion);
if (elements_to_insert > 0) {
if (spatial_dimension == 1) {
doublePointFacet(mesh, mesh_facets, doubled_nodes);
} else {
doubleFacet(mesh, mesh_facets, spatial_dimension - 1, doubled_nodes,
true);
findSubfacetToDouble<false>(mesh, mesh_facets);
if (spatial_dimension == 2) {
doubleSubfacet<2>(mesh, mesh_facets, doubled_nodes);
} else if (spatial_dimension == 3) {
doubleFacet(mesh, mesh_facets, 1, doubled_nodes, false);
findSubfacetToDouble<true>(mesh, mesh_facets);
doubleSubfacet<3>(mesh, mesh_facets, doubled_nodes);
}
}
if (!only_double_facets)
updateCohesiveData(mesh, mesh_facets, new_elements);
}
return elements_to_insert;
}
#endif
/* -------------------------------------------------------------------------- */
void MeshUtils::doubleNodes(Mesh & mesh, const std::vector<UInt> & old_nodes,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
Array<Real> & position = mesh.getNodes();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt old_nb_nodes = position.size();
UInt new_nb_nodes = old_nb_nodes + old_nodes.size();
UInt old_nb_doubled_nodes = doubled_nodes.size();
UInt new_nb_doubled_nodes = old_nb_doubled_nodes + old_nodes.size();
position.resize(new_nb_nodes);
doubled_nodes.resize(new_nb_doubled_nodes);
Array<Real>::iterator<Vector<Real>> position_begin =
position.begin(spatial_dimension);
for (UInt n = 0; n < old_nodes.size(); ++n) {
UInt new_node = old_nb_nodes + n;
/// store doubled nodes
doubled_nodes(old_nb_doubled_nodes + n, 0) = old_nodes[n];
doubled_nodes(old_nb_doubled_nodes + n, 1) = new_node;
/// update position
std::copy(position_begin + old_nodes[n], position_begin + old_nodes[n] + 1,
position_begin + new_node);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::doubleFacet(Mesh & mesh, Mesh & mesh_facets,
UInt facet_dimension, Array<UInt> & doubled_nodes,
bool facet_mode) {
AKANTU_DEBUG_IN();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(facet_dimension, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(facet_dimension, gt_facet);
for (; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
UInt nb_facet_to_double = f_to_double.size();
if (nb_facet_to_double == 0)
continue;
ElementType type_subfacet = Mesh::getFacetType(type_facet);
const UInt nb_subfacet_per_facet =
Mesh::getNbFacetsPerElement(type_facet);
GhostType gt_subfacet = _casper;
Array<std::vector<Element>> * f_to_subfacet = nullptr;
Array<Element> & subfacet_to_facet =
mesh_facets.getSubelementToElement(type_facet, gt_facet);
Array<UInt> & conn_facet =
mesh_facets.getConnectivity(type_facet, gt_facet);
UInt nb_nodes_per_facet = conn_facet.getNbComponent();
UInt old_nb_facet = conn_facet.size();
UInt new_nb_facet = old_nb_facet + nb_facet_to_double;
conn_facet.resize(new_nb_facet);
subfacet_to_facet.resize(new_nb_facet);
UInt new_facet = old_nb_facet - 1;
Element new_facet_el{type_facet, 0, gt_facet};
Array<Element>::iterator<Vector<Element>> subfacet_to_facet_begin =
subfacet_to_facet.begin(nb_subfacet_per_facet);
Array<UInt>::iterator<Vector<UInt>> conn_facet_begin =
conn_facet.begin(nb_nodes_per_facet);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
++new_facet;
/// adding a new facet by copying original one
/// copy connectivity in new facet
std::copy(conn_facet_begin + old_facet,
conn_facet_begin + old_facet + 1,
conn_facet_begin + new_facet);
/// update subfacet_to_facet
std::copy(subfacet_to_facet_begin + old_facet,
subfacet_to_facet_begin + old_facet + 1,
subfacet_to_facet_begin + new_facet);
new_facet_el.element = new_facet;
/// loop on every subfacet
for (UInt sf = 0; sf < nb_subfacet_per_facet; ++sf) {
Element & subfacet = subfacet_to_facet(old_facet, sf);
if (subfacet == ElementNull)
continue;
if (gt_subfacet != subfacet.ghost_type) {
gt_subfacet = subfacet.ghost_type;
f_to_subfacet = &mesh_facets.getElementToSubelement(
type_subfacet, subfacet.ghost_type);
}
/// update facet_to_subfacet array
(*f_to_subfacet)(subfacet.element).push_back(new_facet_el);
}
}
/// update facet_to_subfacet and _segment_3 facets if any
if (!facet_mode) {
updateSubfacetToFacet(mesh_facets, type_facet, gt_facet, true);
updateFacetToSubfacet(mesh_facets, type_facet, gt_facet, true);
updateQuadraticSegments<true>(mesh, mesh_facets, type_facet, gt_facet,
doubled_nodes);
} else
updateQuadraticSegments<false>(mesh, mesh_facets, type_facet, gt_facet,
doubled_nodes);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
UInt MeshUtils::updateFacetToDouble(
Mesh & mesh_facets, const ElementTypeMapArray<bool> & facet_insertion) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
UInt nb_facets_to_double = 0.;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it =
mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end =
mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for (; it != end; ++it) {
ElementType type_facet = *it;
const Array<bool> & f_insertion = facet_insertion(type_facet, gt_facet);
Array<UInt> & f_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
Array<std::vector<Element>> & element_to_facet =
mesh_facets.getElementToSubelement(type_facet, gt_facet);
ElementType el_type = _not_defined;
GhostType el_gt = _casper;
UInt nb_facet_per_element = 0;
Element old_facet_el{type_facet, 0, gt_facet};
Array<Element> * facet_to_element = nullptr;
for (UInt f = 0; f < f_insertion.size(); ++f) {
if (f_insertion(f) == false)
continue;
++nb_facets_to_double;
if (element_to_facet(f)[1].type == _not_defined
#if defined(AKANTU_COHESIVE_ELEMENT)
|| element_to_facet(f)[1].kind() == _ek_cohesive
#endif
) {
AKANTU_DEBUG_WARNING("attempt to double a facet on the boundary");
continue;
}
f_to_double.push_back(f);
UInt new_facet = mesh_facets.getNbElement(type_facet, gt_facet) +
f_to_double.size() - 1;
old_facet_el.element = f;
/// update facet_to_element vector
Element & elem_to_update = element_to_facet(f)[1];
UInt el = elem_to_update.element;
if (elem_to_update.ghost_type != el_gt ||
elem_to_update.type != el_type) {
el_type = elem_to_update.type;
el_gt = elem_to_update.ghost_type;
facet_to_element =
&mesh_facets.getSubelementToElement(el_type, el_gt);
nb_facet_per_element = facet_to_element->getNbComponent();
}
Element * f_update =
std::find(facet_to_element->storage() + el * nb_facet_per_element,
facet_to_element->storage() + el * nb_facet_per_element +
nb_facet_per_element,
old_facet_el);
AKANTU_DEBUG_ASSERT(
facet_to_element->storage() + el * nb_facet_per_element !=
facet_to_element->storage() + el * nb_facet_per_element +
nb_facet_per_element,
"Facet not found");
f_update->element = new_facet;
/// update elements connected to facet
std::vector<Element> first_facet_list = element_to_facet(f);
element_to_facet.push_back(first_facet_list);
/// set new and original facets as boundary facets
element_to_facet(new_facet)[0] = element_to_facet(new_facet)[1];
element_to_facet(f)[1] = ElementNull;
element_to_facet(new_facet)[1] = ElementNull;
}
}
}
AKANTU_DEBUG_OUT();
return nb_facets_to_double;
}
/* -------------------------------------------------------------------------- */
void MeshUtils::resetFacetToDouble(Mesh & mesh_facets) {
AKANTU_DEBUG_IN();
for (UInt g = _not_ghost; g <= _ghost; ++g) {
auto gt = (GhostType)g;
Mesh::type_iterator it = mesh_facets.firstType(_all_dimensions, gt);
Mesh::type_iterator end = mesh_facets.lastType(_all_dimensions, gt);
for (; it != end; ++it) {
ElementType type = *it;
mesh_facets.getDataPointer<UInt>("facet_to_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element>>(
"facets_to_subfacet_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element>>(
"elements_to_subfacet_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element>>(
"subfacets_to_subsubfacet_double", type, gt, 1, false);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool subsubfacet_mode>
void MeshUtils::findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
if (spatial_dimension == 1)
return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it =
mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end =
mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for (; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
UInt nb_facet_to_double = f_to_double.size();
if (nb_facet_to_double == 0)
continue;
ElementType type_subfacet = Mesh::getFacetType(type_facet);
GhostType gt_subfacet = _casper;
ElementType type_subsubfacet = Mesh::getFacetType(type_subfacet);
GhostType gt_subsubfacet = _casper;
Array<UInt> * conn_subfacet = nullptr;
Array<UInt> * sf_to_double = nullptr;
Array<std::vector<Element>> * sf_to_subfacet_double = nullptr;
Array<std::vector<Element>> * f_to_subfacet_double = nullptr;
Array<std::vector<Element>> * el_to_subfacet_double = nullptr;
UInt nb_subfacet = Mesh::getNbFacetsPerElement(type_facet);
UInt nb_subsubfacet;
UInt nb_nodes_per_sf_el;
if (subsubfacet_mode) {
nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subsubfacet);
nb_subsubfacet = Mesh::getNbFacetsPerElement(type_subfacet);
} else
nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subfacet);
Array<Element> & subfacet_to_facet =
mesh_facets.getSubelementToElement(type_facet, gt_facet);
Array<std::vector<Element>> & element_to_facet =
mesh_facets.getElementToSubelement(type_facet, gt_facet);
Array<Element> * subsubfacet_to_subfacet = nullptr;
UInt old_nb_facet = subfacet_to_facet.size() - nb_facet_to_double;
Element current_facet{type_facet, 0, gt_facet};
std::vector<Element> element_list;
std::vector<Element> facet_list;
std::vector<Element> * subfacet_list;
if (subsubfacet_mode)
subfacet_list = new std::vector<Element>;
/// map to filter subfacets
Array<std::vector<Element>> * facet_to_subfacet = nullptr;
/// this is used to make sure that both new and old facets are
/// checked
UInt facets[2];
/// loop on every facet
for (UInt f_index = 0; f_index < 2; ++f_index) {
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
facets[bool(f_index)] = f_to_double(facet);
facets[!bool(f_index)] = old_nb_facet + facet;
UInt old_facet = facets[0];
UInt new_facet = facets[1];
Element & starting_element = element_to_facet(new_facet)[0];
current_facet.element = old_facet;
/// loop on every subfacet
for (UInt sf = 0; sf < nb_subfacet; ++sf) {
Element & subfacet = subfacet_to_facet(old_facet, sf);
if (subfacet == ElementNull)
continue;
if (gt_subfacet != subfacet.ghost_type) {
gt_subfacet = subfacet.ghost_type;
if (subsubfacet_mode) {
subsubfacet_to_subfacet = &mesh_facets.getSubelementToElement(
type_subfacet, gt_subfacet);
} else {
conn_subfacet =
&mesh_facets.getConnectivity(type_subfacet, gt_subfacet);
sf_to_double = &mesh_facets.getData<UInt>(
"facet_to_double", type_subfacet, gt_subfacet);
f_to_subfacet_double =
&mesh_facets.getData<std::vector<Element>>(
"facets_to_subfacet_double", type_subfacet,
gt_subfacet);
el_to_subfacet_double =
&mesh_facets.getData<std::vector<Element>>(
"elements_to_subfacet_double", type_subfacet,
gt_subfacet);
facet_to_subfacet = &mesh_facets.getElementToSubelement(
type_subfacet, gt_subfacet);
}
}
if (subsubfacet_mode) {
/// loop on every subsubfacet
for (UInt ssf = 0; ssf < nb_subsubfacet; ++ssf) {
Element & subsubfacet =
(*subsubfacet_to_subfacet)(subfacet.element, ssf);
if (subsubfacet == ElementNull)
continue;
if (gt_subsubfacet != subsubfacet.ghost_type) {
gt_subsubfacet = subsubfacet.ghost_type;
conn_subfacet = &mesh_facets.getConnectivity(type_subsubfacet,
gt_subsubfacet);
sf_to_double = &mesh_facets.getData<UInt>(
"facet_to_double", type_subsubfacet, gt_subsubfacet);
sf_to_subfacet_double =
&mesh_facets.getData<std::vector<Element>>(
"subfacets_to_subsubfacet_double", type_subsubfacet,
gt_subsubfacet);
f_to_subfacet_double =
&mesh_facets.getData<std::vector<Element>>(
"facets_to_subfacet_double", type_subsubfacet,
gt_subsubfacet);
el_to_subfacet_double =
&mesh_facets.getData<std::vector<Element>>(
"elements_to_subfacet_double", type_subsubfacet,
gt_subsubfacet);
facet_to_subfacet = &mesh_facets.getElementToSubelement(
type_subsubfacet, gt_subsubfacet);
}
UInt global_ssf = subsubfacet.element;
Vector<UInt> subsubfacet_connectivity(
conn_subfacet->storage() + global_ssf * nb_nodes_per_sf_el,
nb_nodes_per_sf_el);
/// check if subsubfacet is to be doubled
if (findElementsAroundSubfacet<true>(
mesh, mesh_facets, starting_element, current_facet,
subsubfacet_connectivity, element_list, facet_list,
subfacet_list) == false &&
removeElementsInVector(*subfacet_list,
(*facet_to_subfacet)(global_ssf)) ==
false) {
sf_to_double->push_back(global_ssf);
sf_to_subfacet_double->push_back(*subfacet_list);
f_to_subfacet_double->push_back(facet_list);
el_to_subfacet_double->push_back(element_list);
}
}
} else {
const UInt global_sf = subfacet.element;
Vector<UInt> subfacet_connectivity(
conn_subfacet->storage() + global_sf * nb_nodes_per_sf_el,
nb_nodes_per_sf_el);
/// check if subfacet is to be doubled
if (findElementsAroundSubfacet<false>(
mesh, mesh_facets, starting_element, current_facet,
subfacet_connectivity, element_list,
facet_list) == false &&
removeElementsInVector(
facet_list, (*facet_to_subfacet)(global_sf)) == false) {
sf_to_double->push_back(global_sf);
f_to_subfacet_double->push_back(facet_list);
el_to_subfacet_double->push_back(element_list);
}
}
}
}
}
if (subsubfacet_mode)
delete subfacet_list;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
void MeshUtils::updateCohesiveData(Mesh & mesh, Mesh & mesh_facets,
Array<Element> & new_elements) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
bool third_dimension = spatial_dimension == 3;
MeshAccessor mesh_facets_accessor(mesh_facets);
for (auto gt_facet : ghost_types) {
for (auto type_facet :
mesh_facets.elementTypes(spatial_dimension - 1, gt_facet)) {
Array<UInt> & f_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
UInt nb_facet_to_double = f_to_double.size();
if (nb_facet_to_double == 0)
continue;
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
auto & facet_to_coh_element =
mesh_facets_accessor.getSubelementToElement(type_cohesive, gt_facet);
auto & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
auto & conn_cohesive = mesh.getConnectivity(type_cohesive, gt_facet);
UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(type_facet);
Array<std::vector<Element>> & element_to_facet =
mesh_facets.getElementToSubelement(type_facet, gt_facet);
UInt old_nb_cohesive_elements = conn_cohesive.size();
UInt new_nb_cohesive_elements = conn_cohesive.size() + nb_facet_to_double;
UInt old_nb_facet = element_to_facet.size() - nb_facet_to_double;
facet_to_coh_element.resize(new_nb_cohesive_elements);
conn_cohesive.resize(new_nb_cohesive_elements);
UInt new_elements_old_size = new_elements.size();
new_elements.resize(new_elements_old_size + nb_facet_to_double);
Element c_element{type_cohesive, 0, gt_facet};
Element f_element{type_facet, 0, gt_facet};
UInt facets[2];
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
/// (in 3D cohesive elements connectivity is inverted)
facets[third_dimension] = f_to_double(facet);
facets[!third_dimension] = old_nb_facet + facet;
UInt cohesive_element = old_nb_cohesive_elements + facet;
/// store doubled facets
f_element.element = facets[0];
facet_to_coh_element(cohesive_element, 0) = f_element;
f_element.element = facets[1];
facet_to_coh_element(cohesive_element, 1) = f_element;
/// modify cohesive elements' connectivity
for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
conn_cohesive(cohesive_element, n) = conn_facet(facets[0], n);
conn_cohesive(cohesive_element, n + nb_nodes_per_facet) =
conn_facet(facets[1], n);
}
/// update element_to_facet vectors
c_element.element = cohesive_element;
element_to_facet(facets[0])[1] = c_element;
element_to_facet(facets[1])[1] = c_element;
/// add cohesive element to the element event list
new_elements(new_elements_old_size + facet) = c_element;
}
}
}
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
void MeshUtils::doublePointFacet(Mesh & mesh, Mesh & mesh_facets,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
if (spatial_dimension != 1)
return;
Array<Real> & position = mesh.getNodes();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it =
mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end =
mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for (; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & conn_facet =
mesh_facets.getConnectivity(type_facet, gt_facet);
Array<std::vector<Element>> & element_to_facet =
mesh_facets.getElementToSubelement(type_facet, gt_facet);
const Array<UInt> & f_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
UInt nb_facet_to_double = f_to_double.size();
UInt old_nb_facet = element_to_facet.size() - nb_facet_to_double;
UInt new_nb_facet = element_to_facet.size();
UInt old_nb_nodes = position.size();
UInt new_nb_nodes = old_nb_nodes + nb_facet_to_double;
position.resize(new_nb_nodes);
conn_facet.resize(new_nb_facet);
UInt old_nb_doubled_nodes = doubled_nodes.size();
doubled_nodes.resize(old_nb_doubled_nodes + nb_facet_to_double);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
UInt new_facet = old_nb_facet + facet;
ElementType type = element_to_facet(new_facet)[0].type;
UInt el = element_to_facet(new_facet)[0].element;
GhostType gt = element_to_facet(new_facet)[0].ghost_type;
UInt old_node = conn_facet(old_facet);
UInt new_node = old_nb_nodes + facet;
/// update position
position(new_node) = position(old_node);
conn_facet(new_facet) = new_node;
Array<UInt> & conn_segment = mesh.getConnectivity(type, gt);
UInt nb_nodes_per_segment = conn_segment.getNbComponent();
/// update facet connectivity
UInt i;
for (i = 0;
conn_segment(el, i) != old_node && i <= nb_nodes_per_segment; ++i)
;
conn_segment(el, i) = new_node;
doubled_nodes(old_nb_doubled_nodes + facet, 0) = old_node;
doubled_nodes(old_nb_doubled_nodes + facet, 1) = new_node;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool third_dim_segments>
void MeshUtils::updateQuadraticSegments(Mesh & mesh, Mesh & mesh_facets,
ElementType type_facet,
GhostType gt_facet,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
if (type_facet != _segment_3)
return;
Array<UInt> & f_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
UInt nb_facet_to_double = f_to_double.size();
UInt old_nb_facet =
mesh_facets.getNbElement(type_facet, gt_facet) - nb_facet_to_double;
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
Array<std::vector<Element>> & element_to_facet =
mesh_facets.getElementToSubelement(type_facet, gt_facet);
/// this ones matter only for segments in 3D
Array<std::vector<Element>> * el_to_subfacet_double = nullptr;
Array<std::vector<Element>> * f_to_subfacet_double = nullptr;
if (third_dim_segments) {
el_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
"elements_to_subfacet_double", type_facet, gt_facet);
f_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
"facets_to_subfacet_double", type_facet, gt_facet);
}
std::vector<UInt> middle_nodes;
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
UInt node = conn_facet(old_facet, 2);
if (!mesh.isPureGhostNode(node))
middle_nodes.push_back(node);
}
UInt n = doubled_nodes.size();
doubleNodes(mesh, middle_nodes, doubled_nodes);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
UInt old_node = conn_facet(old_facet, 2);
if (mesh.isPureGhostNode(old_node))
continue;
UInt new_node = doubled_nodes(n, 1);
UInt new_facet = old_nb_facet + facet;
conn_facet(new_facet, 2) = new_node;
if (third_dim_segments) {
updateElementalConnectivity(mesh_facets, old_node, new_node,
element_to_facet(new_facet));
updateElementalConnectivity(mesh, old_node, new_node,
(*el_to_subfacet_double)(facet),
&(*f_to_subfacet_double)(facet));
} else {
updateElementalConnectivity(mesh, old_node, new_node,
element_to_facet(new_facet));
}
++n;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::updateSubfacetToFacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet, bool facet_mode) {
AKANTU_DEBUG_IN();
Array<UInt> & sf_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_subfacet, gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.size();
/// update subfacet_to_facet vector
ElementType type_facet = _not_defined;
GhostType gt_facet = _casper;
Array<Element> * subfacet_to_facet = nullptr;
UInt nb_subfacet_per_facet = 0;
UInt old_nb_subfacet = mesh_facets.getNbElement(type_subfacet, gt_subfacet) -
nb_subfacet_to_double;
Array<std::vector<Element>> * facet_list = nullptr;
if (facet_mode)
facet_list = &mesh_facets.getData<std::vector<Element>>(
"facets_to_subfacet_double", type_subfacet, gt_subfacet);
else
facet_list = &mesh_facets.getData<std::vector<Element>>(
"subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
Element old_subfacet_el{type_subfacet, 0, gt_subfacet};
Element new_subfacet_el{type_subfacet, 0, gt_subfacet};
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
old_subfacet_el.element = sf_to_double(sf);
new_subfacet_el.element = old_nb_subfacet + sf;
for (UInt f = 0; f < (*facet_list)(sf).size(); ++f) {
Element & facet = (*facet_list)(sf)[f];
if (facet.type != type_facet || facet.ghost_type != gt_facet) {
type_facet = facet.type;
gt_facet = facet.ghost_type;
subfacet_to_facet =
&mesh_facets.getSubelementToElement(type_facet, gt_facet);
nb_subfacet_per_facet = subfacet_to_facet->getNbComponent();
}
Element * sf_update = std::find(
subfacet_to_facet->storage() + facet.element * nb_subfacet_per_facet,
subfacet_to_facet->storage() + facet.element * nb_subfacet_per_facet +
nb_subfacet_per_facet,
old_subfacet_el);
AKANTU_DEBUG_ASSERT(subfacet_to_facet->storage() +
facet.element * nb_subfacet_per_facet !=
subfacet_to_facet->storage() +
facet.element * nb_subfacet_per_facet +
nb_subfacet_per_facet,
"Subfacet not found");
*sf_update = new_subfacet_el;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::updateFacetToSubfacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet, bool facet_mode) {
AKANTU_DEBUG_IN();
Array<UInt> & sf_to_double =
mesh_facets.getData<UInt>("facet_to_double", type_subfacet, gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.size();
Array<std::vector<Element>> & facet_to_subfacet =
mesh_facets.getElementToSubelement(type_subfacet, gt_subfacet);
Array<std::vector<Element>> * facet_to_subfacet_double = nullptr;
if (facet_mode) {
facet_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
"facets_to_subfacet_double", type_subfacet, gt_subfacet);
} else {
facet_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
"subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
}
UInt old_nb_subfacet = facet_to_subfacet.size();
facet_to_subfacet.resize(old_nb_subfacet + nb_subfacet_to_double);
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf)
facet_to_subfacet(old_nb_subfacet + sf) = (*facet_to_subfacet_double)(sf);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MeshUtils::doubleSubfacet(Mesh & mesh, Mesh & mesh_facets,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
if (spatial_dimension == 1)
return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_subfacet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(0, gt_subfacet);
Mesh::type_iterator end = mesh_facets.lastType(0, gt_subfacet);
for (; it != end; ++it) {
ElementType type_subfacet = *it;
Array<UInt> & sf_to_double = mesh_facets.getData<UInt>(
"facet_to_double", type_subfacet, gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.size();
if (nb_subfacet_to_double == 0)
continue;
AKANTU_DEBUG_ASSERT(
type_subfacet == _point_1,
"Only _point_1 subfacet doubling is supported at the moment");
Array<UInt> & conn_subfacet =
mesh_facets.getConnectivity(type_subfacet, gt_subfacet);
UInt old_nb_subfacet = conn_subfacet.size();
UInt new_nb_subfacet = old_nb_subfacet + nb_subfacet_to_double;
conn_subfacet.resize(new_nb_subfacet);
std::vector<UInt> nodes_to_double;
UInt old_nb_doubled_nodes = doubled_nodes.size();
/// double nodes
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt old_subfacet = sf_to_double(sf);
nodes_to_double.push_back(conn_subfacet(old_subfacet));
}
doubleNodes(mesh, nodes_to_double, doubled_nodes);
/// add new nodes in connectivity
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt new_subfacet = old_nb_subfacet + sf;
UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
conn_subfacet(new_subfacet) = new_node;
}
/// update facet and element connectivity
Array<std::vector<Element>> & f_to_subfacet_double =
mesh_facets.getData<std::vector<Element>>("facets_to_subfacet_double",
type_subfacet, gt_subfacet);
Array<std::vector<Element>> & el_to_subfacet_double =
mesh_facets.getData<std::vector<Element>>(
"elements_to_subfacet_double", type_subfacet, gt_subfacet);
Array<std::vector<Element>> * sf_to_subfacet_double = nullptr;
if (spatial_dimension == 3)
sf_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
"subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt old_node = doubled_nodes(old_nb_doubled_nodes + sf, 0);
UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
updateElementalConnectivity(mesh, old_node, new_node,
el_to_subfacet_double(sf),
&f_to_subfacet_double(sf));
updateElementalConnectivity(mesh_facets, old_node, new_node,
f_to_subfacet_double(sf));
if (spatial_dimension == 3)
updateElementalConnectivity(mesh_facets, old_node, new_node,
(*sf_to_subfacet_double)(sf));
}
if (spatial_dimension == 2) {
updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, true);
updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, true);
} else if (spatial_dimension == 3) {
updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, false);
updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, false);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::flipFacets(
Mesh & mesh_facets, const ElementTypeMapArray<UInt> & global_connectivity,
GhostType gt_facet) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
/// get global connectivity for local mesh
ElementTypeMapArray<UInt> global_connectivity_tmp("global_connectivity_tmp",
mesh_facets.getID(),
mesh_facets.getMemoryID());
global_connectivity_tmp.initialize(
mesh_facets, _spatial_dimension = spatial_dimension - 1,
_ghost_type = gt_facet, _with_nb_nodes_per_element = true,
_with_nb_element = true);
mesh_facets.getGlobalConnectivity(global_connectivity_tmp);
/// loop on every facet
for (auto type_facet :
mesh_facets.elementTypes(spatial_dimension - 1, gt_facet)) {
auto & connectivity = mesh_facets.getConnectivity(type_facet, gt_facet);
const auto & g_connectivity = global_connectivity(type_facet, gt_facet);
auto & el_to_f = mesh_facets.getElementToSubelement(type_facet, gt_facet);
auto & subfacet_to_facet =
mesh_facets.getSubelementToElement(type_facet, gt_facet);
UInt nb_subfacet_per_facet = subfacet_to_facet.getNbComponent();
UInt nb_nodes_per_facet = connectivity.getNbComponent();
UInt nb_facet = connectivity.size();
UInt nb_nodes_per_P1_facet =
Mesh::getNbNodesPerElement(Mesh::getP1ElementType(type_facet));
auto & global_conn_tmp = global_connectivity_tmp(type_facet, gt_facet);
auto conn_it = connectivity.begin(nb_nodes_per_facet);
auto gconn_tmp_it = global_conn_tmp.begin(nb_nodes_per_facet);
auto conn_glob_it = g_connectivity.begin(nb_nodes_per_facet);
auto subf_to_f = subfacet_to_facet.begin(nb_subfacet_per_facet);
auto * conn_tmp_pointer = new UInt[nb_nodes_per_facet];
Vector<UInt> conn_tmp(conn_tmp_pointer, nb_nodes_per_facet);
Element el_tmp;
auto * subf_tmp_pointer = new Element[nb_subfacet_per_facet];
Vector<Element> subf_tmp(subf_tmp_pointer, nb_subfacet_per_facet);
for (UInt f = 0; f < nb_facet;
++f, ++conn_it, ++gconn_tmp_it, ++subf_to_f, ++conn_glob_it) {
Vector<UInt> & gconn_tmp = *gconn_tmp_it;
const Vector<UInt> & conn_glob = *conn_glob_it;
Vector<UInt> & conn_local = *conn_it;
/// skip facet if connectivities are the same
if (gconn_tmp == conn_glob)
continue;
/// re-arrange connectivity
conn_tmp = conn_local;
UInt * begin = conn_glob.storage();
UInt * end = conn_glob.storage() + nb_nodes_per_facet;
for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
UInt * new_node = std::find(begin, end, gconn_tmp(n));
AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
UInt new_position = new_node - begin;
conn_local(new_position) = conn_tmp(n);
}
/// if 3D, check if facets are just rotated
if (spatial_dimension == 3) {
/// find first node
UInt * new_node = std::find(begin, end, gconn_tmp(0));
AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
UInt new_position = new_node - begin;
UInt n = 1;
/// count how many nodes in the received connectivity follow
/// the same order of those in the local connectivity
for (; n < nb_nodes_per_P1_facet &&
gconn_tmp(n) ==
conn_glob((new_position + n) % nb_nodes_per_P1_facet);
++n)
;
/// skip the facet inversion if facet is just rotated
if (n == nb_nodes_per_P1_facet)
continue;
}
/// update data to invert facet
el_tmp = el_to_f(f)[0];
el_to_f(f)[0] = el_to_f(f)[1];
el_to_f(f)[1] = el_tmp;
subf_tmp = (*subf_to_f);
(*subf_to_f)(0) = subf_tmp(1);
(*subf_to_f)(1) = subf_tmp(0);
}
delete[] subf_tmp_pointer;
delete[] conn_tmp_pointer;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::fillElementToSubElementsData(Mesh & mesh) {
AKANTU_DEBUG_IN();
if (mesh.getNbElement(mesh.getSpatialDimension() - 1) == 0) {
AKANTU_DEBUG_INFO("There are not facets, add them in the mesh file or call "
"the buildFacet method.");
return;
}
UInt spatial_dimension = mesh.getSpatialDimension();
ElementTypeMapArray<Real> barycenters("barycenter_tmp", mesh.getID(),
mesh.getMemoryID());
barycenters.initialize(mesh, _nb_component = spatial_dimension,
_spatial_dimension = _all_dimensions);
// mesh.initElementTypeMapArray(barycenters, spatial_dimension,
// _all_dimensions);
Element element;
for (auto ghost_type : ghost_types) {
element.ghost_type = ghost_type;
for (auto & type : mesh.elementTypes(_all_dimensions, ghost_type)) {
element.type = type;
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<Real> & barycenters_arr = barycenters(type, ghost_type);
barycenters_arr.resize(nb_element);
auto bary = barycenters_arr.begin(spatial_dimension);
auto bary_end = barycenters_arr.end(spatial_dimension);
for (UInt el = 0; bary != bary_end; ++bary, ++el) {
element.element = el;
mesh.getBarycenter(element, *bary);
}
}
}
MeshAccessor mesh_accessor(mesh);
for (Int sp(spatial_dimension); sp >= 1; --sp) {
if (mesh.getNbElement(sp) == 0)
continue;
for (auto ghost_type : ghost_types) {
for (auto & type : mesh.elementTypes(sp, ghost_type)) {
mesh_accessor.getSubelementToElement(type, ghost_type)
.resize(mesh.getNbElement(type, ghost_type));
mesh_accessor.getSubelementToElement(type, ghost_type).clear();
}
for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
mesh_accessor.getElementToSubelement(type, ghost_type)
.resize(mesh.getNbElement(type, ghost_type));
mesh.getElementToSubelement(type, ghost_type).clear();
}
}
CSR<Element> nodes_to_elements;
buildNode2Elements(mesh, nodes_to_elements, sp);
Element facet_element;
for (auto ghost_type : ghost_types) {
facet_element.ghost_type = ghost_type;
for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
facet_element.type = type;
auto & element_to_subelement =
mesh.getElementToSubelement(type, ghost_type);
const auto & connectivity = mesh.getConnectivity(type, ghost_type);
auto fit = connectivity.begin(mesh.getNbNodesPerElement(type));
auto fend = connectivity.end(mesh.getNbNodesPerElement(type));
UInt fid = 0;
for (; fit != fend; ++fit, ++fid) {
const Vector<UInt> & facet = *fit;
facet_element.element = fid;
std::map<Element, UInt> element_seen_counter;
UInt nb_nodes_per_facet =
mesh.getNbNodesPerElement(Mesh::getP1ElementType(type));
for (UInt n(0); n < nb_nodes_per_facet; ++n) {
auto eit = nodes_to_elements.begin(facet(n));
auto eend = nodes_to_elements.end(facet(n));
for (; eit != eend; ++eit) {
auto & elem = *eit;
auto cit = element_seen_counter.find(elem);
if (cit != element_seen_counter.end()) {
cit->second++;
} else {
element_seen_counter[elem] = 1;
}
}
}
std::vector<Element> connected_elements;
auto cit = element_seen_counter.begin();
auto cend = element_seen_counter.end();
for (; cit != cend; ++cit) {
if (cit->second == nb_nodes_per_facet)
connected_elements.push_back(cit->first);
}
auto ceit = connected_elements.begin();
auto ceend = connected_elements.end();
for (; ceit != ceend; ++ceit)
element_to_subelement(fid).push_back(*ceit);
for (UInt ce = 0; ce < connected_elements.size(); ++ce) {
Element & elem = connected_elements[ce];
Array<Element> & subelement_to_element =
mesh_accessor.getSubelementToElement(elem.type,
elem.ghost_type);
UInt f(0);
for (; f < mesh.getNbFacetsPerElement(elem.type) &&
subelement_to_element(elem.element, f) != ElementNull;
++f)
;
AKANTU_DEBUG_ASSERT(
f < mesh.getNbFacetsPerElement(elem.type),
"The element " << elem << " seems to have too many facets!! ("
<< f << " < "
<< mesh.getNbFacetsPerElement(elem.type) << ")");
subelement_to_element(elem.element, f) = facet_element;
}
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool third_dim_points>
bool MeshUtils::findElementsAroundSubfacet(
const Mesh & mesh, const Mesh & mesh_facets,
const Element & starting_element, const Element & end_facet,
const Vector<UInt> & subfacet_connectivity,
std::vector<Element> & elem_list, std::vector<Element> & facet_list,
std::vector<Element> * subfacet_list) {
AKANTU_DEBUG_IN();
/// preallocated stuff before starting
bool facet_matched = false;
elem_list.clear();
facet_list.clear();
if (third_dim_points)
subfacet_list->clear();
elem_list.push_back(starting_element);
const Array<UInt> * facet_connectivity = nullptr;
const Array<UInt> * sf_connectivity = nullptr;
const Array<Element> * facet_to_element = nullptr;
const Array<Element> * subfacet_to_facet = nullptr;
ElementType current_type = _not_defined;
GhostType current_ghost_type = _casper;
ElementType current_facet_type = _not_defined;
GhostType current_facet_ghost_type = _casper;
ElementType current_subfacet_type = _not_defined;
GhostType current_subfacet_ghost_type = _casper;
const Array<std::vector<Element>> * element_to_facet = nullptr;
const Element * opposing_el = nullptr;
std::queue<Element> elements_to_check;
elements_to_check.push(starting_element);
/// keep going until there are elements to check
while (!elements_to_check.empty()) {
/// check current element
Element & current_el = elements_to_check.front();
if (current_el.type != current_type ||
current_el.ghost_type != current_ghost_type) {
current_type = current_el.type;
current_ghost_type = current_el.ghost_type;
facet_to_element =
&mesh_facets.getSubelementToElement(current_type, current_ghost_type);
}
/// loop over each facet of the element
for (UInt f = 0; f < facet_to_element->getNbComponent(); ++f) {
const Element & current_facet =
(*facet_to_element)(current_el.element, f);
if (current_facet == ElementNull)
continue;
if (current_facet_type != current_facet.type ||
current_facet_ghost_type != current_facet.ghost_type) {
current_facet_type = current_facet.type;
current_facet_ghost_type = current_facet.ghost_type;
element_to_facet = &mesh_facets.getElementToSubelement(
current_facet_type, current_facet_ghost_type);
facet_connectivity = &mesh_facets.getConnectivity(
current_facet_type, current_facet_ghost_type);
if (third_dim_points)
subfacet_to_facet = &mesh_facets.getSubelementToElement(
current_facet_type, current_facet_ghost_type);
}
/// check if end facet is reached
if (current_facet == end_facet)
facet_matched = true;
/// add this facet if not already passed
if (std::find(facet_list.begin(), facet_list.end(), current_facet) ==
facet_list.end() &&
hasElement(*facet_connectivity, current_facet,
subfacet_connectivity)) {
facet_list.push_back(current_facet);
if (third_dim_points) {
/// check subfacets
for (UInt sf = 0; sf < subfacet_to_facet->getNbComponent(); ++sf) {
const Element & current_subfacet =
(*subfacet_to_facet)(current_facet.element, sf);
if (current_subfacet == ElementNull)
continue;
if (current_subfacet_type != current_subfacet.type ||
current_subfacet_ghost_type != current_subfacet.ghost_type) {
current_subfacet_type = current_subfacet.type;
current_subfacet_ghost_type = current_subfacet.ghost_type;
sf_connectivity = &mesh_facets.getConnectivity(
current_subfacet_type, current_subfacet_ghost_type);
}
if (std::find(subfacet_list->begin(), subfacet_list->end(),
current_subfacet) == subfacet_list->end() &&
hasElement(*sf_connectivity, current_subfacet,
subfacet_connectivity))
subfacet_list->push_back(current_subfacet);
}
}
} else
continue;
/// consider opposing element
if ((*element_to_facet)(current_facet.element)[0] == current_el)
opposing_el = &(*element_to_facet)(current_facet.element)[1];
else
opposing_el = &(*element_to_facet)(current_facet.element)[0];
/// skip null elements since they are on a boundary
if (*opposing_el == ElementNull)
continue;
/// skip this element if already added
if (std::find(elem_list.begin(), elem_list.end(), *opposing_el) !=
elem_list.end())
continue;
/// only regular elements have to be checked
if (opposing_el->kind() == _ek_regular)
elements_to_check.push(*opposing_el);
elem_list.push_back(*opposing_el);
#ifndef AKANTU_NDEBUG
const Array<UInt> & conn_elem =
mesh.getConnectivity(opposing_el->type, opposing_el->ghost_type);
AKANTU_DEBUG_ASSERT(
hasElement(conn_elem, *opposing_el, subfacet_connectivity),
"Subfacet doesn't belong to this element");
#endif
}
/// erased checked element from the list
elements_to_check.pop();
}
AKANTU_DEBUG_OUT();
return facet_matched;
}
/* -------------------------------------------------------------------------- */
UInt MeshUtils::updateLocalMasterGlobalConnectivity(Mesh & mesh,
UInt local_nb_new_nodes) {
const auto & comm = mesh.getCommunicator();
Int rank = comm.whoAmI();
Int nb_proc = comm.getNbProc();
if (nb_proc == 1)
return local_nb_new_nodes;
/// resize global ids array
Array<UInt> & nodes_global_ids = mesh.getGlobalNodesIds();
UInt old_nb_nodes = mesh.getNbNodes() - local_nb_new_nodes;
nodes_global_ids.resize(mesh.getNbNodes());
/// compute the number of global nodes based on the number of old nodes
Vector<UInt> old_local_master_nodes(nb_proc);
for (UInt n = 0; n < old_nb_nodes; ++n)
if (mesh.isLocalOrMasterNode(n))
++old_local_master_nodes(rank);
comm.allGather(old_local_master_nodes);
UInt old_global_nodes =
std::accumulate(old_local_master_nodes.storage(),
old_local_master_nodes.storage() + nb_proc, 0);
/// compute amount of local or master doubled nodes
Vector<UInt> local_master_nodes(nb_proc);
for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n)
if (mesh.isLocalOrMasterNode(n))
++local_master_nodes(rank);
comm.allGather(local_master_nodes);
/// update global number of nodes
UInt total_nb_new_nodes = std::accumulate(
local_master_nodes.storage(), local_master_nodes.storage() + nb_proc, 0);
if (total_nb_new_nodes == 0)
return 0;
/// set global ids of local and master nodes
UInt starting_index =
std::accumulate(local_master_nodes.storage(),
local_master_nodes.storage() + rank, old_global_nodes);
for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n) {
if (mesh.isLocalOrMasterNode(n)) {
nodes_global_ids(n) = starting_index;
++starting_index;
}
}
MeshAccessor mesh_accessor(mesh);
mesh_accessor.setNbGlobalNodes(old_global_nodes + total_nb_new_nodes);
return total_nb_new_nodes;
}
/* -------------------------------------------------------------------------- */
void MeshUtils::updateElementalConnectivity(
Mesh & mesh, UInt old_node, UInt new_node,
const std::vector<Element> & element_list,
__attribute__((unused)) const std::vector<Element> * facet_list) {
AKANTU_DEBUG_IN();
ElementType el_type = _not_defined;
GhostType gt_type = _casper;
Array<UInt> * conn_elem = nullptr;
#if defined(AKANTU_COHESIVE_ELEMENT)
const Array<Element> * cohesive_facets = nullptr;
#endif
UInt nb_nodes_per_element = 0;
UInt * n_update = nullptr;
for (UInt el = 0; el < element_list.size(); ++el) {
const Element & elem = element_list[el];
if (elem.type == _not_defined)
continue;
if (elem.type != el_type || elem.ghost_type != gt_type) {
el_type = elem.type;
gt_type = elem.ghost_type;
conn_elem = &mesh.getConnectivity(el_type, gt_type);
nb_nodes_per_element = conn_elem->getNbComponent();
#if defined(AKANTU_COHESIVE_ELEMENT)
if (elem.kind() == _ek_cohesive)
cohesive_facets =
&mesh.getMeshFacets().getSubelementToElement(el_type, gt_type);
#endif
}
#if defined(AKANTU_COHESIVE_ELEMENT)
if (elem.kind() == _ek_cohesive) {
AKANTU_DEBUG_ASSERT(
facet_list != nullptr,
"Provide a facet list in order to update cohesive elements");
/// loop over cohesive element's facets
for (UInt f = 0, n = 0; f < 2; ++f, n += nb_nodes_per_element / 2) {
const Element & facet = (*cohesive_facets)(elem.element, f);
/// skip facets if not present in the list
if (std::find(facet_list->begin(), facet_list->end(), facet) ==
facet_list->end())
continue;
n_update = std::find(
conn_elem->storage() + elem.element * nb_nodes_per_element + n,
conn_elem->storage() + elem.element * nb_nodes_per_element + n +
nb_nodes_per_element / 2,
old_node);
AKANTU_DEBUG_ASSERT(n_update !=
conn_elem->storage() +
elem.element * nb_nodes_per_element + n +
nb_nodes_per_element / 2,
"Node not found in current element");
/// update connectivity
*n_update = new_node;
}
} else {
#endif
n_update =
std::find(conn_elem->storage() + elem.element * nb_nodes_per_element,
conn_elem->storage() + elem.element * nb_nodes_per_element +
nb_nodes_per_element,
old_node);
AKANTU_DEBUG_ASSERT(n_update !=
conn_elem->storage() +
elem.element * nb_nodes_per_element +
nb_nodes_per_element,
"Node not found in current element");
/// update connectivity
*n_update = new_node;
#if defined(AKANTU_COHESIVE_ELEMENT)
}
#endif
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/src/mesh_utils/mesh_utils.hh b/src/mesh_utils/mesh_utils.hh
index 60527380a..f7af08129 100644
--- a/src/mesh_utils/mesh_utils.hh
+++ b/src/mesh_utils/mesh_utils.hh
@@ -1,244 +1,244 @@
/**
* @file mesh_utils.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Oct 02 2015
*
* @brief All mesh utils necessary for various tasks
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "mesh.hh"
#include "aka_csr.hh"
+#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_UTILS_HH__
#define __AKANTU_MESH_UTILS_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class MeshUtils {
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// build a CSR<UInt> that contains for each node the linearized number of
/// the connected elements of a given spatial dimension
// static void buildNode2Elements(const Mesh & mesh, CSR<UInt> & node_to_elem,
// UInt spatial_dimension = _all_dimensions);
/// build a CSR<Element> that contains for each node the list of connected
/// elements of a given spatial dimension
static void buildNode2Elements(const Mesh & mesh, CSR<Element> & node_to_elem,
UInt spatial_dimension = _all_dimensions);
/// build a CSR<UInt> that contains for each node the number of
/// the connected elements of a given ElementType
static void
buildNode2ElementsElementTypeMap(const Mesh & mesh, CSR<UInt> & node_to_elem,
const ElementType & type,
const GhostType & ghost_type = _not_ghost);
/// build the facets elements on the boundaries of a mesh
static void buildFacets(Mesh & mesh);
/// build all the facets elements: boundary and internals and store them in
/// the mesh_facets for element of dimension from_dimension to to_dimension
static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
UInt from_dimension, UInt to_dimension);
/// build all the facets elements: boundary and internals and store them in
/// the mesh_facets
static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
UInt to_dimension = 0);
/// build facets for a given spatial dimension
- static void buildFacetsDimension(
- const Mesh & mesh, Mesh & mesh_facets, bool boundary_only, UInt dimension);
+ static void buildFacetsDimension(const Mesh & mesh, Mesh & mesh_facets,
+ bool boundary_only, UInt dimension);
/// take the local_connectivity array as the array of local and ghost
/// connectivity, renumber the nodes and set the connectivity of the mesh
static void renumberMeshNodes(Mesh & mesh, Array<UInt> & local_connectivities,
UInt nb_local_element, UInt nb_ghost_element,
ElementType type, Array<UInt> & old_nodes);
/// compute pbc pair for a given direction
static void computePBCMap(const Mesh & mymesh, const UInt dir,
std::map<UInt, UInt> & pbc_pair);
/// compute pbc pair for a surface pair
static void computePBCMap(const Mesh & mymesh,
const std::pair<ID, ID> & surface_pair,
std::map<UInt, UInt> & pbc_pair);
/// remove not connected nodes /!\ this functions renumbers the nodes.
static void purifyMesh(Mesh & mesh);
#if defined(AKANTU_COHESIVE_ELEMENT)
/// function to insert cohesive elements on the selected facets
/// @return number of facets that have been doubled
static UInt
insertCohesiveElements(Mesh & mesh, Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion,
Array<UInt> & doubled_nodes,
Array<Element> & new_elements,
bool only_double_facets);
#endif
/// fill the subelement to element and the elements to subelements data
static void fillElementToSubElementsData(Mesh & mesh);
/// flip facets based on global connectivity
static void flipFacets(Mesh & mesh_facets,
const ElementTypeMapArray<UInt> & global_connectivity,
GhostType gt_facet);
/// provide list of elements around a node and check if a given
/// facet is reached
template <bool third_dim_points>
static bool findElementsAroundSubfacet(
const Mesh & mesh, const Mesh & mesh_facets,
const Element & starting_element, const Element & end_facet,
const Vector<UInt> & subfacet_connectivity,
std::vector<Element> & elem_list, std::vector<Element> & facet_list,
std::vector<Element> * subfacet_list = nullptr);
/// function to check if a node belongs to a given element
static inline bool hasElement(const Array<UInt> & connectivity,
const Element & el, const Vector<UInt> & nodes);
/// reset facet_to_double arrays in the Mesh
static void resetFacetToDouble(Mesh & mesh_facets);
/// associate a node type to each segment in the mesh
// static void buildSegmentToNodeType(const Mesh & mesh, Mesh & mesh_facets);
/// update local and master global connectivity when new nodes are added
static UInt updateLocalMasterGlobalConnectivity(Mesh & mesh,
UInt old_nb_nodes);
private:
/// match pairs that are on the associated pbc's
static void matchPBCPairs(const Mesh & mymesh, const UInt dir,
Array<UInt> & selected_left,
Array<UInt> & selected_right,
std::map<UInt, UInt> & pbc_pair);
/// function used by all the renumbering functions
static void
renumberNodesInConnectivity(Array<UInt> & list_nodes, UInt nb_nodes,
std::map<UInt, UInt> & renumbering_map);
/// update facet_to_subfacet
static void updateFacetToSubfacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet, bool facet_mode);
/// update subfacet_to_facet
static void updateSubfacetToFacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet, bool facet_mode);
/// function to double a given facet and update the list of doubled
/// nodes
static void doubleFacet(Mesh & mesh, Mesh & mesh_facets, UInt facet_dimension,
Array<UInt> & doubled_nodes, bool facet_mode);
/// function to double a subfacet given start and end index for
/// local facet_to_subfacet vector, and update the list of doubled
/// nodes
template <UInt spatial_dimension>
static void doubleSubfacet(Mesh & mesh, Mesh & mesh_facets,
Array<UInt> & doubled_nodes);
/// double a node
static void doubleNodes(Mesh & mesh, const std::vector<UInt> & old_nodes,
Array<UInt> & doubled_nodes);
/// fill facet_to_double array in the mesh
/// returns the number of facets to be doubled
static UInt
updateFacetToDouble(Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion);
/// find subfacets to be doubled
template <bool subsubfacet_mode>
static void findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets);
/// double facets (points) in 1D
static void doublePointFacet(Mesh & mesh, Mesh & mesh_facets,
Array<UInt> & doubled_nodes);
#if defined(AKANTU_COHESIVE_ELEMENT)
/// update cohesive element data
static void updateCohesiveData(Mesh & mesh, Mesh & mesh_facets,
Array<Element> & new_elements);
#endif
/// update elemental connectivity after doubling a node
inline static void updateElementalConnectivity(
Mesh & mesh, UInt old_node, UInt new_node,
const std::vector<Element> & element_list,
const std::vector<Element> * facet_list = nullptr);
/// double middle nodes if facets are _segment_3
template <bool third_dim_segments>
static void updateQuadraticSegments(Mesh & mesh, Mesh & mesh_facets,
ElementType type_facet,
GhostType gt_facet,
Array<UInt> & doubled_nodes);
/// remove elements on a vector
inline static bool
removeElementsInVector(const std::vector<Element> & elem_to_remove,
std::vector<Element> & elem_list);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "mesh_utils_inline_impl.cc"
} // akantu
#endif /* __AKANTU_MESH_UTILS_HH__ */
diff --git a/src/mesh_utils/mesh_utils_pbc.cc b/src/mesh_utils/mesh_utils_pbc.cc
index 5e011b23d..ac6a05a95 100644
--- a/src/mesh_utils/mesh_utils_pbc.cc
+++ b/src/mesh_utils/mesh_utils_pbc.cc
@@ -1,298 +1,300 @@
/**
* @file mesh_utils_pbc.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Wed Feb 09 2011
* @date last modification: Tue Sep 15 2015
*
* @brief periodic boundary condition connectivity tweak
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
#include "element_group.hh"
#include "mesh_accessor.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/// class that sorts a set of nodes of same coordinates in 'dir' direction
class CoordinatesComparison {
public:
- CoordinatesComparison(const UInt dimension, const UInt dir_1, const UInt dir_2,
- Real normalization, Real tolerance, const Array<Real> & coords)
- : dim(dimension), dir_1(dir_1), dir_2(dir_2), normalization(normalization),
- tolerance(tolerance), coords_it(coords.begin(dim)) {}
+ CoordinatesComparison(const UInt dimension, const UInt dir_1,
+ const UInt dir_2, Real normalization, Real tolerance,
+ const Array<Real> & coords)
+ : dim(dimension), dir_1(dir_1), dir_2(dir_2),
+ normalization(normalization), tolerance(tolerance),
+ coords_it(coords.begin(dim)) {}
// answers the question whether n2 is larger or equal to n1
bool operator()(const UInt n1, const UInt n2) {
Vector<Real> coords_n1 = coords_it[n1];
Vector<Real> coords_n2 = coords_it[n2];
return this->operator()(coords_n1, coords_n2);
}
- bool operator()(const Vector<Real> & coords_n1, const Vector<Real> & coords_n2) {
- Real diff = coords_n1(dir_1) - coords_n2(dir_1);;
+ bool operator()(const Vector<Real> & coords_n1,
+ const Vector<Real> & coords_n2) {
+ Real diff = coords_n1(dir_1) - coords_n2(dir_1);
+ ;
if (dim == 2 || std::abs(diff) / normalization > tolerance)
return diff > 0. ? false : true;
else if (dim > 2) {
- diff = coords_n1(dir_2) - coords_n2(dir_2);;
+ diff = coords_n1(dir_2) - coords_n2(dir_2);
+ ;
return diff > 0 ? false : true;
}
return true;
}
private:
UInt dim;
UInt dir_1;
UInt dir_2;
Real normalization;
Real tolerance;
const Array<Real>::const_vector_iterator coords_it;
};
/* -------------------------------------------------------------------------- */
void MeshUtils::computePBCMap(const Mesh & mesh, const UInt dir,
std::map<UInt, UInt> & pbc_pair) {
Array<UInt> selected_left;
Array<UInt> selected_right;
const UInt dim = mesh.getSpatialDimension();
auto it = mesh.getNodes().begin(dim);
auto end = mesh.getNodes().end(dim);
if (dim <= dir)
return;
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
AKANTU_DEBUG_INFO("min " << lower_bounds(dir));
AKANTU_DEBUG_INFO("max " << upper_bounds(dir));
for (UInt node = 0; it != end; ++it, ++node) {
const Vector<Real> & coords = *it;
AKANTU_DEBUG_TRACE("treating " << coords(dir));
if (Math::are_float_equal(coords(dir), lower_bounds(dir))) {
AKANTU_DEBUG_TRACE("pushing node " << node << " on the left side");
selected_left.push_back(node);
} else if (Math::are_float_equal(coords(dir), upper_bounds(dir))) {
selected_right.push_back(node);
AKANTU_DEBUG_TRACE("pushing node " << node << " on the right side");
}
}
- AKANTU_DEBUG_INFO(
- "found " << selected_left.size() << " and " << selected_right.size()
- << " nodes at each boundary for direction " << dir);
+ AKANTU_DEBUG_INFO("found "
+ << selected_left.size() << " and " << selected_right.size()
+ << " nodes at each boundary for direction " << dir);
// match pairs
MeshUtils::matchPBCPairs(mesh, dir, selected_left, selected_right, pbc_pair);
}
/* -------------------------------------------------------------------------- */
void MeshUtils::computePBCMap(const Mesh & mesh,
const std::pair<ID, ID> & surface_pair,
std::map<UInt, UInt> & pbc_pair) {
Array<UInt> selected_first;
Array<UInt> selected_second;
// find nodes on surfaces
const ElementGroup & first_surf = mesh.getElementGroup(surface_pair.first);
const ElementGroup & second_surf = mesh.getElementGroup(surface_pair.second);
// if this surface pair is not on this proc
if (first_surf.getNbNodes() == 0 || second_surf.getNbNodes() == 0) {
AKANTU_DEBUG_WARNING("computePBCMap has at least one surface without any "
"nodes. I will ignore it.");
return;
}
// copy nodes from element group
selected_first.copy(first_surf.getNodeGroup().getNodes());
selected_second.copy(second_surf.getNodeGroup().getNodes());
// coordinates
const Array<Real> & coords = mesh.getNodes();
const UInt dim = mesh.getSpatialDimension();
// variables to find min and max of surfaces
Real first_max[3], first_min[3];
Real second_max[3], second_min[3];
for (UInt i = 0; i < dim; ++i) {
first_min[i] = std::numeric_limits<Real>::max();
second_min[i] = std::numeric_limits<Real>::max();
first_max[i] = -std::numeric_limits<Real>::max();
second_max[i] = -std::numeric_limits<Real>::max();
}
// find min and max of surface nodes
- for (auto it = selected_first.begin();
- it != selected_first.end(); ++it) {
+ for (auto it = selected_first.begin(); it != selected_first.end(); ++it) {
for (UInt i = 0; i < dim; ++i) {
if (first_min[i] > coords(*it, i))
first_min[i] = coords(*it, i);
if (first_max[i] < coords(*it, i))
first_max[i] = coords(*it, i);
}
}
- for (auto it = selected_second.begin();
- it != selected_second.end(); ++it) {
+ for (auto it = selected_second.begin(); it != selected_second.end(); ++it) {
for (UInt i = 0; i < dim; ++i) {
if (second_min[i] > coords(*it, i))
second_min[i] = coords(*it, i);
if (second_max[i] < coords(*it, i))
second_max[i] = coords(*it, i);
}
}
// find direction of pbc
Int first_dir = -1;
#ifndef AKANTU_NDEBUG
Int second_dir = -2;
#endif
for (UInt i = 0; i < dim; ++i) {
if (Math::are_float_equal(first_min[i], first_max[i])) {
first_dir = i;
}
#ifndef AKANTU_NDEBUG
if (Math::are_float_equal(second_min[i], second_max[i])) {
second_dir = i;
}
#endif
}
AKANTU_DEBUG_ASSERT(first_dir == second_dir,
"Surface pair has not same direction. Surface "
<< surface_pair.first << " dir=" << first_dir
<< " ; Surface " << surface_pair.second
<< " dir=" << second_dir);
UInt dir = first_dir;
// match pairs
if (first_min[dir] < second_min[dir])
MeshUtils::matchPBCPairs(mesh, dir, selected_first, selected_second,
pbc_pair);
else
MeshUtils::matchPBCPairs(mesh, dir, selected_second, selected_first,
pbc_pair);
}
/* -------------------------------------------------------------------------- */
void MeshUtils::matchPBCPairs(const Mesh & mesh, const UInt dir,
Array<UInt> & selected_left,
Array<UInt> & selected_right,
std::map<UInt, UInt> & pbc_pair) {
// tolerance is that large because most meshers generate points coordinates
// with single precision only (it is the case of GMSH for instance)
Real tolerance = 1e-7;
const UInt dim = mesh.getSpatialDimension();
Real normalization = mesh.getUpperBounds()(dir) - mesh.getLowerBounds()(dir);
AKANTU_DEBUG_ASSERT(std::abs(normalization) > Math::getTolerance(),
"In matchPBCPairs: The normalization is zero. "
<< "Did you compute the bounding box of the mesh?");
auto odir_1 = UInt(-1), odir_2 = UInt(-1);
if (dim == 3) {
if (dir == _x) {
odir_1 = _y;
odir_2 = _z;
} else if (dir == _y) {
odir_1 = _x;
odir_2 = _z;
} else if (dir == _z) {
odir_1 = _x;
odir_2 = _y;
}
} else if (dim == 2) {
if (dir == _x) {
odir_1 = _y;
} else if (dir == _y) {
odir_1 = _x;
}
}
CoordinatesComparison compare_nodes(dim, odir_1, odir_2, normalization,
tolerance, mesh.getNodes());
std::sort(selected_left.begin(), selected_left.end(), compare_nodes);
std::sort(selected_right.begin(), selected_right.end(), compare_nodes);
auto it_left = selected_left.begin();
auto end_left = selected_left.end();
auto it_right = selected_right.begin();
auto end_right = selected_right.end();
auto nit = mesh.getNodes().begin(dim);
while ((it_left != end_left) && (it_right != end_right)) {
UInt i1 = *it_left;
UInt i2 = *it_right;
Vector<Real> coords1 = nit[i1];
Vector<Real> coords2 = nit[i2];
AKANTU_DEBUG_TRACE("do I pair? " << i1 << "(" << coords1 << ") with" << i2
<< "(" << coords2 << ") in direction "
<< dir);
Real dx = 0.0;
Real dy = 0.0;
if (dim >= 2)
dx = coords1(odir_1) - coords2(odir_1);
if (dim == 3)
dy = coords1(odir_2) - coords2(odir_2);
if (std::abs(dx * dx + dy * dy) / normalization < tolerance) {
// then i match these pairs
if (pbc_pair.count(i2)) {
i2 = pbc_pair[i2];
}
pbc_pair[i1] = i2;
- AKANTU_DEBUG_TRACE("pairing "
- << i1 << "(" << coords1
- << ") with" << i2 << "(" << coords2
- << ") in direction " << dir);
+ AKANTU_DEBUG_TRACE("pairing " << i1 << "(" << coords1 << ") with" << i2
+ << "(" << coords2 << ") in direction "
+ << dir);
++it_left;
++it_right;
} else if (compare_nodes(coords1, coords2)) {
++it_left;
} else {
++it_right;
}
}
AKANTU_DEBUG_INFO("found " << pbc_pair.size() << " pairs for direction "
<< dir);
}
} // akantu
diff --git a/src/model/boundary_condition.hh b/src/model/boundary_condition.hh
index 60754053d..dd7775b2f 100644
--- a/src/model/boundary_condition.hh
+++ b/src/model/boundary_condition.hh
@@ -1,106 +1,101 @@
/**
* @file boundary_condition.hh
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Dec 18 2015
*
* @brief XXX
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BOUNDARY_CONDITION_HH__
#define __AKANTU_BOUNDARY_CONDITION_HH__
#include "aka_common.hh"
#include "boundary_condition_functor.hh"
-#include "mesh.hh"
#include "fe_engine.hh"
+#include "mesh.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
namespace akantu {
-template <class ModelType>
-class BoundaryCondition {
+template <class ModelType> class BoundaryCondition {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
private:
-
/* ------------------------------------------------------------------------ */
/* Constructors / Destructors / Initializers */
/* ------------------------------------------------------------------------ */
public:
BoundaryCondition() : model(nullptr) {}
- ///Initialize the boundary conditions
+ /// Initialize the boundary conditions
void initBC(ModelType & ptr, Array<Real> & primal, Array<Real> & dual);
void initBC(ModelType & ptr, Array<Real> & primal,
- Array<Real> & primal_increment, Array<Real> & dual);
+ Array<Real> & primal_increment, Array<Real> & dual);
/* ------------------------------------------------------------------------ */
/* Methods and accessors */
/* ------------------------------------------------------------------------ */
public:
-
- //inline void initBoundaryCondition();
- template<typename FunctorType>
- ///Apply the boundary conditions
+ // inline void initBoundaryCondition();
+ template <typename FunctorType>
+ /// Apply the boundary conditions
inline void applyBC(const FunctorType & func);
- template<class FunctorType>
+ template <class FunctorType>
inline void applyBC(const FunctorType & func, const std::string & group_name);
- template<class FunctorType>
- inline void applyBC(const FunctorType & func, const ElementGroup & element_group);
+ template <class FunctorType>
+ inline void applyBC(const FunctorType & func,
+ const ElementGroup & element_group);
AKANTU_GET_MACRO_NOT_CONST(Model, *model, ModelType &);
- AKANTU_GET_MACRO_NOT_CONST(Primal,*primal, Array<Real> &);
- AKANTU_GET_MACRO_NOT_CONST(Dual, *dual, Array<Real> &);
+ AKANTU_GET_MACRO_NOT_CONST(Primal, *primal, Array<Real> &);
+ AKANTU_GET_MACRO_NOT_CONST(Dual, *dual, Array<Real> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
-
- template<class FunctorType, BC::Functor::Type type = FunctorType::type>
+ template <class FunctorType, BC::Functor::Type type = FunctorType::type>
struct TemplateFunctionWrapper;
private:
-
ModelType * model;
Array<Real> * primal{nullptr};
Array<Real> * dual{nullptr};
Array<Real> * primal_increment{nullptr};
};
} // akantu
#include "boundary_condition_tmpl.hh"
#endif /* __AKANTU_BOUNDARY_CONDITION_HH__ */
-
diff --git a/src/model/boundary_condition_python_functor.cc b/src/model/boundary_condition_python_functor.cc
index fbaf982cd..edc531d6f 100644
--- a/src/model/boundary_condition_python_functor.cc
+++ b/src/model/boundary_condition_python_functor.cc
@@ -1,66 +1,57 @@
/**
* @file boundary_condition_python_functor.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Wed Aug 31 2011
* @date last modification: Fri Nov 13 2015
*
* @brief Interface for BC::Functor written in python
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "boundary_condition_python_functor.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
-
namespace BC {
+ void PythonFunctorDirichlet::operator()(UInt node, Vector<bool> & flags,
+ Vector<Real> & primal,
+ const Vector<Real> & coord) const {
-
- void PythonFunctorDirichlet::operator ()(UInt node,
- Vector<bool> & flags,
- Vector<Real> & primal,
- const Vector<Real> & coord) const{
-
- this->callFunctor<void>("operator",node,flags,primal,coord);
+ this->callFunctor<void>("operator", node, flags, primal, coord);
}
-
-
void PythonFunctorNeumann::operator()(const IntegrationPoint & quad_point,
- Vector<Real> & dual,
- const Vector<Real> & coord,
- const Vector<Real> & normals) const{
+ Vector<Real> & dual,
+ const Vector<Real> & coord,
+ const Vector<Real> & normals) const {
- this->callFunctor<void>("operator",quad_point,dual,coord,normals);
+ this->callFunctor<void>("operator", quad_point, dual, coord, normals);
}
-
-}//end namespace BC
-
+} // end namespace BC
} // akantu
-
diff --git a/src/model/boundary_condition_python_functor.hh b/src/model/boundary_condition_python_functor.hh
index 50549bd2b..da7e44410 100644
--- a/src/model/boundary_condition_python_functor.hh
+++ b/src/model/boundary_condition_python_functor.hh
@@ -1,116 +1,116 @@
/**
* @file boundary_condition_python_functor.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Fri Nov 13 2015
*
* @brief interface for BC::Functor writen in python
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "boundary_condition_functor.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__
#define __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__
/* -------------------------------------------------------------------------- */
#include "boundary_condition_functor.hh"
#include "python_functor.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
-
namespace BC {
-
class PythonFunctorDirichlet : public PythonFunctor, public Functor {
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------
+ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------
+ */
public:
PythonFunctorDirichlet(PyObject * obj) : PythonFunctor(obj) {}
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------
+ */
+ /* Methods */
+ /* ------------------------------------------------------------------------
+ */
public:
- void operator()(UInt node,
- Vector<bool> & flags,
- Vector<Real> & primal,
- const Vector<Real> & coord) const;
+ void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal,
+ const Vector<Real> & coord) const;
- /* ------------------------------------------------------------------------ */
- /* Class Members */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------
+ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------
+ */
public:
static const Type type = _dirichlet;
-
-
};
-/* -------------------------------------------------------------------------- */
-
+ /* --------------------------------------------------------------------------
+ */
- class PythonFunctorNeumann : public PythonFunctor, public Functor{
+ class PythonFunctorNeumann : public PythonFunctor, public Functor {
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------
+ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------
+ */
public:
PythonFunctorNeumann(PyObject * obj) : PythonFunctor(obj) {}
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------
+ */
+ /* Methods */
+ /* ------------------------------------------------------------------------
+ */
public:
-
- void operator()(const IntegrationPoint & quad_point,
- Vector<Real> & dual,
- const Vector<Real> & coord,
- const Vector<Real> & normals) const;
+ void operator()(const IntegrationPoint & quad_point, Vector<Real> & dual,
+ const Vector<Real> & coord,
+ const Vector<Real> & normals) const;
- /* ------------------------------------------------------------------------ */
- /* Class Members */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------
+ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------
+ */
public:
static const Type type = _neumann;
-
};
-
-
-}//end namespace BC
-
+} // end namespace BC
} // akantu
#endif /* __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__ */
diff --git a/src/model/boundary_condition_tmpl.hh b/src/model/boundary_condition_tmpl.hh
index db3c01212..bb4c58039 100644
--- a/src/model/boundary_condition_tmpl.hh
+++ b/src/model/boundary_condition_tmpl.hh
@@ -1,255 +1,256 @@
/**
* @file boundary_condition_tmpl.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
* @date last modification: Fri Oct 16 2015
*
* @brief implementation of the applyBC
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "boundary_condition.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BOUNDARY_CONDITION_TMPL_HH__
#define __AKANTU_BOUNDARY_CONDITION_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename ModelType>
void BoundaryCondition<ModelType>::initBC(ModelType & model,
Array<Real> & primal,
Array<Real> & dual) {
this->model = &model;
this->primal = &primal;
this->dual = &dual;
}
/* -------------------------------------------------------------------------- */
template <typename ModelType>
void BoundaryCondition<ModelType>::initBC(ModelType & model,
Array<Real> & primal,
Array<Real> & primal_increment,
Array<Real> & dual) {
this->initBC(model, primal, dual);
this->primal_increment = &primal_increment;
}
/* -------------------------------------------------------------------------- */
/* Partial specialization for DIRICHLET functors */
template <typename ModelType>
template <typename FunctorType>
struct BoundaryCondition<ModelType>::TemplateFunctionWrapper<
FunctorType, BC::Functor::_dirichlet> {
static inline void applyBC(const FunctorType & func,
const ElementGroup & group,
BoundaryCondition<ModelType> & bc_instance) {
auto & model = bc_instance.getModel();
auto & primal = bc_instance.getPrimal();
const auto & coords = model.getMesh().getNodes();
auto & boundary_flags = model.getBlockedDOFs();
UInt dim = model.getMesh().getSpatialDimension();
auto primal_iter = primal.begin(primal.getNbComponent());
auto coords_iter = coords.begin(dim);
auto flags_iter = boundary_flags.begin(boundary_flags.getNbComponent());
for (auto n : group.getNodeGroup()) {
Vector<bool> flag(flags_iter[n]);
Vector<Real> primal(primal_iter[n]);
Vector<Real> coords(coords_iter[n]);
func(n, flag, primal, coords);
}
}
};
/* -------------------------------------------------------------------------- */
/* Partial specialization for NEUMANN functors */
template <typename ModelType>
template <typename FunctorType>
struct BoundaryCondition<ModelType>::TemplateFunctionWrapper<
FunctorType, BC::Functor::_neumann> {
static inline void applyBC(const FunctorType & func,
const ElementGroup & group,
BoundaryCondition<ModelType> & bc_instance) {
UInt dim = bc_instance.getModel().getSpatialDimension();
switch (dim) {
case 1: {
AKANTU_TO_IMPLEMENT();
break;
}
case 2:
case 3: {
applyBC(func, group, bc_instance, _not_ghost);
applyBC(func, group, bc_instance, _ghost);
break;
}
}
}
static inline void applyBC(const FunctorType & func,
const ElementGroup & group,
BoundaryCondition<ModelType> & bc_instance,
GhostType ghost_type) {
auto & model = bc_instance.getModel();
auto & dual = bc_instance.getDual();
const auto & mesh = model.getMesh();
const auto & nodes_coords = mesh.getNodes();
const auto & fem_boundary = model.getFEEngineBoundary();
UInt dim = model.getSpatialDimension();
UInt nb_degree_of_freedom = dual.getNbComponent();
IntegrationPoint quad_point;
quad_point.ghost_type = ghost_type;
// Loop over the boundary element types
for (auto && type : group.elementTypes(dim - 1, ghost_type)) {
const auto & element_ids = group.getElements(type, ghost_type);
UInt nb_quad_points =
fem_boundary.getNbIntegrationPoints(type, ghost_type);
UInt nb_elements = element_ids.size();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
Array<Real> * dual_before_integ = new Array<Real>(
nb_elements * nb_quad_points, nb_degree_of_freedom, 0.);
Array<Real> * quad_coords =
new Array<Real>(nb_elements * nb_quad_points, dim);
const auto & normals_on_quad =
fem_boundary.getNormalsOnIntegrationPoints(type, ghost_type);
fem_boundary.interpolateOnIntegrationPoints(
nodes_coords, *quad_coords, dim, type, ghost_type, element_ids);
auto normals_begin = normals_on_quad.begin(dim);
decltype(normals_begin) normals_iter;
auto quad_coords_iter = quad_coords->begin(dim);
auto dual_iter = dual_before_integ->begin(nb_degree_of_freedom);
quad_point.type = type;
for (auto el : element_ids) {
quad_point.element = el;
normals_iter = normals_begin + el * nb_quad_points;
for (auto && q : arange(nb_quad_points)) {
quad_point.num_point = q;
func(quad_point, *dual_iter, *quad_coords_iter, *normals_iter);
++dual_iter;
++quad_coords_iter;
++normals_iter;
}
}
delete quad_coords;
/* -------------------------------------------------------------------- */
// Initialization of iterators
auto dual_iter_mat = dual_before_integ->begin(nb_degree_of_freedom, 1);
auto shapes_iter_begin = fem_boundary.getShapes(type, ghost_type)
.begin(1, nb_nodes_per_element);
Array<Real> * dual_by_shapes =
new Array<Real>(nb_elements * nb_quad_points,
nb_degree_of_freedom * nb_nodes_per_element);
auto dual_by_shapes_iter =
dual_by_shapes->begin(nb_degree_of_freedom, nb_nodes_per_element);
/* -------------------------------------------------------------------- */
// Loop computing dual x shapes
for (auto el : element_ids) {
auto shapes_iter = shapes_iter_begin + el * nb_quad_points;
for (UInt q(0); q < nb_quad_points;
++q, ++dual_iter_mat, ++dual_by_shapes_iter, ++shapes_iter) {
- dual_by_shapes_iter->template mul<false, false>(*dual_iter_mat, *shapes_iter);
+ dual_by_shapes_iter->template mul<false, false>(*dual_iter_mat,
+ *shapes_iter);
}
}
delete dual_before_integ;
Array<Real> * dual_by_shapes_integ = new Array<Real>(
nb_elements, nb_degree_of_freedom * nb_nodes_per_element);
fem_boundary.integrate(*dual_by_shapes, *dual_by_shapes_integ,
nb_degree_of_freedom * nb_nodes_per_element, type,
ghost_type, element_ids);
delete dual_by_shapes;
// assemble the result into force vector
model.getDOFManager().assembleElementalArrayLocalArray(
*dual_by_shapes_integ, dual, type, ghost_type, 1., element_ids);
delete dual_by_shapes_integ;
}
}
};
/* -------------------------------------------------------------------------- */
template <typename ModelType>
template <typename FunctorType>
inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func) {
auto bit = model->getMesh().getGroupManager().element_group_begin();
auto bend = model->getMesh().getGroupManager().element_group_end();
for (; bit != bend; ++bit)
applyBC(func, *bit);
}
/* -------------------------------------------------------------------------- */
template <typename ModelType>
template <typename FunctorType>
inline void
BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
const std::string & group_name) {
try {
const ElementGroup & element_group =
model->getMesh().getElementGroup(group_name);
applyBC(func, element_group);
} catch (akantu::debug::Exception e) {
AKANTU_EXCEPTION("Error applying a boundary condition onto \""
<< group_name << "\"! [" << e.what() << "]");
}
}
/* -------------------------------------------------------------------------- */
template <typename ModelType>
template <typename FunctorType>
inline void
BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
const ElementGroup & element_group) {
#if !defined(AKANTU_NDEBUG)
if (element_group.getDimension() != model->getSpatialDimension() - 1)
AKANTU_DEBUG_WARNING("The group "
<< element_group.getName()
<< " does not contain only boundaries elements");
#endif
TemplateFunctionWrapper<FunctorType>::applyBC(func, element_group, *this);
}
#endif /* __AKANTU_BOUNDARY_CONDITION_TMPL_HH__ */
} // namespace akantu
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
index e5496fd7e..6468159a4 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
@@ -1,310 +1,311 @@
/**
* @file neighborhood_max_criterion.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Thu Oct 15 2015
* @date last modification: Tue Nov 24 2015
*
* @brief Implementation of class NeighborhoodMaxCriterion
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "neighborhood_max_criterion.hh"
#include "grid_synchronizer.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
NeighborhoodMaxCriterion::NeighborhoodMaxCriterion(
Model & model, const ElementTypeMapReal & quad_coordinates,
const ID & criterion_id, const ID & id, const MemoryID & memory_id)
: NeighborhoodBase(model, quad_coordinates, id, memory_id),
- Parsable(ParserType::_non_local, id), is_highest("is_highest", id, memory_id),
+ Parsable(ParserType::_non_local, id),
+ is_highest("is_highest", id, memory_id),
criterion(criterion_id, id, memory_id) {
AKANTU_DEBUG_IN();
this->registerParam("radius", neighborhood_radius, 100.,
_pat_parsable | _pat_readable, "Non local radius");
Mesh & mesh = this->model.getMesh();
/// allocate the element type map arrays for _not_ghosts: One entry per quad
GhostType ghost_type = _not_ghost;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
for (; it != last_type; ++it) {
UInt new_size = this->quad_coordinates(*it, ghost_type).size();
this->is_highest.alloc(new_size, 1, *it, ghost_type, true);
this->criterion.alloc(new_size, 1, *it, ghost_type, true);
}
/// criterion needs allocation also for ghost
ghost_type = _ghost;
it = mesh.firstType(spatial_dimension, ghost_type);
last_type = mesh.lastType(spatial_dimension, ghost_type);
for (; it != last_type; ++it) {
UInt new_size = this->quad_coordinates(*it, ghost_type).size();
this->criterion.alloc(new_size, 1, *it, ghost_type, true);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
NeighborhoodMaxCriterion::~NeighborhoodMaxCriterion() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::initNeighborhood() {
AKANTU_DEBUG_IN();
/// parse the input parameter
const Parser & parser = getStaticParser();
const ParserSection & section_neighborhood =
*(parser.getSubSections(ParserType::_neighborhood).first);
this->parseSection(section_neighborhood);
AKANTU_DEBUG_INFO("Creating the grid");
this->createGrid();
/// insert the non-ghost quads into the grid
this->insertAllQuads(_not_ghost);
/// store the number of current ghost elements for each type in the mesh
ElementTypeMap<UInt> nb_ghost_protected;
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
for (; it != last_type; ++it)
nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
/// create the grid synchronizer
this->createGridSynchronizer();
/// insert the ghost quads into the grid
this->insertAllQuads(_ghost);
/// create the pair lists
this->updatePairList();
/// remove the unneccessary ghosts
this->cleanupExtraGhostElements(nb_ghost_protected);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::createGridSynchronizer() {
this->is_creating_grid = true;
std::set<SynchronizationTag> tags;
tags.insert(_gst_nh_criterion);
std::stringstream sstr;
sstr << getID() << ":grid_synchronizer";
this->grid_synchronizer = std::make_unique<GridSynchronizer>(
- this->model.getMesh(), *spatial_grid, * this, tags, sstr.str(), 0, false);
+ this->model.getMesh(), *spatial_grid, *this, tags, sstr.str(), 0, false);
this->is_creating_grid = false;
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::insertAllQuads(const GhostType & ghost_type) {
IntegrationPoint q;
q.ghost_type = ghost_type;
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
for (; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
UInt nb_quad =
this->model.getFEEngine().getNbIntegrationPoints(*it, ghost_type);
const Array<Real> & quads = this->quad_coordinates(*it, ghost_type);
q.type = *it;
auto quad = quads.begin(spatial_dimension);
for (UInt e = 0; e < nb_element; ++e) {
q.element = e;
for (UInt nq = 0; nq < nb_quad; ++nq) {
q.num_point = nq;
q.global_num = q.element * nb_quad + nq;
spatial_grid->insert(q, *quad);
++quad;
}
}
}
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::findMaxQuads(
std::vector<IntegrationPoint> & max_quads) {
AKANTU_DEBUG_IN();
/// clear the element type maps
this->is_highest.clear();
this->criterion.clear();
/// update the values of the criterion
this->model.updateDataForNonLocalCriterion(criterion);
/// start the exchange the value of the criterion on the ghost elements
this->model.asynchronousSynchronize(_gst_nh_criterion);
/// compare to not-ghost neighbors
checkNeighbors(_not_ghost);
/// finish the exchange
this->model.waitEndSynchronize(_gst_nh_criterion);
/// compare to ghost neighbors
checkNeighbors(_ghost);
/// extract the quads with highest criterion in their neighborhood
IntegrationPoint quad;
quad.ghost_type = _not_ghost;
Mesh & mesh = this->model.getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost);
for (; it != last_type; ++it) {
quad.type = *it;
Array<bool>::const_scalar_iterator is_highest_it =
is_highest(*it, _not_ghost).begin();
Array<bool>::const_scalar_iterator is_highest_end =
is_highest(*it, _not_ghost).end();
UInt nb_quadrature_points =
this->model.getFEEngine().getNbIntegrationPoints(*it, _not_ghost);
UInt q = 0;
/// loop over is_highest for the current element type
for (; is_highest_it != is_highest_end; ++is_highest_it, ++q) {
if (*is_highest_it) {
/// gauss point has the highest stress in his neighbourhood
quad.element = q / nb_quadrature_points;
quad.global_num = q;
quad.num_point = q % nb_quadrature_points;
max_quads.push_back(quad);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::checkNeighbors(const GhostType & ghost_type2) {
AKANTU_DEBUG_IN();
PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
PairList::const_iterator last_pair = pair_list[ghost_type2].end();
// Compute the weights
for (; first_pair != last_pair; ++first_pair) {
const IntegrationPoint & lq1 = first_pair->first;
const IntegrationPoint & lq2 = first_pair->second;
Array<bool> & has_highest_eq_stress_1 =
is_highest(lq1.type, lq1.ghost_type);
const Array<Real> & criterion_1 = this->criterion(lq1.type, lq1.ghost_type);
const Array<Real> & criterion_2 = this->criterion(lq2.type, lq2.ghost_type);
if (criterion_1(lq1.global_num) < criterion_2(lq2.global_num))
has_highest_eq_stress_1(lq1.global_num) = false;
else if (ghost_type2 != _ghost) {
Array<bool> & has_highest_eq_stress_2 =
is_highest(lq2.type, lq2.ghost_type);
has_highest_eq_stress_2(lq2.global_num) = false;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NeighborhoodMaxCriterion::cleanupExtraGhostElements(
const ElementTypeMap<UInt> & nb_ghost_protected) {
Mesh & mesh = this->model.getMesh();
/// create remove elements event
RemovedElementsEvent remove_elem(mesh);
/// create set of ghosts to keep
std::set<Element> relevant_ghost_elements;
PairList::const_iterator first_pair = pair_list[_ghost].begin();
PairList::const_iterator last_pair = pair_list[_ghost].end();
for (; first_pair != last_pair; ++first_pair) {
const IntegrationPoint & q2 = first_pair->second;
relevant_ghost_elements.insert(q2);
}
Array<Element> ghosts_to_erase(0);
Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
Element element;
element.ghost_type = _ghost;
auto end = relevant_ghost_elements.end();
for (; it != last_type; ++it) {
element.type = *it;
UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
UInt nb_ghost_elem_protected = 0;
try {
nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
} catch (...) {
}
if (!remove_elem.getNewNumbering().exists(*it, _ghost))
remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
else
remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
for (UInt g = 0; g < nb_ghost_elem; ++g) {
element.element = g;
if (element.element >= nb_ghost_elem_protected &&
relevant_ghost_elements.find(element) == end) {
ghosts_to_erase.push_back(element);
new_numbering(element.element) = UInt(-1);
}
}
/// renumber remaining ghosts
UInt ng = 0;
for (UInt g = 0; g < nb_ghost_elem; ++g) {
if (new_numbering(g) != UInt(-1)) {
new_numbering(g) = ng;
++ng;
}
}
}
mesh.sendEvent(remove_elem);
this->onElementsRemoved(ghosts_to_erase, remove_elem.getNewNumbering(),
remove_elem);
}
} // namespace akantu
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
index c450b91ea..bb2d331cb 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
@@ -1,81 +1,81 @@
/**
* @file neighborhood_max_criterion_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Thu Oct 15 2015
*
* @brief Implementation of inline functions for class NeighborhoodMaxCriterion
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "neighborhood_max_criterion.hh"
#include "model.hh"
+#include "neighborhood_max_criterion.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__
#define __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline UInt
NeighborhoodMaxCriterion::getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
UInt nb_quadrature_points = this->model.getNbIntegrationPoints(elements);
UInt size = 0;
if (tag == _gst_nh_criterion) {
size += sizeof(Real) * nb_quadrature_points;
}
return size;
}
/* -------------------------------------------------------------------------- */
inline void
NeighborhoodMaxCriterion::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag == _gst_nh_criterion) {
this->packElementalDataHelper(criterion, buffer, elements, true,
this->model.getFEEngine());
}
}
/* -------------------------------------------------------------------------- */
inline void
NeighborhoodMaxCriterion::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if (tag == _gst_nh_criterion) {
this->unpackElementalDataHelper(criterion, buffer, elements, true,
this->model.getFEEngine());
}
}
/* -------------------------------------------------------------------------- */
-} // akantu
+} // akantu
#endif /* __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc b/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc
index 795e7fc71..0c185e079 100644
--- a/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc
+++ b/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc
@@ -1,71 +1,70 @@
/**
* @file base_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Thu Oct 15 2015
*
* @brief Implementation of inline function of base weight function
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_BASE_WEIGHT_FUNCTION_INLINE_IMPL_CC__
#define __AKANTU_BASE_WEIGHT_FUNCTION_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline void BaseWeightFunction::init() {
/// compute R^2 for a given non-local radius
this->R2 = this->R * this->R;
}
/* -------------------------------------------------------------------------- */
inline void BaseWeightFunction::setRadius(Real radius) {
/// set the non-local radius and update R^2 accordingly
this->R = radius;
this->R2 = this->R * this->R;
}
/* -------------------------------------------------------------------------- */
-inline Real BaseWeightFunction::
-operator()(Real r, const IntegrationPoint &,
- const IntegrationPoint &) {
+inline Real BaseWeightFunction::operator()(Real r, const IntegrationPoint &,
+ const IntegrationPoint &) {
-/// initialize the weight
+ /// initialize the weight
Real w = 0;
/// compute weight for given r
if (r <= this->R) {
Real alpha = (1. - r * r / this->R2);
w = alpha * alpha;
// *weight = 1 - sqrt(r / radius);
}
return w;
}
} // akantu
#endif /* __AKANTU_BASE_WEIGHT_FUNCTION_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_manager.cc b/src/model/common/non_local_toolbox/non_local_manager.cc
index f03e218bd..386c3ee82 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.cc
+++ b/src/model/common/non_local_toolbox/non_local_manager.cc
@@ -1,638 +1,639 @@
/**
* @file non_local_manager.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Apr 13 2012
* @date last modification: Wed Dec 16 2015
*
* @brief Implementation of non-local manager
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_local_manager.hh"
#include "grid_synchronizer.hh"
#include "model.hh"
#include "non_local_neighborhood.hh"
/* -------------------------------------------------------------------------- */
#include <numeric>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
NonLocalManager::NonLocalManager(Model & model,
NonLocalManagerCallback & callback,
const ID & id, const MemoryID & memory_id)
: Memory(id, memory_id), Parsable(ParserType::_neighborhoods, id),
spatial_dimension(model.getMesh().getSpatialDimension()), model(model),
integration_points_positions("integration_points_positions", id,
memory_id),
volumes("volumes", id, memory_id), compute_stress_calls(0),
dummy_registry(nullptr), dummy_grid(nullptr) {
/// parse the neighborhood information from the input file
const Parser & parser = getStaticParser();
/// iterate over all the non-local sections and store them in a map
std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
weight_sect = parser.getSubSections(ParserType::_non_local);
Parser::const_section_iterator it = weight_sect.first;
for (; it != weight_sect.second; ++it) {
const ParserSection & section = *it;
ID name = section.getName();
this->weight_function_types[name] = section;
}
this->callback = &callback;
}
/* -------------------------------------------------------------------------- */
NonLocalManager::~NonLocalManager() = default;
/* -------------------------------------------------------------------------- */
void NonLocalManager::initialize() {
volumes.initialize(this->model.getFEEngine(),
_spatial_dimension = spatial_dimension);
AKANTU_DEBUG_ASSERT(this->callback,
"A callback should be registered prior to this call");
this->callback->insertIntegrationPointsInNeighborhoods(_not_ghost);
auto & mesh = this->model.getMesh();
mesh.registerEventHandler(*this, _ehp_non_local_manager);
/// store the number of current ghost elements for each type in the mesh
- //ElementTypeMap<UInt> nb_ghost_protected;
+ // ElementTypeMap<UInt> nb_ghost_protected;
// for (auto type : mesh.elementTypes(spatial_dimension, _ghost))
// nb_ghost_protected(mesh.getNbElement(type, _ghost), type, _ghost);
/// exchange the missing ghosts for the non-local neighborhoods
this->createNeighborhoodSynchronizers();
/// insert the ghost quadrature points of the non-local materials into the
/// non-local neighborhoods
this->callback->insertIntegrationPointsInNeighborhoods(_ghost);
FEEngine & fee = this->model.getFEEngine();
this->updatePairLists();
/// cleanup the unneccessary ghost elements
- this->cleanupExtraGhostElements(); //nb_ghost_protected);
+ this->cleanupExtraGhostElements(); // nb_ghost_protected);
this->callback->initializeNonLocal();
this->setJacobians(fee, _ek_regular);
this->initNonLocalVariables();
this->computeWeights();
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::setJacobians(const FEEngine & fe_engine,
const ElementKind & kind) {
Mesh & mesh = this->model.getMesh();
for (auto ghost_type : ghost_types) {
for (auto type : mesh.elementTypes(spatial_dimension, ghost_type, kind)) {
jacobians(type, ghost_type) =
&fe_engine.getIntegratorInterface().getJacobians(type, ghost_type);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::createNeighborhood(const ID & weight_func,
const ID & neighborhood_id) {
AKANTU_DEBUG_IN();
auto weight_func_it = this->weight_function_types.find(weight_func);
AKANTU_DEBUG_ASSERT(weight_func_it != weight_function_types.end(),
"No info found in the input file for the weight_function "
<< weight_func << " in the neighborhood "
<< neighborhood_id);
const ParserSection & section = weight_func_it->second;
const ID weight_func_type = section.getOption();
/// create new neighborhood for given ID
std::stringstream sstr;
sstr << id << ":neighborhood:" << neighborhood_id;
if (weight_func_type == "base_wf")
neighborhoods[neighborhood_id] =
std::make_unique<NonLocalNeighborhood<BaseWeightFunction>>(
*this, this->integration_points_positions, sstr.str());
#if defined(AKANTU_DAMAGE_NON_LOCAL)
else if (weight_func_type == "remove_wf")
neighborhoods[neighborhood_id] =
std::make_unique<NonLocalNeighborhood<RemoveDamagedWeightFunction>>(
*this, this->integration_points_positions, sstr.str());
else if (weight_func_type == "stress_wf")
neighborhoods[neighborhood_id] =
std::make_unique<NonLocalNeighborhood<StressBasedWeightFunction>>(
*this, this->integration_points_positions, sstr.str());
else if (weight_func_type == "damage_wf")
neighborhoods[neighborhood_id] =
std::make_unique<NonLocalNeighborhood<DamagedWeightFunction>>(
*this, this->integration_points_positions, sstr.str());
#endif
else
AKANTU_EXCEPTION("error in weight function type provided in material file");
neighborhoods[neighborhood_id]->parseSection(section);
neighborhoods[neighborhood_id]->initNeighborhood();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::createNeighborhoodSynchronizers() {
/// exchange all the neighborhood IDs, so that every proc knows how many
/// neighborhoods exist globally
/// First: Compute locally the maximum ID size
UInt max_id_size = 0;
UInt current_size = 0;
NeighborhoodMap::const_iterator it;
for (it = neighborhoods.begin(); it != neighborhoods.end(); ++it) {
current_size = it->first.size();
if (current_size > max_id_size)
max_id_size = current_size;
}
/// get the global maximum ID size on each proc
- const Communicator & static_communicator =
- model.getMesh().getCommunicator();
+ const Communicator & static_communicator = model.getMesh().getCommunicator();
static_communicator.allReduce(max_id_size, SynchronizerOperation::_max);
/// get the rank for this proc and the total nb proc
UInt prank = static_communicator.whoAmI();
UInt psize = static_communicator.getNbProc();
/// exchange the number of neighborhoods on each proc
Array<Int> nb_neighborhoods_per_proc(psize);
nb_neighborhoods_per_proc(prank) = neighborhoods.size();
static_communicator.allGather(nb_neighborhoods_per_proc);
/// compute the total number of neighborhoods
UInt nb_neighborhoods_global = std::accumulate(
nb_neighborhoods_per_proc.begin(), nb_neighborhoods_per_proc.end(), 0);
/// allocate an array of chars to store the names of all neighborhoods
Array<char> buffer(nb_neighborhoods_global, max_id_size);
/// starting index on this proc
UInt starting_index =
std::accumulate(nb_neighborhoods_per_proc.begin(),
nb_neighborhoods_per_proc.begin() + prank, 0);
it = neighborhoods.begin();
/// store the names of local neighborhoods in the buffer
for (UInt i = 0; i < neighborhoods.size(); ++i, ++it) {
UInt c = 0;
for (; c < it->first.size(); ++c)
buffer(i + starting_index, c) = it->first[c];
for (; c < max_id_size; ++c)
buffer(i + starting_index, c) = char(0);
}
/// store the nb of data to send in the all gather
Array<Int> buffer_size(nb_neighborhoods_per_proc);
buffer_size *= max_id_size;
/// exchange the names of all the neighborhoods with all procs
static_communicator.allGatherV(buffer, buffer_size);
for (UInt i = 0; i < nb_neighborhoods_global; ++i) {
std::stringstream neighborhood_id;
for (UInt c = 0; c < max_id_size; ++c) {
if (buffer(i, c) == char(0))
break;
neighborhood_id << buffer(i, c);
}
global_neighborhoods.insert(neighborhood_id.str());
}
/// this proc does not know all the neighborhoods -> create dummy
/// grid so that this proc can participate in the all gather for
/// detecting the overlap of neighborhoods this proc doesn't know
Vector<Real> grid_center(this->spatial_dimension,
std::numeric_limits<Real>::max());
Vector<Real> spacing(this->spatial_dimension, 0.);
dummy_grid = std::make_unique<SpatialGrid<IntegrationPoint>>(
this->spatial_dimension, spacing, grid_center);
for (auto & neighborhood_id : global_neighborhoods) {
it = neighborhoods.find(neighborhood_id);
if (it != neighborhoods.end()) {
it->second->createGridSynchronizer();
} else {
dummy_synchronizers[neighborhood_id] = std::make_unique<GridSynchronizer>(
this->model.getMesh(), *dummy_grid,
std::string(this->id + ":" + neighborhood_id + ":grid_synchronizer"),
this->memory_id, false);
}
}
}
/* -------------------------------------------------------------------------- */
-void NonLocalManager::synchronize(DataAccessor<Element> & data_accessor, const SynchronizationTag & tag) {
+void NonLocalManager::synchronize(DataAccessor<Element> & data_accessor,
+ const SynchronizationTag & tag) {
for (auto & neighborhood_id : global_neighborhoods) {
auto it = neighborhoods.find(neighborhood_id);
if (it != neighborhoods.end()) {
it->second->synchronize(data_accessor, tag);
} else {
auto synchronizer_it = dummy_synchronizers.find(neighborhood_id);
- if (synchronizer_it == dummy_synchronizers.end()) continue;
+ if (synchronizer_it == dummy_synchronizers.end())
+ continue;
synchronizer_it->second->synchronizeOnce(data_accessor, tag);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::averageInternals(const GhostType & ghost_type) {
/// update the weights of the weight function
if (ghost_type == _not_ghost)
this->computeWeights();
/// loop over all neighborhoods and compute the non-local variables
for (auto & neighborhood : neighborhoods) {
/// loop over all the non-local variables of the given neighborhood
for (auto & non_local_variable : non_local_variables) {
NonLocalVariable & non_local_var = *non_local_variable.second;
neighborhood.second->weightedAverageOnNeighbours(
non_local_var.local, non_local_var.non_local,
non_local_var.nb_component, ghost_type);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::computeWeights() {
AKANTU_DEBUG_IN();
this->updateWeightFunctionInternals();
this->volumes.clear();
for (const auto & global_neighborhood : global_neighborhoods) {
auto it = neighborhoods.find(global_neighborhood);
if (it != neighborhoods.end())
it->second->updateWeights();
else {
dummy_synchronizers[global_neighborhood]->synchronize(dummy_accessor,
_gst_mnl_weight);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::updatePairLists() {
AKANTU_DEBUG_IN();
integration_points_positions.initialize(
this->model.getFEEngine(), _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension);
/// compute the position of the quadrature points
this->model.getFEEngine().computeIntegrationPointsCoordinates(
integration_points_positions);
for (auto & pair : neighborhoods)
pair.second->updatePairList();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::registerNonLocalVariable(const ID & variable_name,
const ID & nl_variable_name,
UInt nb_component) {
AKANTU_DEBUG_IN();
auto non_local_variable_it = non_local_variables.find(variable_name);
if (non_local_variable_it == non_local_variables.end())
non_local_variables[nl_variable_name] = std::make_unique<NonLocalVariable>(
variable_name, nl_variable_name, this->id, nb_component);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
ElementTypeMapReal &
NonLocalManager::registerWeightFunctionInternal(const ID & field_name) {
AKANTU_DEBUG_IN();
auto it = this->weight_function_internals.find(field_name);
if (it == weight_function_internals.end()) {
weight_function_internals[field_name] =
std::make_unique<ElementTypeMapReal>(field_name, this->id,
this->memory_id);
}
AKANTU_DEBUG_OUT();
return *(weight_function_internals[field_name]);
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::updateWeightFunctionInternals() {
for (auto & pair : this->weight_function_internals) {
auto & internals = *pair.second;
internals.clear();
for (auto ghost_type : ghost_types)
this->callback->updateLocalInternal(internals, ghost_type, _ek_regular);
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::initNonLocalVariables() {
/// loop over all the non-local variables
for (auto & pair : non_local_variables) {
auto & variable = *pair.second;
variable.non_local.initialize(this->model.getFEEngine(),
_nb_component = variable.nb_component,
_spatial_dimension = spatial_dimension);
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::computeAllNonLocalStresses() {
/// update the flattened version of the internals
for (auto & pair : non_local_variables) {
auto & variable = *pair.second;
variable.local.clear();
variable.non_local.clear();
for (auto ghost_type : ghost_types) {
this->callback->updateLocalInternal(variable.local, ghost_type,
_ek_regular);
}
}
this->volumes.clear();
for (auto & pair : neighborhoods) {
auto & neighborhood = *pair.second;
neighborhood.asynchronousSynchronize(_gst_mnl_for_average);
}
this->averageInternals(_not_ghost);
AKANTU_DEBUG_INFO("Wait distant non local stresses");
for (auto & pair : neighborhoods) {
auto & neighborhood = *pair.second;
neighborhood.waitEndSynchronize(_gst_mnl_for_average);
}
this->averageInternals(_ghost);
/// copy the results in the materials
for (auto & pair : non_local_variables) {
auto & variable = *pair.second;
for (auto ghost_type : ghost_types) {
this->callback->updateNonLocalInternal(variable.non_local, ghost_type,
_ek_regular);
}
}
this->callback->computeNonLocalStresses(_not_ghost);
++this->compute_stress_calls;
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::cleanupExtraGhostElements() {
- //ElementTypeMap<UInt> & nb_ghost_protected) {
+ // ElementTypeMap<UInt> & nb_ghost_protected) {
using ElementSet = std::set<Element>;
ElementSet relevant_ghost_elements;
/// loop over all the neighborhoods and get their protected ghosts
for (auto & pair : neighborhoods) {
auto & neighborhood = *pair.second;
ElementSet to_keep_per_neighborhood;
neighborhood.cleanupExtraGhostElements(to_keep_per_neighborhood);
for (auto & element : to_keep_per_neighborhood)
relevant_ghost_elements.insert(element);
}
// /// remove all unneccessary ghosts from the mesh
// /// Create list of element to remove and new numbering for element to keep
// Mesh & mesh = this->model.getMesh();
// ElementSet ghost_to_erase;
// RemovedElementsEvent remove_elem(mesh);
// auto & new_numberings = remove_elem.getNewNumbering();
// Element element;
// element.ghost_type = _ghost;
// for (auto & type : mesh.elementTypes(spatial_dimension, _ghost)) {
// element.type = type;
// UInt nb_ghost_elem = mesh.getNbElement(type, _ghost);
// // UInt nb_ghost_elem_protected = 0;
// // try {
// // nb_ghost_elem_protected = nb_ghost_protected(type, _ghost);
// // } catch (...) {
// // }
// if (!new_numberings.exists(type, _ghost))
// new_numberings.alloc(nb_ghost_elem, 1, type, _ghost);
// else
// new_numberings(type, _ghost).resize(nb_ghost_elem);
// Array<UInt> & new_numbering = new_numberings(type, _ghost);
// for (UInt g = 0; g < nb_ghost_elem; ++g) {
// element.element = g;
// if (element.element >= nb_ghost_elem_protected &&
// relevant_ghost_elements.find(element) ==
// relevant_ghost_elements.end()) {
// remove_elem.getList().push_back(element);
// new_numbering(element.element) = UInt(-1);
// }
// }
// /// renumber remaining ghosts
// UInt ng = 0;
// for (UInt g = 0; g < nb_ghost_elem; ++g) {
// if (new_numbering(g) != UInt(-1)) {
// new_numbering(g) = ng;
// ++ng;
// }
// }
// }
// for (auto & type : mesh.elementTypes(spatial_dimension, _not_ghost)) {
// UInt nb_elem = mesh.getNbElement(type, _not_ghost);
// if (!new_numberings.exists(type, _not_ghost))
// new_numberings.alloc(nb_elem, 1, type, _not_ghost);
// Array<UInt> & new_numbering = new_numberings(type, _not_ghost);
// for (UInt e = 0; e < nb_elem; ++e) {
// new_numbering(e) = e;
// }
// }
// mesh.sendEvent(remove_elem);
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::onElementsRemoved(
const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const RemovedElementsEvent & event) {
FEEngine & fee = this->model.getFEEngine();
this->removeIntegrationPointsFromMap(
event.getNewNumbering(), spatial_dimension, integration_points_positions,
fee, _ek_regular);
this->removeIntegrationPointsFromMap(event.getNewNumbering(), 1, volumes, fee,
_ek_regular);
/// loop over all the neighborhoods and call onElementsRemoved
auto global_neighborhood_it = global_neighborhoods.begin();
NeighborhoodMap::iterator it;
for (; global_neighborhood_it != global_neighborhoods.end();
++global_neighborhood_it) {
it = neighborhoods.find(*global_neighborhood_it);
if (it != neighborhoods.end())
it->second->onElementsRemoved(element_list, new_numbering, event);
else
dummy_synchronizers[*global_neighborhood_it]->onElementsRemoved(
element_list, new_numbering, event);
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::onElementsAdded(const Array<Element> &,
const NewElementsEvent &) {
this->resizeElementTypeMap(1, volumes, model.getFEEngine());
this->resizeElementTypeMap(spatial_dimension, integration_points_positions,
model.getFEEngine());
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::resizeElementTypeMap(UInt nb_component,
ElementTypeMapReal & element_map,
const FEEngine & fee,
const ElementKind el_kind) {
Mesh & mesh = this->model.getMesh();
for (auto gt : ghost_types) {
for (auto type : mesh.elementTypes(spatial_dimension, gt, el_kind)) {
UInt nb_element = mesh.getNbElement(type, gt);
UInt nb_quads = fee.getNbIntegrationPoints(type, gt);
if (!element_map.exists(type, gt))
element_map.alloc(nb_element * nb_quads, nb_component, type, gt);
else
element_map(type, gt).resize(nb_element * nb_quads);
}
}
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::removeIntegrationPointsFromMap(
const ElementTypeMapArray<UInt> & new_numbering, UInt nb_component,
ElementTypeMapReal & element_map, const FEEngine & fee,
const ElementKind el_kind) {
for (auto gt : ghost_types) {
for (auto type : new_numbering.elementTypes(_all_dimensions, gt, el_kind)) {
if (element_map.exists(type, gt)) {
const Array<UInt> & renumbering = new_numbering(type, gt);
Array<Real> & vect = element_map(type, gt);
UInt nb_quad_per_elem = fee.getNbIntegrationPoints(type, gt);
Array<Real> tmp(renumbering.size() * nb_quad_per_elem, nb_component);
AKANTU_DEBUG_ASSERT(
tmp.size() == vect.size(),
"Something strange append some mater was created or disappeared in "
<< vect.getID() << "(" << vect.size() << "!=" << tmp.size()
<< ") "
"!!");
UInt new_size = 0;
for (UInt i = 0; i < renumbering.size(); ++i) {
UInt new_i = renumbering(i);
if (new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component * nb_quad_per_elem,
vect.storage() + i * nb_component * nb_quad_per_elem,
nb_component * nb_quad_per_elem * sizeof(Real));
++new_size;
}
}
tmp.resize(new_size * nb_quad_per_elem);
vect.copy(tmp);
}
}
}
}
/* -------------------------------------------------------------------------- */
UInt NonLocalManager::getNbData(const Array<Element> & elements,
const ID & id) const {
UInt size = 0;
UInt nb_quadrature_points = this->model.getNbIntegrationPoints(elements);
auto it = non_local_variables.find(id);
AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
"The non-local variable " << id << " is not registered");
size += it->second->nb_component * sizeof(Real) * nb_quadrature_points;
return size;
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & id) const {
auto it = non_local_variables.find(id);
AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
"The non-local variable " << id << " is not registered");
DataAccessor<Element>::packElementalDataHelper<Real>(
it->second->local, buffer, elements, true, this->model.getFEEngine());
}
/* -------------------------------------------------------------------------- */
void NonLocalManager::unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & id) const {
auto it = non_local_variables.find(id);
AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
"The non-local variable " << id << " is not registered");
DataAccessor<Element>::unpackElementalDataHelper<Real>(
it->second->local, buffer, elements, true, this->model.getFEEngine());
}
} // namespace akantu
diff --git a/src/model/common/non_local_toolbox/non_local_manager.hh b/src/model/common/non_local_toolbox/non_local_manager.hh
index f249eac9c..cca5c52f1 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.hh
+++ b/src/model/common/non_local_toolbox/non_local_manager.hh
@@ -1,288 +1,292 @@
/**
* @file non_local_manager.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Dec 08 2015
*
* @brief Classes that manages all the non-local neighborhoods
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communication_buffer.hh"
#include "data_accessor.hh"
#include "mesh_events.hh"
#include "non_local_manager_callback.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
#include <map>
#include <set>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_MANAGER_HH__
#define __AKANTU_NON_LOCAL_MANAGER_HH__
namespace akantu {
class Model;
class NonLocalNeighborhoodBase;
class GridSynchronizer;
class SynchronizerRegistry;
class IntegrationPoint;
template <typename T> class SpatialGrid;
class FEEngine;
} // namespace akantu
namespace akantu {
class NonLocalManager : protected Memory,
public MeshEventHandler,
public Parsable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLocalManager(Model & model, NonLocalManagerCallback & callback,
const ID & id = "non_local_manager",
const MemoryID & memory_id = 0);
~NonLocalManager() override;
using NeighborhoodMap =
std::map<ID, std::unique_ptr<NonLocalNeighborhoodBase>>;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ----------------------------------------------------------------------- */
public:
/// register a new internal needed for the weight computations
ElementTypeMapReal & registerWeightFunctionInternal(const ID & field_name);
/// register a non-local variable
void registerNonLocalVariable(const ID & variable_name,
const ID & nl_variable_name, UInt nb_component);
/// register non-local neighborhood
inline void registerNeighborhood(const ID & neighborhood,
const ID & weight_func_id);
// void registerNonLocalManagerCallback(NonLocalManagerCallback & callback);
/// average the internals and compute the non-local stresses
virtual void computeAllNonLocalStresses();
/// initialize the non-local manager: compute pair lists and weights for all
/// neighborhoods
virtual void initialize();
/// synchronize once on a given tag using the neighborhoods synchronizer
- void synchronize(DataAccessor<Element> & data_accessor, const SynchronizationTag &);
+ void synchronize(DataAccessor<Element> & data_accessor,
+ const SynchronizationTag &);
+
protected:
/// create the grid synchronizers for each neighborhood
void createNeighborhoodSynchronizers();
/// compute the weights in each neighborhood for non-local averaging
void computeWeights();
/// compute the weights in each neighborhood for non-local averaging
void updatePairLists();
/// average the non-local variables
void averageInternals(const GhostType & ghost_type = _not_ghost);
/// update the flattened version of the weight function internals
void updateWeightFunctionInternals();
+
protected:
/// create a new neighborhood for a given domain ID
void createNeighborhood(const ID & weight_func, const ID & neighborhood);
/// set the values of the jacobians
void setJacobians(const FEEngine & fe_engine, const ElementKind & kind);
/// allocation of eelment type maps
// void initElementTypeMap(UInt nb_component,
// ElementTypeMapReal & element_map,
// const FEEngine & fe_engine,
// const ElementKind el_kind = _ek_regular);
/// resizing of element type maps
void resizeElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
const FEEngine & fee,
const ElementKind el_kind = _ek_regular);
/// remove integration points from element type maps
void removeIntegrationPointsFromMap(
const ElementTypeMapArray<UInt> & new_numbering, UInt nb_component,
ElementTypeMapReal & element_map, const FEEngine & fee,
const ElementKind el_kind = _ek_regular);
/// allocate the non-local variables
void initNonLocalVariables();
/// cleanup unneccessary ghosts
- void cleanupExtraGhostElements();//ElementTypeMap<UInt> & nb_ghost_protected);
+ void
+ cleanupExtraGhostElements(); // ElementTypeMap<UInt> & nb_ghost_protected);
/* ------------------------------------------------------------------------ */
/* DataAccessor kind of interface */
/* ------------------------------------------------------------------------ */
public:
/// get Nb data for synchronization in parallel
UInt getNbData(const Array<Element> & elements, const ID & id) const;
/// pack data for synchronization in parallel
void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
const ID & id) const;
/// unpack data for synchronization in parallel
void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
const ID & id) const;
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event) override;
void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) override;
void onElementsChanged(const Array<Element> &, const Array<Element> &,
const ElementTypeMapArray<UInt> &,
const ChangedElementsEvent &) override {}
void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override {}
void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
const RemovedNodesEvent &) override{};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
AKANTU_GET_MACRO(Model, model, const Model &);
AKANTU_GET_MACRO_NOT_CONST(Model, model, Model &);
AKANTU_GET_MACRO_NOT_CONST(Volumes, volumes, ElementTypeMapReal &)
AKANTU_GET_MACRO(NbStressCalls, compute_stress_calls, UInt);
/// return the fem object associated with a provided name
inline NonLocalNeighborhoodBase & getNeighborhood(const ID & name) const;
inline const Array<Real> & getJacobians(const ElementType & type,
const GhostType & ghost_type) {
return *jacobians(type, ghost_type);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the spatial dimension
const UInt spatial_dimension;
protected:
/// the non-local neighborhoods present
NeighborhoodMap neighborhoods;
/// list of all the non-local materials in the model
// std::vector<ID> non_local_materials;
struct NonLocalVariable {
NonLocalVariable(const ID & variable_name, const ID & nl_variable_name,
const ID & id, UInt nb_component)
: local(variable_name, id, 0), non_local(nl_variable_name, id, 0),
nb_component(nb_component) {}
ElementTypeMapReal local;
ElementTypeMapReal non_local;
UInt nb_component;
};
/// the non-local variables associated to a certain neighborhood
std::map<ID, std::unique_ptr<NonLocalVariable>> non_local_variables;
/// reference to the model
Model & model;
/// jacobians for all the elements in the mesh
ElementTypeMap<const Array<Real> *> jacobians;
/// store the position of the quadrature points
ElementTypeMapReal integration_points_positions;
/// store the volume of each quadrature point for the non-local weight
/// normalization
ElementTypeMapReal volumes;
/// counter for computeStress calls
UInt compute_stress_calls;
/// map to store weight function types from input file
std::map<ID, ParserSection> weight_function_types;
/// map to store the internals needed by the weight functions
std::map<ID, std::unique_ptr<ElementTypeMapReal>> weight_function_internals;
/* --------------------------------------------------------------------------
*/
/// the following are members needed to make this processor participate in the
/// grid creation of neighborhoods he doesn't own as a member. For details see
/// createGridSynchronizers function
/// synchronizer registry for dummy grid synchronizers
std::unique_ptr<SynchronizerRegistry> dummy_registry;
/// map of dummy synchronizers
std::map<ID, std::unique_ptr<GridSynchronizer>> dummy_synchronizers;
/// dummy spatial grid
std::unique_ptr<SpatialGrid<IntegrationPoint>> dummy_grid;
/// create a set of all neighborhoods present in the simulation
std::set<ID> global_neighborhoods;
class DummyDataAccessor : public DataAccessor<Element> {
public:
inline UInt getNbData(const Array<Element> &,
const SynchronizationTag &) const override {
return 0;
};
inline void packData(CommunicationBuffer &, const Array<Element> &,
const SynchronizationTag &) const override{};
inline void unpackData(CommunicationBuffer &, const Array<Element> &,
const SynchronizationTag &) override{};
};
DummyDataAccessor dummy_accessor;
/* ------------------------------------------------------------------------ */
NonLocalManagerCallback * callback;
};
} // namespace akantu
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "non_local_manager_inline_impl.cc"
#endif /* __AKANTU_NON_LOCAL_MANAGER_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood.hh b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
index b92eb3e3c..a847e9947 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
@@ -1,135 +1,136 @@
/**
* @file non_local_neighborhood.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Wed Nov 25 2015
*
* @brief Non-local neighborhood for non-local averaging based on
* weight function
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__
#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__
/* -------------------------------------------------------------------------- */
#include "base_weight_function.hh"
#include "non_local_neighborhood_base.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class NonLocalManager;
class BaseWeightFunction;
} // namespace akantu
namespace akantu {
template <class WeightFunction = BaseWeightFunction>
class NonLocalNeighborhood : public NonLocalNeighborhoodBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLocalNeighborhood(NonLocalManager & manager,
const ElementTypeMapReal & quad_coordinates,
const ID & id = "neighborhood",
const MemoryID & memory_id = 0);
~NonLocalNeighborhood() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// compute the weights for non-local averaging
void computeWeights() override;
/// save the pair of weights in a file
void saveWeights(const std::string & filename) const override;
/// compute the non-local counter part for a given element type map
// compute the non-local counter part for a given element type map
- void weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
- ElementTypeMapReal & accumulated,
- UInt nb_degree_of_freedom,
- const GhostType & ghost_type2) const override;
+ void
+ weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
+ ElementTypeMapReal & accumulated,
+ UInt nb_degree_of_freedom,
+ const GhostType & ghost_type2) const override;
/// update the weights based on the weight function
void updateWeights() override;
/// register a new non-local variable in the neighborhood
- //void registerNonLocalVariable(const ID & id);
+ // void registerNonLocalVariable(const ID & id);
protected:
template <class Func>
inline void foreach_weight(const GhostType & ghost_type, Func && func);
template <class Func>
inline void foreach_weight(const GhostType & ghost_type, Func && func) const;
inline UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) override;
/* ------------------------------------------------------------------------ */
/* Accessor */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(NonLocalManager, non_local_manager, const NonLocalManager &);
AKANTU_GET_MACRO_NOT_CONST(NonLocalManager, non_local_manager,
NonLocalManager &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// Pointer to non-local manager class
NonLocalManager & non_local_manager;
/// the weights associated to the pairs
std::array<std::unique_ptr<Array<Real>>, 2> pair_weight;
/// weight function
std::unique_ptr<WeightFunction> weight_function;
};
} // namespace akantu
/* -------------------------------------------------------------------------- */
/* Implementation of template functions */
/* -------------------------------------------------------------------------- */
#include "non_local_neighborhood_tmpl.hh"
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "non_local_neighborhood_inline_impl.cc"
#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
index 198afa5c1..81cf8934a 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
@@ -1,117 +1,117 @@
/**
* @file non_local_neighborhood_base.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Wed Nov 25 2015
*
* @brief Implementation of non-local neighborhood base
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_local_neighborhood_base.hh"
#include "grid_synchronizer.hh"
#include "model.hh"
/* -------------------------------------------------------------------------- */
#include <memory>
namespace akantu {
/* -------------------------------------------------------------------------- */
NonLocalNeighborhoodBase::NonLocalNeighborhoodBase(
Model & model, const ElementTypeMapReal & quad_coordinates, const ID & id,
const MemoryID & memory_id)
: NeighborhoodBase(model, quad_coordinates, id, memory_id),
Parsable(ParserType::_non_local, id) {
AKANTU_DEBUG_IN();
this->registerParam("radius", neighborhood_radius, 100.,
_pat_parsable | _pat_readable, "Non local radius");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
NonLocalNeighborhoodBase::~NonLocalNeighborhoodBase() = default;
/* -------------------------------------------------------------------------- */
void NonLocalNeighborhoodBase::createGridSynchronizer() {
this->is_creating_grid = true;
this->grid_synchronizer = std::make_unique<GridSynchronizer>(
this->model.getMesh(), *spatial_grid, *this,
std::set<SynchronizationTag>{_gst_mnl_weight, _gst_mnl_for_average},
std::string(getID() + ":grid_synchronizer"), this->memory_id, false);
this->is_creating_grid = false;
}
/* -------------------------------------------------------------------------- */
void NonLocalNeighborhoodBase::synchronize(
DataAccessor<Element> & data_accessor, const SynchronizationTag & tag) {
if (not grid_synchronizer)
return;
grid_synchronizer->synchronizeOnce(data_accessor, tag);
}
/* -------------------------------------------------------------------------- */
void NonLocalNeighborhoodBase::cleanupExtraGhostElements(
std::set<Element> & relevant_ghost_elements) {
for (auto && pair : pair_list[_ghost]) {
const auto & q2 = pair.second;
relevant_ghost_elements.insert(q2);
}
Array<Element> ghosts_to_erase(0);
auto & mesh = this->model.getMesh();
Element element;
element.ghost_type = _ghost;
auto end = relevant_ghost_elements.end();
for (auto & type : mesh.elementTypes(spatial_dimension, _ghost)) {
element.type = type;
UInt nb_ghost_elem = mesh.getNbElement(type, _ghost);
for (UInt g = 0; g < nb_ghost_elem; ++g) {
element.element = g;
if (relevant_ghost_elements.find(element) == end) {
ghosts_to_erase.push_back(element);
}
}
}
/// remove the unneccessary ghosts from the synchronizer
- //this->grid_synchronizer->removeElements(ghosts_to_erase);
+ // this->grid_synchronizer->removeElements(ghosts_to_erase);
mesh.eraseElements(ghosts_to_erase);
}
/* -------------------------------------------------------------------------- */
void NonLocalNeighborhoodBase::registerNonLocalVariable(const ID & id) {
this->non_local_variables.insert(id);
}
} // namespace akantu
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
index 467869e69..3d6cfbe06 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
@@ -1,130 +1,128 @@
/**
* @file non_local_neighborhood_base.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Wed Nov 25 2015
*
* @brief Non-local neighborhood base class
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "neighborhood_base.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
namespace akantu {
class Model;
}
/* -------------------------------------------------------------------------- */
namespace akantu {
class NonLocalNeighborhoodBase : public NeighborhoodBase, public Parsable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLocalNeighborhoodBase(Model & model,
const ElementTypeMapReal & quad_coordinates,
const ID & id = "non_local_neighborhood",
const MemoryID & memory_id = 0);
~NonLocalNeighborhoodBase() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// create grid synchronizer and exchange ghost cells
void createGridSynchronizer() override;
void synchronize(DataAccessor<Element> & data_accessor,
const SynchronizationTag & tag) override;
/// compute weights, for instance needed for non-local damage computation
virtual void computeWeights(){};
// compute the non-local counter part for a given element type map
virtual void
weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
ElementTypeMapReal & accumulated,
UInt nb_degree_of_freedom,
const GhostType & ghost_type2) const = 0;
/// update the weights for the non-local averaging
virtual void updateWeights() = 0;
/// update the weights for the non-local averaging
- virtual void saveWeights(const std::string &) const {
- AKANTU_TO_IMPLEMENT();
- }
+ virtual void saveWeights(const std::string &) const { AKANTU_TO_IMPLEMENT(); }
/// register a new non-local variable in the neighborhood
virtual void registerNonLocalVariable(const ID & id);
/// clean up the unneccessary ghosts
void cleanupExtraGhostElements(std::set<Element> & relevant_ghost_elements);
protected:
/// create the grid
void createGrid();
/* --------------------------------------------------------------------------
*/
/* DataAccessor inherited members */
/* --------------------------------------------------------------------------
*/
public:
inline UInt getNbData(const Array<Element> &,
const SynchronizationTag &) const override {
return 0;
}
inline void packData(CommunicationBuffer &, const Array<Element> &,
const SynchronizationTag &) const override {}
inline void unpackData(CommunicationBuffer &, const Array<Element> &,
const SynchronizationTag &) override {}
/* --------------------------------------------------------------------------
*/
/* Accessors */
/* --------------------------------------------------------------------------
*/
public:
AKANTU_GET_MACRO(NonLocalVariables, non_local_variables,
const std::set<ID> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// list of non-local variables associated to the neighborhood
std::set<ID> non_local_variables;
};
} // namespace akantu
#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
index 78532e1de..e6283a065 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
@@ -1,280 +1,276 @@
/**
* @file non_local_neighborhood_tmpl.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Sep 28 2015
* @date last modification: Wed Nov 25 2015
*
* @brief Implementation of class non-local neighborhood
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include "communicator.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
template <class Func>
inline void NonLocalNeighborhood<WeightFunction>::foreach_weight(
const GhostType & ghost_type, Func && func) {
auto weight_it =
pair_weight[ghost_type]->begin(pair_weight[ghost_type]->getNbComponent());
for (auto & pair : pair_list[ghost_type]) {
std::forward<decltype(func)>(func)(pair.first, pair.second, *weight_it);
++weight_it;
}
}
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
template <class Func>
inline void NonLocalNeighborhood<WeightFunction>::foreach_weight(
const GhostType & ghost_type, Func && func) const {
auto weight_it =
pair_weight[ghost_type]->begin(pair_weight[ghost_type]->getNbComponent());
for (auto & pair : pair_list[ghost_type]) {
std::forward<decltype(func)>(func)(pair.first, pair.second, *weight_it);
++weight_it;
}
}
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
NonLocalNeighborhood<WeightFunction>::NonLocalNeighborhood(
NonLocalManager & manager, const ElementTypeMapReal & quad_coordinates,
const ID & id, const MemoryID & memory_id)
: NonLocalNeighborhoodBase(manager.getModel(), quad_coordinates, id,
memory_id),
non_local_manager(manager) {
AKANTU_DEBUG_IN();
this->weight_function = std::make_unique<WeightFunction>(manager);
this->registerSubSection(ParserType::_weight_function, "weight_parameter",
*weight_function);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
NonLocalNeighborhood<WeightFunction>::~NonLocalNeighborhood() = default;
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::computeWeights() {
AKANTU_DEBUG_IN();
this->weight_function->setRadius(this->neighborhood_radius);
Vector<Real> q1_coord(this->spatial_dimension);
Vector<Real> q2_coord(this->spatial_dimension);
UInt nb_weights_per_pair = 2; /// w1: q1->q2, w2: q2->q1
/// get the elementtypemap for the neighborhood volume for each quadrature
/// point
ElementTypeMapReal & quadrature_points_volumes =
this->non_local_manager.getVolumes();
/// update the internals of the weight function if applicable (not
/// all the weight functions have internals and do noting in that
/// case)
weight_function->updateInternals();
for (auto ghost_type : ghost_types) {
/// allocate the array to store the weight, if it doesn't exist already
if (!(pair_weight[ghost_type])) {
pair_weight[ghost_type] =
std::make_unique<Array<Real>>(0, nb_weights_per_pair);
}
/// resize the array to the correct size
pair_weight[ghost_type]->resize(pair_list[ghost_type].size());
/// set entries to zero
pair_weight[ghost_type]->clear();
/// loop over all pairs in the current pair list array and their
/// corresponding weights
auto first_pair = pair_list[ghost_type].begin();
auto last_pair = pair_list[ghost_type].end();
- auto weight_it =
- pair_weight[ghost_type]->begin(nb_weights_per_pair);
+ auto weight_it = pair_weight[ghost_type]->begin(nb_weights_per_pair);
// Compute the weights
for (; first_pair != last_pair; ++first_pair, ++weight_it) {
Vector<Real> & weight = *weight_it;
const IntegrationPoint & q1 = first_pair->first;
const IntegrationPoint & q2 = first_pair->second;
/// get the coordinates for the given pair of quads
- auto coords_type_1_it =
- this->quad_coordinates(q1.type, q1.ghost_type)
- .begin(this->spatial_dimension);
+ auto coords_type_1_it = this->quad_coordinates(q1.type, q1.ghost_type)
+ .begin(this->spatial_dimension);
q1_coord = coords_type_1_it[q1.global_num];
- auto coords_type_2_it =
- this->quad_coordinates(q2.type, q2.ghost_type)
- .begin(this->spatial_dimension);
+ auto coords_type_2_it = this->quad_coordinates(q2.type, q2.ghost_type)
+ .begin(this->spatial_dimension);
q2_coord = coords_type_2_it[q2.global_num];
Array<Real> & quad_volumes_1 =
quadrature_points_volumes(q1.type, q1.ghost_type);
const Array<Real> & jacobians_2 =
this->non_local_manager.getJacobians(q2.type, q2.ghost_type);
const Real & q2_wJ = jacobians_2(q2.global_num);
/// compute distance between the two quadrature points
Real r = q1_coord.distance(q2_coord);
/// compute the weight for averaging on q1 based on the distance
Real w1 = this->weight_function->operator()(r, q1, q2);
weight(0) = q2_wJ * w1;
quad_volumes_1(q1.global_num) += weight(0);
if (q2.ghost_type != _ghost && q1.global_num != q2.global_num) {
const Array<Real> & jacobians_1 =
this->non_local_manager.getJacobians(q1.type, q1.ghost_type);
Array<Real> & quad_volumes_2 =
quadrature_points_volumes(q2.type, q2.ghost_type);
/// compute the weight for averaging on q2
const Real & q1_wJ = jacobians_1(q1.global_num);
Real w2 = this->weight_function->operator()(r, q2, q1);
weight(1) = q1_wJ * w2;
quad_volumes_2(q2.global_num) += weight(1);
} else
weight(1) = 0.;
}
}
/// normalize the weights
for (auto ghost_type : ghost_types) {
- foreach_weight(ghost_type, [&](
- const auto & q1, const auto & q2,
+ foreach_weight(ghost_type, [&](const auto & q1, const auto & q2,
auto & weight) {
auto & quad_volumes_1 = quadrature_points_volumes(q1.type, q1.ghost_type);
auto & quad_volumes_2 = quadrature_points_volumes(q2.type, q2.ghost_type);
Real q1_volume = quad_volumes_1(q1.global_num);
auto ghost_type2 = q2.ghost_type;
weight(0) *= 1. / q1_volume;
if (ghost_type2 != _ghost) {
Real q2_volume = quad_volumes_2(q2.global_num);
weight(1) *= 1. / q2_volume;
}
});
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::saveWeights(
const std::string & filename) const {
std::ofstream pout;
std::stringstream sstr;
const Communicator & comm = model.getMesh().getCommunicator();
Int prank = comm.whoAmI();
sstr << filename << "." << prank;
pout.open(sstr.str().c_str());
for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
auto ghost_type = (GhostType)gt;
AKANTU_DEBUG_ASSERT((pair_weight[ghost_type]),
"the weights have not been computed yet");
Array<Real> & weights = *(pair_weight[ghost_type]);
auto weights_it = weights.begin(2);
for (UInt i = 0; i < weights.size(); ++i, ++weights_it)
pout << "w1: " << (*weights_it)(0) << " w2: " << (*weights_it)(1)
<< std::endl;
}
}
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::weightedAverageOnNeighbours(
const ElementTypeMapReal & to_accumulate, ElementTypeMapReal & accumulated,
UInt nb_degree_of_freedom, const GhostType & ghost_type2) const {
auto it = non_local_variables.find(accumulated.getName());
// do averaging only for variables registered in the neighborhood
if (it == non_local_variables.end())
return;
foreach_weight(
ghost_type2,
[ghost_type2, nb_degree_of_freedom, &to_accumulate,
&accumulated](const auto & q1, const auto & q2, auto & weight) {
const Vector<Real> to_acc_1 =
to_accumulate(q1.type, q1.ghost_type)
.begin(nb_degree_of_freedom)[q1.global_num];
const Vector<Real> to_acc_2 =
to_accumulate(q2.type, q2.ghost_type)
.begin(nb_degree_of_freedom)[q2.global_num];
Vector<Real> acc_1 = accumulated(q1.type, q1.ghost_type)
.begin(nb_degree_of_freedom)[q1.global_num];
Vector<Real> acc_2 = accumulated(q2.type, q2.ghost_type)
.begin(nb_degree_of_freedom)[q2.global_num];
acc_1 += weight(0) * to_acc_2;
if (ghost_type2 != _ghost) {
acc_2 += weight(1) * to_acc_1;
}
});
}
/* -------------------------------------------------------------------------- */
template <class WeightFunction>
void NonLocalNeighborhood<WeightFunction>::updateWeights() {
// Update the weights for the non local variable averaging
if (this->weight_function->getUpdateRate() &&
(this->non_local_manager.getNbStressCalls() %
this->weight_function->getUpdateRate() ==
0)) {
SynchronizerRegistry::synchronize(_gst_mnl_weight);
this->computeWeights();
}
}
} // namespace akantu
#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL__ */
diff --git a/src/model/dof_manager.hh b/src/model/dof_manager.hh
index a6e5d903f..981501a3c 100644
--- a/src/model/dof_manager.hh
+++ b/src/model/dof_manager.hh
@@ -1,472 +1,475 @@
/**
* @file dof_manager.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Jul 22 11:43:43 2015
*
* @brief Class handling the different types of dofs
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "aka_memory.hh"
#include "aka_factory.hh"
+#include "aka_memory.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#include <map>
#include <set>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DOF_MANAGER_HH__
#define __AKANTU_DOF_MANAGER_HH__
namespace akantu {
class TermsToAssemble;
class NonLinearSolver;
class TimeStepSolver;
class SparseMatrix;
} // namespace akantu
namespace akantu {
class DOFManager : protected Memory, protected MeshEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DOFManager(const ID & id = "dof_manager", const MemoryID & memory_id = 0);
DOFManager(Mesh & mesh, const ID & id = "dof_manager",
const MemoryID & memory_id = 0);
~DOFManager() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
private:
/// common function to help registering dofs
void registerDOFsInternal(const ID & dof_id, Array<Real> & dofs_array);
public:
/// register an array of degree of freedom
virtual void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
const DOFSupportType & support_type);
/// the dof as an implied type of _dst_nodal and is defined only on a subset
/// of nodes
virtual void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
const ID & group_support);
/// register an array of previous values of the degree of freedom
virtual void registerDOFsPrevious(const ID & dof_id,
Array<Real> & dofs_array);
/// register an array of increment of degree of freedom
virtual void registerDOFsIncrement(const ID & dof_id,
Array<Real> & dofs_array);
/// register an array of derivatives for a particular dof array
virtual void registerDOFsDerivative(const ID & dof_id, UInt order,
Array<Real> & dofs_derivative);
/// register array representing the blocked degree of freedoms
virtual void registerBlockedDOFs(const ID & dof_id,
Array<bool> & blocked_dofs);
/// Assemble an array to the global residual array
virtual void assembleToResidual(const ID & dof_id,
const Array<Real> & array_to_assemble,
Real scale_factor = 1.) = 0;
/// Assemble an array to the global lumped matrix array
virtual void assembleToLumpedMatrix(const ID & dof_id,
const Array<Real> & array_to_assemble,
const ID & lumped_mtx,
Real scale_factor = 1.) = 0;
/**
* Assemble elementary values to a local array of the size nb_nodes *
* nb_dof_per_node. The dof number is implicitly considered as
* conn(el, n) * nb_nodes_per_element + d.
* With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
**/
virtual void assembleElementalArrayLocalArray(
const Array<Real> & elementary_vect, Array<Real> & array_assembeled,
const ElementType & type, const GhostType & ghost_type,
Real scale_factor = 1.,
const Array<UInt> & filter_elements = empty_filter);
/**
* Assemble elementary values to the global residual array. The dof number is
* implicitly considered as conn(el, n) * nb_nodes_per_element + d.
* With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
**/
virtual void assembleElementalArrayToResidual(
const ID & dof_id, const Array<Real> & elementary_vect,
const ElementType & type, const GhostType & ghost_type,
Real scale_factor = 1.,
const Array<UInt> & filter_elements = empty_filter);
/**
* Assemble elementary values to a global array corresponding to a lumped
* matrix
*/
virtual void assembleElementalArrayToLumpedMatrix(
const ID & dof_id, const Array<Real> & elementary_vect,
const ID & lumped_mtx, const ElementType & type,
const GhostType & ghost_type, Real scale_factor = 1.,
const Array<UInt> & filter_elements = empty_filter);
/**
* Assemble elementary values to the global residual array. The dof number is
* implicitly considered as conn(el, n) * nb_nodes_per_element + d. With 0 <
* n < nb_nodes_per_element and 0 < d < nb_dof_per_node
**/
virtual void assembleElementalMatricesToMatrix(
const ID & matrix_id, const ID & dof_id,
const Array<Real> & elementary_mat, const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const MatrixType & elemental_matrix_type = _symmetric,
const Array<UInt> & filter_elements = empty_filter) = 0;
/// multiply a vector by a matrix and assemble the result to the residual
virtual void assembleMatMulVectToResidual(const ID & dof_id, const ID & A_id,
const Array<Real> & x,
Real scale_factor = 1) = 0;
/// multiply the dofs by a matrix and assemble the result to the residual
virtual void assembleMatMulDOFsToResidual(const ID & A_id,
Real scale_factor = 1);
/// multiply a vector by a lumped matrix and assemble the result to the
/// residual
virtual void assembleLumpedMatMulVectToResidual(const ID & dof_id,
const ID & A_id,
const Array<Real> & x,
Real scale_factor = 1) = 0;
/// assemble coupling terms between to dofs
virtual void assemblePreassembledMatrix(const ID & dof_id_m,
const ID & dof_id_n,
const ID & matrix_id,
const TermsToAssemble & terms) = 0;
/// sets the residual to 0
virtual void clearResidual() = 0;
/// sets the matrix to 0
virtual void clearMatrix(const ID & mtx) = 0;
/// sets the lumped matrix to 0
virtual void clearLumpedMatrix(const ID & mtx) = 0;
/// splits the solution storage from a global view to the per dof storages
void splitSolutionPerDOFs();
/// extract a lumped matrix part corresponding to a given dof
virtual void getLumpedMatrixPerDOFs(const ID & dof_id, const ID & lumped_mtx,
Array<Real> & lumped) = 0;
protected:
/// minimum functionality to implement per derived version of the DOFManager
/// to allow the splitSolutionPerDOFs function to work
virtual void getSolutionPerDOFs(const ID & dof_id,
Array<Real> & solution_array) = 0;
protected:
/* ------------------------------------------------------------------------ */
/// register a matrix
SparseMatrix & registerSparseMatrix(const ID & matrix_id,
std::unique_ptr<SparseMatrix> & matrix);
/// register a non linear solver instantiated by a derived class
NonLinearSolver &
registerNonLinearSolver(const ID & non_linear_solver_id,
std::unique_ptr<NonLinearSolver> & non_linear_solver);
/// register a time step solver instantiated by a derived class
TimeStepSolver &
registerTimeStepSolver(const ID & time_step_solver_id,
std::unique_ptr<TimeStepSolver> & time_step_solver);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get the equation numbers corresponding to a dof_id. This might be used to
/// access the matrix.
inline const Array<UInt> & getEquationsNumbers(const ID & dof_id) const;
/// Global number of dofs
AKANTU_GET_MACRO(SystemSize, this->system_size, UInt);
/// Local number of dofs
AKANTU_GET_MACRO(LocalSystemSize, this->local_system_size, UInt);
/// Retrieve all the registered DOFs
std::vector<ID> getDOFIDs() const;
/* ------------------------------------------------------------------------ */
/* DOFs and derivatives accessors */
/* ------------------------------------------------------------------------ */
/// Get a reference to the registered dof array for a given id
inline Array<Real> & getDOFs(const ID & dofs_id);
/// Get the support type of a given dof
inline DOFSupportType getSupportType(const ID & dofs_id) const;
/// are the dofs registered
inline bool hasDOFs(const ID & dofs_id) const;
/// Get a reference to the registered dof derivatives array for a given id
inline Array<Real> & getDOFsDerivatives(const ID & dofs_id, UInt order);
/// Does the dof has derivatives
inline bool hasDOFsDerivatives(const ID & dofs_id, UInt order) const;
/// Get a reference to the blocked dofs array registered for the given id
inline const Array<bool> & getBlockedDOFs(const ID & dofs_id) const;
/// Does the dof has a blocked array
inline bool hasBlockedDOFs(const ID & dofs_id) const;
/// Get a reference to the registered dof increment array for a given id
inline Array<Real> & getDOFsIncrement(const ID & dofs_id);
/// Does the dof has a increment array
inline bool hasDOFsIncrement(const ID & dofs_id) const;
/// Does the dof has a previous array
inline Array<Real> & getPreviousDOFs(const ID & dofs_id);
/// Get a reference to the registered dof array for previous step values a
/// given id
inline bool hasPreviousDOFs(const ID & dofs_id) const;
/// saves the values from dofs to previous dofs
virtual void savePreviousDOFs(const ID & dofs_id);
/// Get a reference to the solution array registered for the given id
inline const Array<Real> & getSolution(const ID & dofs_id) const;
/* ------------------------------------------------------------------------ */
/* Matrices accessors */
/* ------------------------------------------------------------------------ */
/// Get an instance of a new SparseMatrix
virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
const MatrixType & matrix_type) = 0;
/// Get an instance of a new SparseMatrix as a copy of the SparseMatrix
/// matrix_to_copy_id
virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
const ID & matrix_to_copy_id) = 0;
/// Get the reference of an existing matrix
SparseMatrix & getMatrix(const ID & matrix_id);
/// check if the given matrix exists
bool hasMatrix(const ID & matrix_id) const;
/// Get an instance of a new lumped matrix
virtual Array<Real> & getNewLumpedMatrix(const ID & matrix_id);
/// Get the lumped version of a given matrix
const Array<Real> & getLumpedMatrix(const ID & matrix_id) const;
/// Get the lumped version of a given matrix
Array<Real> & getLumpedMatrix(const ID & matrix_id);
/// check if the given matrix exists
bool hasLumpedMatrix(const ID & matrix_id) const;
/* ------------------------------------------------------------------------ */
/* Non linear system solver */
/* ------------------------------------------------------------------------ */
/// Get instance of a non linear solver
virtual NonLinearSolver & getNewNonLinearSolver(
const ID & nls_solver_id,
const NonLinearSolverType & _non_linear_solver_type) = 0;
/// get instance of a non linear solver
virtual NonLinearSolver & getNonLinearSolver(const ID & nls_solver_id);
/// check if the given solver exists
bool hasNonLinearSolver(const ID & solver_id) const;
/* ------------------------------------------------------------------------ */
/* Time-Step Solver */
/* ------------------------------------------------------------------------ */
/// Get instance of a time step solver
virtual TimeStepSolver &
getNewTimeStepSolver(const ID & time_step_solver_id,
const TimeStepSolverType & type,
NonLinearSolver & non_linear_solver) = 0;
/// get instance of a time step solver
virtual TimeStepSolver & getTimeStepSolver(const ID & time_step_solver_id);
/// check if the given solver exists
bool hasTimeStepSolver(const ID & solver_id) const;
/* ------------------------------------------------------------------------ */
const Mesh & getMesh() {
if (mesh) {
return *mesh;
} else {
AKANTU_EXCEPTION("No mesh registered in this dof manager");
}
}
/* ------------------------------------------------------------------------ */
AKANTU_GET_MACRO(Communicator, communicator, const auto &);
AKANTU_GET_MACRO_NOT_CONST(Communicator, communicator, auto &);
/* ------------------------------------------------------------------------ */
/* MeshEventHandler interface */
/* ------------------------------------------------------------------------ */
protected:
/// helper function for the DOFManager::onNodesAdded method
virtual std::pair<UInt, UInt> updateNodalDOFs(const ID & dof_id,
const Array<UInt> & nodes_list);
+
public:
/// function to implement to react on akantu::NewNodesEvent
void onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event) override;
/// function to implement to react on akantu::RemovedNodesEvent
void onNodesRemoved(const Array<UInt> & nodes_list,
const Array<UInt> & new_numbering,
const RemovedNodesEvent & event) override;
/// function to implement to react on akantu::NewElementsEvent
void onElementsAdded(const Array<Element> & elements_list,
const NewElementsEvent & event) override;
/// function to implement to react on akantu::RemovedElementsEvent
void onElementsRemoved(const Array<Element> & elements_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event) override;
/// function to implement to react on akantu::ChangedElementsEvent
void onElementsChanged(const Array<Element> & old_elements_list,
const Array<Element> & new_elements_list,
const ElementTypeMapArray<UInt> & new_numbering,
const ChangedElementsEvent & event) override;
protected:
struct DOFData;
inline DOFData & getDOFData(const ID & dof_id);
inline const DOFData & getDOFData(const ID & dof_id) const;
template <class _DOFData>
inline _DOFData & getDOFDataTyped(const ID & dof_id);
template <class _DOFData>
inline const _DOFData & getDOFDataTyped(const ID & dof_id) const;
virtual DOFData & getNewDOFData(const ID & dof_id);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// dof representations in the dof manager
struct DOFData {
DOFData() = delete;
explicit DOFData(const ID & dof_id);
virtual ~DOFData();
/// DOF support type (nodal, general) this is needed to determine how the
/// dof are shared among processors
DOFSupportType support_type;
ID group_support;
/// Degree of freedom array
Array<Real> * dof;
/// Blocked degree of freedoms array
Array<bool> * blocked_dofs;
/// Degree of freedoms increment
Array<Real> * increment;
/// Degree of freedoms at previous step
Array<Real> * previous;
/// Solution associated to the dof
Array<Real> solution;
/// local numbering equation numbers
Array<UInt> local_equation_number;
/* ---------------------------------------------------------------------- */
/* data for dynamic simulations */
/* ---------------------------------------------------------------------- */
/// Degree of freedom derivatives arrays
std::vector<Array<Real> *> dof_derivatives;
};
/// type to store dofs information
using DOFStorage = std::map<ID, std::unique_ptr<DOFData>>;
/// type to store all the matrices
using SparseMatricesMap = std::map<ID, std::unique_ptr<SparseMatrix>>;
/// type to store all the lumped matrices
using LumpedMatricesMap = std::map<ID, std::unique_ptr<Array<Real>>>;
/// type to store all the non linear solver
using NonLinearSolversMap = std::map<ID, std::unique_ptr<NonLinearSolver>>;
/// type to store all the time step solver
using TimeStepSolversMap = std::map<ID, std::unique_ptr<TimeStepSolver>>;
/// store a reference to the dof arrays
DOFStorage dofs;
/// list of sparse matrices that where created
SparseMatricesMap matrices;
/// list of lumped matrices
LumpedMatricesMap lumped_matrices;
/// non linear solvers storage
NonLinearSolversMap non_linear_solvers;
/// time step solvers storage
TimeStepSolversMap time_step_solvers;
/// reference to the underlying mesh
Mesh * mesh{nullptr};
/// Total number of degrees of freedom (size with the ghosts)
UInt local_system_size{0};
/// Number of purely local dofs (size without the ghosts)
UInt pure_local_system_size{0};
/// Total number of degrees of freedom
UInt system_size{0};
/// Communicator used for this manager, should be the same as in the mesh if a
/// mesh is registered
Communicator & communicator;
};
-using DefaultDOFManagerFactory = Factory<DOFManager, ID, const ID &, const MemoryID &>;
-using DOFManagerFactory = Factory<DOFManager, ID, Mesh &, const ID &, const MemoryID &>;
+using DefaultDOFManagerFactory =
+ Factory<DOFManager, ID, const ID &, const MemoryID &>;
+using DOFManagerFactory =
+ Factory<DOFManager, ID, Mesh &, const ID &, const MemoryID &>;
} // namespace akantu
#include "dof_manager_inline_impl.cc"
#endif /* __AKANTU_DOF_MANAGER_HH__ */
diff --git a/src/model/dof_manager_default.hh b/src/model/dof_manager_default.hh
index 588c00611..8acd160f9 100644
--- a/src/model/dof_manager_default.hh
+++ b/src/model/dof_manager_default.hh
@@ -1,360 +1,360 @@
/**
* @file dof_manager_default.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Aug 11 14:06:18 2015
*
* @brief Default implementation of the dof manager
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dof_manager.hh"
/* -------------------------------------------------------------------------- */
-#include <unordered_map>
#include <functional>
+#include <unordered_map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DOF_MANAGER_DEFAULT_HH__
#define __AKANTU_DOF_MANAGER_DEFAULT_HH__
namespace akantu {
class SparseMatrixAIJ;
class NonLinearSolverDefault;
class TimeStepSolverDefault;
class DOFSynchronizer;
} // namespace akantu
namespace akantu {
class DOFManagerDefault : public DOFManager {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DOFManagerDefault(const ID & id = "dof_manager_default",
const MemoryID & memory_id = 0);
DOFManagerDefault(Mesh & mesh, const ID & id = "dof_manager_default",
const MemoryID & memory_id = 0);
~DOFManagerDefault() override;
protected:
struct DOFDataDefault : public DOFData {
explicit DOFDataDefault(const ID & dof_id);
/// associated node for _dst_nodal dofs only
Array<UInt> associated_nodes;
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
private:
void registerDOFsInternal(const ID & dof_id, UInt nb_dofs,
UInt nb_pure_local_dofs);
public:
/// register an array of degree of freedom
void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
const DOFSupportType & support_type) override;
/// the dof as an implied type of _dst_nodal and is defined only on a subset
/// of nodes
void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
const ID & group_support) override;
/// Assemble an array to the global residual array
void assembleToResidual(const ID & dof_id,
const Array<Real> & array_to_assemble,
Real scale_factor = 1.) override;
/// Assemble an array to the global lumped matrix array
void assembleToLumpedMatrix(const ID & dof_id,
const Array<Real> & array_to_assemble,
const ID & lumped_mtx,
Real scale_factor = 1.) override;
/**
* Assemble elementary values to the global matrix. The dof number is
* implicitly considered as conn(el, n) * nb_nodes_per_element + d.
* With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
**/
void assembleElementalMatricesToMatrix(
const ID & matrix_id, const ID & dof_id,
const Array<Real> & elementary_mat, const ElementType & type,
const GhostType & ghost_type, const MatrixType & elemental_matrix_type,
const Array<UInt> & filter_elements) override;
/// multiply a vector by a matrix and assemble the result to the residual
void assembleMatMulVectToResidual(const ID & dof_id, const ID & A_id,
const Array<Real> & x,
Real scale_factor = 1) override;
/// multiply a vector by a lumped matrix and assemble the result to the
/// residual
void assembleLumpedMatMulVectToResidual(const ID & dof_id, const ID & A_id,
const Array<Real> & x,
Real scale_factor = 1) override;
/// assemble coupling terms between to dofs
void assemblePreassembledMatrix(const ID & dof_id_m, const ID & dof_id_n,
const ID & matrix_id,
const TermsToAssemble & terms) override;
protected:
/// Assemble an array to the global residual array
template <typename T>
void assembleToGlobalArray(const ID & dof_id,
const Array<T> & array_to_assemble,
Array<T> & global_array, T scale_factor);
public:
/// clear the residual
void clearResidual() override;
/// sets the matrix to 0
void clearMatrix(const ID & mtx) override;
/// sets the lumped matrix to 0
void clearLumpedMatrix(const ID & mtx) override;
/// update the global dofs vector
virtual void updateGlobalBlockedDofs();
/// apply boundary conditions to jacobian matrix
virtual void applyBoundary(const ID & matrix_id = "J");
// void getEquationsNumbers(const ID & dof_id,
// Array<UInt> & equation_numbers) override;
protected:
/// Get local part of an array corresponding to a given dofdata
template <typename T>
void getArrayPerDOFs(const ID & dof_id, const Array<T> & global_array,
Array<T> & local_array) const;
/// Get the part of the solution corresponding to the dof_id
void getSolutionPerDOFs(const ID & dof_id,
Array<Real> & solution_array) override;
/// fill a Vector with the equation numbers corresponding to the given
/// connectivity
inline void extractElementEquationNumber(
const Array<UInt> & equation_numbers, const Vector<UInt> & connectivity,
UInt nb_degree_of_freedom, Vector<UInt> & local_equation_number);
public:
/// extract a lumped matrix part corresponding to a given dof
void getLumpedMatrixPerDOFs(const ID & dof_id, const ID & lumped_mtx,
Array<Real> & lumped) override;
private:
/// Add a symmetric matrices to a symmetric sparse matrix
void addSymmetricElementalMatrixToSymmetric(
SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
const Vector<UInt> & equation_numbers, UInt max_size);
/// Add a unsymmetric matrices to a symmetric sparse matrix (i.e. cohesive
/// elements)
void addUnsymmetricElementalMatrixToSymmetric(
SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
const Vector<UInt> & equation_numbers, UInt max_size);
/// Add a matrices to a unsymmetric sparse matrix
void addElementalMatrixToUnsymmetric(SparseMatrixAIJ & matrix,
const Matrix<Real> & element_mat,
const Vector<UInt> & equation_numbers,
UInt max_size);
void addToProfile(const ID & matrix_id, const ID & dof_id,
const ElementType & type, const GhostType & ghost_type);
/* ------------------------------------------------------------------------ */
/* MeshEventHandler interface */
/* ------------------------------------------------------------------------ */
protected:
std::pair<UInt, UInt>
updateNodalDOFs(const ID & dof_id, const Array<UInt> & nodes_list) override;
private:
void updateDOFsData(DOFDataDefault & dof_data, UInt nb_new_local_dofs,
UInt nb_new_pure_local,
const std::function<UInt(UInt)> & getNode);
public:
/// function to implement to react on akantu::NewNodesEvent
void onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event) override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get an instance of a new SparseMatrix
SparseMatrix & getNewMatrix(const ID & matrix_id,
const MatrixType & matrix_type) override;
/// Get an instance of a new SparseMatrix as a copy of the SparseMatrix
/// matrix_to_copy_id
SparseMatrix & getNewMatrix(const ID & matrix_id,
const ID & matrix_to_copy_id) override;
/// Get the reference of an existing matrix
SparseMatrixAIJ & getMatrix(const ID & matrix_id);
/* ------------------------------------------------------------------------ */
/* Non Linear Solver */
/* ------------------------------------------------------------------------ */
/// Get instance of a non linear solver
NonLinearSolver & getNewNonLinearSolver(
const ID & nls_solver_id,
const NonLinearSolverType & _non_linear_solver_type) override;
/* ------------------------------------------------------------------------ */
/* Time-Step Solver */
/* ------------------------------------------------------------------------ */
/// Get instance of a time step solver
TimeStepSolver &
getNewTimeStepSolver(const ID & id, const TimeStepSolverType & type,
NonLinearSolver & non_linear_solver) override;
/* ------------------------------------------------------------------------ */
/// Get the solution array
AKANTU_GET_MACRO_NOT_CONST(GlobalSolution, global_solution, Array<Real> &);
/// Set the global solution array
void setGlobalSolution(const Array<Real> & solution);
/// Get the global residual array across processors (SMP call)
const Array<Real> & getGlobalResidual();
/// Get the residual array
const Array<Real> & getResidual() const;
/// Get the blocked dofs array
AKANTU_GET_MACRO(GlobalBlockedDOFs, global_blocked_dofs, const Array<bool> &);
/// Get the blocked dofs array
AKANTU_GET_MACRO(PreviousGlobalBlockedDOFs, previous_global_blocked_dofs,
const Array<bool> &);
/// Get the location type of a given dof
inline bool isLocalOrMasterDOF(UInt local_dof_num);
/// Answer to the question is a dof a slave dof ?
inline bool isSlaveDOF(UInt local_dof_num);
/// get the equation numbers (in local numbering) corresponding to a dof ID
inline const Array<UInt> & getLocalEquationNumbers(const ID & dof_id) const;
/// tells if the dof manager knows about a global dof
bool hasGlobalEquationNumber(UInt global) const;
/// return the local index of the global equation number
inline UInt globalToLocalEquationNumber(UInt global) const;
/// converts local equation numbers to global equation numbers;
inline UInt localToGlobalEquationNumber(UInt local) const;
/// get the array of dof types (use only if you know what you do...)
inline Int getDOFType(UInt local_id) const;
/// get the array of dof types (use only if you know what you do...)
inline const Array<UInt> & getDOFsAssociatedNodes(const ID & dof_id) const;
/// access the internal dof_synchronizer
AKANTU_GET_MACRO_NOT_CONST(Synchronizer, *synchronizer, DOFSynchronizer &);
/// access the internal dof_synchronizer
bool hasSynchronizer() const { return synchronizer != nullptr; }
protected:
DOFData & getNewDOFData(const ID & dof_id) override;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
// using AIJMatrixMap = std::map<ID, std::unique_ptr<SparseMatrixAIJ>>;
// using DefaultNonLinearSolversMap =
// std::map<ID, std::unique_ptr<NonLinearSolverDefault>>;
// using DefaultTimeStepSolversMap =
// std::map<ID, std::unique_ptr<TimeStepSolverDefault>>;
using DOFToMatrixProfile =
std::map<std::pair<ID, ID>,
std::vector<std::pair<ElementType, GhostType>>>;
/// contains the the dofs that where added to the profile of a given matrix.
DOFToMatrixProfile matrix_profiled_dofs;
/// rhs to the system of equation corresponding to the residual linked to the
/// different dofs
Array<Real> residual;
/// rhs used only on root proc in case of parallel computing, this is the full
/// gathered rhs array
std::unique_ptr<Array<Real>> global_residual;
/// solution of the system of equation corresponding to the different dofs
Array<Real> global_solution;
/// blocked degree of freedom in the system equation corresponding to the
/// different dofs
Array<bool> global_blocked_dofs;
/// blocked degree of freedom in the system equation corresponding to the
/// different dofs
Array<bool> previous_global_blocked_dofs;
/// define the dofs type, local, shared, ghost
Array<Int> dofs_type;
/// Map of the different matrices stored in the dof manager
- //AIJMatrixMap aij_matrices;
+ // AIJMatrixMap aij_matrices;
/// Map of the different time step solvers stored with there real type
- //DefaultTimeStepSolversMap default_time_step_solver_map;
+ // DefaultTimeStepSolversMap default_time_step_solver_map;
/// Memory cache, this is an array to keep the temporary memory needed for
/// some operations, it is meant to be resized or cleared when needed
Array<Real> data_cache;
/// Release at last apply boundary on jacobian
UInt jacobian_release{0};
/// equation number in global numbering
Array<UInt> global_equation_number;
using equation_numbers_map = std::unordered_map<UInt, UInt>;
/// dual information of global_equation_number
equation_numbers_map global_to_local_mapping;
/// accumulator to know what would be the next global id to use
UInt first_global_dof_id{0};
/// synchronizer to maintain coherency in dof fields
std::unique_ptr<DOFSynchronizer> synchronizer;
};
} // namespace akantu
#include "dof_manager_default_inline_impl.cc"
#endif /* __AKANTU_DOF_MANAGER_DEFAULT_HH__ */
diff --git a/src/model/dof_manager_inline_impl.cc b/src/model/dof_manager_inline_impl.cc
index 89762d580..0be0ecd85 100644
--- a/src/model/dof_manager_inline_impl.cc
+++ b/src/model/dof_manager_inline_impl.cc
@@ -1,154 +1,153 @@
/**
* @file dof_manager_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Aug 12 11:07:01 2015
*
* @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dof_manager.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DOF_MANAGER_INLINE_IMPL_CC__
#define __AKANTU_DOF_MANAGER_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline bool DOFManager::hasDOFs(const ID & dof_id) const {
auto it = this->dofs.find(dof_id);
return it != this->dofs.end();
}
/* -------------------------------------------------------------------------- */
inline DOFManager::DOFData & DOFManager::getDOFData(const ID & dof_id) {
auto it = this->dofs.find(dof_id);
if (it == this->dofs.end()) {
AKANTU_EXCEPTION("The dof " << dof_id << " does not exists in "
<< this->id);
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
const DOFManager::DOFData & DOFManager::getDOFData(const ID & dof_id) const {
auto it = this->dofs.find(dof_id);
if (it == this->dofs.end()) {
AKANTU_EXCEPTION("The dof " << dof_id << " does not exists in "
<< this->id);
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
const Array<UInt> & DOFManager::getEquationsNumbers(const ID & dof_id) const {
return getDOFData(dof_id).local_equation_number;
}
/* -------------------------------------------------------------------------- */
template <class _DOFData>
inline _DOFData & DOFManager::getDOFDataTyped(const ID & dof_id) {
return dynamic_cast<_DOFData &>(this->getDOFData(dof_id));
}
/* -------------------------------------------------------------------------- */
template <class _DOFData>
inline const _DOFData & DOFManager::getDOFDataTyped(const ID & dof_id) const {
return dynamic_cast<const _DOFData &>(this->getDOFData(dof_id));
}
/* -------------------------------------------------------------------------- */
inline Array<Real> & DOFManager::getDOFs(const ID & dofs_id) {
return *(this->getDOFData(dofs_id).dof);
}
-
/* -------------------------------------------------------------------------- */
inline DOFSupportType DOFManager::getSupportType(const ID & dofs_id) const {
return this->getDOFData(dofs_id).support_type;
}
/* -------------------------------------------------------------------------- */
inline Array<Real> & DOFManager::getPreviousDOFs(const ID & dofs_id) {
return *(this->getDOFData(dofs_id).previous);
}
/* -------------------------------------------------------------------------- */
inline bool DOFManager::hasPreviousDOFs(const ID & dofs_id) const {
return (this->getDOFData(dofs_id).previous != nullptr);
}
/* -------------------------------------------------------------------------- */
inline Array<Real> & DOFManager::getDOFsIncrement(const ID & dofs_id) {
return *(this->getDOFData(dofs_id).increment);
}
/* -------------------------------------------------------------------------- */
inline bool DOFManager::hasDOFsIncrement(const ID & dofs_id) const {
return (this->getDOFData(dofs_id).increment != nullptr);
}
/* -------------------------------------------------------------------------- */
inline Array<Real> & DOFManager::getDOFsDerivatives(const ID & dofs_id,
UInt order) {
std::vector<Array<Real> *> & derivatives =
this->getDOFData(dofs_id).dof_derivatives;
if ((order > derivatives.size()) || (derivatives[order - 1] == nullptr))
AKANTU_EXCEPTION("No derivatives of order " << order << " present in "
<< this->id << " for dof "
<< dofs_id);
return *derivatives[order - 1];
}
/* -------------------------------------------------------------------------- */
inline bool DOFManager::hasDOFsDerivatives(const ID & dofs_id,
- UInt order) const{
+ UInt order) const {
const std::vector<Array<Real> *> & derivatives =
this->getDOFData(dofs_id).dof_derivatives;
return ((order < derivatives.size()) && (derivatives[order - 1] != nullptr));
}
/* -------------------------------------------------------------------------- */
inline const Array<Real> & DOFManager::getSolution(const ID & dofs_id) const {
return this->getDOFData(dofs_id).solution;
}
/* -------------------------------------------------------------------------- */
inline const Array<bool> &
DOFManager::getBlockedDOFs(const ID & dofs_id) const {
return *(this->getDOFData(dofs_id).blocked_dofs);
}
/* -------------------------------------------------------------------------- */
inline bool DOFManager::hasBlockedDOFs(const ID & dofs_id) const {
return (this->getDOFData(dofs_id).blocked_dofs != nullptr);
}
/* -------------------------------------------------------------------------- */
} // akantu
#endif /* __AKANTU_DOF_MANAGER_INLINE_IMPL_CC__ */
diff --git a/src/model/dof_manager_petsc.cc b/src/model/dof_manager_petsc.cc
index d0d982bf1..0c168640d 100644
--- a/src/model/dof_manager_petsc.cc
+++ b/src/model/dof_manager_petsc.cc
@@ -1,396 +1,395 @@
/**
* @file dof_manager_petsc.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Oct 5 21:19:58 2015
*
* @brief DOFManaterPETSc is the PETSc implementation of the DOFManager
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dof_manager_petsc.hh"
#include "cppargparse.hh"
#if defined(AKANTU_USE_MPI)
-#include "static_communicator.hh"
#include "mpi_type_wrapper.hh"
+#include "static_communicator.hh"
#endif
/* -------------------------------------------------------------------------- */
#include <petscsys.h>
/* -------------------------------------------------------------------------- */
namespace akantu {
#if not defined(PETSC_CLANGUAGE_CXX)
/// small hack to use the c binding of petsc when the cxx binding does notation
/// exists
int aka_PETScError(int ierr) {
CHKERRQ(ierr);
return 0;
}
#endif
UInt DOFManagerPETSc::petsc_dof_manager_instances = 0;
/// Error handler to make PETSc errors caught by Akantu
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
static PetscErrorCode PETScErrorHandler(MPI_Comm, int line, const char * dir,
const char * file,
PetscErrorCode number,
PetscErrorType type,
const char * message, void *) {
AKANTU_ERROR("An error occured in PETSc in file \""
- << file << ":" << line << "\" - PetscErrorCode " << number
- << " - \"" << message << "\"");
+ << file << ":" << line << "\" - PetscErrorCode " << number
+ << " - \"" << message << "\"");
}
#else
static PetscErrorCode PETScErrorHandler(MPI_Comm, int line, const char * func,
const char * dir, const char * file,
PetscErrorCode number,
PetscErrorType type,
const char * message, void *) {
AKANTU_ERROR("An error occured in PETSc in file \""
- << file << ":" << line << "\" - PetscErrorCode " << number
- << " - \"" << message << "\"");
+ << file << ":" << line << "\" - PetscErrorCode " << number
+ << " - \"" << message << "\"");
}
#endif
/* -------------------------------------------------------------------------- */
-DOFManagerPETSc::DOFManagerPETSc(const ID & id,
- const MemoryID & memory_id)
+DOFManagerPETSc::DOFManagerPETSc(const ID & id, const MemoryID & memory_id)
: DOFManager(id, memory_id) {
// check if the akantu types and PETSc one are consistant
#if __cplusplus > 199711L
static_assert(sizeof(Int) == sizeof(PetscInt),
"The integer type of Akantu does not match the one from PETSc");
static_assert(sizeof(Real) == sizeof(PetscReal),
"The integer type of Akantu does not match the one from PETSc");
#else
AKANTU_DEBUG_ASSERT(
sizeof(Int) == sizeof(PetscInt),
"The integer type of Akantu does not match the one from PETSc");
AKANTU_DEBUG_ASSERT(
sizeof(Real) == sizeof(PetscReal),
"The integer type of Akantu does not match the one from PETSc");
#endif
if (this->petsc_dof_manager_instances == 0) {
#if defined(AKANTU_USE_MPI)
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
const StaticCommunicatorMPI & mpi_st_comm =
dynamic_cast<const StaticCommunicatorMPI &>(
comm.getRealStaticCommunicator());
- this->mpi_communicator = mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
+ this->mpi_communicator =
+ mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
#else
this->mpi_communicator = PETSC_COMM_SELF;
#endif
cppargparse::ArgumentParser & argparser = getStaticArgumentParser();
int & argc = argparser.getArgC();
char **& argv = argparser.getArgV();
PetscErrorCode petsc_error = PetscInitialize(&argc, &argv, NULL, NULL);
if (petsc_error != 0) {
- AKANTU_ERROR(
- "An error occured while initializing Petsc (PetscErrorCode "
- << petsc_error << ")");
+ AKANTU_ERROR("An error occured while initializing Petsc (PetscErrorCode "
+ << petsc_error << ")");
}
PetscPushErrorHandler(PETScErrorHandler, NULL);
this->petsc_dof_manager_instances++;
}
VecCreate(PETSC_COMM_WORLD, &this->residual);
VecCreate(PETSC_COMM_WORLD, &this->solution);
}
/* -------------------------------------------------------------------------- */
DOFManagerPETSc::~DOFManagerPETSc() {
PetscErrorCode ierr;
ierr = VecDestroy(&(this->residual));
CHKERRXX(ierr);
ierr = VecDestroy(&(this->solution));
CHKERRXX(ierr);
this->petsc_dof_manager_instances--;
if (this->petsc_dof_manager_instances == 0) {
PetscFinalize();
}
}
/* -------------------------------------------------------------------------- */
void DOFManagerPETSc::registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
DOFSupportType & support_type) {
DOFManager::registerDOFs(dof_id, dofs_array, support_type);
PetscErrorCode ierr;
PetscInt current_size;
ierr = VecGetSize(this->residual, &current_size);
CHKERRXX(ierr);
if (current_size == 0) { // first time vector is set
PetscInt local_size = this->pure_local_system_size;
ierr = VecSetSizes(this->residual, local_size, PETSC_DECIDE);
CHKERRXX(ierr);
ierr = VecSetFromOptions(this->residual);
CHKERRXX(ierr);
#ifndef AKANTU_NDEBUG
PetscInt global_size;
ierr = VecGetSize(this->residual, &global_size);
CHKERRXX(ierr);
AKANTU_DEBUG_ASSERT(this->system_size == UInt(global_size),
"The local value of the system size does not match the "
"one determined by PETSc");
#endif
PetscInt start_dof, end_dof;
VecGetOwnershipRange(this->residual, &start_dof, &end_dof);
PetscInt * global_indices = new PetscInt[local_size];
global_indices[0] = start_dof;
for (PetscInt d = 0; d < local_size; d++)
global_indices[d + 1] = global_indices[d] + 1;
// To be change if we switch to a block definition
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
ISLocalToGlobalMappingCreate(this->communicator, 1, local_size,
global_indices, PETSC_COPY_VALUES,
&this->is_ltog);
#else
ISLocalToGlobalMappingCreate(this->communicator, local_size, global_indices,
PETSC_COPY_VALUES, &this->is_ltog);
#endif
VecSetLocalToGlobalMapping(this->residual, this->is_ltog);
delete[] global_indices;
ierr = VecDuplicate(this->residual, &this->solution);
CHKERRXX(ierr);
} else { // this is an update of the object already created
AKANTU_TO_IMPLEMENT();
}
/// set the solution to zero
// ierr = VecZeroEntries(this->solution);
// CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
/**
* This function creates the non-zero pattern of the PETSc matrix. In
* PETSc the parallel matrix is partitioned across processors such
* that the first m0 rows belong to process 0, the next m1 rows belong
* to process 1, the next m2 rows belong to process 2 etc.. where
* m0,m1,m2,.. are the input parameter 'm'. i.e each processor stores
* values corresponding to [m x N] submatrix
* (http://www.mcs.anl.gov/petsc/).
* @param mesh mesh discretizing the domain we want to analyze
* @param dof_synchronizer dof synchronizer that maps the local
* dofs to the global dofs and the equation numbers, i.e., the
* position at which the dof is assembled in the matrix
*/
// void SparseMatrixPETSc::buildProfile(const Mesh & mesh,
// const DOFSynchronizer &
// dof_synchronizer,
// UInt nb_degree_of_freedom) {
// AKANTU_DEBUG_IN();
// // clearProfile();
// this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
// this->setSize();
// PetscErrorCode ierr;
// /// resize arrays to store the number of nonzeros in each row
// this->d_nnz.resize(this->local_size);
// this->o_nnz.resize(this->local_size);
// /// set arrays to zero everywhere
// this->d_nnz.set(0);
// this->o_nnz.set(0);
// // if(irn_jcn_to_k) delete irn_jcn_to_k;
// // irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
// coordinate_list_map::iterator irn_jcn_k_it;
// Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
// UInt nb_global_dofs = dof_synchronizer.getNbGlobalDOFs();
// Array<Int> index_pair(2);
// /// Loop over all the ghost types
// for (ghost_type_t::iterator gt = ghost_type_t::begin();
// gt != ghost_type_t::end(); ++gt) {
// const GhostType & ghost_type = *gt;
// Mesh::type_iterator it =
// mesh.firstType(mesh.getSpatialDimension(), ghost_type,
// _ek_not_defined);
// Mesh::type_iterator end =
// mesh.lastType(mesh.getSpatialDimension(), ghost_type,
// _ek_not_defined);
// for (; it != end; ++it) {
// UInt nb_element = mesh.getNbElement(*it, ghost_type);
// UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
// UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
// UInt * conn_val = mesh.getConnectivity(*it, ghost_type).storage();
// Int * local_eq_nb_val =
// new Int[nb_degree_of_freedom * nb_nodes_per_element];
// for (UInt e = 0; e < nb_element; ++e) {
// Int * tmp_local_eq_nb_val = local_eq_nb_val;
// for (UInt i = 0; i < nb_nodes_per_element; ++i) {
// UInt n = conn_val[i];
// for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
// /**
// * !!!!!!Careful!!!!!! This is a ugly fix. @todo this is a
// * very ugly fix, because the offset for the global
// * equation number, where the dof will be assembled, is
// * hardcoded. In the future a class dof manager has to be
// * added to Akantu to handle the mapping between the dofs
// * and the equation numbers
// *
// */
// *tmp_local_eq_nb_val++ =
// eq_nb_val[n * nb_degree_of_freedom + d] -
// (dof_synchronizer.isPureGhostDOF(n * nb_degree_of_freedom +
// d)
// ? nb_global_dofs
// : 0);
// }
// }
// for (UInt i = 0; i < size_mat; ++i) {
// Int c_irn = local_eq_nb_val[i];
// UInt j_start = 0;
// for (UInt j = j_start; j < size_mat; ++j) {
// Int c_jcn = local_eq_nb_val[j];
// index_pair(0) = c_irn;
// index_pair(1) = c_jcn;
// AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2,
// index_pair.storage());
// if (index_pair(0) >= first_global_index &&
// index_pair(0) < first_global_index + this->local_size) {
// KeyCOO irn_jcn = keyPETSc(c_irn, c_jcn);
// irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
// if (irn_jcn_k_it == irn_jcn_k.end()) {
// irn_jcn_k[irn_jcn] = nb_non_zero;
// // check if node is slave node
// if (index_pair(1) >= first_global_index &&
// index_pair(1) < first_global_index + this->local_size)
// this->d_nnz(index_pair(0) - first_global_index) += 1;
// else
// this->o_nnz(index_pair(0) - first_global_index) += 1;
// nb_non_zero++;
// }
// }
// }
// }
// conn_val += nb_nodes_per_element;
// }
// delete[] local_eq_nb_val;
// }
// }
// // /// for pbc @todo correct it for parallel
// // if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
// // for (UInt i = 0; i < size; ++i) {
// // KeyCOO irn_jcn = key(i, i);
// // irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
// // if(irn_jcn_k_it == irn_jcn_k.end()) {
// // irn_jcn_k[irn_jcn] = nb_non_zero;
// // irn.push_back(i + 1);
// // jcn.push_back(i + 1);
// // nb_non_zero++;
// // }
// // }
// // }
// // std::string mat_type;
// // mat_type.resize(20, 'a');
// // std::cout << "MatType: " << mat_type << std::endl;
// // const char * mat_type_ptr = mat_type.c_str();
// MatType type;
// MatGetType(this->petsc_matrix_wrapper->mat, &type);
// /// std::cout << "the matrix type is: " << type << std::endl;
// /**
// * PETSc will use only one of the following preallocation commands
// * depending on the matrix type and ignore the rest. Note that for
// * the block matrix format a block size of 1 is used. This might
// * result in bad performance. @todo For better results implement
// * buildProfile() with larger block size.
// *
// */
// /// build profile:
// if (strcmp(type, MATSEQAIJ) == 0) {
// ierr = MatSeqAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 0,
// d_nnz.storage());
// CHKERRXX(ierr);
// } else if ((strcmp(type, MATMPIAIJ) == 0)) {
// ierr = MatMPIAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 0,
// d_nnz.storage(), 0, o_nnz.storage());
// CHKERRXX(ierr);
// } else {
// AKANTU_ERROR("The type " << type
// << " of PETSc matrix is not handled by"
// << " akantu in the preallocation step");
// }
// // ierr = MatSeqSBAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 1,
// // 0, d_nnz.storage()); CHKERRXX(ierr);
// if (this->sparse_matrix_type == _symmetric) {
// /// set flag for symmetry to enable ICC/Cholesky preconditioner
// ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SYMMETRIC,
// PETSC_TRUE);
// CHKERRXX(ierr);
// /// set flag for symmetric positive definite
// ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SPD,
// PETSC_TRUE);
// CHKERRXX(ierr);
// }
// /// once the profile has been build ignore any new nonzero locations
// ierr = MatSetOption(this->petsc_matrix_wrapper->mat,
// MAT_NEW_NONZERO_LOCATIONS, PETSC_TRUE);
// CHKERRXX(ierr);
// AKANTU_DEBUG_OUT();
// }
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/model/dof_manager_petsc.hh b/src/model/dof_manager_petsc.hh
index 0a8140a14..e994d5c73 100644
--- a/src/model/dof_manager_petsc.hh
+++ b/src/model/dof_manager_petsc.hh
@@ -1,172 +1,173 @@
/**
* @file dof_manager_petsc.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Aug 11 14:06:18 2015
*
* @brief PETSc implementation of the dof manager
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dof_manager.hh"
/* -------------------------------------------------------------------------- */
-#include <petscvec.h>
#include <petscis.h>
+#include <petscvec.h>
/* -------------------------------------------------------------------------- */
#if not defined(PETSC_CLANGUAGE_CXX)
extern int aka_PETScError(int ierr);
#define CHKERRXX(x) \
do { \
int error = aka_PETScError(x); \
if (error != 0) { \
AKANTU_EXCEPTION("Error in PETSC"); \
} \
} while (0)
#endif
#ifndef __AKANTU_DOF_MANAGER_PETSC_HH__
#define __AKANTU_DOF_MANAGER_PETSC_HH__
namespace akantu {
class SparseMatrixPETSc;
class DOFManagerPETSc : public DOFManager {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DOFManagerPETSc(const ID & id = "dof_manager_petsc",
const MemoryID & memory_id = 0);
DOFManagerPETSc(Mesh & mesh, const ID & id = "dof_manager_petsc",
const MemoryID & memory_id = 0);
virtual ~DOFManagerPETSc();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// register an array of degree of freedom
void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
DOFSupportType & support_type);
/// Assemble an array to the global residual array
virtual void assembleToResidual(const ID & dof_id,
const Array<Real> & array_to_assemble,
Real scale_factor = 1.);
/**
* Assemble elementary values to the global residual array. The dof number is
* implicitly considered as conn(el, n) * nb_nodes_per_element + d.
* With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
**/
virtual void assembleElementalArrayResidual(
const ID & dof_id, const Array<Real> & array_to_assemble,
const ElementType & type, const GhostType & ghost_type,
Real scale_factor = 1.);
/**
* Assemble elementary values to the global residual array. The dof number is
* implicitly considered as conn(el, n) * nb_nodes_per_element + d.
* With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
**/
virtual void assembleElementalMatricesToMatrix(
const ID & matrix_id, const ID & dof_id,
const Array<Real> & elementary_mat, const ElementType & type,
const GhostType & ghost_type, const MatrixType & elemental_matrix_type,
const Array<UInt> & filter_elements);
protected:
/// Get the part of the solution corresponding to the dof_id
- virtual void getSolutionPerDOFs(const ID & dof_id, Array<Real> & solution_array);
+ virtual void getSolutionPerDOFs(const ID & dof_id,
+ Array<Real> & solution_array);
private:
/// Add a symmetric matrices to a symmetric sparse matrix
inline void addSymmetricElementalMatrixToSymmetric(
SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
const Vector<UInt> & equation_numbers, UInt max_size);
/// Add a unsymmetric matrices to a symmetric sparse matrix (i.e. cohesive
/// elements)
inline void addUnsymmetricElementalMatrixToSymmetric(
SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
const Vector<UInt> & equation_numbers, UInt max_size);
/// Add a matrices to a unsymmetric sparse matrix
inline void addElementalMatrixToUnsymmetric(
SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
const Vector<UInt> & equation_numbers, UInt max_size);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get an instance of a new SparseMatrix
virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
const MatrixType & matrix_type);
/// Get an instance of a new SparseMatrix as a copy of the SparseMatrix
/// matrix_to_copy_id
virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
const ID & matrix_to_copy_id);
/// Get the reference of an existing matrix
SparseMatrixPETSc & getMatrix(const ID & matrix_id);
/// Get the solution array
AKANTU_GET_MACRO_NOT_CONST(GlobalSolution, this->solution, Vec &);
/// Get the residual array
AKANTU_GET_MACRO_NOT_CONST(Residual, this->residual, Vec &);
/// Get the blocked dofs array
// AKANTU_GET_MACRO(BlockedDOFs, blocked_dofs, const Array<bool> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
typedef std::map<ID, SparseMatrixPETSc *> PETScMatrixMap;
/// list of matrices registered to the dof manager
PETScMatrixMap petsc_matrices;
/// PETSc version of the solution
Vec solution;
/// PETSc version of the residual
Vec residual;
/// PETSc local to global mapping of dofs
ISLocalToGlobalMapping is_ltog;
/// Communicator associated to PETSc
MPI_Comm mpi_communicator;
/// Static handler for petsc to know if it was initialized or not
static UInt petsc_dof_manager_instances;
};
} // akantu
#endif /* __AKANTU_DOF_MANAGER_PETSC_HH__ */
diff --git a/src/model/heat_transfer/heat_transfer_model.cc b/src/model/heat_transfer/heat_transfer_model.cc
index 283da8b0c..031214f49 100644
--- a/src/model/heat_transfer/heat_transfer_model.cc
+++ b/src/model/heat_transfer/heat_transfer_model.cc
@@ -1,971 +1,958 @@
/**
* @file heat_transfer_model.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
* @date last modification: Mon Nov 30 2015
*
* @brief Implementation of HeatTransferModel class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "heat_transfer_model.hh"
#include "dumpable_inline_impl.hh"
#include "element_synchronizer.hh"
#include "fe_engine_template.hh"
#include "generalized_trapezoidal.hh"
#include "group_manager_inline_impl.cc"
#include "integrator_gauss.hh"
#include "mesh.hh"
#include "parser.hh"
#include "shape_lagrange.hh"
#ifdef AKANTU_USE_IOHELPER
#include "dumper_element_partition.hh"
#include "dumper_elemental_field.hh"
#include "dumper_internal_material_field.hh"
#include "dumper_iohelper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace heat_transfer {
namespace details {
class ComputeRhoFunctor {
public:
ComputeRhoFunctor(const HeatTransferModel & model) : model(model){};
void operator()(Matrix<Real> & rho, const Element &) const {
rho.set(model.getCapacity());
}
private:
const HeatTransferModel & model;
};
}
}
/* -------------------------------------------------------------------------- */
HeatTransferModel::HeatTransferModel(Mesh & mesh, UInt dim, const ID & id,
const MemoryID & memory_id)
: Model(mesh, ModelType::_heat_transfer_model, dim, id, memory_id),
temperature_gradient("temperature_gradient", id),
temperature_on_qpoints("temperature_on_qpoints", id),
conductivity_on_qpoints("conductivity_on_qpoints", id),
k_gradt_on_qpoints("k_gradt_on_qpoints", id) {
AKANTU_DEBUG_IN();
conductivity = Matrix<Real>(this->spatial_dimension, this->spatial_dimension);
this->initDOFManager();
this->registerDataAccessor(*this);
if (this->mesh.isDistributed()) {
auto & synchronizer = this->mesh.getElementSynchronizer();
this->registerSynchronizer(synchronizer, _gst_htm_capacity);
this->registerSynchronizer(synchronizer, _gst_htm_temperature);
this->registerSynchronizer(synchronizer, _gst_htm_gradient_temperature);
}
registerFEEngineObject<FEEngineType>(id + ":fem", mesh, spatial_dimension);
#ifdef AKANTU_USE_IOHELPER
this->mesh.registerDumper<DumperParaview>("heat_transfer", id, true);
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_regular);
#endif
this->registerParam("conductivity", conductivity, _pat_parsmod);
this->registerParam("conductivity_variation", conductivity_variation, 0.,
_pat_parsmod);
this->registerParam("temperature_reference", T_ref, 0., _pat_parsmod);
this->registerParam("capacity", capacity, _pat_parsmod);
this->registerParam("density", density, _pat_parsmod);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initModel() {
auto & fem = this->getFEEngine();
fem.initShapeFunctions(_not_ghost);
fem.initShapeFunctions(_ghost);
temperature_on_qpoints.initialize(fem, _nb_component = 1);
temperature_gradient.initialize(fem, _nb_component = spatial_dimension);
conductivity_on_qpoints.initialize(
fem, _nb_component = spatial_dimension * spatial_dimension);
k_gradt_on_qpoints.initialize(fem, _nb_component = spatial_dimension);
}
/* -------------------------------------------------------------------------- */
FEEngine & HeatTransferModel::getFEEngineBoundary(const ID & name) {
return dynamic_cast<FEEngine &>(getFEEngineClassBoundary<FEEngineType>(name));
}
/* -------------------------------------------------------------------------- */
template <typename T>
void HeatTransferModel::allocNodalField(Array<T> *& array, const ID & name) {
if (array == nullptr) {
UInt nb_nodes = mesh.getNbNodes();
std::stringstream sstr_disp;
sstr_disp << id << ":" << name;
array = &(alloc<T>(sstr_disp.str(), nb_nodes, 1, T()));
}
}
/* -------------------------------------------------------------------------- */
HeatTransferModel::~HeatTransferModel() = default;
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacityLumped(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
auto & fem = getFEEngineClass<FEEngineType>();
heat_transfer::details::ComputeRhoFunctor compute_rho(*this);
for (auto & type : mesh.elementTypes(spatial_dimension, ghost_type)) {
fem.assembleFieldLumped(compute_rho, "M", "temperature",
this->getDOFManager(), type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MatrixType HeatTransferModel::getMatrixType(const ID & matrix_id) {
if (matrix_id == "K" or matrix_id == "M") {
return _symmetric;
}
return _mt_not_defined;
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleMatrix(const ID & matrix_id) {
if (matrix_id == "K") {
this->assembleConductivityMatrix();
} else if (matrix_id == "M") {
this->assembleCapacity();
} else {
AKANTU_TO_IMPLEMENT();
}
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleLumpedMatrix(const ID & matrix_id) {
if (matrix_id == "M") {
this->assembleCapacityLumped();
} else {
AKANTU_TO_IMPLEMENT();
}
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleResidual() {
AKANTU_DEBUG_IN();
this->assembleInternalHeatRate();
this->getDOFManager().assembleToResidual("temperature",
*this->external_heat_rate, 1);
this->getDOFManager().assembleToResidual("temperature",
*this->internal_heat_rate, 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::predictor() { ++temperature_release; }
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacityLumped() {
AKANTU_DEBUG_IN();
if (!this->getDOFManager().hasLumpedMatrix("M")) {
this->getDOFManager().getNewLumpedMatrix("M");
}
this->getDOFManager().clearLumpedMatrix("M");
assembleCapacityLumped(_not_ghost);
assembleCapacityLumped(_ghost);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initSolver(TimeStepSolverType time_step_solver_type,
NonLinearSolverType) {
DOFManager & dof_manager = this->getDOFManager();
this->allocNodalField(this->temperature, "temperature");
this->allocNodalField(this->external_heat_rate, "external_heat_rate");
this->allocNodalField(this->internal_heat_rate, "internal_heat_rate");
this->allocNodalField(this->blocked_dofs, "blocked_dofs");
if (!dof_manager.hasDOFs("temperature")) {
dof_manager.registerDOFs("temperature", *this->temperature, _dst_nodal);
dof_manager.registerBlockedDOFs("temperature", *this->blocked_dofs);
}
if (time_step_solver_type == _tsst_dynamic ||
time_step_solver_type == _tsst_dynamic_lumped) {
this->allocNodalField(this->temperature_rate, "temperature_rate");
if (!dof_manager.hasDOFsDerivatives("temperature", 1)) {
dof_manager.registerDOFsDerivative("temperature", 1,
*this->temperature_rate);
}
}
}
/* -------------------------------------------------------------------------- */
std::tuple<ID, TimeStepSolverType>
HeatTransferModel::getDefaultSolverID(const AnalysisMethod & method) {
switch (method) {
case _explicit_lumped_mass: {
return std::make_tuple("explicit_lumped", _tsst_dynamic_lumped);
}
case _static: {
return std::make_tuple("static", _tsst_static);
}
case _implicit_dynamic: {
return std::make_tuple("implicit", _tsst_dynamic);
}
default:
return std::make_tuple("unknown", _tsst_not_defined);
}
}
/* -------------------------------------------------------------------------- */
ModelSolverOptions HeatTransferModel::getDefaultSolverOptions(
const TimeStepSolverType & type) const {
ModelSolverOptions options;
switch (type) {
case _tsst_dynamic_lumped: {
options.non_linear_solver_type = _nls_lumped;
options.integration_scheme_type["temperature"] = _ist_forward_euler;
options.solution_type["temperature"] = IntegrationScheme::_temperature_rate;
break;
}
case _tsst_static: {
options.non_linear_solver_type = _nls_newton_raphson;
options.integration_scheme_type["temperature"] = _ist_pseudo_time;
options.solution_type["temperature"] = IntegrationScheme::_not_defined;
break;
}
case _tsst_dynamic: {
if (this->method == _explicit_consistent_mass) {
options.non_linear_solver_type = _nls_newton_raphson;
options.integration_scheme_type["temperature"] = _ist_forward_euler;
options.solution_type["temperature"] =
IntegrationScheme::_temperature_rate;
} else {
options.non_linear_solver_type = _nls_newton_raphson;
options.integration_scheme_type["temperature"] = _ist_trapezoidal_rule_1;
options.solution_type["temperature"] = IntegrationScheme::_temperature;
}
break;
}
default:
AKANTU_EXCEPTION(type << " is not a valid time step solver type");
}
return options;
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleConductivityMatrix() {
AKANTU_DEBUG_IN();
this->computeConductivityOnQuadPoints(_not_ghost);
if (conductivity_release[_not_ghost] == conductivity_matrix_release)
return;
if (!this->getDOFManager().hasMatrix("K")) {
this->getDOFManager().getNewMatrix("K", getMatrixType("K"));
}
this->getDOFManager().clearMatrix("K");
switch (mesh.getSpatialDimension()) {
case 1:
this->assembleConductivityMatrix<1>(_not_ghost);
break;
case 2:
this->assembleConductivityMatrix<2>(_not_ghost);
break;
case 3:
this->assembleConductivityMatrix<3>(_not_ghost);
break;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void HeatTransferModel::assembleConductivityMatrix(
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
auto & fem = this->getFEEngine();
for (auto && type : mesh.elementTypes(spatial_dimension, ghost_type)) {
auto nb_element = mesh.getNbElement(type, ghost_type);
auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
auto nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
auto bt_d_b = std::make_unique<Array<Real>>(
nb_element * nb_quadrature_points,
nb_nodes_per_element * nb_nodes_per_element, "B^t*D*B");
fem.computeBtDB(conductivity_on_qpoints(type, ghost_type), *bt_d_b, 2, type,
ghost_type);
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
auto K_e = std::make_unique<Array<Real>>(
nb_element, nb_nodes_per_element * nb_nodes_per_element, "K_e");
fem.integrate(*bt_d_b, *K_e, nb_nodes_per_element * nb_nodes_per_element,
type, ghost_type);
this->getDOFManager().assembleElementalMatricesToMatrix(
"K", "temperature", *K_e, type, ghost_type, _symmetric);
}
conductivity_matrix_release = conductivity_release[ghost_type];
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::computeConductivityOnQuadPoints(
const GhostType & ghost_type) {
// if already computed once check if need to compute
if (not initial_conductivity[ghost_type]) {
// if temperature did not change, condictivity will not vary
if (temperature_release == conductivity_release[ghost_type])
return;
// if conductivity_variation is 0 no need to recompute
if (conductivity_variation == 0.)
return;
}
for (auto & type : mesh.elementTypes(spatial_dimension, ghost_type)) {
auto & temperature_interpolated = temperature_on_qpoints(type, ghost_type);
// compute the temperature on quadrature points
this->getFEEngine().interpolateOnIntegrationPoints(
*temperature, temperature_interpolated, 1, type, ghost_type);
auto & cond = conductivity_on_qpoints(type, ghost_type);
for (auto && tuple :
zip(make_view(cond, spatial_dimension, spatial_dimension),
temperature_interpolated)) {
auto & C = std::get<0>(tuple);
auto & T = std::get<1>(tuple);
C = conductivity;
Matrix<Real> variation(spatial_dimension, spatial_dimension,
conductivity_variation * (T - T_ref));
// @TODO: Guillaume are you sure ? why due you compute variation then ?
C += conductivity_variation;
}
}
conductivity_release[ghost_type] = temperature_release;
initial_conductivity[ghost_type] = false;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::computeKgradT(const GhostType & ghost_type) {
computeConductivityOnQuadPoints(ghost_type);
for (auto & type : mesh.elementTypes(spatial_dimension, ghost_type)) {
auto & gradient = temperature_gradient(type, ghost_type);
this->getFEEngine().gradientOnIntegrationPoints(*temperature, gradient, 1,
type, ghost_type);
for (auto && values :
zip(make_view(conductivity_on_qpoints(type, ghost_type),
spatial_dimension, spatial_dimension),
make_view(gradient, spatial_dimension),
make_view(k_gradt_on_qpoints(type, ghost_type),
spatial_dimension))) {
const auto & C = std::get<0>(values);
const auto & BT = std::get<1>(values);
auto & k_BT = std::get<2>(values);
k_BT.mul<false>(C, BT);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleInternalHeatRate() {
AKANTU_DEBUG_IN();
this->internal_heat_rate->clear();
this->synchronize(_gst_htm_temperature);
auto & fem = this->getFEEngine();
for (auto ghost_type : ghost_types) {
// compute k \grad T
computeKgradT(ghost_type);
for (auto type : mesh.elementTypes(spatial_dimension, ghost_type)) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
auto & k_gradt_on_qpoints_vect = k_gradt_on_qpoints(type, ghost_type);
UInt nb_quad_points = k_gradt_on_qpoints_vect.size();
Array<Real> bt_k_gT(nb_quad_points, nb_nodes_per_element);
fem.computeBtD(k_gradt_on_qpoints_vect, bt_k_gT, type, ghost_type);
UInt nb_elements = mesh.getNbElement(type, ghost_type);
Array<Real> int_bt_k_gT(nb_elements, nb_nodes_per_element);
fem.integrate(bt_k_gT, int_bt_k_gT, nb_nodes_per_element, type,
ghost_type);
this->getDOFManager().assembleElementalArrayLocalArray(
int_bt_k_gT, *this->internal_heat_rate, type, ghost_type, -1);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getStableTimeStep() {
AKANTU_DEBUG_IN();
Real el_size;
Real min_el_size = std::numeric_limits<Real>::max();
Real conductivitymax = conductivity(0, 0);
// get the biggest parameter from k11 until k33//
for (UInt i = 0; i < spatial_dimension; i++)
for (UInt j = 0; j < spatial_dimension; j++)
conductivitymax = std::max(conductivity(i, j), conductivitymax);
for (auto & type : mesh.elementTypes(spatial_dimension, _not_ghost)) {
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
Array<Real> coord(0, nb_nodes_per_element * spatial_dimension);
FEEngine::extractNodalToElementField(mesh, mesh.getNodes(), coord, type,
_not_ghost);
auto el_coord = coord.begin(spatial_dimension, nb_nodes_per_element);
UInt nb_element = mesh.getNbElement(type);
for (UInt el = 0; el < nb_element; ++el, ++el_coord) {
el_size = getFEEngine().getElementInradius(*el_coord, type);
min_el_size = std::min(min_el_size, el_size);
}
AKANTU_DEBUG_INFO("The minimum element size : "
<< min_el_size
<< " and the max conductivity is : " << conductivitymax);
}
Real min_dt =
2 * min_el_size * min_el_size * density * capacity / conductivitymax;
mesh.getCommunicator().allReduce(min_dt, SynchronizerOperation::_min);
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::readMaterials() {
auto sect = this->getParserSection();
if (not std::get<1>(sect)) {
const auto & section = std::get<0>(sect);
this->parseSection(section);
}
conductivity_on_qpoints.set(conductivity);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initFullImpl(const ModelOptions & options) {
Model::initFullImpl(options);
readMaterials();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacity() {
AKANTU_DEBUG_IN();
auto ghost_type = _not_ghost;
auto & fem = getFEEngineClass<FEEngineType>();
heat_transfer::details::ComputeRhoFunctor rho_functor(*this);
for (auto && type : mesh.elementTypes(spatial_dimension, ghost_type)) {
fem.assembleFieldMatrix(rho_functor, "M", "temperature",
this->getDOFManager(), type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::computeRho(Array<Real> & rho, ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
FEEngine & fem = this->getFEEngine();
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
rho.resize(nb_element * nb_quadrature_points);
rho.set(this->capacity);
// Real * rho_1_val = rho.storage();
// /// compute @f$ rho @f$ for each nodes of each element
// for (UInt el = 0; el < nb_element; ++el) {
// for (UInt n = 0; n < nb_quadrature_points; ++n) {
// *rho_1_val++ = this->capacity;
// }
// }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::computeThermalEnergyByNode() {
AKANTU_DEBUG_IN();
Real ethermal = 0.;
for (auto && pair : enumerate(make_view(
*internal_heat_rate, internal_heat_rate->getNbComponent()))) {
auto n = std::get<0>(pair);
auto & heat_rate = std::get<1>(pair);
Real heat = 0.;
bool is_local_node = mesh.isLocalOrMasterNode(n);
bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
bool count_node = is_local_node && is_not_pbc_slave_node;
for (UInt i = 0; i < heat_rate.size(); ++i) {
if (count_node)
heat += heat_rate[i] * time_step;
}
ethermal += heat;
}
mesh.getCommunicator().allReduce(ethermal, SynchronizerOperation::_sum);
AKANTU_DEBUG_OUT();
return ethermal;
}
/* -------------------------------------------------------------------------- */
template <class iterator>
void HeatTransferModel::getThermalEnergy(
iterator Eth, Array<Real>::const_iterator<Real> T_it,
Array<Real>::const_iterator<Real> T_end) const {
for (; T_it != T_end; ++T_it, ++Eth) {
*Eth = capacity * density * *T_it;
}
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getThermalEnergy(const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
Vector<Real> Eth_on_quarature_points(nb_quadrature_points);
auto T_it = this->temperature_on_qpoints(type).begin();
T_it += index * nb_quadrature_points;
auto T_end = T_it + nb_quadrature_points;
getThermalEnergy(Eth_on_quarature_points.storage(), T_it, T_end);
return getFEEngine().integrate(Eth_on_quarature_points, type, index);
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getThermalEnergy() {
Real Eth = 0;
auto & fem = getFEEngine();
for (auto && type : mesh.elementTypes(spatial_dimension)) {
auto nb_element = mesh.getNbElement(type, _not_ghost);
auto nb_quadrature_points = fem.getNbIntegrationPoints(type, _not_ghost);
Array<Real> Eth_per_quad(nb_element * nb_quadrature_points, 1);
auto & temperature_interpolated = temperature_on_qpoints(type);
// compute the temperature on quadrature points
this->getFEEngine().interpolateOnIntegrationPoints(
*temperature, temperature_interpolated, 1, type);
auto T_it = temperature_interpolated.begin();
auto T_end = temperature_interpolated.end();
getThermalEnergy(Eth_per_quad.begin(), T_it, T_end);
Eth += fem.integrate(Eth_per_quad, type);
}
return Eth;
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getEnergy(const std::string & id) {
AKANTU_DEBUG_IN();
Real energy = 0;
if (id == "thermal")
energy = getThermalEnergy();
// reduction sum over all processors
mesh.getCommunicator().allReduce(energy, SynchronizerOperation::_sum);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getEnergy(const std::string & id,
const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
Real energy = 0.;
if (id == "thermal")
energy = getThermalEnergy(type, index);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
dumper::Field * HeatTransferModel::createNodalFieldBool(
const std::string & field_name, const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
std::map<std::string, Array<bool> *> uint_nodal_fields;
uint_nodal_fields["blocked_dofs"] = blocked_dofs;
dumper::Field * field = nullptr;
field = mesh.createNodalField(uint_nodal_fields[field_name], group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createNodalFieldReal(
const std::string & field_name, const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
std::map<std::string, Array<Real> *> real_nodal_fields;
real_nodal_fields["temperature"] = temperature;
real_nodal_fields["temperature_rate"] = temperature_rate;
real_nodal_fields["external_heat_rate"] = external_heat_rate;
real_nodal_fields["internal_heat_rate"] = internal_heat_rate;
real_nodal_fields["capacity_lumped"] = capacity_lumped;
real_nodal_fields["increment"] = increment;
dumper::Field * field =
mesh.createNodalField(real_nodal_fields[field_name], group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createElementalField(
const std::string & field_name, const std::string & group_name,
__attribute__((unused)) bool padding_flag,
__attribute__((unused)) const UInt & spatial_dimension,
const ElementKind & element_kind) {
dumper::Field * field = nullptr;
if (field_name == "partitions")
field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(
mesh.getConnectivities(), group_name, this->spatial_dimension,
element_kind);
else if (field_name == "temperature_gradient") {
ElementTypeMap<UInt> nb_data_per_elem =
this->mesh.getNbDataPerElem(temperature_gradient, element_kind);
field = mesh.createElementalField<Real, dumper::InternalMaterialField>(
temperature_gradient, group_name, this->spatial_dimension, element_kind,
nb_data_per_elem);
} else if (field_name == "conductivity") {
ElementTypeMap<UInt> nb_data_per_elem =
this->mesh.getNbDataPerElem(conductivity_on_qpoints, element_kind);
field = mesh.createElementalField<Real, dumper::InternalMaterialField>(
conductivity_on_qpoints, group_name, this->spatial_dimension,
element_kind, nb_data_per_elem);
}
return field;
}
/* -------------------------------------------------------------------------- */
#else
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createElementalField(
__attribute__((unused)) const std::string & field_name,
__attribute__((unused)) const std::string & group_name,
__attribute__((unused)) bool padding_flag,
__attribute__((unused)) const ElementKind & element_kind) {
return nullptr;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createNodalFieldBool(
__attribute__((unused)) const std::string & field_name,
__attribute__((unused)) const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
return nullptr;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createNodalFieldReal(
__attribute__((unused)) const std::string & field_name,
__attribute__((unused)) const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
return nullptr;
}
#endif
-
/* -------------------------------------------------------------------------- */
void HeatTransferModel::dump(const std::string & dumper_name) {
mesh.dump(dumper_name);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::dump(const std::string & dumper_name, UInt step) {
mesh.dump(dumper_name, step);
}
/* ------------------------------------------------------------------------- */
void HeatTransferModel::dump(const std::string & dumper_name, Real time,
UInt step) {
mesh.dump(dumper_name, time, step);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::dump() { mesh.dump(); }
/* -------------------------------------------------------------------------- */
void HeatTransferModel::dump(UInt step) { mesh.dump(step); }
/* -------------------------------------------------------------------------- */
void HeatTransferModel::dump(Real time, UInt step) { mesh.dump(time, step); }
/* -------------------------------------------------------------------------- */
inline UInt HeatTransferModel::getNbData(const Array<UInt> & indexes,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
UInt nb_nodes = indexes.size();
switch (tag) {
case _gst_htm_capacity:
case _gst_htm_temperature: {
size += nb_nodes * sizeof(Real);
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::packData(CommunicationBuffer & buffer,
const Array<UInt> & indexes,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
for (auto index : indexes) {
switch (tag) {
case _gst_htm_capacity:
buffer << (*capacity_lumped)(index);
break;
case _gst_htm_temperature: {
buffer << (*temperature)(index);
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::unpackData(CommunicationBuffer & buffer,
const Array<UInt> & indexes,
const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
for (auto index : indexes) {
switch (tag) {
case _gst_htm_capacity: {
buffer >> (*capacity_lumped)(index);
break;
}
case _gst_htm_temperature: {
buffer >> (*temperature)(index);
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline UInt HeatTransferModel::getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
UInt nb_nodes_per_element = 0;
Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
}
switch (tag) {
case _gst_htm_capacity: {
size += nb_nodes_per_element * sizeof(Real); // capacity vector
break;
}
case _gst_htm_temperature: {
size += nb_nodes_per_element * sizeof(Real); // temperature
break;
}
case _gst_htm_gradient_temperature: {
// temperature gradient
size += getNbIntegrationPoints(elements) * spatial_dimension * sizeof(Real);
size += nb_nodes_per_element * sizeof(Real); // nodal temperatures
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const {
switch (tag) {
case _gst_htm_capacity: {
packNodalDataHelper(*capacity_lumped, buffer, elements, mesh);
break;
}
case _gst_htm_temperature: {
packNodalDataHelper(*temperature, buffer, elements, mesh);
break;
}
case _gst_htm_gradient_temperature: {
packElementalDataHelper(temperature_gradient, buffer, elements, true,
getFEEngine());
packNodalDataHelper(*temperature, buffer, elements, mesh);
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
}
/* -------------------------------------------------------------------------- */
inline void HeatTransferModel::unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) {
switch (tag) {
case _gst_htm_capacity: {
unpackNodalDataHelper(*capacity_lumped, buffer, elements, mesh);
break;
}
case _gst_htm_temperature: {
unpackNodalDataHelper(*temperature, buffer, elements, mesh);
break;
}
case _gst_htm_gradient_temperature: {
unpackElementalDataHelper(temperature_gradient, buffer, elements, true,
getFEEngine());
unpackNodalDataHelper(*temperature, buffer, elements, mesh);
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
index 18ad2d1fe..9eca9dd79 100644
--- a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
+++ b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
@@ -1,43 +1,42 @@
/**
* @file heat_transfer_model_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
*
* @date creation: Fri Aug 20 2010
* @date last modification: Tue Dec 08 2015
*
* @brief Implementation of the inline functions of the HeatTransferModel class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_HEAT_TRANSFER_MODEL_INLINE_IMPL_CC__
#define __AKANTU_HEAT_TRANSFER_MODEL_INLINE_IMPL_CC__
namespace akantu {
-
/* -------------------------------------------------------------------------- */
} // namespace akantu
#endif /* __AKANTU_HEAT_TRANSFER_MODEL_INLINE_IMPL_CC__ */
diff --git a/src/model/integration_scheme/generalized_trapezoidal.cc b/src/model/integration_scheme/generalized_trapezoidal.cc
index 6fa4eb236..9dc57650c 100644
--- a/src/model/integration_scheme/generalized_trapezoidal.cc
+++ b/src/model/integration_scheme/generalized_trapezoidal.cc
@@ -1,192 +1,193 @@
/**
* @file generalized_trapezoidal.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 04 2011
* @date last modification: Thu Jun 05 2014
*
* @brief implementation of inline functions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "generalized_trapezoidal.hh"
-#include "mesh.hh"
#include "aka_array.hh"
#include "dof_manager.hh"
+#include "mesh.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
GeneralizedTrapezoidal::GeneralizedTrapezoidal(DOFManager & dof_manager,
const ID & dof_id, Real alpha)
: IntegrationScheme1stOrder(dof_manager, dof_id), alpha(alpha) {
- this->registerParam("alpha", this->alpha, alpha, _pat_parsmod, "The alpha parameter");
+ this->registerParam("alpha", this->alpha, alpha, _pat_parsmod,
+ "The alpha parameter");
}
/* -------------------------------------------------------------------------- */
void GeneralizedTrapezoidal::predictor(Real delta_t, Array<Real> & u,
Array<Real> & u_dot,
const Array<bool> & blocked_dofs) const {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.size();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt d = 0; d < nb_degree_of_freedom; d++) {
if (!(*blocked_dofs_val)) {
*u_val += (1. - alpha) * delta_t * *u_dot_val;
}
u_val++;
u_dot_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GeneralizedTrapezoidal::corrector(const SolutionType & type, Real delta_t,
Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & blocked_dofs,
const Array<Real> & delta) const {
AKANTU_DEBUG_IN();
switch (type) {
case _temperature:
this->allCorrector<_temperature>(delta_t, u, u_dot, blocked_dofs, delta);
break;
case _temperature_rate:
this->allCorrector<_temperature_rate>(delta_t, u, u_dot, blocked_dofs,
delta);
break;
default:
AKANTU_EXCEPTION("The corrector type : "
<< type
<< " is not supported by this type of integration scheme");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real GeneralizedTrapezoidal::getTemperatureCoefficient(
const SolutionType & type, Real delta_t) const {
switch (type) {
case _temperature:
return 1.;
case _temperature_rate:
return alpha * delta_t;
default:
AKANTU_EXCEPTION("The corrector type : "
<< type
<< " is not supported by this type of integration scheme");
}
}
/* -------------------------------------------------------------------------- */
Real GeneralizedTrapezoidal::getTemperatureRateCoefficient(
const SolutionType & type, Real delta_t) const {
switch (type) {
case _temperature:
return 1. / (alpha * delta_t);
case _temperature_rate:
return 1.;
default:
AKANTU_EXCEPTION("The corrector type : "
<< type
<< " is not supported by this type of integration scheme");
}
}
/* -------------------------------------------------------------------------- */
template <IntegrationScheme::SolutionType type>
void GeneralizedTrapezoidal::allCorrector(Real delta_t, Array<Real> & u,
Array<Real> & u_dot,
const Array<bool> & blocked_dofs,
const Array<Real> & delta) const {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.size();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real e = getTemperatureCoefficient(type, delta_t);
Real d = getTemperatureRateCoefficient(type, delta_t);
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
Real * delta_val = delta.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt dof = 0; dof < nb_degree_of_freedom; dof++) {
if (!(*blocked_dofs_val)) {
- *u_val += e ** delta_val;
- *u_dot_val += d ** delta_val;
+ *u_val += e * *delta_val;
+ *u_dot_val += d * *delta_val;
}
u_val++;
u_dot_val++;
delta_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GeneralizedTrapezoidal::assembleJacobian(const SolutionType & type,
Real delta_t) {
AKANTU_DEBUG_IN();
SparseMatrix & J = this->dof_manager.getMatrix("J");
const SparseMatrix & M = this->dof_manager.getMatrix("M");
const SparseMatrix & K = this->dof_manager.getMatrix("K");
bool does_j_need_update = false;
does_j_need_update |= M.getRelease() != m_release;
does_j_need_update |= K.getRelease() != k_release;
if (!does_j_need_update) {
AKANTU_DEBUG_OUT();
return;
}
J.clear();
Real c = this->getTemperatureRateCoefficient(type, delta_t);
Real e = this->getTemperatureCoefficient(type, delta_t);
J.add(M, e);
J.add(K, c);
m_release = M.getRelease();
k_release = K.getRelease();
AKANTU_DEBUG_OUT();
}
} // akantu
diff --git a/src/model/integration_scheme/integration_scheme.cc b/src/model/integration_scheme/integration_scheme.cc
index 2a4766f69..dc28ebb5e 100644
--- a/src/model/integration_scheme/integration_scheme.cc
+++ b/src/model/integration_scheme/integration_scheme.cc
@@ -1,66 +1,66 @@
/**
* @file integration_scheme.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Oct 23 15:33:36 2015
*
* @brief Common interface to all interface schemes
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "integration_scheme.hh"
#include "dof_manager.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
IntegrationScheme::IntegrationScheme(DOFManager & dof_manager,
const ID & dof_id, UInt order)
- : Parsable(ParserType::_integration_scheme, dof_id), dof_manager(dof_manager),
- dof_id(dof_id), order(order) {}
+ : Parsable(ParserType::_integration_scheme, dof_id),
+ dof_manager(dof_manager), dof_id(dof_id), order(order) {}
/* -------------------------------------------------------------------------- */
/// standard input stream operator for SolutionType
std::istream & operator>>(std::istream & stream,
IntegrationScheme::SolutionType & type) {
std::string str;
stream >> str;
if (str == "displacement")
type = IntegrationScheme::_displacement;
else if (str == "temperature")
type = IntegrationScheme::_temperature;
else if (str == "velocity")
type = IntegrationScheme::_velocity;
else if (str == "temperature_rate")
type = IntegrationScheme::_temperature_rate;
else if (str == "acceleration")
type = IntegrationScheme::_acceleration;
else {
stream.setstate(std::ios::failbit);
}
return stream;
}
} // akantu
diff --git a/src/model/integration_scheme/integration_scheme_1st_order.cc b/src/model/integration_scheme/integration_scheme_1st_order.cc
index dc6ff5075..e9701c486 100644
--- a/src/model/integration_scheme/integration_scheme_1st_order.cc
+++ b/src/model/integration_scheme/integration_scheme_1st_order.cc
@@ -1,95 +1,95 @@
/**
* @file integration_scheme_1st_order.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Oct 23 12:31:32 2015
*
* @brief Implementation of the common functions for 1st order time
*integrations
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "integration_scheme_1st_order.hh"
#include "dof_manager.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
std::vector<std::string> IntegrationScheme1stOrder::getNeededMatrixList() {
return {"K", "M"};
}
/* -------------------------------------------------------------------------- */
void IntegrationScheme1stOrder::predictor(Real delta_t) {
AKANTU_DEBUG_IN();
Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
const Array<bool> & blocked_dofs =
this->dof_manager.getBlockedDOFs(this->dof_id);
this->predictor(delta_t, u, u_dot, blocked_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void IntegrationScheme1stOrder::corrector(const SolutionType & type,
Real delta_t) {
AKANTU_DEBUG_IN();
Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
const Array<Real> & solution = this->dof_manager.getSolution(this->dof_id);
const Array<bool> & blocked_dofs =
this->dof_manager.getBlockedDOFs(this->dof_id);
this->corrector(type, delta_t, u, u_dot, blocked_dofs, solution);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void IntegrationScheme1stOrder::assembleResidual(bool is_lumped) {
AKANTU_DEBUG_IN();
const Array<Real> & first_derivative =
dof_manager.getDOFsDerivatives(this->dof_id, 1);
if (not is_lumped) {
if (this->dof_manager.hasMatrix("M"))
this->dof_manager.assembleMatMulVectToResidual(this->dof_id, "M",
first_derivative, -1);
} else {
if (this->dof_manager.hasLumpedMatrix("M"))
- this->dof_manager.assembleLumpedMatMulVectToResidual(this->dof_id, "M",
- first_derivative, -1);
+ this->dof_manager.assembleLumpedMatMulVectToResidual(
+ this->dof_id, "M", first_derivative, -1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/model/integration_scheme/integration_scheme_1st_order.hh b/src/model/integration_scheme/integration_scheme_1st_order.hh
index 7c1ae27c3..d15ec19df 100644
--- a/src/model/integration_scheme/integration_scheme_1st_order.hh
+++ b/src/model/integration_scheme/integration_scheme_1st_order.hh
@@ -1,95 +1,95 @@
/**
* @file integration_scheme_1st_order.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Oct 23 2015
*
* @brief Interface of the time integrator of first order
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "integration_scheme.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
#define __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
namespace akantu {
class IntegrationScheme1stOrder : public IntegrationScheme {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegrationScheme1stOrder(DOFManager & dof_manager, const ID & dof_id)
- : IntegrationScheme(dof_manager, dof_id, 1){};
+ : IntegrationScheme(dof_manager, dof_id, 1){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get list of needed matrices
std::vector<std::string> getNeededMatrixList() override;
/// generic interface of a predictor
void predictor(Real delta_t) override;
/// generic interface of a corrector
void corrector(const SolutionType & type, Real delta_t) override;
/// assemble the residual
void assembleResidual(bool is_lumped) override;
protected:
/// generic interface of a predictor of 1st order
virtual void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & boundary) const = 0;
/// generic interface of a corrector of 1st order
virtual void corrector(const SolutionType & type, Real delta_t,
Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & boundary,
const Array<Real> & delta) const = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
protected:
virtual Real getTemperatureCoefficient(const SolutionType & type,
Real delta_t) const = 0;
virtual Real getTemperatureRateCoefficient(const SolutionType & type,
Real delta_t) const = 0;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
} // akantu
#include "generalized_trapezoidal.hh"
#endif /* __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__ */
diff --git a/src/model/integration_scheme/integration_scheme_2nd_order.cc b/src/model/integration_scheme/integration_scheme_2nd_order.cc
index 0e1993fb3..e308331dc 100644
--- a/src/model/integration_scheme/integration_scheme_2nd_order.cc
+++ b/src/model/integration_scheme/integration_scheme_2nd_order.cc
@@ -1,106 +1,105 @@
/**
* @file integration_scheme_2nd_order.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Oct 20 10:41:12 2015
*
* @brief Implementation of the common part of 2nd order integration schemes
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "integration_scheme_2nd_order.hh"
#include "dof_manager.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
-std::vector<std::string>
-IntegrationScheme2ndOrder::getNeededMatrixList() {
+std::vector<std::string> IntegrationScheme2ndOrder::getNeededMatrixList() {
return {"K", "M", "C"};
}
/* -------------------------------------------------------------------------- */
void IntegrationScheme2ndOrder::predictor(Real delta_t) {
AKANTU_DEBUG_IN();
Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
Array<Real> & u_dot_dot =
this->dof_manager.getDOFsDerivatives(this->dof_id, 2);
const Array<bool> & blocked_dofs =
this->dof_manager.getBlockedDOFs(this->dof_id);
this->predictor(delta_t, u, u_dot, u_dot_dot, blocked_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void IntegrationScheme2ndOrder::corrector(const SolutionType & type,
Real delta_t) {
AKANTU_DEBUG_IN();
Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
Array<Real> & u_dot_dot =
this->dof_manager.getDOFsDerivatives(this->dof_id, 2);
const Array<Real> & solution = this->dof_manager.getSolution(this->dof_id);
const Array<bool> & blocked_dofs =
this->dof_manager.getBlockedDOFs(this->dof_id);
this->corrector(type, delta_t, u, u_dot, u_dot_dot, blocked_dofs, solution);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void IntegrationScheme2ndOrder::assembleResidual(bool is_lumped) {
AKANTU_DEBUG_IN();
if (this->dof_manager.hasMatrix("C")) {
const Array<Real> & first_derivative =
this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
this->dof_manager.assembleMatMulVectToResidual(this->dof_id, "C",
first_derivative, -1);
}
const Array<Real> & second_derivative =
this->dof_manager.getDOFsDerivatives(this->dof_id, 2);
if (not is_lumped) {
this->dof_manager.assembleMatMulVectToResidual(this->dof_id, "M",
second_derivative, -1);
} else {
this->dof_manager.assembleLumpedMatMulVectToResidual(this->dof_id, "M",
second_derivative, -1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/integration_scheme/pseudo_time.cc b/src/model/integration_scheme/pseudo_time.cc
index a8a4c891a..6b350562d 100644
--- a/src/model/integration_scheme/pseudo_time.cc
+++ b/src/model/integration_scheme/pseudo_time.cc
@@ -1,83 +1,81 @@
/**
* @file pseudo_time.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Feb 17 09:49:10 2016
*
* @brief Implementation of a really simple integration scheme
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "pseudo_time.hh"
#include "dof_manager.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
PseudoTime::PseudoTime(DOFManager & dof_manager, const ID & dof_id)
: IntegrationScheme(dof_manager, dof_id, 0), k_release(0) {}
/* -------------------------------------------------------------------------- */
-std::vector<std::string> PseudoTime::getNeededMatrixList() {
- return {"K"};
-}
+std::vector<std::string> PseudoTime::getNeededMatrixList() { return {"K"}; }
/* -------------------------------------------------------------------------- */
void PseudoTime::predictor(Real) {}
/* -------------------------------------------------------------------------- */
void PseudoTime::corrector(const SolutionType &, Real) {
auto & us = this->dof_manager.getDOFs(this->dof_id);
const auto & deltas = this->dof_manager.getSolution(this->dof_id);
const auto & blocked_dofs = this->dof_manager.getBlockedDOFs(this->dof_id);
for (auto && tuple : zip(make_view(us), deltas, make_view(blocked_dofs))) {
auto & u = std::get<0>(tuple);
const auto & delta = std::get<1>(tuple);
const auto & bld = std::get<2>(tuple);
if (not bld)
u += delta;
}
}
/* -------------------------------------------------------------------------- */
void PseudoTime::assembleJacobian(const SolutionType &, Real) {
SparseMatrix & J = this->dof_manager.getMatrix("J");
const SparseMatrix & K = this->dof_manager.getMatrix("K");
if (K.getRelease() == k_release)
return;
J.clear();
J.add(K);
k_release = K.getRelease();
}
/* -------------------------------------------------------------------------- */
void PseudoTime::assembleResidual(bool) {}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/model/model.cc b/src/model/model.cc
index 684e072c8..959a2fba5 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,370 +1,369 @@
/**
* @file model.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Oct 03 2011
* @date last modification: Thu Nov 19 2015
*
* @brief implementation of model common parts
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "model.hh"
#include "communicator.hh"
#include "data_accessor.hh"
#include "element_group.hh"
#include "element_synchronizer.hh"
#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
Model::Model(Mesh & mesh, const ModelType & type, UInt dim, const ID & id,
const MemoryID & memory_id)
: Memory(id, memory_id), ModelSolver(mesh, type, id, memory_id), mesh(mesh),
spatial_dimension(dim == _all_dimensions ? mesh.getSpatialDimension()
: dim),
is_pbc_slave_node(0, 1, "is_pbc_slave_node"), parser(getStaticParser()) {
AKANTU_DEBUG_IN();
this->mesh.registerEventHandler(*this, _ehp_model);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Model::~Model() = default;
/* -------------------------------------------------------------------------- */
// void Model::setParser(Parser & parser) { this->parser = &parser; }
/* -------------------------------------------------------------------------- */
void Model::initFullImpl(const ModelOptions & options) {
AKANTU_DEBUG_IN();
method = options.analysis_method;
if (!this->hasDefaultSolver()) {
this->initNewSolver(this->method);
}
initModel();
initFEEngineBoundary();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Model::initNewSolver(const AnalysisMethod & method) {
ID solver_name;
TimeStepSolverType tss_type;
std::tie(solver_name, tss_type) = this->getDefaultSolverID(method);
if (not this->hasSolver(solver_name)) {
ModelSolverOptions options = this->getDefaultSolverOptions(tss_type);
this->getNewSolver(solver_name, tss_type, options.non_linear_solver_type);
for (auto && is_type : options.integration_scheme_type) {
if (!this->hasIntegrationScheme(solver_name, is_type.first)) {
this->setIntegrationScheme(solver_name, is_type.first, is_type.second,
options.solution_type[is_type.first]);
}
}
}
this->method = method;
this->setDefaultSolver(solver_name);
}
/* -------------------------------------------------------------------------- */
void Model::initPBC() {
auto it = pbc_pair.begin();
auto end = pbc_pair.end();
is_pbc_slave_node.resize(mesh.getNbNodes());
#ifndef AKANTU_NDEBUG
- auto coord_it =
- mesh.getNodes().begin(this->spatial_dimension);
+ auto coord_it = mesh.getNodes().begin(this->spatial_dimension);
#endif
while (it != end) {
UInt i1 = (*it).first;
is_pbc_slave_node(i1) = true;
#ifndef AKANTU_NDEBUG
UInt i2 = (*it).second;
UInt slave = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i1) : i1;
UInt master = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i2) : i2;
AKANTU_DEBUG_INFO("pairing " << slave << " (" << Vector<Real>(coord_it[i1])
<< ") with " << master << " ("
<< Vector<Real>(coord_it[i2]) << ")");
#endif
++it;
}
}
/* -------------------------------------------------------------------------- */
void Model::initFEEngineBoundary() {
FEEngine & fem_boundary = getFEEngineBoundary();
fem_boundary.initShapeFunctions(_not_ghost);
fem_boundary.initShapeFunctions(_ghost);
fem_boundary.computeNormalsOnIntegrationPoints(_not_ghost);
fem_boundary.computeNormalsOnIntegrationPoints(_ghost);
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup(const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.dump();
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup(const std::string & group_name,
const std::string & dumper_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.dump(dumper_name);
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup() {
auto bit = mesh.element_group_begin();
auto bend = mesh.element_group_end();
for (; bit != bend; ++bit) {
bit->second->dump();
}
}
/* -------------------------------------------------------------------------- */
void Model::setGroupDirectory(const std::string & directory) {
auto bit = mesh.element_group_begin();
auto bend = mesh.element_group_end();
for (; bit != bend; ++bit) {
bit->second->setDirectory(directory);
}
}
/* -------------------------------------------------------------------------- */
void Model::setGroupDirectory(const std::string & directory,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Model::setGroupBaseName(const std::string & basename,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.setBaseName(basename);
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Model::getGroupDumper(const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
return group.getDumper();
}
/* -------------------------------------------------------------------------- */
// DUMPER stuff
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & field_id,
dumper::Field * field,
DumperIOHelper & dumper) {
#ifdef AKANTU_USE_IOHELPER
dumper.registerField(field_id, field);
#endif
}
/* -------------------------------------------------------------------------- */
void Model::addDumpField(const std::string & field_id) {
this->addDumpFieldToDumper(mesh.getDefaultDumperName(), field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldVector(const std::string & field_id) {
this->addDumpFieldVectorToDumper(mesh.getDefaultDumperName(), field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldTensor(const std::string & field_id) {
this->addDumpFieldTensorToDumper(mesh.getDefaultDumperName(), field_id);
}
/* -------------------------------------------------------------------------- */
void Model::setBaseName(const std::string & field_id) {
mesh.setBaseName(field_id);
}
/* -------------------------------------------------------------------------- */
void Model::setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename) {
mesh.setBaseNameToDumper(dumper_name, basename);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
false);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupField(const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->addDumpGroupFieldToDumper(group.getDefaultDumperName(), field_id,
group_name, _ek_regular, false);
}
/* -------------------------------------------------------------------------- */
void Model::removeDumpGroupField(const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->removeDumpGroupFieldFromDumper(group.getDefaultDumperName(), field_id,
group_name);
}
/* -------------------------------------------------------------------------- */
void Model::removeDumpGroupFieldFromDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.removeDumpFieldFromDumper(dumper_name, field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
true);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldVector(const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->addDumpGroupFieldVectorToDumper(group.getDefaultDumperName(), field_id,
group_name);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name) {
this->addDumpGroupFieldToDumper(dumper_name, field_id, group_name,
_ek_regular, true);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
true);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag) {
this->addDumpGroupFieldToDumper(dumper_name, field_id, group_name,
this->spatial_dimension, element_kind,
padding_flag);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & element_kind,
bool padding_flag) {
#ifdef AKANTU_USE_IOHELPER
dumper::Field * field = nullptr;
if (!field)
field = this->createNodalFieldReal(field_id, group_name, padding_flag);
if (!field)
field = this->createNodalFieldUInt(field_id, group_name, padding_flag);
if (!field)
field = this->createNodalFieldBool(field_id, group_name, padding_flag);
if (!field)
field = this->createElementalField(field_id, group_name, padding_flag,
spatial_dimension, element_kind);
if (!field)
field = this->mesh.createFieldFromAttachedData<UInt>(field_id, group_name,
element_kind);
if (!field)
field = this->mesh.createFieldFromAttachedData<Real>(field_id, group_name,
element_kind);
#ifndef AKANTU_NDEBUG
if (!field) {
AKANTU_DEBUG_WARNING("No field could be found based on name: " << field_id);
}
#endif
if (field) {
DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name, group_name);
this->addDumpGroupFieldToDumper(field_id, field, dumper);
}
#endif
}
/* -------------------------------------------------------------------------- */
void Model::dump() { mesh.dump(); }
/* -------------------------------------------------------------------------- */
void Model::setDirectory(const std::string & directory) {
mesh.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Model::setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory) {
mesh.setDirectoryToDumper(dumper_name, directory);
}
/* -------------------------------------------------------------------------- */
void Model::setTextModeToDumper() { mesh.setTextModeToDumper(); }
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/model.hh b/src/model/model.hh
index f79ade1eb..af1032fae 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,377 +1,376 @@
/**
* @file model.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Oct 16 2015
*
* @brief Interface of a model
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "aka_named_argument.hh"
#include "fe_engine.hh"
#include "mesh.hh"
#include "model_options.hh"
#include "model_solver.hh"
/* -------------------------------------------------------------------------- */
#include <typeindex>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_HH__
#define __AKANTU_MODEL_HH__
namespace akantu {
class SynchronizerRegistry;
class Parser;
class DumperIOHelper;
} // namespace akantu
/* -------------------------------------------------------------------------- */
namespace akantu {
class Model : public Memory, public ModelSolver, public MeshEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Model(Mesh & mesh, const ModelType & type,
UInt spatial_dimension = _all_dimensions, const ID & id = "model",
const MemoryID & memory_id = 0);
~Model() override;
using FEEngineMap = std::map<std::string, std::unique_ptr<FEEngine>>;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
virtual void initFullImpl(const ModelOptions & options);
public:
-
#ifndef SWIG
template <typename... pack>
std::enable_if_t<are_named_argument<pack...>::value>
initFull(pack &&... _pack) {
switch (this->model_type) {
#ifdef AKANTU_SOLID_MECHANICS
case ModelType::_solid_mechanics_model:
this->initFullImpl(SolidMechanicsModelOptions{
use_named_args, std::forward<decltype(_pack)>(_pack)...});
break;
#endif
#ifdef AKANTU_COHESIVE_ELEMENT
case ModelType::_solid_mechanics_model_cohesive:
this->initFullImpl(SolidMechanicsModelCohesiveOptions{
use_named_args, std::forward<decltype(_pack)>(_pack)...});
break;
#endif
#ifdef AKANTU_HEAT_TRANSFER
case ModelType::_heat_transfer_model:
this->initFullImpl(HeatTransferModelOptions{
use_named_args, std::forward<decltype(_pack)>(_pack)...});
break;
#endif
#ifdef AKANTU_EMBEDDED
case ModelType::_embedded_model:
this->initFullImpl(EmbeddedInterfaceModelOptions{
use_named_args, std::forward<decltype(_pack)>(_pack)...});
break;
#endif
default:
this->initFullImpl(ModelOptions{use_named_args,
std::forward<decltype(_pack)>(_pack)...});
}
}
template <typename... pack>
std::enable_if_t<not are_named_argument<pack...>::value>
initFull(pack &&... _pack) {
this->initFullImpl(std::forward<decltype(_pack)>(_pack)...);
}
#endif
/// initialize a new solver if needed
void initNewSolver(const AnalysisMethod & method);
protected:
/// get some default values for derived classes
virtual std::tuple<ID, TimeStepSolverType>
getDefaultSolverID(const AnalysisMethod & method) = 0;
virtual void initModel() = 0;
virtual void initFEEngineBoundary();
// /// change local equation number so that PBC is assembled properly
// void changeLocalEquationNumberForPBC(std::map<UInt, UInt> & pbc_pair,
// UInt dimension);
/// function to print the containt of the class
void printself(std::ostream &, int = 0) const override{};
// /// initialize the model for PBC
// void setPBC(UInt x, UInt y, UInt z);
// void setPBC(SurfacePairList & surface_pairs);
public:
virtual void initPBC();
/// set the parser to use
// void setParser(Parser & parser);
/* ------------------------------------------------------------------------ */
/* Access to the dumpable interface of the boundaries */
/* ------------------------------------------------------------------------ */
/// Dump the data for a given group
void dumpGroup(const std::string & group_name);
void dumpGroup(const std::string & group_name,
const std::string & dumper_name);
/// Dump the data for all boundaries
void dumpGroup();
/// Set the directory for a given group
void setGroupDirectory(const std::string & directory,
const std::string & group_name);
/// Set the directory for all boundaries
void setGroupDirectory(const std::string & directory);
/// Set the base name for a given group
void setGroupBaseName(const std::string & basename,
const std::string & group_name);
/// Get the internal dumper of a given group
DumperIOHelper & getGroupDumper(const std::string & group_name);
/* ------------------------------------------------------------------------ */
/* Function for non local capabilities */
/* ------------------------------------------------------------------------ */
virtual void updateDataForNonLocalCriterion(__attribute__((unused))
ElementTypeMapReal & criterion) {
AKANTU_TO_IMPLEMENT();
}
protected:
template <typename T>
void allocNodalField(Array<T> *& array, UInt nb_component, const ID & name);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get id of model
AKANTU_GET_MACRO(ID, id, const ID)
/// get the number of surfaces
AKANTU_GET_MACRO(Mesh, mesh, Mesh &)
/// synchronize the boundary in case of parallel run
virtual void synchronizeBoundaries(){};
/// return the fem object associated with a provided name
inline FEEngine & getFEEngine(const ID & name = "") const;
/// return the fem boundary object associated with a provided name
virtual FEEngine & getFEEngineBoundary(const ID & name = "");
/// register a fem object associated with name
template <typename FEEngineClass>
inline void registerFEEngineObject(const std::string & name, Mesh & mesh,
UInt spatial_dimension);
/// unregister a fem object associated with name
inline void unRegisterFEEngineObject(const std::string & name);
/// return the synchronizer registry
SynchronizerRegistry & getSynchronizerRegistry();
/// return the fem object associated with a provided name
template <typename FEEngineClass>
inline FEEngineClass & getFEEngineClass(std::string name = "") const;
/// return the fem boundary object associated with a provided name
template <typename FEEngineClass>
inline FEEngineClass & getFEEngineClassBoundary(std::string name = "");
/// get the pbc pairs
std::map<UInt, UInt> & getPBCPairs() { return pbc_pair; };
/// returns if node is slave in pbc
inline bool isPBCSlaveNode(const UInt) const {
throw;
return false; /* TODO repair PBC*/
}
/// returns the array of pbc slave nodes (boolean information)
AKANTU_GET_MACRO(IsPBCSlaveNode, is_pbc_slave_node, const Array<bool> &)
/// Get the type of analysis method used
AKANTU_GET_MACRO(AnalysisMethod, method, AnalysisMethod);
/* ------------------------------------------------------------------------ */
/* Pack and unpack helper functions */
/* ------------------------------------------------------------------------ */
public:
inline UInt getNbIntegrationPoints(const Array<Element> & elements,
const ID & fem_id = ID()) const;
/* ------------------------------------------------------------------------ */
/* Dumpable interface (kept for convenience) and dumper relative functions */
/* ------------------------------------------------------------------------ */
void setTextModeToDumper();
virtual void addDumpGroupFieldToDumper(const std::string & field_id,
dumper::Field * field,
DumperIOHelper & dumper);
virtual void addDumpField(const std::string & field_id);
virtual void addDumpFieldVector(const std::string & field_id);
virtual void addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensor(const std::string & field_id);
virtual void setBaseName(const std::string & basename);
virtual void setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename);
virtual void addDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag);
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & element_kind,
bool padding_flag);
virtual void removeDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void removeDumpGroupFieldFromDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVector(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
virtual dumper::Field *
createNodalFieldReal(__attribute__((unused)) const std::string & field_name,
__attribute__((unused)) const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
return nullptr;
}
virtual dumper::Field *
createNodalFieldUInt(__attribute__((unused)) const std::string & field_name,
__attribute__((unused)) const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
return nullptr;
}
virtual dumper::Field *
createNodalFieldBool(__attribute__((unused)) const std::string & field_name,
__attribute__((unused)) const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
return nullptr;
}
virtual dumper::Field *
createElementalField(__attribute__((unused)) const std::string & field_name,
__attribute__((unused)) const std::string & group_name,
__attribute__((unused)) bool padding_flag,
__attribute__((unused)) const UInt & spatial_dimension,
__attribute__((unused)) const ElementKind & kind) {
return nullptr;
}
void setDirectory(const std::string & directory);
void setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory);
virtual void dump();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
friend std::ostream & operator<<(std::ostream &, const Model &);
/// analysis method check the list in akantu::AnalysisMethod
AnalysisMethod method;
/// Mesh
Mesh & mesh;
/// Spatial dimension of the problem
UInt spatial_dimension;
/// the main fem object present in all models
FEEngineMap fems;
/// the fem object present in all models for boundaries
FEEngineMap fems_boundary;
/// default fem object
std::string default_fem;
/// pbc pairs
std::map<UInt, UInt> pbc_pair;
/// flag per node to know is pbc slave
Array<bool> is_pbc_slave_node;
/// parser to the pointer to use
Parser & parser;
};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream, const Model & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "model_inline_impl.cc"
#endif /* __AKANTU_MODEL_HH__ */
diff --git a/src/model/model_inline_impl.cc b/src/model/model_inline_impl.cc
index 989145ac8..c57bbf7ed 100644
--- a/src/model/model_inline_impl.cc
+++ b/src/model/model_inline_impl.cc
@@ -1,215 +1,217 @@
/**
* @file model_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 25 2010
* @date last modification: Wed Nov 11 2015
*
* @brief inline implementation of the model class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "model.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_INLINE_IMPL_CC__
#define __AKANTU_MODEL_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline FEEngineClass & Model::getFEEngineClassBoundary(std::string name) {
AKANTU_DEBUG_IN();
if (name == "")
name = default_fem;
FEEngineMap::const_iterator it_boun = fems_boundary.find(name);
if (it_boun == fems_boundary.end()) {
AKANTU_DEBUG_INFO("Creating FEEngine boundary " << name);
FEEngineMap::const_iterator it = fems.find(name);
- AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEEngine "
- << name << " is not registered");
+ AKANTU_DEBUG_ASSERT(it != fems.end(),
+ "The FEEngine " << name << " is not registered");
UInt spatial_dimension = it->second->getElementDimension();
std::stringstream sstr;
sstr << id << ":fem_boundary:" << name;
fems_boundary[name] = std::make_unique<FEEngineClass>(
it->second->getMesh(), spatial_dimension - 1, sstr.str(), memory_id);
}
AKANTU_DEBUG_OUT();
return dynamic_cast<FEEngineClass &>(*fems_boundary[name]);
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline FEEngineClass & Model::getFEEngineClass(std::string name) const {
AKANTU_DEBUG_IN();
if (name == "")
name = default_fem;
auto it = fems.find(name);
- AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEEngine "
- << name << " is not registered");
+ AKANTU_DEBUG_ASSERT(it != fems.end(),
+ "The FEEngine " << name << " is not registered");
AKANTU_DEBUG_OUT();
return dynamic_cast<FEEngineClass &>(*(it->second));
}
/* -------------------------------------------------------------------------- */
inline void Model::unRegisterFEEngineObject(const std::string & name) {
auto it = fems.find(name);
- AKANTU_DEBUG_ASSERT(it != fems.end(), "FEEngine object with name "
- << name << " was not found");
+ AKANTU_DEBUG_ASSERT(it != fems.end(),
+ "FEEngine object with name " << name << " was not found");
fems.erase(it);
if (!fems.empty())
default_fem = (*fems.begin()).first;
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline void Model::registerFEEngineObject(const std::string & name, Mesh & mesh,
UInt spatial_dimension) {
if (fems.size() == 0)
default_fem = name;
#ifndef AKANTU_NDEBUG
auto it = fems.find(name);
- AKANTU_DEBUG_ASSERT(it == fems.end(), "FEEngine object with name "
- << name << " was already created");
+ AKANTU_DEBUG_ASSERT(it == fems.end(),
+ "FEEngine object with name " << name
+ << " was already created");
#endif
std::stringstream sstr;
sstr << id << ":fem:" << name << memory_id;
- fems[name] = std::make_unique<FEEngineClass>(mesh, spatial_dimension, sstr.str(), memory_id);
+ fems[name] = std::make_unique<FEEngineClass>(mesh, spatial_dimension,
+ sstr.str(), memory_id);
}
/* -------------------------------------------------------------------------- */
inline FEEngine & Model::getFEEngine(const ID & name) const {
AKANTU_DEBUG_IN();
ID tmp_name = name;
if (name == "")
tmp_name = default_fem;
auto it = fems.find(tmp_name);
AKANTU_DEBUG_ASSERT(it != fems.end(),
"The FEEngine " << tmp_name << " is not registered");
AKANTU_DEBUG_OUT();
- return *(it->second);\
+ return *(it->second);
}
/* -------------------------------------------------------------------------- */
inline FEEngine & Model::getFEEngineBoundary(const ID & name) {
AKANTU_DEBUG_IN();
ID tmp_name = name;
if (name == "")
tmp_name = default_fem;
FEEngineMap::const_iterator it = fems_boundary.find(tmp_name);
- AKANTU_DEBUG_ASSERT(it != fems_boundary.end(), "The FEEngine boundary "
- << tmp_name
- << " is not registered");
- AKANTU_DEBUG_ASSERT(it->second != nullptr, "The FEEngine boundary "
- << tmp_name
- << " was not created");
+ AKANTU_DEBUG_ASSERT(it != fems_boundary.end(),
+ "The FEEngine boundary " << tmp_name
+ << " is not registered");
+ AKANTU_DEBUG_ASSERT(it->second != nullptr,
+ "The FEEngine boundary " << tmp_name
+ << " was not created");
AKANTU_DEBUG_OUT();
return *(it->second);
}
// /* --------------------------------------------------------------------------
// */
// /// @todo : should merge with a single function which handles local and
// global
// inline void Model::changeLocalEquationNumberForPBC(std::map<UInt,UInt> &
// pbc_pair,
// UInt dimension){
// for (std::map<UInt,UInt>::iterator it = pbc_pair.begin();
// it != pbc_pair.end();++it) {
// Int node_master = (*it).second;
// Int node_slave = (*it).first;
// for (UInt i = 0; i < dimension; ++i) {
// (*dof_synchronizer->getLocalDOFEquationNumbersPointer())
// (node_slave*dimension+i) = dimension*node_master+i;
// (*dof_synchronizer->getGlobalDOFEquationNumbersPointer())
// (node_slave*dimension+i) = dimension*node_master+i;
// }
// }
// }
// /* --------------------------------------------------------------------------
// */
// inline bool Model::isPBCSlaveNode(const UInt node) const {
// // if no pbc is defined, is_pbc_slave_node is of size zero
// if (is_pbc_slave_node.size() == 0)
// return false;
// else
// return is_pbc_slave_node(node);
// }
/* -------------------------------------------------------------------------- */
template <typename T>
-void Model::allocNodalField(Array<T> *& array, UInt nb_component, const ID & name) {
+void Model::allocNodalField(Array<T> *& array, UInt nb_component,
+ const ID & name) {
if (array == nullptr) {
UInt nb_nodes = mesh.getNbNodes();
std::stringstream sstr_disp;
sstr_disp << id << ":" << name;
- array =
- &(alloc<T>(sstr_disp.str(), nb_nodes, nb_component, T()));
+ array = &(alloc<T>(sstr_disp.str(), nb_nodes, nb_component, T()));
}
}
/* -------------------------------------------------------------------------- */
inline UInt Model::getNbIntegrationPoints(const Array<Element> & elements,
const ID & fem_id) const {
UInt nb_quad = 0;
Array<Element>::const_iterator<Element> it = elements.begin();
Array<Element>::const_iterator<Element> end = elements.end();
for (; it != end; ++it) {
const Element & el = *it;
nb_quad +=
getFEEngine(fem_id).getNbIntegrationPoints(el.type, el.ghost_type);
}
return nb_quad;
}
/* -------------------------------------------------------------------------- */
} // akantu
#endif /* __AKANTU_MODEL_INLINE_IMPL_CC__ */
diff --git a/src/model/model_options.hh b/src/model/model_options.hh
index a4d1d8f58..c431d6931 100644
--- a/src/model/model_options.hh
+++ b/src/model/model_options.hh
@@ -1,137 +1,137 @@
/**
* @file model_options.hh
*
* @author Nicolas Richart
*
* @date creation Mon Dec 04 2017
*
* @brief A Documented file.
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_named_argument.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_OPTIONS_HH__
#define __AKANTU_MODEL_OPTIONS_HH__
namespace akantu {
namespace {
DECLARE_NAMED_ARGUMENT(analysis_method);
}
struct ModelOptions {
explicit ModelOptions(AnalysisMethod analysis_method = _static)
: analysis_method(analysis_method) {}
template <typename... pack>
ModelOptions(use_named_args_t, pack &&... _pack)
: ModelOptions(OPTIONAL_NAMED_ARG(analysis_method, _static)) {}
virtual ~ModelOptions() = default;
AnalysisMethod analysis_method;
};
#ifdef AKANTU_SOLID_MECHANICS
/* -------------------------------------------------------------------------- */
struct SolidMechanicsModelOptions : public ModelOptions {
explicit SolidMechanicsModelOptions(
AnalysisMethod analysis_method = _explicit_lumped_mass)
: ModelOptions(analysis_method) {}
template <typename... pack>
SolidMechanicsModelOptions(use_named_args_t, pack &&... _pack)
: SolidMechanicsModelOptions(
OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass)) {}
};
#endif
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_COHESIVE_ELEMENT
namespace {
DECLARE_NAMED_ARGUMENT(is_extrinsic);
}
/* -------------------------------------------------------------------------- */
struct SolidMechanicsModelCohesiveOptions : public SolidMechanicsModelOptions {
SolidMechanicsModelCohesiveOptions(
AnalysisMethod analysis_method = _explicit_lumped_mass,
bool extrinsic = false)
: SolidMechanicsModelOptions(analysis_method), extrinsic(extrinsic) {}
template <typename... pack>
SolidMechanicsModelCohesiveOptions(use_named_args_t, pack &&... _pack)
: SolidMechanicsModelCohesiveOptions(
OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass),
OPTIONAL_NAMED_ARG(is_extrinsic, false)) {}
bool extrinsic{false};
};
#endif
#ifdef AKANTU_HEAT_TRANSFER
/* -------------------------------------------------------------------------- */
struct HeatTransferModelOptions : public ModelOptions {
explicit HeatTransferModelOptions(
AnalysisMethod analysis_method = _explicit_lumped_mass)
: ModelOptions(analysis_method) {}
template <typename... pack>
HeatTransferModelOptions(use_named_args_t, pack &&... _pack)
: HeatTransferModelOptions(
OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass)) {}
};
#endif
#ifdef AKANTU_EMBEDDED
namespace {
DECLARE_NAMED_ARGUMENT(init_intersections);
}
/* -------------------------------------------------------------------------- */
struct EmbeddedInterfaceModelOptions : SolidMechanicsModelOptions {
/**
* @brief Constructor for EmbeddedInterfaceModelOptions
* @param analysis_method see SolidMechanicsModelOptions
* @param init_intersections compute intersections
*/
- EmbeddedInterfaceModelOptions(AnalysisMethod analysis_method = _explicit_lumped_mass,
- bool init_intersections = true):
- SolidMechanicsModelOptions(analysis_method),
- has_intersections(init_intersections)
- {}
+ EmbeddedInterfaceModelOptions(
+ AnalysisMethod analysis_method = _explicit_lumped_mass,
+ bool init_intersections = true)
+ : SolidMechanicsModelOptions(analysis_method),
+ has_intersections(init_intersections) {}
template <typename... pack>
EmbeddedInterfaceModelOptions(use_named_args_t, pack &&... _pack)
: EmbeddedInterfaceModelOptions(
OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass),
OPTIONAL_NAMED_ARG(init_intersections, true)) {}
/// Should consider reinforcements
bool has_intersections;
};
#endif
} // akantu
#endif /* __AKANTU_MODEL_OPTIONS_HH__ */
diff --git a/src/model/model_solver.hh b/src/model/model_solver.hh
index d469f4880..4c6179ad9 100644
--- a/src/model/model_solver.hh
+++ b/src/model/model_solver.hh
@@ -1,193 +1,193 @@
/**
* @file model_solver.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Jul 22 10:53:10 2015
*
* @brief Class regrouping the common solve interface to the different models
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "integration_scheme.hh"
#include "parsable.hh"
#include "solver_callback.hh"
#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
#include <set>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_SOLVER_HH__
#define __AKANTU_MODEL_SOLVER_HH__
namespace akantu {
class Mesh;
class DOFManager;
class TimeStepSolver;
class NonLinearSolver;
struct ModelSolverOptions;
}
namespace akantu {
class ModelSolver : public Parsable,
public SolverCallback,
public SynchronizerRegistry {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ModelSolver(Mesh & mesh, const ModelType & type, const ID & id,
UInt memory_id);
~ModelSolver() override;
/// initialize the dof manager based on solver type passed in the input file
void initDOFManager();
/// initialize the dof manager based on the used chosen solver type
void initDOFManager(const ID & solver_type);
protected:
/// initialize the dof manager based on the used chosen solver type
void initDOFManager(const ParserSection & section, const ID & solver_type);
/// Callback for the model to instantiate the matricees when needed
virtual void initSolver(TimeStepSolverType /*time_step_solver_type*/,
NonLinearSolverType /*non_linear_solver_type*/) {}
/// get the section in the input file (if it exsits) corresponding to this
/// model
std::tuple<ParserSection, bool> getParserSection();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// solve a step using a given pre instantiated time step solver and
/// nondynamic linear solver
virtual void solveStep(const ID & solver_id = "");
/// Initialize a time solver that can be used afterwards with its id
void getNewSolver(const ID & solver_id,
TimeStepSolverType time_step_solver_type,
NonLinearSolverType non_linear_solver_type = _nls_auto);
/// set an integration scheme for a given dof and a given solver
void
setIntegrationScheme(const ID & solver_id, const ID & dof_id,
const IntegrationSchemeType & integration_scheme_type,
IntegrationScheme::SolutionType solution_type =
IntegrationScheme::_not_defined);
/// set an externally instantiated integration scheme
void setIntegrationScheme(const ID & solver_id, const ID & dof_id,
IntegrationScheme & integration_scheme,
IntegrationScheme::SolutionType solution_type =
IntegrationScheme::_not_defined);
/* ------------------------------------------------------------------------ */
/* SolverCallback interface */
/* ------------------------------------------------------------------------ */
public:
/// Predictor interface for the callback
void predictor() override;
/// Corrector interface for the callback
void corrector() override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Default time step solver to instantiate for this model
virtual TimeStepSolverType getDefaultSolverType() const;
/// Default configurations for a given time step solver
virtual ModelSolverOptions
getDefaultSolverOptions(const TimeStepSolverType & type) const;
/// get access to the internal dof manager
DOFManager & getDOFManager() { return *this->dof_manager; }
/// get the time step of a given solver
Real getTimeStep(const ID & solver_id = "") const;
/// set the time step of a given solver
virtual void setTimeStep(Real time_step, const ID & solver_id = "");
/// set the parameter 'param' of the solver 'solver_id'
// template <typename T>
// void set(const ID & param, const T & value, const ID & solver_id = "");
/// get the parameter 'param' of the solver 'solver_id'
- //const Parameter & get(const ID & param, const ID & solver_id = "") const;
+ // const Parameter & get(const ID & param, const ID & solver_id = "") const;
/// answer to the question "does the solver exists ?"
bool hasSolver(const ID & solver_id) const;
/// changes the current default solver
void setDefaultSolver(const ID & solver_id);
/// is a default solver defined
bool hasDefaultSolver() const;
/// is an integration scheme set for a given solver and a given dof
bool hasIntegrationScheme(const ID & solver_id, const ID & dof_id) const;
TimeStepSolver & getTimeStepSolver(const ID & solver_id = "");
NonLinearSolver & getNonLinearSolver(const ID & solver_id = "");
const TimeStepSolver & getTimeStepSolver(const ID & solver_id = "") const;
const NonLinearSolver & getNonLinearSolver(const ID & solver_id = "") const;
private:
TimeStepSolver & getSolver(const ID & solver_id);
const TimeStepSolver & getSolver(const ID & solver_id) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
ModelType model_type;
private:
ID parent_id;
UInt parent_memory_id;
/// Underlying mesh
Mesh & mesh;
/// Underlying dof_manager (the brain...)
std::unique_ptr<DOFManager> dof_manager;
/// Default time step solver to use
ID default_solver_id;
};
struct ModelSolverOptions {
NonLinearSolverType non_linear_solver_type;
std::map<ID, IntegrationSchemeType> integration_scheme_type;
std::map<ID, IntegrationScheme::SolutionType> solution_type;
};
} // akantu
#endif /* __AKANTU_MODEL_SOLVER_HH__ */
diff --git a/src/model/non_linear_solver_callback.hh b/src/model/non_linear_solver_callback.hh
index 4b9953d8c..43895ca8e 100644
--- a/src/model/non_linear_solver_callback.hh
+++ b/src/model/non_linear_solver_callback.hh
@@ -1,61 +1,60 @@
/**
* @file non_linear_solver_callback.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Sep 28 18:48:21 2015
*
* @brief Interface to implement for the non linear solver to work
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LINEAR_SOLVER_CALLBACK_HH__
#define __AKANTU_NON_LINEAR_SOLVER_CALLBACK_HH__
namespace akantu {
class NonLinearSolverCallback {
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// callback to assemble the Jacobian Matrix
virtual void assembleJacobian() { AKANTU_TO_IMPLEMENT(); }
/// callback to assemble the residual (rhs)
virtual void assembleResidual() { AKANTU_TO_IMPLEMENT(); }
/* ------------------------------------------------------------------------ */
/* Dynamic simulations part */
/* ------------------------------------------------------------------------ */
/// callback for the predictor (in case of dynamic simulation)
virtual void predictor() { AKANTU_TO_IMPLEMENT(); }
/// callback for the corrector (in case of dynamic simulation)
virtual void corrector() { AKANTU_TO_IMPLEMENT(); }
};
} // akantu
-
#endif /* __AKANTU_NON_LINEAR_SOLVER_CALLBACK_HH__ */
diff --git a/src/model/non_linear_solver_default.hh b/src/model/non_linear_solver_default.hh
index f3e1aac6d..3f7dad3e2 100644
--- a/src/model/non_linear_solver_default.hh
+++ b/src/model/non_linear_solver_default.hh
@@ -1,45 +1,44 @@
/**
* @file non_linear_solver_default.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Feb 16 10:37:01 2016
*
* @brief Include for the default non linear solvers
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LINEAR_SOLVER_DEFAULT_HH__
#define __AKANTU_NON_LINEAR_SOLVER_DEFAULT_HH__
#if defined(AKANTU_IMPLICIT)
-# include "non_linear_solver_newton_raphson.hh"
-# include "non_linear_solver_linear.hh"
+#include "non_linear_solver_linear.hh"
+#include "non_linear_solver_newton_raphson.hh"
#endif
#include "non_linear_solver_lumped.hh"
-
#endif /* __AKANTU_NON_LINEAR_SOLVER_DEFAULT_HH__ */
diff --git a/src/model/non_linear_solver_linear.hh b/src/model/non_linear_solver_linear.hh
index 289fff390..d402ec16e 100644
--- a/src/model/non_linear_solver_linear.hh
+++ b/src/model/non_linear_solver_linear.hh
@@ -1,78 +1,78 @@
/**
* @file non_linear_solver_linear.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Aug 25 00:48:07 2015
*
* @brief Default implementation of NonLinearSolver, in case no external library
* is there to do the job
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_linear_solver.hh"
#include "sparse_solver_mumps.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LINEAR_SOLVER_LINEAR_HH__
#define __AKANTU_NON_LINEAR_SOLVER_LINEAR_HH__
namespace akantu {
- class DOFManagerDefault;
+class DOFManagerDefault;
}
namespace akantu {
class NonLinearSolverLinear : public NonLinearSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLinearSolverLinear(DOFManagerDefault & dof_manager,
- const NonLinearSolverType & non_linear_solver_type,
- const ID & id = "non_linear_solver_linear",
- UInt memory_id = 0);
+ const NonLinearSolverType & non_linear_solver_type,
+ const ID & id = "non_linear_solver_linear",
+ UInt memory_id = 0);
~NonLinearSolverLinear() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Function that solve the non linear system described by the dof manager and
/// the solver callback functions
void solve(SolverCallback & solver_callback) override;
AKANTU_GET_MACRO_NOT_CONST(Solver, solver, SparseSolverMumps &);
AKANTU_GET_MACRO(Solver, solver, const SparseSolverMumps &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
DOFManagerDefault & dof_manager;
/// Sparse solver used for the linear solves
SparseSolverMumps solver;
};
} // akantu
#endif /* __AKANTU_NON_LINEAR_SOLVER_LINEAR_HH__ */
diff --git a/src/model/non_linear_solver_lumped.cc b/src/model/non_linear_solver_lumped.cc
index 30f02ad2e..1b0f70487 100644
--- a/src/model/non_linear_solver_lumped.cc
+++ b/src/model/non_linear_solver_lumped.cc
@@ -1,102 +1,102 @@
/**
* @file non_linear_solver_lumped.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Aug 25 00:57:00 2015
*
* @brief Implementation of the default NonLinearSolver
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_linear_solver_lumped.hh"
+#include "communicator.hh"
#include "dof_manager_default.hh"
#include "solver_callback.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
NonLinearSolverLumped::NonLinearSolverLumped(
DOFManagerDefault & dof_manager,
const NonLinearSolverType & non_linear_solver_type, const ID & id,
UInt memory_id)
: NonLinearSolver(dof_manager, non_linear_solver_type, id, memory_id),
dof_manager(dof_manager) {
this->supported_type.insert(_nls_lumped);
this->checkIfTypeIsSupported();
this->registerParam("b_a2x", this->alpha, 1., _pat_parsmod,
"Conversion coefficient between x and A^{-1} b");
}
/* -------------------------------------------------------------------------- */
NonLinearSolverLumped::~NonLinearSolverLumped() = default;
/* ------------------------------------------------------------------------ */
void NonLinearSolverLumped::solve(SolverCallback & solver_callback) {
this->dof_manager.updateGlobalBlockedDofs();
solver_callback.predictor();
auto & x = this->dof_manager.getGlobalSolution();
const auto & b = this->dof_manager.getResidual();
x.resize(b.size());
this->dof_manager.updateGlobalBlockedDofs();
const Array<bool> & blocked_dofs = this->dof_manager.getGlobalBlockedDOFs();
solver_callback.assembleResidual();
const auto & A = this->dof_manager.getLumpedMatrix("M");
// alpha is the conversion factor from from force/mass to acceleration needed
// in model coupled with atomistic \todo find a way to define alpha per dof
// type
this->solveLumped(A, x, b, blocked_dofs, alpha);
this->dof_manager.splitSolutionPerDOFs();
solver_callback.corrector();
}
/* -------------------------------------------------------------------------- */
void NonLinearSolverLumped::solveLumped(const Array<Real> & A, Array<Real> & x,
const Array<Real> & b,
const Array<bool> & blocked_dofs,
Real alpha) {
auto A_it = A.begin();
auto x_it = x.begin();
auto x_end = x.end();
auto b_it = b.begin();
auto blocked_it = blocked_dofs.begin();
for (; x_it != x_end; ++x_it, ++b_it, ++A_it, ++blocked_it) {
if (!(*blocked_it)) {
- *x_it = alpha *(*b_it / *A_it);
+ *x_it = alpha * (*b_it / *A_it);
}
}
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/model/non_linear_solver_lumped.hh b/src/model/non_linear_solver_lumped.hh
index 49fb89af3..b27623579 100644
--- a/src/model/non_linear_solver_lumped.hh
+++ b/src/model/non_linear_solver_lumped.hh
@@ -1,81 +1,79 @@
/**
* @file non_linear_solver_lumped.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Aug 25 00:48:07 2015
*
* @brief Default implementation of NonLinearSolver, in case no external library
* is there to do the job
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_linear_solver.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LINEAR_SOLVER_LUMPED_HH__
#define __AKANTU_NON_LINEAR_SOLVER_LUMPED_HH__
namespace akantu {
- class DOFManagerDefault;
+class DOFManagerDefault;
}
namespace akantu {
class NonLinearSolverLumped : public NonLinearSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NonLinearSolverLumped(DOFManagerDefault & dof_manager,
- const NonLinearSolverType & non_linear_solver_type,
- const ID & id = "non_linear_solver_lumped",
- UInt memory_id = 0);
+ const NonLinearSolverType & non_linear_solver_type,
+ const ID & id = "non_linear_solver_lumped",
+ UInt memory_id = 0);
~NonLinearSolverLumped() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Function that solve the non linear system described by the dof manager and
/// the solver callback functions
void solve(SolverCallback & solver_callback) override;
- static void solveLumped(const Array<Real> & A,
- Array<Real> & x,
+ static void solveLumped(const Array<Real> & A, Array<Real> & x,
const Array<Real> & b,
- const Array<bool> & blocked_dofs,
- Real alpha);
+ const Array<bool> & blocked_dofs, Real alpha);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
DOFManagerDefault & dof_manager;
/// Coefficient to apply between x and A^{-1} b
Real alpha;
};
} // akantu
#endif /* __AKANTU_NON_LINEAR_SOLVER_LUMPED_HH__ */
diff --git a/src/model/non_linear_solver_newton_raphson.hh b/src/model/non_linear_solver_newton_raphson.hh
index 36260f624..aff6ee6b8 100644
--- a/src/model/non_linear_solver_newton_raphson.hh
+++ b/src/model/non_linear_solver_newton_raphson.hh
@@ -1,104 +1,104 @@
/**
* @file non_linear_solver_newton_raphson.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Aug 25 00:48:07 2015
*
* @brief Default implementation of NonLinearSolver, in case no external library
* is there to do the job
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_linear_solver.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__
#define __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__
namespace akantu {
- class DOFManagerDefault;
- class SparseSolverMumps;
+class DOFManagerDefault;
+class SparseSolverMumps;
}
namespace akantu {
class NonLinearSolverNewtonRaphson : public NonLinearSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- NonLinearSolverNewtonRaphson(DOFManagerDefault & dof_manager,
- const NonLinearSolverType & non_linear_solver_type,
- const ID & id = "non_linear_solver_newton_raphson",
- UInt memory_id = 0);
+ NonLinearSolverNewtonRaphson(
+ DOFManagerDefault & dof_manager,
+ const NonLinearSolverType & non_linear_solver_type,
+ const ID & id = "non_linear_solver_newton_raphson", UInt memory_id = 0);
~NonLinearSolverNewtonRaphson() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Function that solve the non linear system described by the dof manager and
/// the solver callback functions
void solve(SolverCallback & solver_callback) override;
AKANTU_GET_MACRO_NOT_CONST(Solver, *solver, SparseSolverMumps &);
AKANTU_GET_MACRO(Solver, *solver, const SparseSolverMumps &);
protected:
/// test the convergence compare norm of array to convergence_criteria
bool testConvergence(const Array<Real> & array);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
DOFManagerDefault & dof_manager;
/// Sparse solver used for the linear solves
std::unique_ptr<SparseSolverMumps> solver;
/// Type of convergence criteria
SolveConvergenceCriteria convergence_criteria_type;
/// convergence threshold
Real convergence_criteria;
/// Max number of iterations
int max_iterations;
/// Number of iterations at last solve call
int n_iter{0};
/// Convergence error at last solve call
Real error{0.};
/// Did the last call to solve reached convergence
bool converged{false};
/// Force a re-computation of the jacobian matrix
bool force_linear_recompute{true};
};
} // akantu
#endif /* __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__ */
diff --git a/src/model/solid_mechanics/material.cc b/src/model/solid_mechanics/material.cc
index 270238636..d266c906c 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1378 +1,1377 @@
/**
* @file material.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Tue Nov 24 2015
*
* @brief Implementation of the common part of the material class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
Material::Material(SolidMechanicsModel & model, const ID & id)
: Memory(id, model.getMemoryID()), Parsable(ParserType::_material, id),
is_init(false), fem(model.getFEEngine()), finite_deformation(false),
name(""), model(model),
spatial_dimension(this->model.getSpatialDimension()),
element_filter("element_filter", id, this->memory_id),
stress("stress", *this), eigengradu("eigen_grad_u", *this),
gradu("grad_u", *this), green_strain("green_strain", *this),
piola_kirchhoff_2("piola_kirchhoff_2", *this),
potential_energy("potential_energy", *this), is_non_local(false),
use_previous_stress(false), use_previous_gradu(false),
interpolation_inverse_coordinates("interpolation inverse coordinates",
*this),
interpolation_points_matrices("interpolation points matrices", *this) {
AKANTU_DEBUG_IN();
/// for each connectivity types allocate the element filer array of the
/// material
element_filter.initialize(model.getMesh(),
_spatial_dimension = spatial_dimension);
// model.getMesh().initElementTypeMapArray(element_filter, 1,
// spatial_dimension,
// false, _ek_regular);
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Material::Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
FEEngine & fe_engine, const ID & id)
: Memory(id, model.getMemoryID()), Parsable(ParserType::_material, id),
is_init(false), fem(fe_engine), finite_deformation(false), name(""),
model(model), spatial_dimension(dim),
element_filter("element_filter", id, this->memory_id),
stress("stress", *this, dim, fe_engine, this->element_filter),
eigengradu("eigen_grad_u", *this, dim, fe_engine, this->element_filter),
gradu("gradu", *this, dim, fe_engine, this->element_filter),
green_strain("green_strain", *this, dim, fe_engine, this->element_filter),
piola_kirchhoff_2("piola_kirchhoff_2", *this, dim, fe_engine,
this->element_filter),
potential_energy("potential_energy", *this, dim, fe_engine,
this->element_filter),
is_non_local(false), use_previous_stress(false),
use_previous_gradu(false),
interpolation_inverse_coordinates("interpolation inverse_coordinates",
*this, dim, fe_engine,
this->element_filter),
interpolation_points_matrices("interpolation points matrices", *this, dim,
fe_engine, this->element_filter) {
AKANTU_DEBUG_IN();
element_filter.initialize(mesh, _spatial_dimension = spatial_dimension);
// mesh.initElementTypeMapArray(element_filter, 1, spatial_dimension, false,
// _ek_regular);
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Material::~Material() = default;
/* -------------------------------------------------------------------------- */
void Material::initialize() {
registerParam("rho", rho, Real(0.), _pat_parsable | _pat_modifiable,
"Density");
registerParam("name", name, std::string(), _pat_parsable | _pat_readable);
registerParam("finite_deformation", finite_deformation, false,
_pat_parsable | _pat_readable, "Is finite deformation");
registerParam("inelastic_deformation", inelastic_deformation, false,
_pat_internal, "Is inelastic deformation");
/// allocate gradu stress for local elements
eigengradu.initialize(spatial_dimension * spatial_dimension);
gradu.initialize(spatial_dimension * spatial_dimension);
stress.initialize(spatial_dimension * spatial_dimension);
potential_energy.initialize(1);
this->model.registerEventHandler(*this);
}
/* -------------------------------------------------------------------------- */
void Material::initMaterial() {
AKANTU_DEBUG_IN();
if (finite_deformation) {
this->piola_kirchhoff_2.initialize(spatial_dimension * spatial_dimension);
if (use_previous_stress)
this->piola_kirchhoff_2.initializeHistory();
this->green_strain.initialize(spatial_dimension * spatial_dimension);
}
if (use_previous_stress)
this->stress.initializeHistory();
if (use_previous_gradu)
this->gradu.initializeHistory();
for (auto it = internal_vectors_real.begin();
it != internal_vectors_real.end(); ++it)
it->second->resize();
for (auto it = internal_vectors_uint.begin();
it != internal_vectors_uint.end(); ++it)
it->second->resize();
for (auto it = internal_vectors_bool.begin();
it != internal_vectors_bool.end(); ++it)
it->second->resize();
is_init = true;
updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::savePreviousState() {
AKANTU_DEBUG_IN();
for (auto it = internal_vectors_real.begin();
it != internal_vectors_real.end(); ++it) {
if (it->second->hasHistory())
it->second->saveCurrentValues();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the residual by assembling @f$\int_{e} \sigma_e \frac{\partial
* \varphi}{\partial X} dX @f$
*
* @param[in] displacements nodes displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
// void Material::updateResidual(GhostType ghost_type) {
// AKANTU_DEBUG_IN();
// computeAllStresses(ghost_type);
// assembleResidual(ghost_type);
// AKANTU_DEBUG_OUT();
// }
/* -------------------------------------------------------------------------- */
void Material::assembleInternalForces(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
if (!finite_deformation) {
auto & internal_force = const_cast<Array<Real> &>(model.getInternalForce());
// Mesh & mesh = fem.getMesh();
for (auto && type :
element_filter.elementTypes(spatial_dimension, ghost_type)) {
Array<UInt> & elem_filter = element_filter(type, ghost_type);
UInt nb_element = elem_filter.size();
if (nb_element == 0)
continue;
const Array<Real> & shapes_derivatives =
fem.getShapesDerivatives(type, ghost_type);
UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
/// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by
/// @f$\mathbf{B}^t \mathbf{\sigma}_q@f$
Array<Real> * sigma_dphi_dx =
new Array<Real>(nb_element * nb_quadrature_points,
size_of_shapes_derivatives, "sigma_x_dphi_/_dX");
fem.computeBtD(stress(type, ghost_type), *sigma_dphi_dx, type, ghost_type,
elem_filter);
/**
* compute @f$\int \sigma * \frac{\partial \varphi}{\partial X}dX@f$ by
* @f$ \sum_q \mathbf{B}^t
* \mathbf{\sigma}_q \overline w_q J_q@f$
*/
Array<Real> * int_sigma_dphi_dx =
new Array<Real>(nb_element, nb_nodes_per_element * spatial_dimension,
"int_sigma_x_dphi_/_dX");
fem.integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
size_of_shapes_derivatives, type, ghost_type, elem_filter);
delete sigma_dphi_dx;
/// assemble
model.getDOFManager().assembleElementalArrayLocalArray(
*int_sigma_dphi_dx, internal_force, type, ghost_type, -1,
elem_filter);
delete int_sigma_dphi_dx;
}
} else {
switch (spatial_dimension) {
case 1:
this->assembleInternalForces<1>(ghost_type);
break;
case 2:
this->assembleInternalForces<2>(ghost_type);
break;
case 3:
this->assembleInternalForces<3>(ghost_type);
break;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the stress from the gradu
*
* @param[in] current_position nodes postition + displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::computeAllStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
for (const auto & type :
element_filter.elementTypes(spatial_dimension, ghost_type)) {
Array<UInt> & elem_filter = element_filter(type, ghost_type);
if (elem_filter.size() == 0)
continue;
Array<Real> & gradu_vect = gradu(type, ghost_type);
/// compute @f$\nabla u@f$
fem.gradientOnIntegrationPoints(model.getDisplacement(), gradu_vect,
spatial_dimension, type, ghost_type,
elem_filter);
gradu_vect -= eigengradu(type, ghost_type);
/// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$
computeStress(type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computeAllCauchyStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(finite_deformation, "The Cauchy stress can only be "
"computed if you are working in "
"finite deformation.");
for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
switch (spatial_dimension) {
case 1:
this->computeCauchyStress<1>(type, ghost_type);
break;
case 2:
this->computeCauchyStress<2>(type, ghost_type);
break;
case 3:
this->computeCauchyStress<3>(type, ghost_type);
break;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void Material::computeCauchyStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator gradu_it =
this->gradu(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator gradu_end =
this->gradu(el_type, ghost_type).end(dim, dim);
Array<Real>::matrix_iterator piola_it =
this->piola_kirchhoff_2(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator stress_it =
this->stress(el_type, ghost_type).begin(dim, dim);
Matrix<Real> F_tensor(dim, dim);
for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it) {
Matrix<Real> & grad_u = *gradu_it;
Matrix<Real> & piola = *piola_it;
Matrix<Real> & sigma = *stress_it;
gradUToF<dim>(grad_u, F_tensor);
this->computeCauchyStressOnQuad<dim>(F_tensor, piola, sigma);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::setToSteadyState(GhostType ghost_type) {
AKANTU_DEBUG_IN();
const Array<Real> & displacement = model.getDisplacement();
// resizeInternalArray(gradu);
UInt spatial_dimension = model.getSpatialDimension();
for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
Array<UInt> & elem_filter = element_filter(type, ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
/// compute @f$\nabla u@f$
fem.gradientOnIntegrationPoints(displacement, gradu_vect, spatial_dimension,
type, ghost_type, elem_filter);
setToSteadyState(type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the stiffness matrix by assembling @f$\int_{\omega} B^t \times D
* \times B d\omega @f$
*
* @param[in] current_position nodes postition + displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::assembleStiffnessMatrix(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
if (finite_deformation) {
switch (spatial_dimension) {
case 1: {
assembleStiffnessMatrixNL<1>(type, ghost_type);
assembleStiffnessMatrixL2<1>(type, ghost_type);
break;
}
case 2: {
assembleStiffnessMatrixNL<2>(type, ghost_type);
assembleStiffnessMatrixL2<2>(type, ghost_type);
break;
}
case 3: {
assembleStiffnessMatrixNL<3>(type, ghost_type);
assembleStiffnessMatrixL2<3>(type, ghost_type);
break;
}
}
} else {
switch (spatial_dimension) {
case 1: {
assembleStiffnessMatrix<1>(type, ghost_type);
break;
}
case 2: {
assembleStiffnessMatrix<2>(type, ghost_type);
break;
}
case 3: {
assembleStiffnessMatrix<3>(type, ghost_type);
break;
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void Material::assembleStiffnessMatrix(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<UInt> & elem_filter = element_filter(type, ghost_type);
if (elem_filter.size() == 0) {
AKANTU_DEBUG_OUT();
return;
}
// const Array<Real> & shapes_derivatives =
// fem.getShapesDerivatives(type, ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
UInt nb_element = elem_filter.size();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
fem.gradientOnIntegrationPoints(model.getDisplacement(), gradu_vect, dim,
type, ghost_type, elem_filter);
UInt tangent_size = getTangentStiffnessVoigtSize(dim);
Array<Real> * tangent_stiffness_matrix =
new Array<Real>(nb_element * nb_quadrature_points,
tangent_size * tangent_size, "tangent_stiffness_matrix");
tangent_stiffness_matrix->clear();
computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
bt_d_b_size * bt_d_b_size, "B^t*D*B");
fem.computeBtDB(*tangent_stiffness_matrix, *bt_d_b, 4, type, ghost_type,
elem_filter);
delete tangent_stiffness_matrix;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e =
new Array<Real>(nb_element, bt_d_b_size * bt_d_b_size, "K_e");
fem.integrate(*bt_d_b, *K_e, bt_d_b_size * bt_d_b_size, type, ghost_type,
elem_filter);
delete bt_d_b;
model.getDOFManager().assembleElementalMatricesToMatrix(
"K", "displacement", *K_e, type, ghost_type, _symmetric, elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void Material::assembleStiffnessMatrixNL(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
const Array<Real> & shapes_derivatives =
fem.getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
// Array<Real> & gradu_vect = delta_gradu(type, ghost_type);
UInt nb_element = elem_filter.size();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
Array<Real> * shapes_derivatives_filtered = new Array<Real>(
nb_element * nb_quadrature_points, dim * nb_nodes_per_element,
"shapes derivatives filtered");
fem.filterElementalData(fem.getMesh(), shapes_derivatives,
*shapes_derivatives_filtered, type, ghost_type,
elem_filter);
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_s_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_s_b = new Array<Real>(nb_element * nb_quadrature_points,
bt_s_b_size * bt_s_b_size, "B^t*D*B");
UInt piola_matrix_size = getCauchyStressMatrixSize(dim);
Matrix<Real> B(piola_matrix_size, bt_s_b_size);
Matrix<Real> Bt_S(bt_s_b_size, piola_matrix_size);
Matrix<Real> S(piola_matrix_size, piola_matrix_size);
auto shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
spatial_dimension, nb_nodes_per_element);
auto Bt_S_B_it = bt_s_b->begin(bt_s_b_size, bt_s_b_size);
auto Bt_S_B_end = bt_s_b->end(bt_s_b_size, bt_s_b_size);
auto piola_it = piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
for (; Bt_S_B_it != Bt_S_B_end;
++Bt_S_B_it, ++shapes_derivatives_filtered_it, ++piola_it) {
auto & Bt_S_B = *Bt_S_B_it;
const auto & Piola_kirchhoff_matrix = *piola_it;
setCauchyStressMatrix<dim>(Piola_kirchhoff_matrix, S);
VoigtHelper<dim>::transferBMatrixToBNL(*shapes_derivatives_filtered_it, B,
nb_nodes_per_element);
Bt_S.template mul<true, false>(B, S);
Bt_S_B.template mul<false, false>(Bt_S, B);
}
delete shapes_derivatives_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e =
new Array<Real>(nb_element, bt_s_b_size * bt_s_b_size, "K_e");
fem.integrate(*bt_s_b, *K_e, bt_s_b_size * bt_s_b_size, type, ghost_type,
elem_filter);
delete bt_s_b;
model.getDOFManager().assembleElementalMatricesToMatrix(
"K", "displacement", *K_e, type, ghost_type, _symmetric, elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void Material::assembleStiffnessMatrixL2(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
const Array<Real> & shapes_derivatives =
fem.getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
UInt nb_element = elem_filter.size();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
fem.gradientOnIntegrationPoints(model.getDisplacement(), gradu_vect, dim,
type, ghost_type, elem_filter);
UInt tangent_size = getTangentStiffnessVoigtSize(dim);
Array<Real> * tangent_stiffness_matrix =
new Array<Real>(nb_element * nb_quadrature_points,
tangent_size * tangent_size, "tangent_stiffness_matrix");
tangent_stiffness_matrix->clear();
computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
Array<Real> * shapes_derivatives_filtered = new Array<Real>(
nb_element * nb_quadrature_points, dim * nb_nodes_per_element,
"shapes derivatives filtered");
fem.filterElementalData(fem.getMesh(), shapes_derivatives,
*shapes_derivatives_filtered, type, ghost_type,
elem_filter);
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
bt_d_b_size * bt_d_b_size, "B^t*D*B");
Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
Matrix<Real> B2(tangent_size, dim * nb_nodes_per_element);
Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
auto shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
spatial_dimension, nb_nodes_per_element);
auto Bt_D_B_it = bt_d_b->begin(bt_d_b_size, bt_d_b_size);
auto grad_u_it = gradu_vect.begin(dim, dim);
auto D_it = tangent_stiffness_matrix->begin(tangent_size, tangent_size);
auto D_end = tangent_stiffness_matrix->end(tangent_size, tangent_size);
for (; D_it != D_end;
++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it, ++grad_u_it) {
const auto & grad_u = *grad_u_it;
const auto & D = *D_it;
auto & Bt_D_B = *Bt_D_B_it;
// transferBMatrixToBL1<dim > (*shapes_derivatives_filtered_it, B,
// nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it,
grad_u, B2, nb_nodes_per_element);
B += B2;
Bt_D.template mul<true, false>(B, D);
Bt_D_B.template mul<false, false>(Bt_D, B);
}
delete tangent_stiffness_matrix;
delete shapes_derivatives_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e =
new Array<Real>(nb_element, bt_d_b_size * bt_d_b_size, "K_e");
fem.integrate(*bt_d_b, *K_e, bt_d_b_size * bt_d_b_size, type, ghost_type,
elem_filter);
delete bt_d_b;
model.getDOFManager().assembleElementalMatricesToMatrix(
"K", "displacement", *K_e, type, ghost_type, _symmetric, elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void Material::assembleInternalForces(GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real> & internal_force = model.getInternalForce();
Mesh & mesh = fem.getMesh();
for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
const Array<Real> & shapes_derivatives =
fem.getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
if (elem_filter.size() == 0)
continue;
UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
UInt nb_element = elem_filter.size();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
Array<Real> * shapesd_filtered = new Array<Real>(
nb_element, size_of_shapes_derivatives, "filtered shapesd");
fem.filterElementalData(mesh, shapes_derivatives, *shapesd_filtered, type,
ghost_type, elem_filter);
Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
shapesd_filtered->begin(dim, nb_nodes_per_element);
// Set stress vectors
UInt stress_size = getTangentStiffnessVoigtSize(dim);
// Set matrices B and BNL*
UInt bt_s_size = dim * nb_nodes_per_element;
auto * bt_s =
new Array<Real>(nb_element * nb_quadrature_points, bt_s_size, "B^t*S");
auto grad_u_it = this->gradu(type, ghost_type).begin(dim, dim);
auto grad_u_end = this->gradu(type, ghost_type).end(dim, dim);
auto stress_it = this->piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
shapes_derivatives_filtered_it =
shapesd_filtered->begin(dim, nb_nodes_per_element);
Array<Real>::matrix_iterator bt_s_it = bt_s->begin(bt_s_size, 1);
Matrix<Real> S_vect(stress_size, 1);
Matrix<Real> B_tensor(stress_size, bt_s_size);
Matrix<Real> B2_tensor(stress_size, bt_s_size);
for (; grad_u_it != grad_u_end; ++grad_u_it, ++stress_it,
++shapes_derivatives_filtered_it,
++bt_s_it) {
auto & grad_u = *grad_u_it;
auto & r_it = *bt_s_it;
auto & S_it = *stress_it;
setCauchyStressArray<dim>(S_it, S_vect);
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
*shapes_derivatives_filtered_it, B_tensor, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it,
grad_u, B2_tensor,
nb_nodes_per_element);
B_tensor += B2_tensor;
r_it.template mul<true, false>(B_tensor, S_vect);
}
delete shapesd_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * r_e = new Array<Real>(nb_element, bt_s_size, "r_e");
fem.integrate(*bt_s, *r_e, bt_s_size, type, ghost_type, elem_filter);
delete bt_s;
model.getDOFManager().assembleElementalArrayLocalArray(
*r_e, internal_force, type, ghost_type, -1., elem_filter);
delete r_e;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computePotentialEnergyByElements() {
AKANTU_DEBUG_IN();
for (auto type : element_filter.elementTypes(spatial_dimension, _not_ghost)) {
computePotentialEnergy(type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computePotentialEnergy(ElementType, GhostType) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real Material::getPotentialEnergy() {
AKANTU_DEBUG_IN();
Real epot = 0.;
computePotentialEnergyByElements();
/// integrate the potential energy for each type of elements
for (auto type : element_filter.elementTypes(spatial_dimension, _not_ghost)) {
epot += fem.integrate(potential_energy(type, _not_ghost), type, _not_ghost,
element_filter(type, _not_ghost));
}
AKANTU_DEBUG_OUT();
return epot;
}
/* -------------------------------------------------------------------------- */
Real Material::getPotentialEnergy(ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
Real epot = 0.;
Vector<Real> epot_on_quad_points(fem.getNbIntegrationPoints(type));
computePotentialEnergyByElement(type, index, epot_on_quad_points);
epot = fem.integrate(epot_on_quad_points, type, element_filter(type)(index));
AKANTU_DEBUG_OUT();
return epot;
}
/* -------------------------------------------------------------------------- */
Real Material::getEnergy(const std::string & type) {
AKANTU_DEBUG_IN();
if (type == "potential")
return getPotentialEnergy();
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
Real Material::getEnergy(const std::string & energy_id, ElementType type,
UInt index) {
AKANTU_DEBUG_IN();
if (energy_id == "potential")
return getPotentialEnergy(type, index);
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
void Material::initElementalFieldInterpolation(
const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
AKANTU_DEBUG_IN();
this->fem.initElementalFieldInterpolationFromIntegrationPoints(
interpolation_points_coordinates, this->interpolation_points_matrices,
this->interpolation_inverse_coordinates, &(this->element_filter));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::interpolateStress(ElementTypeMapArray<Real> & result,
const GhostType ghost_type) {
this->fem.interpolateElementalFieldFromIntegrationPoints(
this->stress, this->interpolation_points_matrices,
this->interpolation_inverse_coordinates, result, ghost_type,
&(this->element_filter));
}
/* -------------------------------------------------------------------------- */
void Material::interpolateStressOnFacets(
ElementTypeMapArray<Real> & result,
ElementTypeMapArray<Real> & by_elem_result, const GhostType ghost_type) {
interpolateStress(by_elem_result, ghost_type);
UInt stress_size = this->stress.getNbComponent();
const Mesh & mesh = this->model.getMesh();
const Mesh & mesh_facets = mesh.getMeshFacets();
for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
Array<UInt> & elem_fil = element_filter(type, ghost_type);
Array<Real> & by_elem_res = by_elem_result(type, ghost_type);
UInt nb_element = elem_fil.size();
UInt nb_element_full = this->model.getMesh().getNbElement(type, ghost_type);
UInt nb_interpolation_points_per_elem =
by_elem_res.size() / nb_element_full;
const Array<Element> & facet_to_element =
mesh_facets.getSubelementToElement(type, ghost_type);
ElementType type_facet = Mesh::getFacetType(type);
UInt nb_facet_per_elem = facet_to_element.getNbComponent();
UInt nb_quad_per_facet =
nb_interpolation_points_per_elem / nb_facet_per_elem;
Element element_for_comparison{type, 0, ghost_type};
const Array<std::vector<Element>> * element_to_facet = nullptr;
GhostType current_ghost_type = _casper;
Array<Real> * result_vec = nullptr;
Array<Real>::const_matrix_iterator result_it =
by_elem_res.begin_reinterpret(
stress_size, nb_interpolation_points_per_elem, nb_element_full);
for (UInt el = 0; el < nb_element; ++el) {
UInt global_el = elem_fil(el);
element_for_comparison.element = global_el;
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
Element facet_elem = facet_to_element(global_el, f);
UInt global_facet = facet_elem.element;
if (facet_elem.ghost_type != current_ghost_type) {
current_ghost_type = facet_elem.ghost_type;
element_to_facet = &mesh_facets.getElementToSubelement(
type_facet, current_ghost_type);
result_vec = &result(type_facet, current_ghost_type);
}
bool is_second_element =
(*element_to_facet)(global_facet)[0] != element_for_comparison;
for (UInt q = 0; q < nb_quad_per_facet; ++q) {
Vector<Real> result_local(result_vec->storage() +
(global_facet * nb_quad_per_facet + q) *
result_vec->getNbComponent() +
is_second_element * stress_size,
stress_size);
const Matrix<Real> & result_tmp(result_it[global_el]);
result_local = result_tmp(f * nb_quad_per_facet + q);
}
}
}
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
const Array<T> & Material::getArray(const ID & /*vect_id*/,
const ElementType & /*type*/,
const GhostType & /*ghost_type*/) const {
AKANTU_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
template <typename T>
Array<T> & Material::getArray(const ID & /*vect_id*/,
const ElementType & /*type*/,
const GhostType & /*ghost_type*/) {
AKANTU_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template <>
const Array<Real> & Material::getArray(const ID & vect_id,
const ElementType & type,
const GhostType & ghost_type) const {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost)
ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<Real>(fvect_id);
} catch (debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain a vector "
<< vect_id << " (" << fvect_id
<< ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template <>
Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type,
const GhostType & ghost_type) {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost)
ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<Real>(fvect_id);
} catch (debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain a vector "
<< vect_id << " (" << fvect_id
<< ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template <>
const Array<UInt> & Material::getArray(const ID & vect_id,
const ElementType & type,
const GhostType & ghost_type) const {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost)
ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<UInt>(fvect_id);
} catch (debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain a vector "
<< vect_id << " (" << fvect_id
<< ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template <>
Array<UInt> & Material::getArray(const ID & vect_id, const ElementType & type,
const GhostType & ghost_type) {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost)
ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
return Memory::getArray<UInt>(fvect_id);
} catch (debug::Exception & e) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain a vector "
<< vect_id << "(" << fvect_id
<< ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
const InternalField<T> & Material::getInternal(__attribute__((unused))
const ID & int_id) const {
AKANTU_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
template <typename T>
InternalField<T> & Material::getInternal(__attribute__((unused))
const ID & int_id) {
AKANTU_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
template <>
const InternalField<Real> & Material::getInternal(const ID & int_id) const {
auto it = internal_vectors_real.find(getID() + ":" + int_id);
if (it == internal_vectors_real.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " ("
<< (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
template <> InternalField<Real> & Material::getInternal(const ID & int_id) {
auto it = internal_vectors_real.find(getID() + ":" + int_id);
if (it == internal_vectors_real.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " ("
<< (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
template <>
const InternalField<UInt> & Material::getInternal(const ID & int_id) const {
auto it = internal_vectors_uint.find(getID() + ":" + int_id);
if (it == internal_vectors_uint.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " ("
<< (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
template <> InternalField<UInt> & Material::getInternal(const ID & int_id) {
auto it = internal_vectors_uint.find(getID() + ":" + int_id);
if (it == internal_vectors_uint.end()) {
AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " ("
<< (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
void Material::addElements(const Array<Element> & elements_to_add) {
AKANTU_DEBUG_IN();
UInt mat_id = model.getInternalIndexFromID(getID());
Array<Element>::const_iterator<Element> el_begin = elements_to_add.begin();
Array<Element>::const_iterator<Element> el_end = elements_to_add.end();
for (; el_begin != el_end; ++el_begin) {
const Element & element = *el_begin;
Array<UInt> & mat_indexes =
model.getMaterialByElement(element.type, element.ghost_type);
Array<UInt> & mat_loc_num =
model.getMaterialLocalNumbering(element.type, element.ghost_type);
UInt index =
this->addElement(element.type, element.element, element.ghost_type);
mat_indexes(element.element) = mat_id;
mat_loc_num(element.element) = index;
}
this->resizeInternals();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::removeElements(const Array<Element> & elements_to_remove) {
AKANTU_DEBUG_IN();
Array<Element>::const_iterator<Element> el_begin = elements_to_remove.begin();
Array<Element>::const_iterator<Element> el_end = elements_to_remove.end();
if (el_begin == el_end)
return;
ElementTypeMapArray<UInt> material_local_new_numbering(
"remove mat filter elem", getID(), getMemoryID());
Element element;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
element.ghost_type = ghost_type;
ElementTypeMapArray<UInt>::type_iterator it =
element_filter.firstType(_all_dimensions, ghost_type, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end =
element_filter.lastType(_all_dimensions, ghost_type, _ek_not_defined);
for (; it != end; ++it) {
ElementType type = *it;
element.type = type;
Array<UInt> & elem_filter = this->element_filter(type, ghost_type);
Array<UInt> & mat_loc_num =
this->model.getMaterialLocalNumbering(type, ghost_type);
if (!material_local_new_numbering.exists(type, ghost_type))
material_local_new_numbering.alloc(elem_filter.size(), 1, type,
ghost_type);
Array<UInt> & mat_renumbering =
material_local_new_numbering(type, ghost_type);
UInt nb_element = elem_filter.size();
Array<UInt> elem_filter_tmp;
UInt new_id = 0;
for (UInt el = 0; el < nb_element; ++el) {
element.element = elem_filter(el);
if (std::find(el_begin, el_end, element) == el_end) {
elem_filter_tmp.push_back(element.element);
mat_renumbering(el) = new_id;
mat_loc_num(element.element) = new_id;
++new_id;
} else {
mat_renumbering(el) = UInt(-1);
}
}
elem_filter.resize(elem_filter_tmp.size());
elem_filter.copy(elem_filter_tmp);
}
}
for (auto it = internal_vectors_real.begin();
it != internal_vectors_real.end(); ++it)
it->second->removeIntegrationPoints(material_local_new_numbering);
for (auto it = internal_vectors_uint.begin();
it != internal_vectors_uint.end(); ++it)
it->second->removeIntegrationPoints(material_local_new_numbering);
for (auto it = internal_vectors_bool.begin();
it != internal_vectors_bool.end(); ++it)
it->second->removeIntegrationPoints(material_local_new_numbering);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::resizeInternals() {
AKANTU_DEBUG_IN();
for (auto it = internal_vectors_real.begin();
it != internal_vectors_real.end(); ++it)
it->second->resize();
for (auto it = internal_vectors_uint.begin();
it != internal_vectors_uint.end(); ++it)
it->second->resize();
for (auto it = internal_vectors_bool.begin();
it != internal_vectors_bool.end(); ++it)
it->second->resize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::onElementsAdded(const Array<Element> &,
const NewElementsEvent &) {
this->resizeInternals();
}
/* -------------------------------------------------------------------------- */
void Material::onElementsRemoved(
const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
__attribute__((unused)) const RemovedElementsEvent & event) {
UInt my_num = model.getInternalIndexFromID(getID());
ElementTypeMapArray<UInt> material_local_new_numbering(
"remove mat filter elem", getID(), getMemoryID());
auto el_begin = element_list.begin();
auto el_end = element_list.end();
for (auto && gt : ghost_types) {
for (auto && type :
new_numbering.elementTypes(_all_dimensions, gt, _ek_not_defined)) {
if (not element_filter.exists(type, gt) ||
element_filter(type, gt).size() == 0)
continue;
auto & elem_filter = element_filter(type, gt);
auto & mat_indexes = this->model.getMaterialByElement(type, gt);
- auto & mat_loc_num =
- this->model.getMaterialLocalNumbering(type, gt);
+ auto & mat_loc_num = this->model.getMaterialLocalNumbering(type, gt);
auto nb_element = this->model.getMesh().getNbElement(type, gt);
// all materials will resize of the same size...
mat_indexes.resize(nb_element);
mat_loc_num.resize(nb_element);
if (!material_local_new_numbering.exists(type, gt))
material_local_new_numbering.alloc(elem_filter.size(), 1, type, gt);
auto & mat_renumbering = material_local_new_numbering(type, gt);
const auto & renumbering = new_numbering(type, gt);
Array<UInt> elem_filter_tmp;
UInt ni = 0;
Element el{type, 0, gt};
for (UInt i = 0; i < elem_filter.size(); ++i) {
el.element = elem_filter(i);
if (std::find(el_begin, el_end, el) == el_end) {
UInt new_el = renumbering(el.element);
AKANTU_DEBUG_ASSERT(new_el != UInt(-1),
"A not removed element as been badly renumbered");
elem_filter_tmp.push_back(new_el);
mat_renumbering(i) = ni;
mat_indexes(new_el) = my_num;
mat_loc_num(new_el) = ni;
++ni;
} else {
mat_renumbering(i) = UInt(-1);
}
}
elem_filter.resize(elem_filter_tmp.size());
elem_filter.copy(elem_filter_tmp);
}
}
for (auto it = internal_vectors_real.begin();
it != internal_vectors_real.end(); ++it)
it->second->removeIntegrationPoints(material_local_new_numbering);
for (auto it = internal_vectors_uint.begin();
it != internal_vectors_uint.end(); ++it)
it->second->removeIntegrationPoints(material_local_new_numbering);
for (auto it = internal_vectors_bool.begin();
it != internal_vectors_bool.end(); ++it)
it->second->removeIntegrationPoints(material_local_new_numbering);
}
/* -------------------------------------------------------------------------- */
void Material::beforeSolveStep() { this->savePreviousState(); }
/* -------------------------------------------------------------------------- */
void Material::afterSolveStep() {
for (auto & type : element_filter.elementTypes(_all_dimensions, _not_ghost,
_ek_not_defined)) {
this->updateEnergies(type, _not_ghost);
}
}
/* -------------------------------------------------------------------------- */
void Material::onDamageIteration() { this->savePreviousState(); }
/* -------------------------------------------------------------------------- */
void Material::onDamageUpdate() {
ElementTypeMapArray<UInt>::type_iterator it = this->element_filter.firstType(
_all_dimensions, _not_ghost, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end =
element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
for (; it != end; ++it) {
this->updateEnergiesAfterDamage(*it, _not_ghost);
}
}
/* -------------------------------------------------------------------------- */
void Material::onDump() {
if (this->isFiniteDeformation())
this->computeAllCauchyStresses(_not_ghost);
}
/* -------------------------------------------------------------------------- */
void Material::printself(std::ostream & stream, int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
std::string type = getID().substr(getID().find_last_of(':') + 1);
stream << space << "Material " << type << " [" << std::endl;
Parsable::printself(stream, indent);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/// extrapolate internal values
void Material::extrapolateInternal(const ID & id, const Element & element,
__attribute__((unused))
const Matrix<Real> & point,
Matrix<Real> & extrapolated) {
if (this->isInternal<Real>(id, element.kind())) {
UInt nb_element =
this->element_filter(element.type, element.ghost_type).size();
const ID name = this->getID() + ":" + id;
UInt nb_quads =
this->internal_vectors_real[name]->getFEEngine().getNbIntegrationPoints(
element.type, element.ghost_type);
const Array<Real> & internal =
this->getArray<Real>(id, element.type, element.ghost_type);
UInt nb_component = internal.getNbComponent();
Array<Real>::const_matrix_iterator internal_it =
internal.begin_reinterpret(nb_component, nb_quads, nb_element);
Element local_element = this->convertToLocalElement(element);
/// instead of really extrapolating, here the value of the first GP
/// is copied into the result vector. This works only for linear
/// elements
/// @todo extrapolate!!!!
AKANTU_DEBUG_WARNING("This is a fix, values are not truly extrapolated");
const Matrix<Real> & values = internal_it[local_element.element];
UInt index = 0;
Vector<Real> tmp(nb_component);
for (UInt j = 0; j < values.cols(); ++j) {
tmp = values(j);
if (tmp.norm() > 0) {
index = j;
break;
}
}
for (UInt i = 0; i < extrapolated.size(); ++i) {
extrapolated(i) = values(index);
}
} else {
Matrix<Real> default_values(extrapolated.rows(), extrapolated.cols(), 0.);
extrapolated = default_values;
}
}
/* -------------------------------------------------------------------------- */
void Material::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
const GhostType ghost_type) {
for (auto && type : element_filter.elementTypes(_all_dimensions, _not_ghost,
_ek_not_defined)) {
if (!element_filter(type, ghost_type).size())
continue;
auto eigen_it = this->eigengradu(type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto eigen_end = this->eigengradu(type, ghost_type)
.end(spatial_dimension, spatial_dimension);
for (; eigen_it != eigen_end; ++eigen_it) {
auto & current_eigengradu = *eigen_it;
current_eigengradu = prescribed_eigen_grad_u;
}
}
}
} // namespace akantu
diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh
index c7c82a97a..d66f49984 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,680 +1,680 @@
/**
* @file material.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Wed Nov 25 2015
*
* @brief Mother class for all materials
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_factory.hh"
#include "aka_voigthelper.hh"
#include "data_accessor.hh"
#include "integration_point.hh"
#include "parsable.hh"
#include "parser.hh"
/* -------------------------------------------------------------------------- */
#include "internal_field.hh"
#include "random_internal_field.hh"
/* -------------------------------------------------------------------------- */
#include "mesh_events.hh"
#include "solid_mechanics_model_event_handler.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_HH__
#define __AKANTU_MATERIAL_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class Model;
class SolidMechanicsModel;
} // namespace akantu
namespace akantu {
/**
* Interface of all materials
* Prerequisites for a new material
* - inherit from this class
* - implement the following methods:
* \code
* virtual Real getStableTimeStep(Real h, const Element & element =
* ElementNull);
*
* virtual void computeStress(ElementType el_type,
* GhostType ghost_type = _not_ghost);
*
* virtual void computeTangentStiffness(const ElementType & el_type,
* Array<Real> & tangent_matrix,
* GhostType ghost_type = _not_ghost);
* \endcode
*
*/
class Material : public Memory,
public DataAccessor<Element>,
public Parsable,
public MeshEventHandler,
protected SolidMechanicsModelEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
#if __cplusplus > 199711L
Material(const Material & mat) = delete;
Material & operator=(const Material & mat) = delete;
#endif
/// Initialize material with defaults
Material(SolidMechanicsModel & model, const ID & id = "");
/// Initialize material with custom mesh & fe_engine
Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
FEEngine & fe_engine, const ID & id = "");
/// Destructor
~Material() override;
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Function that materials can/should reimplement */
/* ------------------------------------------------------------------------ */
protected:
/// constitutive law
virtual void computeStress(__attribute__((unused)) ElementType el_type,
__attribute__((unused))
GhostType ghost_type = _not_ghost) {
AKANTU_TO_IMPLEMENT();
}
/// compute the tangent stiffness matrix
virtual void computeTangentModuli(__attribute__((unused))
const ElementType & el_type,
__attribute__((unused))
Array<Real> & tangent_matrix,
__attribute__((unused))
GhostType ghost_type = _not_ghost) {
AKANTU_TO_IMPLEMENT();
}
/// compute the potential energy
virtual void computePotentialEnergy(ElementType el_type,
GhostType ghost_type = _not_ghost);
/// compute the potential energy for an element
virtual void
computePotentialEnergyByElement(__attribute__((unused)) ElementType type,
__attribute__((unused)) UInt index,
__attribute__((unused))
Vector<Real> & epot_on_quad_points) {
AKANTU_TO_IMPLEMENT();
}
virtual void updateEnergies(__attribute__((unused)) ElementType el_type,
__attribute__((unused))
GhostType ghost_type = _not_ghost) {}
virtual void updateEnergiesAfterDamage(__attribute__((unused))
ElementType el_type,
__attribute__((unused))
GhostType ghost_type = _not_ghost) {}
/// set the material to steady state (to be implemented for materials that
/// need it)
virtual void setToSteadyState(__attribute__((unused)) ElementType el_type,
__attribute__((unused))
GhostType ghost_type = _not_ghost) {}
/// function called to update the internal parameters when the modifiable
/// parameters are modified
virtual void updateInternalParameters() {}
public:
/// extrapolate internal values
virtual void extrapolateInternal(const ID & id, const Element & element,
const Matrix<Real> & points,
Matrix<Real> & extrapolated);
/// compute the p-wave speed in the material
virtual Real getPushWaveSpeed(__attribute__((unused))
const Element & element) const {
AKANTU_TO_IMPLEMENT();
}
/// compute the s-wave speed in the material
virtual Real getShearWaveSpeed(__attribute__((unused))
const Element & element) const {
AKANTU_TO_IMPLEMENT();
}
/// get a material celerity to compute the stable time step (default: is the
/// push wave speed)
virtual Real getCelerity(const Element & element) const {
return getPushWaveSpeed(element);
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template <typename T>
void registerInternal(__attribute__((unused)) InternalField<T> & vect) {
AKANTU_TO_IMPLEMENT();
}
template <typename T>
void unregisterInternal(__attribute__((unused)) InternalField<T> & vect) {
AKANTU_TO_IMPLEMENT();
}
/// initialize the material computed parameter
virtual void initMaterial();
/// compute the residual for this material
// virtual void updateResidual(GhostType ghost_type = _not_ghost);
/// assemble the residual for this material
virtual void assembleInternalForces(GhostType ghost_type);
/// save the stress in the previous_stress if needed
virtual void savePreviousState();
/// compute the stresses for this material
virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
// virtual void
// computeAllStressesFromTangentModuli(GhostType ghost_type = _not_ghost);
virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost);
/// set material to steady state
void setToSteadyState(GhostType ghost_type = _not_ghost);
/// compute the stiffness matrix
virtual void assembleStiffnessMatrix(GhostType ghost_type);
/// add an element to the local mesh filter
inline UInt addElement(const ElementType & type, UInt element,
const GhostType & ghost_type);
inline UInt addElement(const Element & element);
/// add many elements at once
void addElements(const Array<Element> & elements_to_add);
/// remove many element at once
void removeElements(const Array<Element> & elements_to_remove);
/// function to print the contain of the class
void printself(std::ostream & stream, int indent = 0) const override;
/**
* interpolate stress on given positions for each element by means
* of a geometrical interpolation on quadrature points
*/
void interpolateStress(ElementTypeMapArray<Real> & result,
const GhostType ghost_type = _not_ghost);
/**
* interpolate stress on given positions for each element by means
* of a geometrical interpolation on quadrature points and store the
* results per facet
*/
void interpolateStressOnFacets(ElementTypeMapArray<Real> & result,
ElementTypeMapArray<Real> & by_elem_result,
const GhostType ghost_type = _not_ghost);
/**
* function to initialize the elemental field interpolation
* function by inverting the quadrature points' coordinates
*/
void initElementalFieldInterpolation(
const ElementTypeMapArray<Real> & interpolation_points_coordinates);
/* ------------------------------------------------------------------------ */
/* Common part */
/* ------------------------------------------------------------------------ */
protected:
/* ------------------------------------------------------------------------ */
inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const;
/// compute the potential energy by element
void computePotentialEnergyByElements();
/// resize the intenals arrays
virtual void resizeInternals();
/* ------------------------------------------------------------------------ */
/* Finite deformation functions */
/* This functions area implementing what is described in the paper of Bathe */
/* et al, in IJNME, Finite Element Formulations For Large Deformation */
/* Dynamic Analysis, Vol 9, 353-386, 1975 */
/* ------------------------------------------------------------------------ */
protected:
/// assemble the residual
template <UInt dim> void assembleInternalForces(GhostType ghost_type);
/// Computation of Cauchy stress tensor in the case of finite deformation from
/// the 2nd Piola-Kirchhoff for a given element type
template <UInt dim>
void computeCauchyStress(ElementType el_type,
GhostType ghost_type = _not_ghost);
/// Computation the Cauchy stress the 2nd Piola-Kirchhoff and the deformation
/// gradient
template <UInt dim>
inline void computeCauchyStressOnQuad(const Matrix<Real> & F,
const Matrix<Real> & S,
Matrix<Real> & cauchy,
const Real & C33 = 1.0) const;
template <UInt dim>
void computeAllStressesFromTangentModuli(const ElementType & type,
GhostType ghost_type);
template <UInt dim>
void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
/// assembling in finite deformation
template <UInt dim>
void assembleStiffnessMatrixNL(const ElementType & type,
GhostType ghost_type);
template <UInt dim>
void assembleStiffnessMatrixL2(const ElementType & type,
GhostType ghost_type);
/// Size of the Stress matrix for the case of finite deformation see: Bathe et
/// al, IJNME, Vol 9, 353-386, 1975
inline UInt getCauchyStressMatrixSize(UInt spatial_dimension) const;
/// Sets the stress matrix according to Bathe et al, IJNME, Vol 9, 353-386,
/// 1975
template <UInt dim>
inline void setCauchyStressMatrix(const Matrix<Real> & S_t,
Matrix<Real> & sigma);
/// write the stress tensor in the Voigt notation.
template <UInt dim>
inline void setCauchyStressArray(const Matrix<Real> & S_t,
Matrix<Real> & sigma_voight);
/* ------------------------------------------------------------------------ */
/* Conversion functions */
/* ------------------------------------------------------------------------ */
public:
template <UInt dim>
static inline void gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F);
static inline void rightCauchy(const Matrix<Real> & F, Matrix<Real> & C);
static inline void leftCauchy(const Matrix<Real> & F, Matrix<Real> & B);
template <UInt dim>
static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon);
template <UInt dim>
static inline void gradUToGreenStrain(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon);
static inline Real stressToVonMises(const Matrix<Real> & stress);
protected:
/// converts global element to local element
inline Element convertToLocalElement(const Element & global_element) const;
/// converts local element to global element
inline Element convertToGlobalElement(const Element & local_element) const;
/// converts global quadrature point to local quadrature point
inline IntegrationPoint
convertToLocalPoint(const IntegrationPoint & global_point) const;
/// converts local quadrature point to global quadrature point
inline IntegrationPoint
convertToGlobalPoint(const IntegrationPoint & local_point) const;
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
inline UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const override;
inline void unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) override;
template <typename T>
inline void packElementDataHelper(const ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & fem_id = ID()) const;
template <typename T>
inline void unpackElementDataHelper(ElementTypeMapArray<T> & data_to_unpack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & fem_id = ID());
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override{};
void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
const RemovedNodesEvent &) override{};
void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) override;
void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event) override;
void onElementsChanged(const Array<Element> &, const Array<Element> &,
const ElementTypeMapArray<UInt> &,
const ChangedElementsEvent &) override{};
/* ------------------------------------------------------------------------ */
/* SolidMechanicsModelEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual void beforeSolveStep();
virtual void afterSolveStep();
void onDamageIteration() override;
void onDamageUpdate() override;
void onDump() override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Name, name, const std::string &);
AKANTU_GET_MACRO(Model, model, const SolidMechanicsModel &)
AKANTU_GET_MACRO(ID, Memory::getID(), const ID &);
AKANTU_GET_MACRO(Rho, rho, Real);
AKANTU_SET_MACRO(Rho, rho, Real);
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// return the potential energy for the subset of elements contained by the
/// material
Real getPotentialEnergy();
/// return the potential energy for the provided element
Real getPotentialEnergy(ElementType & type, UInt index);
/// return the energy (identified by id) for the subset of elements contained
/// by the material
virtual Real getEnergy(const std::string & energy_id);
/// return the energy (identified by id) for the provided element
virtual Real getEnergy(const std::string & energy_id, ElementType type,
UInt index);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(GradU, gradu, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy,
Real);
AKANTU_GET_MACRO(GradU, gradu, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(Stress, stress, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(ElementFilter, element_filter,
const ElementTypeMapArray<UInt> &);
AKANTU_GET_MACRO(FEEngine, fem, FEEngine &);
bool isNonLocal() const { return is_non_local; }
template <typename T>
const Array<T> & getArray(const ID & id, const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
template <typename T>
Array<T> & getArray(const ID & id, const ElementType & type,
const GhostType & ghost_type = _not_ghost);
template <typename T>
const InternalField<T> & getInternal(const ID & id) const;
template <typename T> InternalField<T> & getInternal(const ID & id);
template <typename T>
inline bool isInternal(const ID & id, const ElementKind & element_kind) const;
template <typename T>
ElementTypeMap<UInt>
getInternalDataPerElem(const ID & id, const ElementKind & element_kind) const;
bool isFiniteDeformation() const { return finite_deformation; }
bool isInelasticDeformation() const { return inelastic_deformation; }
template <typename T> inline void setParam(const ID & param, T value);
inline const Parameter & getParam(const ID & param) const;
template <typename T>
void flattenInternal(const std::string & field_id,
ElementTypeMapArray<T> & internal_flat,
const GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined) const;
/// apply a constant eigengrad_u everywhere in the material
virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
const GhostType = _not_ghost);
/// specify if the matrix need to be recomputed for this material
virtual bool hasStiffnessMatrixChanged() { return true; }
protected:
bool isInit() const { return is_init; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// boolean to know if the material has been initialized
bool is_init;
std::map<ID, InternalField<Real> *> internal_vectors_real;
std::map<ID, InternalField<UInt> *> internal_vectors_uint;
std::map<ID, InternalField<bool> *> internal_vectors_bool;
protected:
/// Link to the fem object in the model
FEEngine & fem;
/// Finite deformation
bool finite_deformation;
/// Finite deformation
bool inelastic_deformation;
/// material name
std::string name;
/// The model to witch the material belong
SolidMechanicsModel & model;
/// density : rho
Real rho;
/// spatial dimension
UInt spatial_dimension;
/// list of element handled by the material
ElementTypeMapArray<UInt> element_filter;
/// stresses arrays ordered by element types
InternalField<Real> stress;
/// eigengrad_u arrays ordered by element types
InternalField<Real> eigengradu;
/// grad_u arrays ordered by element types
InternalField<Real> gradu;
/// Green Lagrange strain (Finite deformation)
InternalField<Real> green_strain;
/// Second Piola-Kirchhoff stress tensor arrays ordered by element types
/// (Finite deformation)
InternalField<Real> piola_kirchhoff_2;
/// potential energy by element
InternalField<Real> potential_energy;
/// tell if using in non local mode or not
bool is_non_local;
/// tell if the material need the previous stress state
bool use_previous_stress;
/// tell if the material need the previous strain state
bool use_previous_gradu;
/// elemental field interpolation coordinates
InternalField<Real> interpolation_inverse_coordinates;
/// elemental field interpolation points
InternalField<Real> interpolation_points_matrices;
/// vector that contains the names of all the internals that need to
/// be transferred when material interfaces move
std::vector<ID> internals_to_transfer;
};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const Material & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#include "material_inline_impl.cc"
#include "internal_field_tmpl.hh"
#include "random_internal_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
/* Auto loop */
/* -------------------------------------------------------------------------- */
/// This can be used to automatically write the loop on quadrature points in
/// functions such as computeStress. This macro in addition to write the loop
/// provides two tensors (matrices) sigma and grad_u
#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type) \
Array<Real>::matrix_iterator gradu_it = \
this->gradu(el_type, ghost_type) \
.begin(this->spatial_dimension, this->spatial_dimension); \
Array<Real>::matrix_iterator gradu_end = \
this->gradu(el_type, ghost_type) \
.end(this->spatial_dimension, this->spatial_dimension); \
\
this->stress(el_type, ghost_type) \
.resize(this->gradu(el_type, ghost_type).size()); \
\
Array<Real>::iterator<Matrix<Real>> stress_it = \
this->stress(el_type, ghost_type) \
.begin(this->spatial_dimension, this->spatial_dimension); \
\
if (this->isFiniteDeformation()) { \
this->piola_kirchhoff_2(el_type, ghost_type) \
.resize(this->gradu(el_type, ghost_type).size()); \
stress_it = this->piola_kirchhoff_2(el_type, ghost_type) \
.begin(this->spatial_dimension, this->spatial_dimension); \
} \
\
for (; gradu_it != gradu_end; ++gradu_it, ++stress_it) { \
Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
Matrix<Real> & __attribute__((unused)) sigma = *stress_it
#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END }
/// This can be used to automatically write the loop on quadrature points in
/// functions such as computeTangentModuli. This macro in addition to write the
/// loop provides two tensors (matrices) sigma_tensor, grad_u, and a matrix
/// where the elemental tangent moduli should be stored in Voigt Notation
#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat) \
Array<Real>::matrix_iterator gradu_it = \
this->gradu(el_type, ghost_type) \
.begin(this->spatial_dimension, this->spatial_dimension); \
Array<Real>::matrix_iterator gradu_end = \
this->gradu(el_type, ghost_type) \
.end(this->spatial_dimension, this->spatial_dimension); \
Array<Real>::matrix_iterator sigma_it = \
this->stress(el_type, ghost_type) \
.begin(this->spatial_dimension, this->spatial_dimension); \
\
tangent_mat.resize(this->gradu(el_type, ghost_type).size()); \
\
UInt tangent_size = \
this->getTangentStiffnessVoigtSize(this->spatial_dimension); \
Array<Real>::matrix_iterator tangent_it = \
tangent_mat.begin(tangent_size, tangent_size); \
\
for (; gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) { \
Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
Matrix<Real> & __attribute__((unused)) sigma_tensor = *sigma_it; \
Matrix<Real> & tangent = *tangent_it
#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END }
/* -------------------------------------------------------------------------- */
namespace akantu {
using MaterialFactory =
Factory<Material, ID, UInt, const ID &, SolidMechanicsModel &, const ID &>;
} // namespace akantu
#define INSTANTIATE_MATERIAL_ONLY(mat_name) \
template class mat_name<1>; \
template class mat_name<2>; \
template class mat_name<3>
#define MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name) \
[](UInt dim, const ID &, SolidMechanicsModel & model, \
const ID & id) -> std::unique_ptr<Material> { \
switch (dim) { \
case 1: \
return std::make_unique<mat_name<1>>(model, id); \
case 2: \
return std::make_unique<mat_name<2>>(model, id); \
case 3: \
return std::make_unique<mat_name<3>>(model, id); \
default: \
AKANTU_EXCEPTION("The dimension " \
<< dim << "is not a valid dimension for the material " \
<< #id); \
} \
}
#define INSTANTIATE_MATERIAL(id, mat_name) \
INSTANTIATE_MATERIAL_ONLY(mat_name); \
- static bool material_is_alocated_##id [[gnu::unused]] = \
+ static bool material_is_alocated_##id[[gnu::unused]] = \
MaterialFactory::getInstance().registerAllocator( \
#id, MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name))
#endif /* __AKANTU_MATERIAL_HH__ */
diff --git a/src/model/solid_mechanics/material_inline_impl.cc b/src/model/solid_mechanics/material_inline_impl.cc
index aaedb2e96..41f6de00b 100644
--- a/src/model/solid_mechanics/material_inline_impl.cc
+++ b/src/model/solid_mechanics/material_inline_impl.cc
@@ -1,464 +1,462 @@
/**
* @file material_inline_impl.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Wed Nov 25 2015
*
* @brief Implementation of the inline functions of the class material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_INLINE_IMPL_CC__
#define __AKANTU_MATERIAL_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline UInt Material::addElement(const ElementType & type, UInt element,
const GhostType & ghost_type) {
Array<UInt> & el_filter = this->element_filter(type, ghost_type);
el_filter.push_back(element);
return el_filter.size() - 1;
}
/* -------------------------------------------------------------------------- */
inline UInt Material::addElement(const Element & element) {
return this->addElement(element.type, element.element, element.ghost_type);
}
/* -------------------------------------------------------------------------- */
inline UInt Material::getTangentStiffnessVoigtSize(UInt dim) const {
return (dim * (dim - 1) / 2 + dim);
}
/* -------------------------------------------------------------------------- */
inline UInt Material::getCauchyStressMatrixSize(UInt dim) const {
return (dim * dim);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F) {
AKANTU_DEBUG_ASSERT(F.size() >= grad_u.size() && grad_u.size() == dim * dim,
"The dimension of the tensor F should be greater or "
"equal to the dimension of the tensor grad_u.");
F.eye();
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
F(i, j) += grad_u(i, j);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::computeCauchyStressOnQuad(const Matrix<Real> & F,
const Matrix<Real> & piola,
Matrix<Real> & sigma,
const Real & C33) const {
Real J = F.det() * sqrt(C33);
Matrix<Real> F_S(dim, dim);
F_S.mul<false, false>(F, piola);
Real constant = J ? 1. / J : 0;
sigma.mul<false, true>(F_S, F, constant);
}
/* -------------------------------------------------------------------------- */
inline void Material::rightCauchy(const Matrix<Real> & F, Matrix<Real> & C) {
C.mul<true, false>(F, F);
}
/* -------------------------------------------------------------------------- */
inline void Material::leftCauchy(const Matrix<Real> & F, Matrix<Real> & B) {
B.mul<false, true>(F, F);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::gradUToEpsilon(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon) {
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
epsilon(i, j) = 0.5 * (grad_u(i, j) + grad_u(j, i));
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::gradUToGreenStrain(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon) {
epsilon.mul<true, false>(grad_u, grad_u, .5);
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
epsilon(i, j) += 0.5 * (grad_u(i, j) + grad_u(j, i));
}
/* -------------------------------------------------------------------------- */
inline Real Material::stressToVonMises(const Matrix<Real> & stress) {
// compute deviatoric stress
UInt dim = stress.cols();
Matrix<Real> deviatoric_stress =
Matrix<Real>::eye(dim, -1. * stress.trace() / 3.);
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
deviatoric_stress(i, j) += stress(i, j);
// return Von Mises stress
return std::sqrt(3. * deviatoric_stress.doubleDot(deviatoric_stress) / 2.);
}
/* ---------------------------------------------------------------------------*/
template <UInt dim>
inline void Material::setCauchyStressArray(const Matrix<Real> & S_t,
Matrix<Real> & sigma_voight) {
AKANTU_DEBUG_IN();
sigma_voight.clear();
// see Finite element formulations for large deformation dynamic analysis,
// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
/*
* 1d: [ s11 ]'
* 2d: [ s11 s22 s12 ]'
* 3d: [ s11 s22 s33 s23 s13 s12 ]
*/
for (UInt i = 0; i < dim; ++i) // diagonal terms
sigma_voight(i, 0) = S_t(i, i);
for (UInt i = 1; i < dim; ++i) // term s12 in 2D and terms s23 s13 in 3D
sigma_voight(dim + i - 1, 0) = S_t(dim - i - 1, dim - 1);
for (UInt i = 2; i < dim; ++i) // term s13 in 3D
sigma_voight(dim + i, 0) = S_t(0, 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t,
Matrix<Real> & sigma) {
AKANTU_DEBUG_IN();
sigma.clear();
/// see Finite ekement formulations for large deformation dynamic analysis,
/// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
for (UInt i = 0; i < dim; ++i) {
for (UInt m = 0; m < dim; ++m) {
for (UInt n = 0; n < dim; ++n) {
sigma(i * dim + m, i * dim + n) = S_t(m, n);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline Element
Material::convertToLocalElement(const Element & global_element) const {
UInt ge = global_element.element;
#ifndef AKANTU_NDEBUG
UInt model_mat_index = this->model.getMaterialByElement(
global_element.type, global_element.ghost_type)(ge);
UInt mat_index = this->model.getMaterialIndex(this->name);
AKANTU_DEBUG_ASSERT(model_mat_index == mat_index,
"Conversion of a global element in a local element for "
"the wrong material "
<< this->name << std::endl);
#endif
UInt le = this->model.getMaterialLocalNumbering(
global_element.type, global_element.ghost_type)(ge);
Element tmp_quad{global_element.type, le, global_element.ghost_type};
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline Element
Material::convertToGlobalElement(const Element & local_element) const {
UInt le = local_element.element;
UInt ge =
this->element_filter(local_element.type, local_element.ghost_type)(le);
Element tmp_quad{local_element.type, ge, local_element.ghost_type};
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline IntegrationPoint
Material::convertToLocalPoint(const IntegrationPoint & global_point) const {
const FEEngine & fem = this->model.getFEEngine();
UInt nb_quad = fem.getNbIntegrationPoints(global_point.type);
Element el =
this->convertToLocalElement(static_cast<const Element &>(global_point));
IntegrationPoint tmp_quad(el, global_point.num_point, nb_quad);
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline IntegrationPoint
Material::convertToGlobalPoint(const IntegrationPoint & local_point) const {
const FEEngine & fem = this->model.getFEEngine();
UInt nb_quad = fem.getNbIntegrationPoints(local_point.type);
Element el =
this->convertToGlobalElement(static_cast<const Element &>(local_point));
IntegrationPoint tmp_quad(el, local_point.num_point, nb_quad);
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline UInt Material::getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const {
if (tag == _gst_smm_stress) {
return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension *
spatial_dimension * sizeof(Real) *
this->getModel().getNbIntegrationPoints(elements);
}
return 0;
}
/* -------------------------------------------------------------------------- */
inline void Material::packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const {
if (tag == _gst_smm_stress) {
if (this->isFiniteDeformation()) {
packElementDataHelper(piola_kirchhoff_2, buffer, elements);
packElementDataHelper(gradu, buffer, elements);
}
packElementDataHelper(stress, buffer, elements);
}
}
/* -------------------------------------------------------------------------- */
inline void Material::unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) {
if (tag == _gst_smm_stress) {
if (this->isFiniteDeformation()) {
unpackElementDataHelper(piola_kirchhoff_2, buffer, elements);
unpackElementDataHelper(gradu, buffer, elements);
}
unpackElementDataHelper(stress, buffer, elements);
}
}
/* -------------------------------------------------------------------------- */
inline const Parameter & Material::getParam(const ID & param) const {
try {
return get(param);
} catch (...) {
AKANTU_EXCEPTION("No parameter " << param << " in the material "
<< getID());
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Material::setParam(const ID & param, T value) {
try {
set<T>(param, value);
} catch (...) {
AKANTU_EXCEPTION("No parameter " << param << " in the material "
<< getID());
}
updateInternalParameters();
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Material::packElementDataHelper(
const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
const Array<Element> & elements, const ID & fem_id) const {
DataAccessor::packElementalDataHelper<T>(data_to_pack, buffer, elements, true,
model.getFEEngine(fem_id));
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void Material::unpackElementDataHelper(
ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
const Array<Element> & elements, const ID & fem_id) {
DataAccessor::unpackElementalDataHelper<T>(data_to_unpack, buffer, elements,
true, model.getFEEngine(fem_id));
}
/* -------------------------------------------------------------------------- */
template <>
inline void Material::registerInternal<Real>(InternalField<Real> & vect) {
internal_vectors_real[vect.getID()] = &vect;
}
template <>
inline void Material::registerInternal<UInt>(InternalField<UInt> & vect) {
internal_vectors_uint[vect.getID()] = &vect;
}
template <>
inline void Material::registerInternal<bool>(InternalField<bool> & vect) {
internal_vectors_bool[vect.getID()] = &vect;
}
/* -------------------------------------------------------------------------- */
template <>
inline void Material::unregisterInternal<Real>(InternalField<Real> & vect) {
internal_vectors_real.erase(vect.getID());
}
template <>
inline void Material::unregisterInternal<UInt>(InternalField<UInt> & vect) {
internal_vectors_uint.erase(vect.getID());
}
template <>
inline void Material::unregisterInternal<bool>(InternalField<bool> & vect) {
internal_vectors_bool.erase(vect.getID());
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline bool Material::isInternal(__attribute__((unused)) const ID & id,
__attribute__((unused))
const ElementKind & element_kind) const {
AKANTU_TO_IMPLEMENT();
}
template <>
inline bool Material::isInternal<Real>(const ID & id,
const ElementKind & element_kind) const {
auto internal_array = internal_vectors_real.find(this->getID() + ":" + id);
if (internal_array == internal_vectors_real.end() ||
internal_array->second->getElementKind() != element_kind)
return false;
return true;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline ElementTypeMap<UInt>
Material::getInternalDataPerElem(const ID & field_id,
const ElementKind & element_kind) const {
if (!this->template isInternal<T>(field_id, element_kind))
AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
<< this->name);
const InternalField<T> & internal_field =
this->template getInternal<T>(field_id);
const FEEngine & fe_engine = internal_field.getFEEngine();
UInt nb_data_per_quad = internal_field.getNbComponent();
ElementTypeMap<UInt> res;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
using type_iterator = typename InternalField<T>::type_iterator;
type_iterator tit = internal_field.firstType(*gt);
type_iterator tend = internal_field.lastType(*gt);
for (; tit != tend; ++tit) {
UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(*tit, *gt);
res(*tit, *gt) = nb_data_per_quad * nb_quadrature_points;
}
}
return res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Material::flattenInternal(const std::string & field_id,
ElementTypeMapArray<T> & internal_flat,
const GhostType ghost_type,
ElementKind element_kind) const {
if (!this->template isInternal<T>(field_id, element_kind))
AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
<< this->name);
const InternalField<T> & internal_field =
this->template getInternal<T>(field_id);
const FEEngine & fe_engine = internal_field.getFEEngine();
const Mesh & mesh = fe_engine.getMesh();
using type_iterator = typename InternalField<T>::filter_type_iterator;
type_iterator tit = internal_field.filterFirstType(ghost_type);
type_iterator tend = internal_field.filterLastType(ghost_type);
for (; tit != tend; ++tit) {
ElementType type = *tit;
const Array<Real> & src_vect = internal_field(type, ghost_type);
const Array<UInt> & filter = internal_field.getFilter(type, ghost_type);
// total number of elements in the corresponding mesh
UInt nb_element_dst = mesh.getNbElement(type, ghost_type);
// number of element in the internal field
UInt nb_element_src = filter.size();
// number of quadrature points per elem
UInt nb_quad_per_elem = fe_engine.getNbIntegrationPoints(type);
// number of data per quadrature point
UInt nb_data_per_quad = internal_field.getNbComponent();
if (!internal_flat.exists(type, ghost_type)) {
internal_flat.alloc(nb_element_dst * nb_quad_per_elem, nb_data_per_quad,
type, ghost_type);
}
if (nb_element_src == 0)
continue;
// number of data per element
UInt nb_data = nb_quad_per_elem * nb_data_per_quad;
Array<Real> & dst_vect = internal_flat(type, ghost_type);
dst_vect.resize(nb_element_dst * nb_quad_per_elem);
Array<UInt>::const_scalar_iterator it = filter.begin();
Array<UInt>::const_scalar_iterator end = filter.end();
- auto it_src =
- src_vect.begin_reinterpret(nb_data, nb_element_src);
- auto it_dst =
- dst_vect.begin_reinterpret(nb_data, nb_element_dst);
+ auto it_src = src_vect.begin_reinterpret(nb_data, nb_element_src);
+ auto it_dst = dst_vect.begin_reinterpret(nb_data, nb_element_dst);
for (; it != end; ++it, ++it_src) {
it_dst[*it] = *it_src;
}
}
}
} // akantu
#endif /* __AKANTU_MATERIAL_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/material_selector.hh b/src/model/solid_mechanics/material_selector.hh
index ccbf3b1b4..eb9d161b8 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,163 +1,160 @@
/**
* @file material_selector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Thu Dec 17 2015
*
* @brief class describing how to choose a material for a given element
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh.hh"
#include "element.hh"
+#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#include <memory>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_SELECTOR_HH__
#define __AKANTU_MATERIAL_SELECTOR_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class SolidMechanicsModel;
/**
* main class to assign same or different materials for different
* elements
*/
class MaterialSelector : public std::enable_shared_from_this<MaterialSelector> {
public:
MaterialSelector() = default;
virtual ~MaterialSelector() = default;
virtual inline UInt operator()(const Element & element) {
if (fallback_selector)
return (*fallback_selector)(element);
return fallback_value;
}
inline void setFallback(UInt f) { fallback_value = f; }
inline void
setFallback(const std::shared_ptr<MaterialSelector> & fallback_selector) {
this->fallback_selector = fallback_selector;
}
- inline void
- setFallback(MaterialSelector & fallback_selector) {
+ inline void setFallback(MaterialSelector & fallback_selector) {
this->fallback_selector = fallback_selector.shared_from_this();
}
inline std::shared_ptr<MaterialSelector> & getFallbackSelector() {
return this->fallback_selector;
}
- inline UInt getFallbackValue() {
- return this->fallback_value;
- }
+ inline UInt getFallbackValue() { return this->fallback_value; }
protected:
UInt fallback_value{0};
std::shared_ptr<MaterialSelector> fallback_selector;
};
/* -------------------------------------------------------------------------- */
/**
* class that assigns the first material to regular elements by default
*/
class DefaultMaterialSelector : public MaterialSelector {
public:
explicit DefaultMaterialSelector(
const ElementTypeMapArray<UInt> & material_index)
: material_index(material_index) {}
UInt operator()(const Element & element) override {
if (not material_index.exists(element.type, element.ghost_type))
return MaterialSelector::operator()(element);
const auto & mat_indexes = material_index(element.type, element.ghost_type);
if (element.element < mat_indexes.size()) {
auto && tmp_mat = mat_indexes(element.element);
if (tmp_mat != UInt(-1))
return tmp_mat;
}
return MaterialSelector::operator()(element);
}
private:
const ElementTypeMapArray<UInt> & material_index;
};
/* -------------------------------------------------------------------------- */
/**
* Use elemental data to assign materials
*/
template <typename T>
class ElementDataMaterialSelector : public MaterialSelector {
public:
ElementDataMaterialSelector(const ElementTypeMapArray<T> & element_data,
const SolidMechanicsModel & model,
UInt first_index = 1)
: element_data(element_data), model(model), first_index(first_index) {}
inline T elementData(const Element & element) {
DebugLevel dbl = debug::getDebugLevel();
debug::setDebugLevel(dblError);
T data = element_data(element.type, element.ghost_type)(element.element);
debug::setDebugLevel(dbl);
return data;
}
inline UInt operator()(const Element & element) override {
return MaterialSelector::operator()(element);
}
protected:
/// list of element with the specified data (i.e. tag value)
const ElementTypeMapArray<T> & element_data;
/// the model that the materials belong
const SolidMechanicsModel & model;
/// first material index: equal to 1 if none specified
UInt first_index;
};
/* -------------------------------------------------------------------------- */
/**
* class to use mesh data information to assign different materials
* where name is the tag value: tag_0, tag_1
*/
template <typename T>
class MeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
public:
MeshDataMaterialSelector(const std::string & name,
const SolidMechanicsModel & model,
UInt first_index = 1);
};
} // namespace akantu
#endif /* __AKANTU_MATERIAL_SELECTOR_HH__ */
diff --git a/src/model/solid_mechanics/materials/internal_field.hh b/src/model/solid_mechanics/materials/internal_field.hh
index d28b6a811..af8ae8eaa 100644
--- a/src/model/solid_mechanics/materials/internal_field.hh
+++ b/src/model/solid_mechanics/materials/internal_field.hh
@@ -1,258 +1,260 @@
/**
* @file internal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Dec 08 2015
*
* @brief Material internal properties
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "element_type_map.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTERNAL_FIELD_HH__
#define __AKANTU_INTERNAL_FIELD_HH__
namespace akantu {
class Material;
class FEEngine;
/**
* class for the internal fields of materials
* to store values for each quadrature
*/
template <typename T> class InternalField : public ElementTypeMapArray<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
InternalField(const ID & id, Material & material);
~InternalField() override;
/// This constructor is only here to let cohesive elements compile
InternalField(const ID & id, Material & material, FEEngine & fem,
const ElementTypeMapArray<UInt> & element_filter);
/// More general constructor
InternalField(const ID & id, Material & material, UInt dim, FEEngine & fem,
const ElementTypeMapArray<UInt> & element_filter);
InternalField(const ID & id, const InternalField<T> & other);
private:
InternalField operator=(__attribute__((unused))
const InternalField & other){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to reset the FEEngine for the internal field
virtual void setFEEngine(FEEngine & fe_engine);
/// function to reset the element kind for the internal
virtual void setElementKind(ElementKind element_kind);
/// initialize the field to a given number of component
virtual void initialize(UInt nb_component);
/// activate the history of this field
virtual void initializeHistory();
/// resize the arrays and set the new element to 0
virtual void resize();
/// set the field to a given value v
virtual void setDefaultValue(const T & v);
/// reset all the fields to the default value
virtual void reset();
/// save the current values in the history
virtual void saveCurrentValues();
/// remove the quadrature points corresponding to suppressed elements
virtual void
removeIntegrationPoints(const ElementTypeMapArray<UInt> & new_numbering);
/// print the content
void printself(std::ostream & stream, int /*indent*/ = 0) const override;
/// get the default value
inline operator T() const;
virtual FEEngine & getFEEngine() { return *fem; }
virtual const FEEngine & getFEEngine() const { return *fem; }
/// AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &);
protected:
/// initialize the arrays in the ElementTypeMapArray<T>
void internalInitialize(UInt nb_component);
/// set the values for new internals
virtual void setArrayValues(T * begin, T * end);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
using type_iterator = typename ElementTypeMapArray<T>::type_iterator;
using filter_type_iterator =
typename ElementTypeMapArray<UInt>::type_iterator;
/// get the type iterator on all types contained in the internal field
type_iterator firstType(const GhostType & ghost_type = _not_ghost) const {
- return ElementTypeMapArray<T>::firstType(this->spatial_dimension, ghost_type,
- this->element_kind);
+ return ElementTypeMapArray<T>::firstType(this->spatial_dimension,
+ ghost_type, this->element_kind);
}
/// get the type iterator on the last type contained in the internal field
type_iterator lastType(const GhostType & ghost_type = _not_ghost) const {
return ElementTypeMapArray<T>::lastType(this->spatial_dimension, ghost_type,
this->element_kind);
}
- /// get the type iterator on all types contained in the internal field
- filter_type_iterator filterFirstType(const GhostType & ghost_type = _not_ghost) const {
+ /// get the type iterator on all types contained in the internal field
+ filter_type_iterator
+ filterFirstType(const GhostType & ghost_type = _not_ghost) const {
return this->element_filter.firstType(this->spatial_dimension, ghost_type,
- this->element_kind);
+ this->element_kind);
}
/// get the type iterator on the last type contained in the internal field
- filter_type_iterator filterLastType(const GhostType & ghost_type = _not_ghost) const {
+ filter_type_iterator
+ filterLastType(const GhostType & ghost_type = _not_ghost) const {
return this->element_filter.lastType(this->spatial_dimension, ghost_type,
- this->element_kind);
+ this->element_kind);
}
/// get the array for a given type of the element_filter
const Array<UInt> getFilter(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
return this->element_filter(type, ghost_type);
}
/// get the Array corresponding to the type en ghost_type specified
virtual Array<T> & operator()(const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
return ElementTypeMapArray<T>::operator()(type, ghost_type);
}
virtual const Array<T> &
operator()(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
return ElementTypeMapArray<T>::operator()(type, ghost_type);
}
virtual Array<T> & previous(const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
AKANTU_DEBUG_ASSERT(previous_values != nullptr,
"The history of the internal "
<< this->getID() << " has not been activated");
return this->previous_values->operator()(type, ghost_type);
}
virtual const Array<T> &
previous(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
AKANTU_DEBUG_ASSERT(previous_values != nullptr,
"The history of the internal "
<< this->getID() << " has not been activated");
return this->previous_values->operator()(type, ghost_type);
}
virtual InternalField<T> & previous() {
AKANTU_DEBUG_ASSERT(previous_values != nullptr,
"The history of the internal "
<< this->getID() << " has not been activated");
return *(this->previous_values);
}
virtual const InternalField<T> & previous() const {
AKANTU_DEBUG_ASSERT(previous_values != nullptr,
"The history of the internal "
<< this->getID() << " has not been activated");
return *(this->previous_values);
}
/// check if the history is used or not
bool hasHistory() const { return (previous_values != nullptr); }
/// get the kind treated by the internal
const ElementKind & getElementKind() const { return element_kind; }
/// return the number of components
UInt getNbComponent() const { return nb_component; }
/// return the spatial dimension corresponding to the internal element type
/// loop filter
UInt getSpatialDimension() const { return this->spatial_dimension; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the material for which this is an internal parameter
Material & material;
/// the fem containing the mesh and the element informations
FEEngine * fem;
/// Element filter if needed
const ElementTypeMapArray<UInt> & element_filter;
/// default value
T default_value;
/// spatial dimension of the element to consider
UInt spatial_dimension;
/// ElementKind of the element to consider
ElementKind element_kind;
/// Number of component of the internal field
UInt nb_component;
/// Is the field initialized
bool is_init;
/// previous values
InternalField<T> * previous_values;
};
/// standard output stream operator
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
const InternalField<T> & _this) {
_this.printself(stream);
return stream;
}
} // akantu
#endif /* __AKANTU_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_core_includes.hh b/src/model/solid_mechanics/materials/material_core_includes.hh
index 2b35c35f2..5804db7da 100644
--- a/src/model/solid_mechanics/materials/material_core_includes.hh
+++ b/src/model/solid_mechanics/materials/material_core_includes.hh
@@ -1,69 +1,68 @@
/**
* @file material_core_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Sat Jul 18 2015
*
* @brief List of materials for core package
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_CORE_INCLUDES_HH__
#define __AKANTU_MATERIAL_CORE_INCLUDES_HH__
/* -------------------------------------------------------------------------- */
/* Material list */
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
// elastic materials
#include "material_elastic.hh"
-#include "material_neohookean.hh"
-#include "material_elastic_orthotropic.hh"
#include "material_elastic_linear_anisotropic.hh"
+#include "material_elastic_orthotropic.hh"
+#include "material_neohookean.hh"
// visco-elastic materials
#include "material_standard_linear_solid_deviatoric.hh"
// damage laws
#include "material_marigo.hh"
#include "material_mazars.hh"
// small-deformation plasticity
#include "material_linear_isotropic_hardening.hh"
#endif
-#define AKANTU_CORE_MATERIAL_LIST \
- ((2, (elastic , MaterialElastic ))) \
- ((2, (neohookean , MaterialNeohookean ))) \
- ((2, (elastic_orthotropic, MaterialElasticOrthotropic ))) \
- ((2, (elastic_anisotropic, MaterialElasticLinearAnisotropic ))) \
- ((2, (sls_deviatoric , MaterialStandardLinearSolidDeviatoric))) \
- ((2, (marigo , MaterialMarigo ))) \
- ((2, (mazars , MaterialMazars ))) \
- ((2, (plastic_linear_isotropic_hardening, MaterialLinearIsotropicHardening)))
+#define AKANTU_CORE_MATERIAL_LIST \
+ ((2, (elastic, MaterialElastic)))((2, (neohookean, MaterialNeohookean)))( \
+ (2, (elastic_orthotropic, MaterialElasticOrthotropic)))( \
+ (2, (elastic_anisotropic, MaterialElasticLinearAnisotropic)))( \
+ (2, (sls_deviatoric, MaterialStandardLinearSolidDeviatoric)))( \
+ (2, (marigo, MaterialMarigo)))((2, (mazars, MaterialMazars)))( \
+ (2, (plastic_linear_isotropic_hardening, \
+ MaterialLinearIsotropicHardening)))
#endif /* __AKANTU_MATERIAL_CORE_INCLUDES_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
index 7cc81a295..707acab2a 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
@@ -1,74 +1,74 @@
/**
* @file material_damage_non_local.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Aug 23 2012
* @date last modification: Wed Oct 21 2015
*
* @brief interface for non local damage material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__
namespace akantu {
template <UInt dim, class MaterialDamageLocal>
-class MaterialDamageNonLocal : public MaterialNonLocal<dim, MaterialDamageLocal> {
+class MaterialDamageNonLocal
+ : public MaterialNonLocal<dim, MaterialDamageLocal> {
public:
using MaterialParent = MaterialNonLocal<dim, MaterialDamageLocal>;
MaterialDamageNonLocal(SolidMechanicsModel & model, const ID & id)
- : MaterialParent(model, id) {};
+ : MaterialParent(model, id){};
protected:
/* ------------------------------------------------------------------------ */
virtual void computeNonLocalStress(ElementType type,
GhostType ghost_type = _not_ghost) = 0;
/* ------------------------------------------------------------------------ */
void computeNonLocalStresses(GhostType ghost_type) override {
AKANTU_DEBUG_IN();
- for (auto type :
- this->element_filter.elementTypes(dim, ghost_type)) {
+ for (auto type : this->element_filter.elementTypes(dim, ghost_type)) {
auto & elem_filter = this->element_filter(type, ghost_type);
if (elem_filter.size() == 0)
continue;
computeNonLocalStress(type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
};
} // namespace akantu
#endif /* __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
index 1adbf12dd..a0df92944 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
@@ -1,131 +1,132 @@
/**
* @file material_marigo_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 04 2010
* @date last modification: Thu Oct 15 2015
*
* @brief Implementation of the inline functions of the material marigo
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_marigo.hh"
#ifndef __AKANTU_MATERIAL_MARIGO_INLINE_IMPL_CC__
#define __AKANTU_MATERIAL_MARIGO_INLINE_IMPL_CC__
namespace akantu {
template <UInt spatial_dimension>
inline void MaterialMarigo<spatial_dimension>::computeStressOnQuad(
Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam, Real & Y,
Real & Ydq) {
MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
Y = 0;
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
Y += sigma(i, j) * (grad_u(i, j) + grad_u(j, i)) / 2.;
}
}
Y *= 0.5;
if (damage_in_y)
Y *= (1 - dam);
if (yc_limit)
Y = std::min(Y, Yc);
if (!this->is_non_local) {
computeDamageAndStressOnQuad(sigma, dam, Y, Ydq);
}
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
inline void MaterialMarigo<spatial_dimension>::computeDamageAndStressOnQuad(
Matrix<Real> & sigma, Real & dam, Real & Y, Real & Ydq) {
Real Fd = Y - Ydq - Sd * dam;
if (Fd > 0)
dam = (Y - Ydq) / Sd;
dam = std::min(dam, Real(1.));
sigma *= 1 - dam;
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
inline UInt MaterialMarigo<spatial_dimension>::getNbData(
const Array<Element> & elements, const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
if (tag == _gst_smm_init_mat) {
size += sizeof(Real) * this->getModel().getNbIntegrationPoints(elements);
}
size += MaterialDamage<spatial_dimension>::getNbData(elements, tag);
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
inline void MaterialMarigo<spatial_dimension>::packData(
CommunicationBuffer & buffer, const Array<Element> & elements,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
if (tag == _gst_smm_init_mat) {
this->packElementDataHelper(Yd, buffer, elements);
}
MaterialDamage<spatial_dimension>::packData(buffer, elements, tag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
-inline void MaterialMarigo<spatial_dimension>::unpackData(
- CommunicationBuffer & buffer, const Array<Element> & elements,
- const SynchronizationTag & tag) {
+inline void
+MaterialMarigo<spatial_dimension>::unpackData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
if (tag == _gst_smm_init_mat) {
this->unpackElementDataHelper(Yd, buffer, elements);
}
MaterialDamage<spatial_dimension>::unpackData(buffer, elements, tag);
AKANTU_DEBUG_OUT();
}
-} // akantu
+} // akantu
#endif /* __AKANTU_MATERIAL_MARIGO_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
index 461bc2591..6eb060efe 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
@@ -1,106 +1,106 @@
/**
* @file material_marigo_non_local.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 15 2015
*
* @brief Marigo non-local inline function implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_marigo_non_local.hh"
#include "non_local_neighborhood_base.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialMarigoNonLocal<spatial_dimension>::MaterialMarigoNonLocal(
SolidMechanicsModel & model, const ID & id)
: MaterialMarigoNonLocalParent(model, id), Y("Y", *this),
Ynl("Y non local", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
this->Y.initialize(1);
this->Ynl.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialMarigoNonLocal<spatial_dimension>::registerNonLocalVariables() {
+ this->model.getNonLocalManager().registerNonLocalVariable(this->Y.getName(),
+ Ynl.getName(), 1);
this->model.getNonLocalManager()
- .registerNonLocalVariable(this->Y.getName(), Ynl.getName(), 1);
- this->model.getNonLocalManager()
- .getNeighborhood(this->name)
- .registerNonLocalVariable(Ynl.getName());
+ .getNeighborhood(this->name)
+ .registerNonLocalVariable(Ynl.getName());
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialMarigoNonLocal<spatial_dimension>::computeStress(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(el_type, ghost_type).storage();
Real * Yt = this->Y(el_type, ghost_type).storage();
Real * Ydq = this->Yd(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
MaterialMarigo<spatial_dimension>::computeStressOnQuad(grad_u, sigma, *dam,
*Yt, *Ydq);
++dam;
++Yt;
++Ydq;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialMarigoNonLocal<spatial_dimension>::computeNonLocalStress(
ElementType type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * dam = this->damage(type, ghost_type).storage();
Real * Ydq = this->Yd(type, ghost_type).storage();
Real * Ynlt = this->Ynl(type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(type, ghost_type);
this->computeDamageAndStressOnQuad(sigma, *dam, *Ynlt, *Ydq);
++dam;
++Ynlt;
++Ydq;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
INSTANTIATE_MATERIAL(marigo_non_local, MaterialMarigoNonLocal);
} // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
index 716d2e9af..74150eb04 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
@@ -1,154 +1,155 @@
/**
* @file material_mazars_inline_impl.cc
*
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Apr 06 2011
* @date last modification: Tue Aug 04 2015
*
* @brief Implementation of the inline functions of the material damage
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void
-MaterialMazars<spatial_dimension>::computeStressOnQuad(const Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- Real & dam,
- Real & Ehat) {
+template <UInt spatial_dimension>
+inline void MaterialMazars<spatial_dimension>::computeStressOnQuad(
+ const Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam,
+ Real & Ehat) {
Matrix<Real> epsilon(3, 3);
epsilon.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
- epsilon(i,j) = .5*(grad_u(i,j) + grad_u(j,i));
+ epsilon(i, j) = .5 * (grad_u(i, j) + grad_u(j, i));
Vector<Real> Fdiag(3);
Math::matrixEig(3, epsilon.storage(), Fdiag.storage());
Ehat = 0.;
for (UInt i = 0; i < 3; ++i) {
Real epsilon_p = std::max(Real(0.), Fdiag(i));
Ehat += epsilon_p * epsilon_p;
}
Ehat = sqrt(Ehat);
MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
- if(damage_in_compute_stress) {
+ if (damage_in_compute_stress) {
computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
}
- if(!this->is_non_local) {
+ if (!this->is_non_local) {
computeDamageAndStressOnQuad(grad_u, sigma, dam, Ehat);
}
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void
-MaterialMazars<spatial_dimension>::computeDamageAndStressOnQuad(const Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- Real & dam,
- Real & Ehat) {
- if(!damage_in_compute_stress) {
+template <UInt spatial_dimension>
+inline void MaterialMazars<spatial_dimension>::computeDamageAndStressOnQuad(
+ const Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam,
+ Real & Ehat) {
+ if (!damage_in_compute_stress) {
Vector<Real> Fdiag(3);
Fdiag.clear();
Matrix<Real> epsilon(3, 3);
epsilon.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
- epsilon(i,j) = .5*(grad_u(i,j) + grad_u(j,i));
+ epsilon(i, j) = .5 * (grad_u(i, j) + grad_u(j, i));
Math::matrixEig(3, epsilon.storage(), Fdiag.storage());
computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
}
sigma *= 1 - dam;
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void
-MaterialMazars<spatial_dimension>::computeDamageOnQuad(const Real & epsilon_equ,
- __attribute__((unused)) const Matrix<Real> & sigma,
- const Vector<Real> & epsilon_princ,
- Real & dam) {
+template <UInt spatial_dimension>
+inline void MaterialMazars<spatial_dimension>::computeDamageOnQuad(
+ const Real & epsilon_equ,
+ __attribute__((unused)) const Matrix<Real> & sigma,
+ const Vector<Real> & epsilon_princ, Real & dam) {
Real Fs = epsilon_equ - K0;
if (Fs > 0.) {
Real dam_t;
Real dam_c;
- dam_t = 1 - K0*(1 - At)/epsilon_equ - At*(exp(-Bt*(epsilon_equ - K0)));
- dam_c = 1 - K0*(1 - Ac)/epsilon_equ - Ac*(exp(-Bc*(epsilon_equ - K0)));
+ dam_t =
+ 1 - K0 * (1 - At) / epsilon_equ - At * (exp(-Bt * (epsilon_equ - K0)));
+ dam_c =
+ 1 - K0 * (1 - Ac) / epsilon_equ - Ac * (exp(-Bc * (epsilon_equ - K0)));
Real Cdiag;
- Cdiag = this->E*(1-this->nu)/((1+this->nu)*(1-2*this->nu));
+ Cdiag = this->E * (1 - this->nu) / ((1 + this->nu) * (1 - 2 * this->nu));
Vector<Real> sigma_princ(3);
- sigma_princ(0) = Cdiag*epsilon_princ(0) + this->lambda*(epsilon_princ(1) + epsilon_princ(2));
- sigma_princ(1) = Cdiag*epsilon_princ(1) + this->lambda*(epsilon_princ(0) + epsilon_princ(2));
- sigma_princ(2) = Cdiag*epsilon_princ(2) + this->lambda*(epsilon_princ(1) + epsilon_princ(0));
+ sigma_princ(0) = Cdiag * epsilon_princ(0) +
+ this->lambda * (epsilon_princ(1) + epsilon_princ(2));
+ sigma_princ(1) = Cdiag * epsilon_princ(1) +
+ this->lambda * (epsilon_princ(0) + epsilon_princ(2));
+ sigma_princ(2) = Cdiag * epsilon_princ(2) +
+ this->lambda * (epsilon_princ(1) + epsilon_princ(0));
Vector<Real> sigma_p(3);
- for (UInt i = 0; i < 3; i++) sigma_p(i) = std::max(Real(0.), sigma_princ(i));
+ for (UInt i = 0; i < 3; i++)
+ sigma_p(i) = std::max(Real(0.), sigma_princ(i));
sigma_p *= 1. - dam;
Real trace_p = this->nu / this->E * (sigma_p(0) + sigma_p(1) + sigma_p(2));
Real alpha_t = 0;
for (UInt i = 0; i < 3; ++i) {
- Real epsilon_t = (1 + this->nu)/this->E * sigma_p(i) - trace_p;
+ Real epsilon_t = (1 + this->nu) / this->E * sigma_p(i) - trace_p;
Real epsilon_p = std::max(Real(0.), epsilon_princ(i));
alpha_t += epsilon_t * epsilon_p;
}
alpha_t /= epsilon_equ * epsilon_equ;
alpha_t = std::min(alpha_t, Real(1.));
Real alpha_c = 1. - alpha_t;
alpha_t = std::pow(alpha_t, beta);
alpha_c = std::pow(alpha_c, beta);
Real damtemp;
damtemp = alpha_t * dam_t + alpha_c * dam_c;
dam = std::max(damtemp, dam);
dam = std::min(dam, Real(1.));
}
}
-
/* -------------------------------------------------------------------------- */
// template<UInt spatial_dimension>
-// inline void MaterialMazars<spatial_dimension>::computeTangentModuliOnQuad(Matrix<Real> & tangent) {
+// inline void
+// MaterialMazars<spatial_dimension>::computeTangentModuliOnQuad(Matrix<Real> &
+// tangent) {
// MaterialElastic<spatial_dimension>::computeTangentModuliOnQuad(tangent);
// tangent *= (1-dam);
// }
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
index 4fb33b7e9..e7f28b042 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
@@ -1,91 +1,92 @@
/**
* @file material_mazars_non_local.hh
*
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 08 2015
*
* @brief Mazars non-local description
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "material_mazars.hh"
#include "material_damage_non_local.hh"
+#include "material_mazars.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__
namespace akantu {
/**
* Material Mazars Non local
*
* parameters in the material files :
*/
template <UInt spatial_dimension>
class MaterialMazarsNonLocal
: public MaterialDamageNonLocal<spatial_dimension,
MaterialMazars<spatial_dimension>> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
using MaterialNonLocalParent =
- MaterialDamageNonLocal<spatial_dimension, MaterialMazars<spatial_dimension>>;
+ MaterialDamageNonLocal<spatial_dimension,
+ MaterialMazars<spatial_dimension>>;
MaterialMazarsNonLocal(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// constitutive law for all element of a type
void computeStress(ElementType el_type,
GhostType ghost_type = _not_ghost) override;
void computeNonLocalStress(ElementType el_type,
GhostType ghost_type = _not_ghost) override;
void registerNonLocalVariables() override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the ehat per quadrature points to perform the averaging
InternalField<Real> Ehat;
InternalField<Real> non_local_variable;
};
} // namespace akantu
#endif /* __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic.cc b/src/model/solid_mechanics/materials/material_elastic.cc
index ffea72e8b..894d86e3c 100644
--- a/src/model/solid_mechanics/materials/material_elastic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic.cc
@@ -1,264 +1,264 @@
/**
* @file material_elastic.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 15 2015
*
* @brief Specialization of the material class for the elastic material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_elastic.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt dim>
MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
const ID & id)
: Parent(model, id), was_stiffness_assembled(false) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
__attribute__((unused)) UInt a_dim,
const Mesh & mesh, FEEngine & fe_engine,
const ID & id)
: Parent(model, dim, mesh, fe_engine, id), was_stiffness_assembled(false) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim> void MaterialElastic<dim>::initialize() {
this->registerParam("lambda", lambda, _pat_readable,
"First Lamé coefficient");
this->registerParam("mu", mu, _pat_readable, "Second Lamé coefficient");
this->registerParam("kapa", kpa, _pat_readable, "Bulk coefficient");
}
/* -------------------------------------------------------------------------- */
template <UInt dim> void MaterialElastic<dim>::initMaterial() {
AKANTU_DEBUG_IN();
Parent::initMaterial();
if (dim == 1)
this->nu = 0.;
this->updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim> void MaterialElastic<dim>::updateInternalParameters() {
MaterialThermal<dim>::updateInternalParameters();
this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2 * this->nu));
this->mu = this->E / (2 * (1 + this->nu));
this->kpa = this->lambda + 2. / 3. * this->mu;
this->was_stiffness_assembled = false;
}
/* -------------------------------------------------------------------------- */
template <> void MaterialElastic<2>::updateInternalParameters() {
MaterialThermal<2>::updateInternalParameters();
this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2 * this->nu));
this->mu = this->E / (2 * (1 + this->nu));
if (this->plane_stress)
this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - this->nu));
this->kpa = this->lambda + 2. / 3. * this->mu;
this->was_stiffness_assembled = false;
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computeStress(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Parent::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator sigma_th_it =
this->sigma_th(el_type, ghost_type).begin();
if (!this->finite_deformation) {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
const Real & sigma_th = *sigma_th_it;
this->computeStressOnQuad(grad_u, sigma, sigma_th);
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
} else {
/// finite gradus
Matrix<Real> E(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
/// compute E
this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
const Real & sigma_th = *sigma_th_it;
/// compute second Piola-Kirchhoff stress tensor
this->computeStressOnQuad(E, sigma, sigma_th);
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computeTangentModuli(
- const ElementType & el_type, Array<Real> & tangent_matrix, GhostType ghost_type) {
+ const ElementType & el_type, Array<Real> & tangent_matrix,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
this->computeTangentModuliOnQuad(tangent);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
this->was_stiffness_assembled = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
Real MaterialElastic<spatial_dimension>::getPushWaveSpeed(
const Element &) const {
return sqrt((lambda + 2 * mu) / this->rho);
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
Real MaterialElastic<spatial_dimension>::getShearWaveSpeed(
const Element &) const {
return sqrt(mu / this->rho);
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computePotentialEnergy(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialThermal<spatial_dimension>::computePotentialEnergy(el_type,
ghost_type);
if (ghost_type != _not_ghost)
return;
auto epot = this->potential_energy(el_type, ghost_type).begin();
if (!this->finite_deformation) {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->computePotentialEnergyOnQuad(grad_u, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
} else {
Matrix<Real> E(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
this->computePotentialEnergyOnQuad(E, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computePotentialEnergyByElement(
ElementType type, UInt index, Vector<Real> & epot_on_quad_points) {
auto gradu_it = this->gradu(type).begin(spatial_dimension, spatial_dimension);
auto gradu_end =
this->gradu(type).begin(spatial_dimension, spatial_dimension);
auto stress_it =
this->stress(type).begin(spatial_dimension, spatial_dimension);
if (this->finite_deformation)
stress_it = this->piola_kirchhoff_2(type).begin(spatial_dimension,
spatial_dimension);
- UInt nb_quadrature_points =
- this->fem.getNbIntegrationPoints(type);
+ UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
gradu_it += index * nb_quadrature_points;
gradu_end += (index + 1) * nb_quadrature_points;
stress_it += index * nb_quadrature_points;
Real * epot_quad = epot_on_quad_points.storage();
Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
for (; gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
if (this->finite_deformation)
this->template gradUToGreenStrain<spatial_dimension>(*gradu_it, grad_u);
else
grad_u.copy(*gradu_it);
this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
}
}
/* -------------------------------------------------------------------------- */
template <>
Real MaterialElastic<1>::getPushWaveSpeed(const Element & /*element*/) const {
return std::sqrt(this->E / this->rho);
}
template <>
Real MaterialElastic<1>::getShearWaveSpeed(const Element & /*element*/) const {
AKANTU_EXCEPTION("There is no shear wave speed in 1D");
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(elastic, MaterialElastic);
} // akantu
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
index 72e8c8fe5..84c1608fa 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
@@ -1,263 +1,263 @@
/**
* @file material_elastic_linear_anisotropic.cc
*
* @author Till Junge <till.junge@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 25 2013
* @date last modification: Thu Oct 15 2015
*
* @brief Anisotropic elastic material
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "material_elastic_linear_anisotropic.hh"
#include "solid_mechanics_model.hh"
#include <algorithm>
#include <sstream>
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt dim>
MaterialElasticLinearAnisotropic<dim>::MaterialElasticLinearAnisotropic(
SolidMechanicsModel & model, const ID & id, bool symmetric)
: Material(model, id), rot_mat(dim, dim), Cprime(dim * dim, dim * dim),
C(voigt_h::size, voigt_h::size), eigC(voigt_h::size),
symmetric(symmetric), alpha(0), was_stiffness_assembled(false) {
AKANTU_DEBUG_IN();
this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
(*this->dir_vecs.back())[0] = 1.;
this->registerParam("n1", *(this->dir_vecs.back()), _pat_parsmod,
"Direction of main material axis");
if (dim > 1) {
this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
(*this->dir_vecs.back())[1] = 1.;
this->registerParam("n2", *(this->dir_vecs.back()), _pat_parsmod,
"Direction of secondary material axis");
}
if (dim > 2) {
this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
(*this->dir_vecs.back())[2] = 1.;
this->registerParam("n3", *(this->dir_vecs.back()), _pat_parsmod,
"Direction of tertiary material axis");
}
for (UInt i = 0; i < voigt_h::size; ++i) {
UInt start = 0;
if (this->symmetric) {
start = i;
}
for (UInt j = start; j < voigt_h::size; ++j) {
std::stringstream param("C");
param << "C" << i + 1 << j + 1;
this->registerParam(param.str(), this->Cprime(i, j), Real(0.),
_pat_parsmod, "Coefficient " + param.str());
}
}
this->registerParam("alpha", this->alpha, _pat_parsmod,
"Proportion of viscous stress");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim> void MaterialElasticLinearAnisotropic<dim>::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void MaterialElasticLinearAnisotropic<dim>::updateInternalParameters() {
Material::updateInternalParameters();
if (this->symmetric) {
for (UInt i = 0; i < voigt_h::size; ++i) {
for (UInt j = i + 1; j < voigt_h::size; ++j) {
this->Cprime(j, i) = this->Cprime(i, j);
}
}
}
this->rotateCprime();
this->C.eig(this->eigC);
this->was_stiffness_assembled = false;
}
/* -------------------------------------------------------------------------- */
template <UInt Dim> void MaterialElasticLinearAnisotropic<Dim>::rotateCprime() {
// start by filling the empty parts fo Cprime
UInt diff = Dim * Dim - voigt_h::size;
for (UInt i = voigt_h::size; i < Dim * Dim; ++i) {
for (UInt j = 0; j < Dim * Dim; ++j) {
this->Cprime(i, j) = this->Cprime(i - diff, j);
}
}
for (UInt i = 0; i < Dim * Dim; ++i) {
for (UInt j = voigt_h::size; j < Dim * Dim; ++j) {
this->Cprime(i, j) = this->Cprime(i, j - diff);
}
}
// construction of rotator tensor
// normalise rotation matrix
for (UInt j = 0; j < Dim; ++j) {
Vector<Real> rot_vec = this->rot_mat(j);
rot_vec = *this->dir_vecs[j];
rot_vec.normalize();
}
// make sure the vectors form a right-handed base
Vector<Real> test_axis(3);
Vector<Real> v1(3), v2(3), v3(3);
if (Dim == 2) {
for (UInt i = 0; i < Dim; ++i) {
v1[i] = this->rot_mat(0, i);
v2[i] = this->rot_mat(1, i);
v3[i] = 0.;
}
v3[2] = 1.;
v1[2] = 0.;
v2[2] = 0.;
} else if (Dim == 3) {
v1 = this->rot_mat(0);
v2 = this->rot_mat(1);
v3 = this->rot_mat(2);
}
test_axis.crossProduct(v1, v2);
test_axis -= v3;
if (test_axis.norm() > 8 * std::numeric_limits<Real>::epsilon()) {
AKANTU_ERROR("The axis vectors do not form a right-handed coordinate "
- << "system. I. e., ||n1 x n2 - n3|| should be zero, but "
- << "it is " << test_axis.norm() << ".");
+ << "system. I. e., ||n1 x n2 - n3|| should be zero, but "
+ << "it is " << test_axis.norm() << ".");
}
// create the rotator and the reverse rotator
Matrix<Real> rotator(Dim * Dim, Dim * Dim);
Matrix<Real> revrotor(Dim * Dim, Dim * Dim);
for (UInt i = 0; i < Dim; ++i) {
for (UInt j = 0; j < Dim; ++j) {
for (UInt k = 0; k < Dim; ++k) {
for (UInt l = 0; l < Dim; ++l) {
UInt I = voigt_h::mat[i][j];
UInt J = voigt_h::mat[k][l];
rotator(I, J) = this->rot_mat(k, i) * this->rot_mat(l, j);
revrotor(I, J) = this->rot_mat(i, k) * this->rot_mat(j, l);
}
}
}
}
// create the full rotated matrix
Matrix<Real> Cfull(Dim * Dim, Dim * Dim);
Cfull = rotator * Cprime * revrotor;
for (UInt i = 0; i < voigt_h::size; ++i) {
for (UInt j = 0; j < voigt_h::size; ++j) {
this->C(i, j) = Cfull(i, j);
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
-void MaterialElasticLinearAnisotropic<dim>::computeStress(ElementType el_type,
- GhostType ghost_type) {
+void MaterialElasticLinearAnisotropic<dim>::computeStress(
+ ElementType el_type, GhostType ghost_type) {
// Wikipedia convention:
// 2*eps_ij (i!=j) = voigt_eps_I
// http://en.wikipedia.org/wiki/Voigt_notation
AKANTU_DEBUG_IN();
Matrix<Real> strain(dim, dim);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
- this->computeStressOnQuad(strain,sigma);
+ this->computeStressOnQuad(strain, sigma);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void MaterialElasticLinearAnisotropic<dim>::computeTangentModuli(
const ElementType & el_type, Array<Real> & tangent_matrix,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
this->computeTangentModuliOnQuad(tangent);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
this->was_stiffness_assembled = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
void MaterialElasticLinearAnisotropic<dim>::computePotentialEnergy(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
AKANTU_DEBUG_ASSERT(!this->finite_deformation,
"finite deformation not possible in material anisotropic "
"(TO BE IMPLEMENTED)");
if (ghost_type != _not_ghost)
return;
Array<Real>::scalar_iterator epot =
- this->potential_energy(el_type, ghost_type).begin();
+ this->potential_energy(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computePotentialEnergyOnQuad(grad_u, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
Real MaterialElasticLinearAnisotropic<dim>::getCelerity(
__attribute__((unused)) const Element & element) const {
return std::sqrt(this->eigC(0) / rho);
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(elastic_anisotropic, MaterialElasticLinearAnisotropic);
} // akantu
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc
index 900b8d5ae..1d608fe60 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc
@@ -1,96 +1,93 @@
/**
* @file material_elastic_linear_anisotropic_inline_impl.cc
*
* @author Enrico Milanese <enrico.milanese@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Feb 12 2018
* @date last modification: Mon Feb 12 2018
*
* @brief Implementation of the inline functions of the material elastic linear
* anisotropic
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_elastic_linear_anisotropic.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_CC__
#define __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt dim>
-inline void MaterialElasticLinearAnisotropic<dim>::computeStressOnQuad(const Matrix<Real> & grad_u,
- Matrix<Real> & sigma) const {
+inline void MaterialElasticLinearAnisotropic<dim>::computeStressOnQuad(
+ const Matrix<Real> & grad_u, Matrix<Real> & sigma) const {
// Wikipedia convention:
// 2*eps_ij (i!=j) = voigt_eps_I
// http://en.wikipedia.org/wiki/Voigt_notation
Vector<Real> voigt_strain(voigt_h::size);
Vector<Real> voigt_stress(voigt_h::size);
- for (UInt I = 0; I < voigt_h::size; ++I){
+ for (UInt I = 0; I < voigt_h::size; ++I) {
Real voigt_factor = voigt_h::factors[I];
UInt i = voigt_h::vec[I][0];
UInt j = voigt_h::vec[I][1];
voigt_strain(I) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.;
-
}
voigt_stress = this->C * voigt_strain;
- for (UInt I = 0; I < voigt_h::size; ++I){
+ for (UInt I = 0; I < voigt_h::size; ++I) {
UInt i = voigt_h::vec[I][0];
UInt j = voigt_h::vec[I][1];
sigma(i, j) = sigma(j, i) = voigt_stress(I);
-
}
-
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
-inline void MaterialElasticLinearAnisotropic<dim>::computeTangentModuliOnQuad(Matrix<Real> & tangent) const {
+inline void MaterialElasticLinearAnisotropic<dim>::computeTangentModuliOnQuad(
+ Matrix<Real> & tangent) const {
tangent.copy(this->C);
-
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialElasticLinearAnisotropic<dim>::computePotentialEnergyOnQuad(
const Matrix<Real> & grad_u, const Matrix<Real> & sigma, Real & epot) {
AKANTU_DEBUG_ASSERT(this->symmetric,
"The elastic constants matrix is not symmetric,"
"energy is not path independent.");
epot = .5 * sigma.doubleDot(grad_u);
}
} // akantu
#endif /* __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
index c14e5784a..320f2bb44 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
@@ -1,168 +1,168 @@
/**
* @file material_elastic_orthotropic.cc
*
* @author Till Junge <till.junge@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 15 2015
*
* @brief Orthotropic elastic material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "material_elastic_orthotropic.hh"
#include "solid_mechanics_model.hh"
#include <algorithm>
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt Dim>
MaterialElasticOrthotropic<Dim>::MaterialElasticOrthotropic(
SolidMechanicsModel & model, const ID & id)
: MaterialElasticLinearAnisotropic<Dim>(model, id) {
AKANTU_DEBUG_IN();
this->registerParam("E1", E1, Real(0.), _pat_parsmod, "Young's modulus (n1)");
this->registerParam("E2", E2, Real(0.), _pat_parsmod, "Young's modulus (n2)");
this->registerParam("nu12", nu12, Real(0.), _pat_parsmod,
"Poisson's ratio (12)");
this->registerParam("G12", G12, Real(0.), _pat_parsmod, "Shear modulus (12)");
if (Dim > 2) {
this->registerParam("E3", E3, Real(0.), _pat_parsmod,
"Young's modulus (n3)");
this->registerParam("nu13", nu13, Real(0.), _pat_parsmod,
"Poisson's ratio (13)");
this->registerParam("nu23", nu23, Real(0.), _pat_parsmod,
"Poisson's ratio (23)");
this->registerParam("G13", G13, Real(0.), _pat_parsmod,
"Shear modulus (13)");
this->registerParam("G23", G23, Real(0.), _pat_parsmod,
"Shear modulus (23)");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt Dim> void MaterialElasticOrthotropic<Dim>::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt Dim>
void MaterialElasticOrthotropic<Dim>::updateInternalParameters() {
/* 1) construction of temporary material frame stiffness tensor------------ */
// http://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php#Sect3_2_13
Real nu21 = nu12 * E2 / E1;
Real nu31 = nu13 * E3 / E1;
Real nu32 = nu23 * E3 / E2;
// Full (i.e. dim^2 by dim^2) stiffness tensor in material frame
if (Dim == 1) {
AKANTU_ERROR("Dimensions 1 not implemented: makes no sense to have "
- "orthotropy for 1D");
+ "orthotropy for 1D");
}
Real Gamma;
if (Dim == 3)
Gamma = 1 / (1 - nu12 * nu21 - nu23 * nu32 - nu31 * nu13 -
2 * nu21 * nu32 * nu13);
if (Dim == 2)
Gamma = 1 / (1 - nu12 * nu21);
// Lamé's first parameters
this->Cprime(0, 0) = E1 * (1 - nu23 * nu32) * Gamma;
this->Cprime(1, 1) = E2 * (1 - nu13 * nu31) * Gamma;
if (Dim == 3)
this->Cprime(2, 2) = E3 * (1 - nu12 * nu21) * Gamma;
// normalised poisson's ratio's
this->Cprime(1, 0) = this->Cprime(0, 1) = E1 * (nu21 + nu31 * nu23) * Gamma;
if (Dim == 3) {
this->Cprime(2, 0) = this->Cprime(0, 2) = E1 * (nu31 + nu21 * nu32) * Gamma;
this->Cprime(2, 1) = this->Cprime(1, 2) = E2 * (nu32 + nu12 * nu31) * Gamma;
}
// Lamé's second parameters (shear moduli)
if (Dim == 3) {
this->Cprime(3, 3) = G23;
this->Cprime(4, 4) = G13;
this->Cprime(5, 5) = G12;
} else
this->Cprime(2, 2) = G12;
/* 1) rotation of C into the global frame */
this->rotateCprime();
this->C.eig(this->eigC);
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialElasticOrthotropic<spatial_dimension>::
computePotentialEnergyByElement(ElementType type, UInt index,
Vector<Real> & epot_on_quad_points) {
AKANTU_DEBUG_ASSERT(!this->finite_deformation,
"finite deformation not possible in material orthotropic "
"(TO BE IMPLEMENTED)");
Array<Real>::matrix_iterator gradu_it =
this->gradu(type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator gradu_end =
this->gradu(type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator stress_it =
this->stress(type).begin(spatial_dimension, spatial_dimension);
UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
gradu_it += index * nb_quadrature_points;
gradu_end += (index + 1) * nb_quadrature_points;
stress_it += index * nb_quadrature_points;
Real * epot_quad = epot_on_quad_points.storage();
Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
for (; gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
grad_u.copy(*gradu_it);
this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
}
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(elastic_orthotropic, MaterialElasticOrthotropic);
} // akantu
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh b/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
index 3c04d7b6b..29362ed2c 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
@@ -1,41 +1,41 @@
/**
* @file material_embedded_includes.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Fri May 29 2015
*
* @brief List of includes for embedded elements
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
-# include "material_reinforcement.hh"
+#include "material_reinforcement.hh"
#endif
-#define AKANTU_MATERIAL_REINFORCEMENT_LAW_TMPL_LIST \
- ((elastic, (MaterialElastic<1>))) \
- ((plastic, (MaterialLinearIsotropicHardening<1>)))
+#define AKANTU_MATERIAL_REINFORCEMENT_LAW_TMPL_LIST \
+ ((elastic, (MaterialElastic<1>)))( \
+ (plastic, (MaterialLinearIsotropicHardening<1>)))
-#define AKANTU_EMBEDDED_MATERIAL_LIST \
+#define AKANTU_EMBEDDED_MATERIAL_LIST \
((2, (reinforcement, MaterialReinforcement)))
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
index fa320e42a..172508a2e 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
@@ -1,209 +1,209 @@
/**
* @file material_reinforcement.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Mar 13 2015
* @date last modification: Tue Nov 24 2015
*
* @brief Reinforcement material
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_REINFORCEMENT_HH__
#define __AKANTU_MATERIAL_REINFORCEMENT_HH__
#include "aka_common.hh"
-#include "material.hh"
#include "embedded_interface_model.hh"
+#include "material.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
* @brief Material used to represent embedded reinforcements
*
* This class is used for computing the reinforcement stiffness matrix
* along with the reinforcement residual. Room is made for constitutive law,
* but actual use of contitutive laws is made in MaterialReinforcementTemplate.
*
* Be careful with the dimensions in this class :
* - this->spatial_dimension is always 1
* - the template parameter dim is the dimension of the problem
*/
template <class Mat, UInt dim> class MaterialReinforcement : public Mat {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/// Constructor
MaterialReinforcement(EmbeddedInterfaceModel & model, const ID & id = "");
/// Destructor
~MaterialReinforcement() override;
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Init the material
void initMaterial() override;
/// Init the filters for background elements
void initFilters();
/// Init the background shape derivatives
void initBackgroundShapeDerivatives();
/// Init the cosine matrices
void initDirectingCosines();
/// Assemble stiffness matrix
void assembleStiffnessMatrix(GhostType ghost_type) override;
/// Compute all the stresses !
void computeAllStresses(GhostType ghost_type) override;
/// Compute energy
Real getEnergy(const std::string & id) override;
/// Assemble the residual of one type of element (typically _segment_2)
void assembleInternalForces(GhostType ghost_type) override;
/* ------------------------------------------------------------------------ */
/* Protected methods */
/* ------------------------------------------------------------------------ */
protected:
/// Allocate the background shape derivatives
void allocBackgroundShapeDerivatives();
/// Compute the directing cosines matrix for one element type
void computeDirectingCosines(const ElementType & type, GhostType ghost_type);
/// Compute the directing cosines matrix on quadrature points.
inline void computeDirectingCosinesOnQuad(const Matrix<Real> & nodes,
Matrix<Real> & cosines);
/// Add the prestress to the computed stress
void addPrestress(const ElementType & type, GhostType ghost_type);
/// Compute displacement gradient in reinforcement
void computeGradU(const ElementType & interface_type, GhostType ghost_type);
/// Assemble the stiffness matrix for an element type (typically _segment_2)
void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
/// Assemble the stiffness matrix for background & interface types
void assembleStiffnessMatrixInterface(const ElementType & interface_type,
const ElementType & background_type,
GhostType ghost_type);
/// Compute the background shape derivatives for a type
void computeBackgroundShapeDerivatives(const ElementType & type,
GhostType ghost_type);
/// Compute the background shape derivatives for a type pair
void computeBackgroundShapeDerivatives(const ElementType & interface_type,
- const ElementType & bg_type,
- GhostType ghost_type,
- const Array<UInt> & filter);
+ const ElementType & bg_type,
+ GhostType ghost_type,
+ const Array<UInt> & filter);
/// Filter elements crossed by interface of a type
void filterInterfaceBackgroundElements(Array<UInt> & foreground,
- Array<UInt> & background,
+ Array<UInt> & background,
const ElementType & type,
const ElementType & interface_type,
GhostType ghost_type);
/// Assemble the residual of one type of element (typically _segment_2)
void assembleInternalForces(const ElementType & type, GhostType ghost_type);
/// Assemble the residual for a pair of elements
void assembleInternalForcesInterface(const ElementType & interface_type,
const ElementType & background_type,
GhostType ghost_type);
// TODO figure out why voigt size is 4 in 2D
inline void stressTensorToVoigtVector(const Matrix<Real> & tensor,
Vector<Real> & vector);
inline void strainTensorToVoigtVector(const Matrix<Real> & tensor,
Vector<Real> & vector);
/// Get background filter
Array<UInt> & getBackgroundFilter(const ElementType & fg_type,
const ElementType & bg_type,
GhostType ghost_type) {
return (*background_filter(fg_type, ghost_type))(bg_type, ghost_type);
}
/// Get foreground filter
Array<UInt> & getForegroundFilter(const ElementType & fg_type,
const ElementType & bg_type,
GhostType ghost_type) {
return (*foreground_filter(fg_type, ghost_type))(bg_type, ghost_type);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Embedded model
EmbeddedInterfaceModel & emodel;
/// Gradu of concrete on reinforcement
InternalField<Real> gradu_embedded;
/// C matrix on quad
InternalField<Real> directing_cosines;
/// Prestress on quad
InternalField<Real> pre_stress;
/// Cross-sectional area
Real area;
template <typename T>
using CrossMap = ElementTypeMap<std::unique_ptr<ElementTypeMapArray<T>>>;
/// Background mesh shape derivatives
CrossMap<Real> shape_derivatives;
/// Foreground mesh filter (contains segment ids)
CrossMap<UInt> foreground_filter;
/// Background element filter (contains bg ids)
CrossMap<UInt> background_filter;
};
} // akantu
#include "material_reinforcement_tmpl.hh"
#endif // __AKANTU_MATERIAL_REINFORCEMENT_HH__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
index b4393907c..e8f8c5ef9 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
@@ -1,803 +1,800 @@
/**
* @file material_reinforcement_tmpl.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Thu Feb 1 2018
*
* @brief Reinforcement material
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_voigthelper.hh"
#include "material_reinforcement.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
MaterialReinforcement<Mat, dim>::MaterialReinforcement(
EmbeddedInterfaceModel & model, const ID & id)
- : Mat(model, 1,
- model.getInterfaceMesh(),
+ : Mat(model, 1, model.getInterfaceMesh(),
model.getFEEngine("EmbeddedInterfaceFEEngine"), id),
emodel(model),
gradu_embedded("gradu_embedded", *this, 1,
model.getFEEngine("EmbeddedInterfaceFEEngine"),
this->element_filter),
directing_cosines("directing_cosines", *this, 1,
model.getFEEngine("EmbeddedInterfaceFEEngine"),
this->element_filter),
pre_stress("pre_stress", *this, 1,
model.getFEEngine("EmbeddedInterfaceFEEngine"),
this->element_filter),
area(1.0), shape_derivatives() {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::initialize() {
AKANTU_DEBUG_IN();
this->registerParam("area", area, _pat_parsable | _pat_modifiable,
"Reinforcement cross-sectional area");
this->registerParam("pre_stress", pre_stress, _pat_parsable | _pat_modifiable,
"Uniform pre-stress");
// this->unregisterInternal(this->stress);
// Fool the AvgHomogenizingFunctor
// stress.initialize(dim * dim);
// Reallocate the element filter
this->element_filter.initialize(this->emodel.getInterfaceMesh(),
_spatial_dimension = 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
MaterialReinforcement<Mat, dim>::~MaterialReinforcement() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::initMaterial() {
Mat::initMaterial();
gradu_embedded.initialize(dim * dim);
pre_stress.initialize(1);
/// We initialise the stuff that is not going to change during the simulation
this->initFilters();
this->allocBackgroundShapeDerivatives();
this->initBackgroundShapeDerivatives();
this->initDirectingCosines();
}
/* -------------------------------------------------------------------------- */
/// Initialize the filter for background elements
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::initFilters() {
for (auto gt : ghost_types) {
for (auto && type : emodel.getInterfaceMesh().elementTypes(1, gt)) {
std::string shaped_id = "filter";
if (gt == _ghost)
shaped_id += ":ghost";
auto & background =
background_filter(std::make_unique<ElementTypeMapArray<UInt>>(
"bg_" + shaped_id, this->name),
type, gt);
auto & foreground = foreground_filter(
std::make_unique<ElementTypeMapArray<UInt>>(shaped_id, this->name),
type, gt);
foreground->initialize(emodel.getMesh(), _nb_component = 1,
_ghost_type = gt);
background->initialize(emodel.getMesh(), _nb_component = 1,
_ghost_type = gt);
// Computing filters
for (auto && bg_type : background->elementTypes(dim, gt)) {
filterInterfaceBackgroundElements(
(*foreground)(bg_type), (*background)(bg_type), bg_type, type, gt);
}
}
}
}
/* -------------------------------------------------------------------------- */
/// Construct a filter for a (interface_type, background_type) pair
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::filterInterfaceBackgroundElements(
Array<UInt> & foreground, Array<UInt> & background,
const ElementType & type, const ElementType & interface_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
foreground.resize(0);
background.resize(0);
Array<Element> & elements =
emodel.getInterfaceAssociatedElements(interface_type, ghost_type);
Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
for (auto & elem_id : elem_filter) {
Element & elem = elements(elem_id);
if (elem.type == type) {
background.push_back(elem.element);
foreground.push_back(elem_id);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
namespace detail {
class BackgroundShapeDInitializer : public ElementTypeMapArrayInitializer {
public:
BackgroundShapeDInitializer(UInt spatial_dimension, FEEngine & engine,
const ElementType & foreground_type,
const ElementTypeMapArray<UInt> & filter,
const GhostType & ghost_type)
: ElementTypeMapArrayInitializer(
[](const ElementType & bgtype, const GhostType &) {
return ShapeFunctions::getShapeDerivativesSize(bgtype);
},
spatial_dimension, ghost_type, _ek_regular) {
auto nb_quad = engine.getNbIntegrationPoints(foreground_type);
// Counting how many background elements are affected by elements of
// interface_type
for (auto type : filter.elementTypes(this->spatial_dimension)) {
// Inserting size
array_size_per_bg_type(filter(type).size() * nb_quad, type,
this->ghost_type);
}
}
auto elementTypes() const -> decltype(auto) {
return array_size_per_bg_type.elementTypes();
}
UInt size(const ElementType & bgtype) const {
return array_size_per_bg_type(bgtype, this->ghost_type);
}
protected:
ElementTypeMap<UInt> array_size_per_bg_type;
};
}
/**
* Background shape derivatives need to be stored per background element
* types but also per embedded element type, which is why they are stored
* in an ElementTypeMap<ElementTypeMapArray<Real> *>. The outer ElementTypeMap
* refers to the embedded types, and the inner refers to the background types.
*/
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::allocBackgroundShapeDerivatives() {
AKANTU_DEBUG_IN();
for (auto gt : ghost_types) {
for (auto && type : emodel.getInterfaceMesh().elementTypes(1, gt)) {
std::string shaped_id = "embedded_shape_derivatives";
if (gt == _ghost)
shaped_id += ":ghost";
auto & shaped_etma = shape_derivatives(
std::make_unique<ElementTypeMapArray<Real>>(shaped_id, this->name),
type, gt);
shaped_etma->initialize(
detail::BackgroundShapeDInitializer(
emodel.getSpatialDimension(),
emodel.getFEEngine("EmbeddedInterfaceFEEngine"), type,
*background_filter(type, gt), gt),
0, true);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::initBackgroundShapeDerivatives() {
AKANTU_DEBUG_IN();
for (auto interface_type :
this->element_filter.elementTypes(this->spatial_dimension)) {
for (auto type : background_filter(interface_type)->elementTypes(dim)) {
computeBackgroundShapeDerivatives(interface_type, type, _not_ghost,
this->element_filter(interface_type));
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::computeBackgroundShapeDerivatives(
const ElementType & interface_type, const ElementType & bg_type,
GhostType ghost_type, const Array<UInt> & filter) {
auto & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
auto & engine = emodel.getFEEngine();
auto & interface_mesh = emodel.getInterfaceMesh();
const auto nb_nodes_elem_bg = Mesh::getNbNodesPerElement(bg_type);
// const auto nb_strss = VoigtHelper<dim>::size;
const auto nb_quads_per_elem =
interface_engine.getNbIntegrationPoints(interface_type);
Array<Real> quad_pos(0, dim, "interface_quad_pos");
interface_engine.interpolateOnIntegrationPoints(interface_mesh.getNodes(),
quad_pos, dim, interface_type,
ghost_type, filter);
auto & background_shapesd =
(*shape_derivatives(interface_type, ghost_type))(bg_type, ghost_type);
auto & background_elements =
(*background_filter(interface_type, ghost_type))(bg_type, ghost_type);
auto & foreground_elements =
(*foreground_filter(interface_type, ghost_type))(bg_type, ghost_type);
auto shapesd_begin =
- background_shapesd.begin(dim, nb_nodes_elem_bg, nb_quads_per_elem);
+ background_shapesd.begin(dim, nb_nodes_elem_bg, nb_quads_per_elem);
auto quad_begin = quad_pos.begin(dim, nb_quads_per_elem);
for (auto && tuple : zip(background_elements, foreground_elements)) {
UInt bg = std::get<0>(tuple), fg = std::get<1>(tuple);
for (UInt i = 0; i < nb_quads_per_elem; ++i) {
Matrix<Real> shapesd = Tensor3<Real>(shapesd_begin[fg])(i);
Vector<Real> quads = Matrix<Real>(quad_begin[fg])(i);
- engine.computeShapeDerivatives(quads, bg, bg_type, shapesd,
- ghost_type);
+ engine.computeShapeDerivatives(quads, bg, bg_type, shapesd, ghost_type);
}
}
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::initDirectingCosines() {
AKANTU_DEBUG_IN();
Mesh & mesh = emodel.getInterfaceMesh();
Mesh::type_iterator type_it = mesh.firstType(1, _not_ghost);
Mesh::type_iterator type_end = mesh.lastType(1, _not_ghost);
const UInt voigt_size = VoigtHelper<dim>::size;
directing_cosines.initialize(voigt_size);
for (; type_it != type_end; ++type_it) {
computeDirectingCosines(*type_it, _not_ghost);
// computeDirectingCosines(*type_it, _ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrix(
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = emodel.getInterfaceMesh();
Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
for (; type_it != type_end; ++type_it) {
assembleStiffnessMatrix(*type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::assembleInternalForces(
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = emodel.getInterfaceMesh();
Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
for (; type_it != type_end; ++type_it) {
this->assembleInternalForces(*type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::computeAllStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = emodel.getInterfaceMesh().firstType();
Mesh::type_iterator last_type = emodel.getInterfaceMesh().lastType();
for (; it != last_type; ++it) {
computeGradU(*it, ghost_type);
this->computeStress(*it, ghost_type);
addPrestress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::addPrestress(const ElementType & type,
GhostType ghost_type) {
auto & stress = this->stress(type, ghost_type);
auto & sigma_p = this->pre_stress(type, ghost_type);
for (auto && tuple : zip(stress, sigma_p)) {
std::get<0>(tuple) += std::get<1>(tuple);
}
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::assembleInternalForces(
const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & mesh = emodel.getMesh();
Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
for (; type_it != type_end; ++type_it) {
assembleInternalForcesInterface(type, *type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Computes and assemble the residual. Residual in reinforcement is computed as:
*
* \f[
* \vec{r} = A_s \int_S{\mathbf{B}^T\mathbf{C}^T \vec{\sigma_s}\,\mathrm{d}s}
* \f]
*/
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::assembleInternalForcesInterface(
const ElementType & interface_type, const ElementType & background_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt voigt_size = VoigtHelper<dim>::size;
FEEngine & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
UInt nb_quadrature_points =
interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
UInt nb_element = elem_filter.size();
UInt back_dof = dim * nodes_per_background_e;
Array<Real> & shapesd = (*shape_derivatives(interface_type, ghost_type))(
background_type, ghost_type);
Array<Real> integrant(nb_quadrature_points * nb_element, back_dof,
"integrant");
auto integrant_it = integrant.begin(back_dof);
auto integrant_end = integrant.end(back_dof);
Array<Real>::matrix_iterator B_it =
shapesd.begin(dim, nodes_per_background_e);
- auto C_it =
- directing_cosines(interface_type, ghost_type).begin(voigt_size);
+ auto C_it = directing_cosines(interface_type, ghost_type).begin(voigt_size);
auto sigma_it = this->stress(interface_type, ghost_type).begin();
Matrix<Real> Bvoigt(voigt_size, back_dof);
for (; integrant_it != integrant_end;
++integrant_it, ++B_it, ++C_it, ++sigma_it) {
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*B_it, Bvoigt,
nodes_per_background_e);
Vector<Real> & C = *C_it;
Vector<Real> & BtCt_sigma = *integrant_it;
BtCt_sigma.mul<true>(Bvoigt, C);
BtCt_sigma *= *sigma_it * area;
}
Array<Real> residual_interface(nb_element, back_dof, "residual_interface");
interface_engine.integrate(integrant, residual_interface, back_dof,
interface_type, ghost_type, elem_filter);
integrant.resize(0);
Array<UInt> background_filter(nb_element, 1, "background_filter");
auto & filter =
getBackgroundFilter(interface_type, background_type, ghost_type);
emodel.getDOFManager().assembleElementalArrayLocalArray(
residual_interface, emodel.getInternalForce(), background_type,
ghost_type, -1., filter);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::computeDirectingCosines(
const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & interface_mesh = emodel.getInterfaceMesh();
const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const UInt steel_dof = dim * nb_nodes_per_element;
const UInt voigt_size = VoigtHelper<dim>::size;
const UInt nb_quad_points = emodel.getFEEngine("EmbeddedInterfaceFEEngine")
.getNbIntegrationPoints(type, ghost_type);
Array<Real> node_coordinates(this->element_filter(type, ghost_type).size(),
steel_dof);
this->emodel.getFEEngine().template extractNodalToElementField<Real>(
interface_mesh, interface_mesh.getNodes(), node_coordinates, type,
ghost_type, this->element_filter(type, ghost_type));
Array<Real>::matrix_iterator directing_cosines_it =
- directing_cosines(type, ghost_type).begin(1, voigt_size);
+ directing_cosines(type, ghost_type).begin(1, voigt_size);
Array<Real>::matrix_iterator node_coordinates_it =
node_coordinates.begin(dim, nb_nodes_per_element);
Array<Real>::matrix_iterator node_coordinates_end =
node_coordinates.end(dim, nb_nodes_per_element);
for (; node_coordinates_it != node_coordinates_end; ++node_coordinates_it) {
for (UInt i = 0; i < nb_quad_points; i++, ++directing_cosines_it) {
Matrix<Real> & nodes = *node_coordinates_it;
Matrix<Real> & cosines = *directing_cosines_it;
computeDirectingCosinesOnQuad(nodes, cosines);
}
}
// Mauro: the directing_cosines internal is defined on the quadrature points
// of each element
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrix(
const ElementType & type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Mesh & mesh = emodel.getMesh();
Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
for (; type_it != type_end; ++type_it) {
assembleStiffnessMatrixInterface(type, *type_it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Computes the reinforcement stiffness matrix (Gomes & Awruch, 2001)
* \f[
* \mathbf{K}_e = \sum_{i=1}^R{A_i\int_{S_i}{\mathbf{B}^T
* \mathbf{C}_i^T \mathbf{D}_{s, i} \mathbf{C}_i \mathbf{B}\,\mathrm{d}s}}
* \f]
*/
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrixInterface(
const ElementType & interface_type, const ElementType & background_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt voigt_size = VoigtHelper<dim>::size;
FEEngine & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
Array<Real> & grad_u = gradu_embedded(interface_type, ghost_type);
UInt nb_element = elem_filter.size();
UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
UInt nb_quadrature_points =
interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
UInt back_dof = dim * nodes_per_background_e;
UInt integrant_size = back_dof;
grad_u.resize(nb_quadrature_points * nb_element);
Array<Real> tangent_moduli(nb_element * nb_quadrature_points, 1,
"interface_tangent_moduli");
this->computeTangentModuli(interface_type, tangent_moduli, ghost_type);
Array<Real> & shapesd = (*shape_derivatives(interface_type, ghost_type))(
background_type, ghost_type);
Array<Real> integrant(nb_element * nb_quadrature_points,
integrant_size * integrant_size, "B^t*C^t*D*C*B");
/// Temporary matrices for integrant product
Matrix<Real> Bvoigt(voigt_size, back_dof);
Matrix<Real> DCB(1, back_dof);
Matrix<Real> CtDCB(voigt_size, back_dof);
Array<Real>::scalar_iterator D_it = tangent_moduli.begin();
Array<Real>::scalar_iterator D_end = tangent_moduli.end();
Array<Real>::matrix_iterator C_it =
directing_cosines(interface_type, ghost_type).begin(1, voigt_size);
Array<Real>::matrix_iterator B_it =
shapesd.begin(dim, nodes_per_background_e);
Array<Real>::matrix_iterator integrant_it =
integrant.begin(integrant_size, integrant_size);
for (; D_it != D_end; ++D_it, ++C_it, ++B_it, ++integrant_it) {
Real & D = *D_it;
Matrix<Real> & C = *C_it;
Matrix<Real> & B = *B_it;
Matrix<Real> & BtCtDCB = *integrant_it;
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(B, Bvoigt,
nodes_per_background_e);
DCB.mul<false, false>(C, Bvoigt);
DCB *= D * area;
CtDCB.mul<true, false>(C, DCB);
BtCtDCB.mul<true, false>(Bvoigt, CtDCB);
}
tangent_moduli.resize(0);
Array<Real> K_interface(nb_element, integrant_size * integrant_size,
"K_interface");
interface_engine.integrate(integrant, K_interface,
integrant_size * integrant_size, interface_type,
ghost_type, elem_filter);
integrant.resize(0);
// Mauro: Here K_interface contains the local stiffness matrices,
// directing_cosines contains the information about the orientation
// of the reinforcements, any rotation of the local stiffness matrix
// can be done here
auto & filter =
getBackgroundFilter(interface_type, background_type, ghost_type);
emodel.getDOFManager().assembleElementalMatricesToMatrix(
"K", "displacement", K_interface, background_type, ghost_type, _symmetric,
filter);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
Real MaterialReinforcement<Mat, dim>::getEnergy(const std::string & id) {
AKANTU_DEBUG_IN();
if (id == "potential") {
Real epot = 0.;
this->computePotentialEnergyByElements();
Mesh::type_iterator it = this->element_filter.firstType(
this->spatial_dimension),
end = this->element_filter.lastType(
this->spatial_dimension);
for (; it != end; ++it) {
FEEngine & interface_engine =
emodel.getFEEngine("EmbeddedInterfaceFEEngine");
epot += interface_engine.integrate(
this->potential_energy(*it, _not_ghost), *it, _not_ghost,
this->element_filter(*it, _not_ghost));
epot *= area;
}
return epot;
}
AKANTU_DEBUG_OUT();
return 0;
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
void MaterialReinforcement<Mat, dim>::computeGradU(
const ElementType & interface_type, GhostType ghost_type) {
// Looping over background types
for (auto && bg_type :
background_filter(interface_type, ghost_type)->elementTypes(dim)) {
const UInt nodes_per_background_e = Mesh::getNbNodesPerElement(bg_type);
const UInt voigt_size = VoigtHelper<dim>::size;
auto & bg_shapesd =
(*shape_derivatives(interface_type, ghost_type))(bg_type, ghost_type);
auto & filter = getBackgroundFilter(interface_type, bg_type, ghost_type);
Array<Real> disp_per_element(0, dim * nodes_per_background_e, "disp_elem");
FEEngine::extractNodalToElementField(
emodel.getMesh(), emodel.getDisplacement(), disp_per_element, bg_type,
ghost_type, filter);
Matrix<Real> concrete_du(dim, dim);
Matrix<Real> epsilon(dim, dim);
Vector<Real> evoigt(voigt_size);
for (auto && tuple :
zip(make_view(disp_per_element, dim, nodes_per_background_e),
make_view(bg_shapesd, dim, nodes_per_background_e),
this->gradu(interface_type, ghost_type),
make_view(this->directing_cosines(interface_type, ghost_type),
voigt_size))) {
auto & u = std::get<0>(tuple);
auto & B = std::get<1>(tuple);
auto & du = std::get<2>(tuple);
auto & C = std::get<3>(tuple);
concrete_du.mul<false, true>(u, B);
auto epsilon = 0.5 * (concrete_du + concrete_du.transpose());
strainTensorToVoigtVector(epsilon, evoigt);
du = C.dot(evoigt);
}
}
}
/* -------------------------------------------------------------------------- */
/**
* The structure of the directing cosines matrix is :
* \f{eqnarray*}{
* C_{1,\cdot} & = & (l^2, m^2, n^2, mn, ln, lm) \\
* C_{i,j} & = & 0
* \f}
*
* with :
* \f[
* (l, m, n) = \frac{1}{\|\frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}\|} \cdot
* \frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}
* \f]
*/
template <class Mat, UInt dim>
inline void MaterialReinforcement<Mat, dim>::computeDirectingCosinesOnQuad(
const Matrix<Real> & nodes, Matrix<Real> & cosines) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(nodes.cols() == 2,
"Higher order reinforcement elements not implemented");
const Vector<Real> a = nodes(0), b = nodes(1);
Vector<Real> delta = b - a;
Real sq_length = 0.;
for (UInt i = 0; i < dim; i++) {
sq_length += delta(i) * delta(i);
}
if (dim == 2) {
cosines(0, 0) = delta(0) * delta(0); // l^2
cosines(0, 1) = delta(1) * delta(1); // m^2
cosines(0, 2) = delta(0) * delta(1); // lm
} else if (dim == 3) {
cosines(0, 0) = delta(0) * delta(0); // l^2
cosines(0, 1) = delta(1) * delta(1); // m^2
cosines(0, 2) = delta(2) * delta(2); // n^2
cosines(0, 3) = delta(1) * delta(2); // mn
cosines(0, 4) = delta(0) * delta(2); // ln
cosines(0, 5) = delta(0) * delta(1); // lm
}
cosines /= sq_length;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
inline void MaterialReinforcement<Mat, dim>::stressTensorToVoigtVector(
const Matrix<Real> & tensor, Vector<Real> & vector) {
AKANTU_DEBUG_IN();
for (UInt i = 0; i < dim; i++) {
vector(i) = tensor(i, i);
}
if (dim == 2) {
vector(2) = tensor(0, 1);
} else if (dim == 3) {
vector(3) = tensor(1, 2);
vector(4) = tensor(0, 2);
vector(5) = tensor(0, 1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Mat, UInt dim>
inline void MaterialReinforcement<Mat, dim>::strainTensorToVoigtVector(
const Matrix<Real> & tensor, Vector<Real> & vector) {
AKANTU_DEBUG_IN();
for (UInt i = 0; i < dim; i++) {
vector(i) = tensor(i, i);
}
if (dim == 2) {
vector(2) = 2 * tensor(0, 1);
} else if (dim == 3) {
vector(3) = 2 * tensor(1, 2);
vector(4) = 2 * tensor(0, 2);
vector(5) = 2 * tensor(0, 1);
}
AKANTU_DEBUG_OUT();
}
} // akantu
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
index 8ef06aa89..96d6b1b7c 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
@@ -1,174 +1,169 @@
/**
* @file material_neohookean.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 08 2015
*
* @brief Material isotropic elastic
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
#include "plane_stress_toolbox.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_NEOHOOKEAN_HH__
#define __AKANTU_MATERIAL_NEOHOOKEAN_HH__
namespace akantu {
/**
* Material elastic isotropic
*
* parameters in the material files :
* - rho : density (default: 0)
* - E : Young's modulus (default: 0)
* - nu : Poisson's ratio (default: 1/2)
* - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
*/
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
class MaterialNeohookean : public PlaneStressToolbox<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialNeohookean(SolidMechanicsModel & model, const ID & id = "");
~MaterialNeohookean() override = default;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// initialize the material computed parameter
void initMaterial() override;
/// constitutive law for all element of a type
void computeStress(ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/// Computation of the cauchy stress for plane strain materials
void
computeCauchyStressPlaneStress(ElementType el_type,
GhostType ghost_type = _not_ghost) override;
- /// Non linear computation of the third direction strain in 2D plane stress case
+ /// Non linear computation of the third direction strain in 2D plane stress
+ /// case
void computeThirdAxisDeformation(ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/// compute the elastic potential energy
void computePotentialEnergy(ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/// compute the tangent stiffness matrix for an element type
void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost) override;
/// compute the p-wave speed in the material
Real getPushWaveSpeed(const Element & element) const override;
/// compute the s-wave speed in the material
Real getShearWaveSpeed(const Element & element) const override;
protected:
-
/// constitutive law for a given quadrature point
- inline void computePiolaKirchhoffOnQuad(const Matrix<Real> &E,
- Matrix<Real> &S);
+ inline void computePiolaKirchhoffOnQuad(const Matrix<Real> & E,
+ Matrix<Real> & S);
/// constitutive law for a given quadrature point (first piola)
- inline void computeFirstPiolaKirchhoffOnQuad(const Matrix<Real> &grad_u,
- const Matrix<Real> &S,
- Matrix<Real> &P);
+ inline void computeFirstPiolaKirchhoffOnQuad(const Matrix<Real> & grad_u,
+ const Matrix<Real> & S,
+ Matrix<Real> & P);
/// constitutive law for a given quadrature point
- inline void computeDeltaStressOnQuad(const Matrix<Real> & grad_u, const Matrix<Real> & grad_delta_u,
- Matrix<Real> & delta_S);
+ inline void computeDeltaStressOnQuad(const Matrix<Real> & grad_u,
+ const Matrix<Real> & grad_delta_u,
+ Matrix<Real> & delta_S);
/// constitutive law for a given quadrature point
- inline void computeStressOnQuad(Matrix<Real> & grad_u,
- Matrix<Real> & S,
- const Real & C33 = 1.0 );
+ inline void computeStressOnQuad(Matrix<Real> & grad_u, Matrix<Real> & S,
+ const Real & C33 = 1.0);
/// constitutive law for a given quadrature point
- inline void computeThirdAxisDeformationOnQuad(Matrix<Real> & grad_u, Real & c33_value);
+ inline void computeThirdAxisDeformationOnQuad(Matrix<Real> & grad_u,
+ Real & c33_value);
/// constitutive law for a given quadrature point
- //inline void updateStressOnQuad(const Matrix<Real> & sigma,
+ // inline void updateStressOnQuad(const Matrix<Real> & sigma,
// Matrix<Real> & cauchy_sigma);
/// compute the potential energy for a quadrature point
inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
Real & epot);
/// compute the tangent stiffness matrix for an element
- void computeTangentModuliOnQuad(Matrix<Real> & tangent,
- Matrix<Real> & grad_u,
- const Real & C33 = 1.0 );
+ void computeTangentModuliOnQuad(Matrix<Real> & tangent, Matrix<Real> & grad_u,
+ const Real & C33 = 1.0);
/// recompute the lame coefficient if E or nu changes
void updateInternalParameters() override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// the young modulus
Real E;
/// Poisson coefficient
Real nu;
/// First Lamé coefficient
Real lambda;
/// Second Lamé coefficient (shear modulus)
Real mu;
/// Bulk modulus
Real kpa;
-
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_neohookean_inline_impl.cc"
} // akantu
#endif /* __AKANTU_MATERIAL_NEOHOOKEAN_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
index eb3480ba6..b99d4e14f 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
@@ -1,191 +1,191 @@
/**
* @file material_neohookean_inline_impl.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Mon Apr 08 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the inline functions of the material elastic
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <iostream>
#include "material_neohookean.hh"
#include <cmath>
#include <utility>
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialNeohookean<dim>::computeDeltaStressOnQuad(
__attribute__((unused)) const Matrix<Real> & grad_u,
__attribute__((unused)) const Matrix<Real> & grad_delta_u,
__attribute__((unused)) Matrix<Real> & delta_S) {}
//! computes the second piola kirchhoff stress, called S
template <UInt dim>
inline void MaterialNeohookean<dim>::computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & S,
const Real & C33) {
// Neo hookean book
Matrix<Real> F(dim, dim);
- Matrix<Real> C(dim, dim); // Right green
+ Matrix<Real> C(dim, dim); // Right green
Matrix<Real> Cminus(dim, dim); // Right green
this->template gradUToF<dim>(grad_u, F);
this->rightCauchy(F, C);
Real J = F.det() * sqrt(C33); // the term sqrt(C33) corresponds to the off
// plane strain (2D plane stress)
// std::cout<<"det(F) -> "<<J<<std::endl;
Cminus.inverse(C);
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
S(i, j) = (i == j) * mu + (lambda * log(J) - mu) * Cminus(i, j);
}
/* -------------------------------------------------------------------------- */
class C33_NR : public Math::NewtonRaphsonFunctor {
public:
C33_NR(std::string name, const Real & lambda, const Real & mu,
const Matrix<Real> & C)
: NewtonRaphsonFunctor(std::move(name)), lambda(lambda), mu(mu), C(C) {}
inline Real f(Real x) const override {
return (this->lambda / 2. *
(std::log(x) + std::log(this->C(0, 0) * this->C(1, 1) -
Math::pow<2>(this->C(0, 1)))) +
this->mu * (x - 1.));
}
inline Real f_prime(Real x) const override {
AKANTU_DEBUG_ASSERT(std::abs(x) > Math::getTolerance(),
"x is zero (x should be the off plane right Cauchy"
<< " measure in this function so you made a mistake"
<< " somewhere else that lead to a zero here!!!");
return (this->lambda / (2. * x) + this->mu);
}
private:
const Real & lambda;
const Real & mu;
const Matrix<Real> & C;
};
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialNeohookean<dim>::computeThirdAxisDeformationOnQuad(
Matrix<Real> & grad_u, Real & c33_value) {
// Neo hookean book
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim); // Right green
this->template gradUToF<dim>(grad_u, F);
this->rightCauchy(F, C);
Math::NewtonRaphson nr(1e-5, 100);
c33_value = nr.solve(
C33_NR("Neohookean_plan_stress", this->lambda, this->mu, C), c33_value);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void
MaterialNeohookean<dim>::computePiolaKirchhoffOnQuad(const Matrix<Real> & E,
Matrix<Real> & S) {
Real trace = E.trace(); /// trace = (\nabla u)_{kk}
/// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
/// u_{ij} + \nabla u_{ji})
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
S(i, j) = (i == j) * lambda * trace + 2.0 * mu * E(i, j);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialNeohookean<dim>::computeFirstPiolaKirchhoffOnQuad(
const Matrix<Real> & grad_u, const Matrix<Real> & S, Matrix<Real> & P) {
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim); // Right green
this->template gradUToF<dim>(grad_u, F);
// first Piola-Kirchhoff is computed as the product of the deformation
// gracient
// tensor and the second Piola-Kirchhoff stress tensor
P = F * S;
}
/**************************************************************************************/
/* Computation of the potential energy for a this neo hookean material */
template <UInt dim>
inline void MaterialNeohookean<dim>::computePotentialEnergyOnQuad(
const Matrix<Real> & grad_u, Real & epot) {
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim); // Right green
this->template gradUToF<dim>(grad_u, F);
this->rightCauchy(F, C);
Real J = F.det();
// std::cout<<"det(F) -> "<<J<<std::endl;
epot =
0.5 * lambda * pow(log(J), 2.) + mu * (-log(J) + 0.5 * (C.trace() - dim));
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialNeohookean<dim>::computeTangentModuliOnQuad(
Matrix<Real> & tangent, Matrix<Real> & grad_u, const Real & C33) {
// Neo hookean book
UInt cols = tangent.cols();
UInt rows = tangent.rows();
Matrix<Real> F(dim, dim);
Matrix<Real> C(dim, dim);
Matrix<Real> Cminus(dim, dim);
this->template gradUToF<dim>(grad_u, F);
this->rightCauchy(F, C);
Real J = F.det() * sqrt(C33);
// std::cout<<"det(F) -> "<<J<<std::endl;
Cminus.inverse(C);
for (UInt m = 0; m < rows; m++) {
UInt i = VoigtHelper<dim>::vec[m][0];
UInt j = VoigtHelper<dim>::vec[m][1];
for (UInt n = 0; n < cols; n++) {
UInt k = VoigtHelper<dim>::vec[n][0];
UInt l = VoigtHelper<dim>::vec[n][1];
// book belytchko
tangent(m, n) = lambda * Cminus(i, j) * Cminus(k, l) +
(mu - lambda * log(J)) * (Cminus(i, k) * Cminus(j, l) +
Cminus(i, l) * Cminus(k, j));
}
}
}
/* -------------------------------------------------------------------------- */
diff --git a/src/model/solid_mechanics/materials/material_non_local.hh b/src/model/solid_mechanics/materials/material_non_local.hh
index 78e21e27f..acff2d771 100644
--- a/src/model/solid_mechanics/materials/material_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_non_local.hh
@@ -1,122 +1,120 @@
/**
* @file material_non_local.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Dec 08 2015
*
* @brief Material class that handle the non locality of a law for example
* damage.
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_NON_LOCAL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
class MaterialNonLocalInterface {
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material the non local parts of the material
void initMaterialNonLocal() {
this->registerNeighborhood();
this->registerNonLocalVariables();
};
/// insert the quadrature points in the neighborhoods of the non-local manager
virtual void insertIntegrationPointsInNeighborhoods(
const GhostType & ghost_type,
const ElementTypeMapReal & quadrature_points_coordinates) = 0;
/// update the values in the non-local internal fields
virtual void updateNonLocalInternals(ElementTypeMapReal & non_local_flattened,
const ID & field_id,
const GhostType & ghost_type,
const ElementKind & kind) = 0;
/// constitutive law
virtual void computeNonLocalStresses(GhostType ghost_type = _not_ghost) = 0;
protected:
/// get the name of the neighborhood for this material
- virtual ID getNeighborhoodName() =0;
+ virtual ID getNeighborhoodName() = 0;
/// register the neighborhoods for the material
virtual void registerNeighborhood() = 0;
/// register the non local internal variable
virtual void registerNonLocalVariables() = 0;
virtual inline void onElementsAdded(const Array<Element> &,
const NewElementsEvent &) {}
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <UInt dim, class LocalParent>
class MaterialNonLocal : public MaterialNonLocalInterface, public LocalParent {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
explicit MaterialNonLocal(SolidMechanicsModel & model, const ID & id);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// insert the quadrature points in the neighborhoods of the non-local manager
void insertIntegrationPointsInNeighborhoods(
const GhostType & ghost_type,
const ElementTypeMapReal & quadrature_points_coordinates) override;
/// update the values in the non-local internal fields
void updateNonLocalInternals(ElementTypeMapReal & non_local_flattened,
const ID & field_id,
const GhostType & ghost_type,
const ElementKind & kind) override;
/// register the neighborhoods for the material
void registerNeighborhood() override;
protected:
/// get the name of the neighborhood for this material
- ID getNeighborhoodName() override {
- return this->name;
- }
+ ID getNeighborhoodName() override { return this->name; }
};
} // namespace akantu
/* -------------------------------------------------------------------------- */
#include "material_non_local_tmpl.hh"
#endif /* __AKANTU_MATERIAL_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_non_local_includes.hh b/src/model/solid_mechanics/materials/material_non_local_includes.hh
index 204edfab0..d3b20179f 100644
--- a/src/model/solid_mechanics/materials/material_non_local_includes.hh
+++ b/src/model/solid_mechanics/materials/material_non_local_includes.hh
@@ -1,40 +1,40 @@
/**
* @file material_non_local_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Oct 31 2012
* @date last modification: Wed Nov 18 2015
*
* @brief Non local materials includes
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
-# include "material_marigo_non_local.hh"
-# include "material_mazars_non_local.hh"
+#include "material_marigo_non_local.hh"
+#include "material_mazars_non_local.hh"
#endif
-#define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST \
- ((2, (marigo_non_local , MaterialMarigoNonLocal))) \
- ((2, (mazars_non_local , MaterialMazarsNonLocal)))
+#define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST \
+ ((2, (marigo_non_local, MaterialMarigoNonLocal)))( \
+ (2, (mazars_non_local, MaterialMazarsNonLocal)))
diff --git a/src/model/solid_mechanics/materials/material_non_local_tmpl.hh b/src/model/solid_mechanics/materials/material_non_local_tmpl.hh
index 43f87b8c2..ccfd93508 100644
--- a/src/model/solid_mechanics/materials/material_non_local_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_non_local_tmpl.hh
@@ -1,128 +1,128 @@
/**
* @file material_non_local.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Tue Dec 08 2015
*
* @brief Implementation of material non-local
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material.hh"
#include "material_non_local.hh"
#include "non_local_neighborhood.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt dim, class LocalParent>
MaterialNonLocal<dim, LocalParent>::MaterialNonLocal(
SolidMechanicsModel & model, const ID & id)
: LocalParent(model, id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim, class LocalParent>
void MaterialNonLocal<dim, LocalParent>::insertIntegrationPointsInNeighborhoods(
const GhostType & ghost_type,
const ElementTypeMapReal & quadrature_points_coordinates) {
IntegrationPoint q;
q.ghost_type = ghost_type;
- auto & neighborhood =
- this->model.getNonLocalManager().getNeighborhood(this->getNeighborhoodName());
+ auto & neighborhood = this->model.getNonLocalManager().getNeighborhood(
+ this->getNeighborhoodName());
for (auto & type :
this->element_filter.elementTypes(dim, ghost_type, _ek_regular)) {
q.type = type;
const auto & elem_filter = this->element_filter(type, ghost_type);
UInt nb_element = elem_filter.size();
if (nb_element) {
UInt nb_quad =
this->getFEEngine().getNbIntegrationPoints(type, ghost_type);
const auto & quads = quadrature_points_coordinates(type, ghost_type);
auto nb_total_element =
this->model.getMesh().getNbElement(type, ghost_type);
auto quads_it = quads.begin_reinterpret(dim, nb_quad, nb_total_element);
for (auto & elem : elem_filter) {
Matrix<Real> quads = quads_it[elem];
q.element = elem;
for (UInt nq = 0; nq < nb_quad; ++nq) {
q.num_point = nq;
q.global_num = q.element * nb_quad + nq;
neighborhood.insertIntegrationPoint(q, quads(nq));
}
}
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim, class LocalParent>
void MaterialNonLocal<dim, LocalParent>::updateNonLocalInternals(
ElementTypeMapReal & non_local_flattened, const ID & field_id,
const GhostType & ghost_type, const ElementKind & kind) {
/// loop over all types in the material
for (auto & el_type :
this->element_filter.elementTypes(dim, ghost_type, kind)) {
Array<Real> & internal =
this->template getInternal<Real>(field_id)(el_type, ghost_type);
auto & internal_flat = non_local_flattened(el_type, ghost_type);
auto nb_component = internal_flat.getNbComponent();
auto internal_it = internal.begin(nb_component);
auto internal_flat_it = internal_flat.begin(nb_component);
/// loop all elements for the given type
const auto & filter = this->element_filter(el_type, ghost_type);
UInt nb_quads =
this->getFEEngine().getNbIntegrationPoints(el_type, ghost_type);
for (auto & elem : filter) {
for (UInt q = 0; q < nb_quads; ++q, ++internal_it) {
UInt global_quad = elem * nb_quads + q;
*internal_it = internal_flat_it[global_quad];
}
}
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim, class LocalParent>
void MaterialNonLocal<dim, LocalParent>::registerNeighborhood() {
ID name = this->getNeighborhoodName();
this->model.getNonLocalManager().registerNeighborhood(name, name);
}
} // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
index f209f0d85..d5db9fa1a 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
@@ -1,200 +1,201 @@
/**
* @file material_linear_isotropic_hardening.cc
*
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Apr 07 2014
* @date last modification: Tue Aug 18 2015
*
* @brief Specialization of the material class for isotropic finite deformation
* linear hardening plasticity
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_linear_isotropic_hardening.hh"
#include "solid_mechanics_model.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt dim>
MaterialLinearIsotropicHardening<dim>::MaterialLinearIsotropicHardening(
SolidMechanicsModel & model, const ID & id)
: MaterialPlastic<dim>(model, id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialLinearIsotropicHardening<spatial_dimension>::
MaterialLinearIsotropicHardening(SolidMechanicsModel & model, UInt dim,
const Mesh & mesh, FEEngine & fe_engine,
const ID & id)
- : MaterialPlastic<spatial_dimension>(model, dim, mesh, fe_engine, id) {}
+ : MaterialPlastic<spatial_dimension>(model, dim, mesh, fe_engine, id) {}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialLinearIsotropicHardening<spatial_dimension>::computeStress(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialThermal<spatial_dimension>::computeStress(el_type, ghost_type);
// infinitesimal and finite deformation
auto sigma_th_it = this->sigma_th(el_type, ghost_type).begin();
auto previous_sigma_th_it =
this->sigma_th.previous(el_type, ghost_type).begin();
auto previous_gradu_it = this->gradu.previous(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto previous_stress_it = this->stress.previous(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto inelastic_strain_it = this->inelastic_strain(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto previous_inelastic_strain_it =
this->inelastic_strain.previous(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto iso_hardening_it = this->iso_hardening(el_type, ghost_type).begin();
auto previous_iso_hardening_it =
this->iso_hardening.previous(el_type, ghost_type).begin();
//
// Finite Deformations
//
if (this->finite_deformation) {
auto previous_piola_kirchhoff_2_it =
this->piola_kirchhoff_2.previous(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto green_strain_it = this->green_strain(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
auto & inelastic_strain_tensor = *inelastic_strain_it;
auto & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
auto & previous_grad_u = *previous_gradu_it;
auto & previous_sigma = *previous_piola_kirchhoff_2_it;
auto & green_strain = *green_strain_it;
this->template gradUToGreenStrain<spatial_dimension>(grad_u, green_strain);
Matrix<Real> previous_green_strain(spatial_dimension, spatial_dimension);
this->template gradUToGreenStrain<spatial_dimension>(previous_grad_u,
previous_green_strain);
Matrix<Real> F_tensor(spatial_dimension, spatial_dimension);
this->template gradUToF<spatial_dimension>(grad_u, F_tensor);
computeStressOnQuad(green_strain, previous_green_strain, sigma,
previous_sigma, inelastic_strain_tensor,
previous_inelastic_strain_tensor, *iso_hardening_it,
*previous_iso_hardening_it, *sigma_th_it,
*previous_sigma_th_it, F_tensor);
++sigma_th_it;
++inelastic_strain_it;
++iso_hardening_it;
++previous_sigma_th_it;
//++previous_stress_it;
++previous_gradu_it;
++green_strain_it;
++previous_inelastic_strain_it;
++previous_iso_hardening_it;
++previous_piola_kirchhoff_2_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
// Infinitesimal deformations
else {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
auto & inelastic_strain_tensor = *inelastic_strain_it;
auto & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
auto & previous_grad_u = *previous_gradu_it;
auto & previous_sigma = *previous_stress_it;
computeStressOnQuad(
grad_u, previous_grad_u, sigma, previous_sigma, inelastic_strain_tensor,
previous_inelastic_strain_tensor, *iso_hardening_it,
*previous_iso_hardening_it, *sigma_th_it, *previous_sigma_th_it);
++sigma_th_it;
++inelastic_strain_it;
++iso_hardening_it;
++previous_sigma_th_it;
++previous_stress_it;
++previous_gradu_it;
++previous_inelastic_strain_it;
++previous_iso_hardening_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialLinearIsotropicHardening<spatial_dimension>::computeTangentModuli(
const ElementType & el_type, Array<Real> & tangent_matrix,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
auto previous_gradu_it = this->gradu.previous(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto previous_stress_it = this->stress.previous(el_type, ghost_type)
.begin(spatial_dimension, spatial_dimension);
auto iso_hardening = this->iso_hardening(el_type, ghost_type).begin();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u, *previous_gradu_it, sigma_tensor,
*previous_stress_it, *iso_hardening);
++previous_gradu_it;
++previous_stress_it;
++iso_hardening;
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
this->was_stiffness_assembled = true;
-
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-INSTANTIATE_MATERIAL(plastic_linear_isotropic_hardening, MaterialLinearIsotropicHardening);
+INSTANTIATE_MATERIAL(plastic_linear_isotropic_hardening,
+ MaterialLinearIsotropicHardening);
} // akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
index 477b993b6..1b1b2749b 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
@@ -1,143 +1,130 @@
/**
* @file material_plastic.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 08 2015
*
* @brief Common interface for plastic materials
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_elastic.hh"
/* -------------------------------------------------------------------------- */
-
#ifndef __AKANTU_MATERIAL_PLASTIC_HH__
#define __AKANTU_MATERIAL_PLASTIC_HH__
namespace akantu {
/**
* Parent class for the plastic constitutive laws
* parameters in the material files :
* - h : Hardening parameter (default: 0)
* - sigmay : Yield stress
*/
-template<UInt dim>
-class MaterialPlastic : public MaterialElastic<dim> {
+template <UInt dim> class MaterialPlastic : public MaterialElastic<dim> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialPlastic(SolidMechanicsModel & model, const ID & id = "");
- MaterialPlastic(SolidMechanicsModel & model,
- UInt a_dim,
- const Mesh & mesh,
- FEEngine & fe_engine,
- const ID & id = "");
+ MaterialPlastic(SolidMechanicsModel & model, UInt a_dim, const Mesh & mesh,
+ FEEngine & fe_engine, const ID & id = "");
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// get the energy specifying the type for the time step
Real getEnergy(const std::string & type) override;
/// Compute the plastic energy
void updateEnergies(ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/// Compute the true potential energy
- void computePotentialEnergy(ElementType el_type, GhostType ghost_type) override;
+ void computePotentialEnergy(ElementType el_type,
+ GhostType ghost_type) override;
protected:
-
/// compute the stress and inelastic strain for the quadrature point
- inline void computeStressAndInelasticStrainOnQuad(const Matrix<Real> & grad_u,
- const Matrix<Real> & previous_grad_u,
- Matrix<Real> & sigma,
- const Matrix<Real> & previous_sigma,
- Matrix<Real> & inelas_strain,
- const Matrix<Real> & previous_inelas_strain,
- const Matrix<Real> & delta_inelastic_strain) const;
-
- inline void computeStressAndInelasticStrainOnQuad(const Matrix<Real> & delta_grad_u,
- Matrix<Real> & sigma,
- const Matrix<Real> & previous_sigma,
- Matrix<Real> & inelas_strain,
- const Matrix<Real> & previous_inelas_strain,
- const Matrix<Real> & delta_inelastic_strain) const;
+ inline void computeStressAndInelasticStrainOnQuad(
+ const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
+ Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
+ Matrix<Real> & inelas_strain, const Matrix<Real> & previous_inelas_strain,
+ const Matrix<Real> & delta_inelastic_strain) const;
+
+ inline void computeStressAndInelasticStrainOnQuad(
+ const Matrix<Real> & delta_grad_u, Matrix<Real> & sigma,
+ const Matrix<Real> & previous_sigma, Matrix<Real> & inelas_strain,
+ const Matrix<Real> & previous_inelas_strain,
+ const Matrix<Real> & delta_inelastic_strain) const;
/// get the plastic energy for the time step
Real getPlasticEnergy();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Yield stresss
Real sigma_y;
/// hardening modulus
Real h;
/// isotropic hardening, r
InternalField<Real> iso_hardening;
/// inelastic strain arrays ordered by element types (inelastic deformation)
InternalField<Real> inelastic_strain;
/// Plastic energy
InternalField<Real> plastic_energy;
- /// @todo : add a coefficient beta that will multiply the plastic energy increment
+ /// @todo : add a coefficient beta that will multiply the plastic energy
+ /// increment
/// to compute the energy converted to heat
/// Plastic energy increment
InternalField<Real> d_plastic_energy;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-
-
} // akantu
#include "material_plastic_inline_impl.cc"
#endif /* __AKANTU_MATERIAL_PLASTIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_python/material_python.cc b/src/model/solid_mechanics/materials/material_python/material_python.cc
index 24bd2dd46..3c3087c87 100644
--- a/src/model/solid_mechanics/materials/material_python/material_python.cc
+++ b/src/model/solid_mechanics/materials/material_python/material_python.cc
@@ -1,213 +1,214 @@
/**
* @file material_python.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Fri Nov 13 2015
* @date last modification: Fri Nov 13 2015
*
* @brief Material python implementation
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_python.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
MaterialPython::MaterialPython(SolidMechanicsModel & model, PyObject * obj,
const ID & id)
: Material(model, id), PythonFunctor(obj) {
AKANTU_DEBUG_IN();
this->registerInternals();
std::vector<std::string> param_names =
this->callFunctor<std::vector<std::string>>("registerParam");
for (UInt i = 0; i < param_names.size(); ++i) {
std::stringstream sstr;
sstr << "PythonParameter" << i;
this->registerParam(param_names[i], local_params[param_names[i]], 0.,
- _pat_parsable | _pat_readable, sstr.str());
+ _pat_parsable | _pat_readable, sstr.str());
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialPython::registerInternals() {
std::vector<std::string> internal_names =
this->callFunctor<std::vector<std::string>>("registerInternals");
std::vector<UInt> internal_sizes;
try {
internal_sizes =
this->callFunctor<std::vector<UInt>>("registerInternalSizes");
} catch (...) {
internal_sizes.assign(internal_names.size(), 1);
}
for (UInt i = 0; i < internal_names.size(); ++i) {
std::stringstream sstr;
sstr << "PythonInternal" << i;
this->internals[internal_names[i]] =
std::make_unique<InternalField<Real>>(internal_names[i], *this);
AKANTU_DEBUG_INFO("alloc internal " << internal_names[i] << " "
<< &this->internals[internal_names[i]]);
this->internals[internal_names[i]]->initialize(internal_sizes[i]);
}
// making an internal with the quadrature points coordinates
this->internals["quad_coordinates"] =
std::make_unique<InternalField<Real>>("quad_coordinates", *this);
auto && coords = *this->internals["quad_coordinates"];
coords.initialize(this->getSpatialDimension());
}
/* -------------------------------------------------------------------------- */
void MaterialPython::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
auto && coords = *this->internals["quad_coordinates"];
this->model.getFEEngine().computeIntegrationPointsCoordinates(
coords, &this->element_filter);
auto params = local_params;
params["rho"] = this->rho;
try {
this->callFunctor<void>("initMaterial", this->internals, params);
} catch (...) {
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialPython::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
auto params = local_params;
params["rho"] = this->rho;
std::map<std::string, Array<Real> *> internal_arrays;
for (auto & i : this->internals) {
auto & array = (*i.second)(el_type, ghost_type);
auto & name = i.first;
internal_arrays[name] = &array;
}
this->callFunctor<void>("computeStress", this->gradu(el_type, ghost_type),
this->stress(el_type, ghost_type), internal_arrays,
params);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialPython::computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type) {
auto params = local_params;
params["rho"] = this->rho;
std::map<std::string, Array<Real> *> internal_arrays;
for (auto & i : this->internals) {
auto & array = (*i.second)(el_type, ghost_type);
auto & name = i.first;
internal_arrays[name] = &array;
}
this->callFunctor<void>("computeTangentModuli",
this->gradu(el_type, ghost_type), tangent_matrix,
internal_arrays, params);
}
/* -------------------------------------------------------------------------- */
Real MaterialPython::getPushWaveSpeed(const Element &) const {
auto params = local_params;
params["rho"] = this->rho;
return this->callFunctor<Real>("getPushWaveSpeed", params);
}
/* -------------------------------------------------------------------------- */
-Real MaterialPython::getEnergyForType(const std::string & type, ElementType el_type) {
+Real MaterialPython::getEnergyForType(const std::string & type,
+ ElementType el_type) {
AKANTU_DEBUG_IN();
std::map<std::string, Array<Real> *> internal_arrays;
for (auto & i : this->internals) {
auto & array = (*i.second)(el_type, _not_ghost);
auto & name = i.first;
internal_arrays[name] = &array;
}
auto params = local_params;
params["rho"] = this->rho;
auto & energy_density = *internal_arrays[type];
this->callFunctor<void>("getEnergyDensity", type, energy_density,
this->gradu(el_type, _not_ghost),
this->stress(el_type, _not_ghost), internal_arrays,
params);
Real energy = fem.integrate(energy_density, el_type, _not_ghost,
element_filter(el_type, _not_ghost));
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
Real MaterialPython::getEnergy(const std::string & type) {
AKANTU_DEBUG_IN();
if (this->internals.find(type) == this->internals.end()) {
AKANTU_EXCEPTION("unknown energy type: "
<< type << " you must declare an internal named " << type);
}
Real energy = 0.;
/// integrate the potential energy for each type of elements
Mesh::type_iterator it = element_filter.firstType(spatial_dimension);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension);
for (; it != last_type; ++it) {
energy += this->getEnergyForType(type, *it);
}
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/model/solid_mechanics/materials/material_thermal.cc b/src/model/solid_mechanics/materials/material_thermal.cc
index 44b341e13..70222c54f 100644
--- a/src/model/solid_mechanics/materials/material_thermal.cc
+++ b/src/model/solid_mechanics/materials/material_thermal.cc
@@ -1,111 +1,111 @@
/**
* @file material_thermal.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Aug 04 2015
*
* @brief Specialization of the material class for the thermal material
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_thermal.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model, const ID & id) :
- Material(model, id),
- delta_T("delta_T", *this),
- sigma_th("sigma_th", *this),
- use_previous_stress_thermal(false) {
+template <UInt spatial_dimension>
+MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model,
+ const ID & id)
+ : Material(model, id), delta_T("delta_T", *this),
+ sigma_th("sigma_th", *this), use_previous_stress_thermal(false) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model,
- UInt dim,
- const Mesh & mesh,
+ UInt dim, const Mesh & mesh,
FEEngine & fe_engine,
- const ID & id) :
- Material(model, dim, mesh, fe_engine, id),
- delta_T("delta_T", *this, dim, fe_engine, this->element_filter),
- sigma_th("sigma_th", *this, dim, fe_engine, this->element_filter),
- use_previous_stress_thermal(false) {
+ const ID & id)
+ : Material(model, dim, mesh, fe_engine, id),
+ delta_T("delta_T", *this, dim, fe_engine, this->element_filter),
+ sigma_th("sigma_th", *this, dim, fe_engine, this->element_filter),
+ use_previous_stress_thermal(false) {
AKANTU_DEBUG_IN();
this->initialize();
AKANTU_DEBUG_OUT();
}
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialThermal<spatial_dimension>::initialize() {
- this->registerParam("E" , E , Real(0. ) , _pat_parsable | _pat_modifiable, "Young's modulus" );
- this->registerParam("nu" , nu , Real(0.5) , _pat_parsable | _pat_modifiable, "Poisson's ratio" );
- this->registerParam("alpha" , alpha , Real(0. ) , _pat_parsable | _pat_modifiable, "Thermal expansion coefficient");
- this->registerParam("delta_T", delta_T, _pat_parsable | _pat_modifiable, "Uniform temperature field");
+ this->registerParam("E", E, Real(0.), _pat_parsable | _pat_modifiable,
+ "Young's modulus");
+ this->registerParam("nu", nu, Real(0.5), _pat_parsable | _pat_modifiable,
+ "Poisson's ratio");
+ this->registerParam("alpha", alpha, Real(0.), _pat_parsable | _pat_modifiable,
+ "Thermal expansion coefficient");
+ this->registerParam("delta_T", delta_T, _pat_parsable | _pat_modifiable,
+ "Uniform temperature field");
delta_T.initialize(1);
}
-
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialThermal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
sigma_th.initialize(1);
-
- if(use_previous_stress_thermal) {
+ if (use_previous_stress_thermal) {
sigma_th.initializeHistory();
}
Material::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
-void MaterialThermal<dim>::computeStress(ElementType el_type, GhostType ghost_type) {
+void MaterialThermal<dim>::computeStress(ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
for (auto && tuple : zip(this->delta_T(el_type, ghost_type),
this->sigma_th(el_type, ghost_type))) {
computeStressOnQuad(std::get<1>(tuple), std::get<0>(tuple));
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-
INSTANTIATE_MATERIAL_ONLY(MaterialThermal);
} // akantu
diff --git a/src/model/solid_mechanics/materials/material_thermal.hh b/src/model/solid_mechanics/materials/material_thermal.hh
index a1ed866e5..ee1a0fe94 100644
--- a/src/model/solid_mechanics/materials/material_thermal.hh
+++ b/src/model/solid_mechanics/materials/material_thermal.hh
@@ -1,113 +1,108 @@
/**
* @file material_thermal.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Aug 18 2015
*
* @brief Material isotropic thermo-elastic
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_THERMAL_HH__
#define __AKANTU_MATERIAL_THERMAL_HH__
namespace akantu {
-template<UInt spatial_dimension>
-class MaterialThermal : public Material {
+template <UInt spatial_dimension> class MaterialThermal : public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialThermal(SolidMechanicsModel & model, const ID & id = "");
- MaterialThermal(SolidMechanicsModel & model,
- UInt dim,
- const Mesh & mesh,
- FEEngine & fe_engine,
- const ID & id = "");
+ MaterialThermal(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
+ FEEngine & fe_engine, const ID & id = "");
~MaterialThermal() override = default;
protected:
void initialize();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void initMaterial() override;
/// constitutive law for all element of a type
void computeStress(ElementType el_type, GhostType ghost_type) override;
/// local computation of thermal stress
inline void computeStressOnQuad(Real & sigma, const Real & deltaT);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Young modulus
Real E;
/// Poisson ratio
Real nu;
/// Thermal expansion coefficient
/// TODO : implement alpha as a matrix
Real alpha;
/// Temperature field
InternalField<Real> delta_T;
/// Current thermal stress
InternalField<Real> sigma_th;
/// Tell if we need to use the previous thermal stress
bool use_previous_stress_thermal;
};
/* ------------------------------------------------------------------------ */
/* Inline impl */
/* ------------------------------------------------------------------------ */
template <UInt dim>
inline void MaterialThermal<dim>::computeStressOnQuad(Real & sigma,
const Real & deltaT) {
sigma = -this->E / (1. - 2. * this->nu) * this->alpha * deltaT;
}
template <>
inline void MaterialThermal<1>::computeStressOnQuad(Real & sigma,
const Real & deltaT) {
sigma = -this->E * this->alpha * deltaT;
}
} // akantu
#endif /* __AKANTU_MATERIAL_THERMAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
index 8f5d0f5b8..f21887a1b 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
@@ -1,326 +1,325 @@
/**
* @file material_standard_linear_solid_deviatoric.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
*
* @date creation: Wed May 04 2011
* @date last modification: Thu Oct 15 2015
*
* @brief Material Visco-elastic
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_standard_linear_solid_deviatoric.hh"
#include "solid_mechanics_model.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialStandardLinearSolidDeviatoric<spatial_dimension>::
MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model,
const ID & id)
: MaterialElastic<spatial_dimension>(model, id),
stress_dev("stress_dev", *this),
history_integral("history_integral", *this),
dissipated_energy("dissipated_energy", *this) {
AKANTU_DEBUG_IN();
this->registerParam("Eta", eta, Real(1.), _pat_parsable | _pat_modifiable,
"Viscosity");
this->registerParam("Ev", Ev, Real(1.), _pat_parsable | _pat_modifiable,
"Stiffness of the viscous element");
this->registerParam("Einf", E_inf, Real(1.), _pat_readable,
"Stiffness of the elastic element");
UInt stress_size = spatial_dimension * spatial_dimension;
this->stress_dev.initialize(stress_size);
this->history_integral.initialize(stress_size);
this->dissipated_energy.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
updateInternalParameters();
MaterialElastic<spatial_dimension>::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<
spatial_dimension>::updateInternalParameters() {
MaterialElastic<spatial_dimension>::updateInternalParameters();
E_inf = this->E - this->Ev;
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::setToSteadyState(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
Array<Real>::matrix_iterator stress_d =
stress_dev_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator history_int =
history_int_vect.begin(spatial_dimension, spatial_dimension);
/// Loop on all quadrature points
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & dev_s = *stress_d;
Matrix<Real> & h = *history_int;
/// Compute the first invariant of strain
Real Theta = grad_u.trace();
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
- dev_s(i, j) =
- 2 * this->mu *
- (.5 * (grad_u(i, j) + grad_u(j, i)) - 1. / 3. * Theta * (i == j));
+ dev_s(i, j) = 2 * this->mu * (.5 * (grad_u(i, j) + grad_u(j, i)) -
+ 1. / 3. * Theta * (i == j));
h(i, j) = 0.;
}
/// Save the deviator of stress
++stress_d;
++history_int;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::computeStress(
ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real tau = 0.;
// if(std::abs(Ev) > std::numeric_limits<Real>::epsilon())
tau = eta / Ev;
Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
Array<Real>::matrix_iterator stress_d =
stress_dev_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator history_int =
history_int_vect.begin(spatial_dimension, spatial_dimension);
Matrix<Real> s(spatial_dimension, spatial_dimension);
Real dt = this->model.getTimeStep();
Real exp_dt_tau = exp(-dt / tau);
Real exp_dt_tau_2 = exp(-.5 * dt / tau);
Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
/// Loop on all quadrature points
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & dev_s = *stress_d;
Matrix<Real> & h = *history_int;
s.clear();
sigma.clear();
/// Compute the first invariant of strain
Real gamma_inf = E_inf / this->E;
Real gamma_v = Ev / this->E;
this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
Real Theta = epsilon_d.trace();
epsilon_v.eye(Theta / Real(3.));
epsilon_d -= epsilon_v;
Matrix<Real> U_rond_prim(spatial_dimension, spatial_dimension);
U_rond_prim.eye(gamma_inf * this->kpa * Theta);
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
s(i, j) = 2 * this->mu * epsilon_d(i, j);
h(i, j) = exp_dt_tau * h(i, j) + exp_dt_tau_2 * (s(i, j) - dev_s(i, j));
dev_s(i, j) = s(i, j);
sigma(i, j) = U_rond_prim(i, j) + gamma_inf * s(i, j) + gamma_v * h(i, j);
}
/// Save the deviator of stress
++stress_d;
++history_int;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
this->updateDissipatedEnergy(el_type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialStandardLinearSolidDeviatoric<
spatial_dimension>::updateDissipatedEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
// if(ghost_type == _ghost) return 0.;
Real tau = 0.;
tau = eta / Ev;
Real * dis_energy = dissipated_energy(el_type, ghost_type).storage();
Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
Array<Real>::matrix_iterator stress_d =
stress_dev_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator history_int =
history_int_vect.begin(spatial_dimension, spatial_dimension);
Matrix<Real> q(spatial_dimension, spatial_dimension);
Matrix<Real> q_rate(spatial_dimension, spatial_dimension);
Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
Real dt = this->model.getTimeStep();
Real gamma_v = Ev / this->E;
Real alpha = 1. / (2. * this->mu * gamma_v);
/// Loop on all quadrature points
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
Matrix<Real> & dev_s = *stress_d;
Matrix<Real> & h = *history_int;
/// Compute the first invariant of strain
this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
Real Theta = epsilon_d.trace();
epsilon_v.eye(Theta / Real(3.));
epsilon_d -= epsilon_v;
q.copy(dev_s);
q -= h;
q *= gamma_v;
q_rate.copy(dev_s);
q_rate *= gamma_v;
q_rate -= q;
q_rate /= tau;
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
*dis_energy += (epsilon_d(i, j) - alpha * q(i, j)) * q_rate(i, j) * dt;
/// Save the deviator of stress
++stress_d;
++history_int;
++dis_energy;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<
spatial_dimension>::getDissipatedEnergy() const {
AKANTU_DEBUG_IN();
Real de = 0.;
/// integrate the dissipated energy for each type of elements
for (auto & type :
this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
de +=
this->fem.integrate(dissipated_energy(type, _not_ghost), type,
_not_ghost, this->element_filter(type, _not_ghost));
}
AKANTU_DEBUG_OUT();
return de;
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<
spatial_dimension>::getDissipatedEnergy(ElementType type,
UInt index) const {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
auto it =
this->dissipated_energy(type, _not_ghost).begin(nb_quadrature_points);
UInt gindex = (this->element_filter(type, _not_ghost))(index);
AKANTU_DEBUG_OUT();
return this->fem.integrate(it[index], type, gindex);
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(
const std::string & type) {
if (type == "dissipated")
return getDissipatedEnergy();
else if (type == "dissipated_sls_deviatoric")
return getDissipatedEnergy();
else
return MaterialElastic<spatial_dimension>::getEnergy(type);
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(
const std::string & energy_id, ElementType type, UInt index) {
if (energy_id == "dissipated")
return getDissipatedEnergy(type, index);
else if (energy_id == "dissipated_sls_deviatoric")
return getDissipatedEnergy(type, index);
else
return MaterialElastic<spatial_dimension>::getEnergy(energy_id, type,
index);
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(sls_deviatoric, MaterialStandardLinearSolidDeviatoric);
} // namespace akantu
diff --git a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
index 146f2d1a3..1387b8f97 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
@@ -1,103 +1,102 @@
/**
* @file plane_stress_toolbox.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 16 2014
* @date last modification: Tue Aug 18 2015
*
* @brief Tools to implement the plane stress behavior in a material
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PLANE_STRESS_TOOLBOX_HH__
#define __AKANTU_PLANE_STRESS_TOOLBOX_HH__
namespace akantu {
class SolidMechanicsModel;
class FEEngine;
-} // akantu
-
+} // akantu
namespace akantu {
/**
* Empty class in dimensions different from 2
* This class is only specialized for 2D in the tmpl file
*/
template <UInt dim, class ParentMaterial = Material>
class PlaneStressToolbox : public ParentMaterial {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PlaneStressToolbox(SolidMechanicsModel & model, const ID & id = "")
: ParentMaterial(model, id) {}
PlaneStressToolbox(SolidMechanicsModel & model, UInt spatial_dimension,
const Mesh & mesh, FEEngine & fe_engine,
const ID & id = "")
: ParentMaterial(model, spatial_dimension, mesh, fe_engine, id) {}
~PlaneStressToolbox() override = default;
protected:
void initialize();
public:
void computeAllCauchyStresses(GhostType ghost_type = _not_ghost) override {
ParentMaterial::computeAllCauchyStresses(ghost_type);
}
virtual void computeCauchyStressPlaneStress(ElementType /*el_type*/,
GhostType /*ghost_type*/) {
AKANTU_DEBUG_IN();
AKANTU_ERROR("The function \"computeCauchyStressPlaneStress\" can "
- "only be used in 2D Plane stress problems, which means "
- "that you made a mistake somewhere!! ");
+ "only be used in 2D Plane stress problems, which means "
+ "that you made a mistake somewhere!! ");
AKANTU_DEBUG_OUT();
}
virtual void computeThirdAxisDeformation(ElementType, GhostType) {}
protected:
bool initialize_third_axis_deformation{false};
};
#define AKANTU_PLANE_STRESS_TOOL_SPEC(dim) \
template <> \
inline PlaneStressToolbox<dim, Material>::PlaneStressToolbox( \
SolidMechanicsModel & model, const ID & id) \
: Material(model, id) {}
AKANTU_PLANE_STRESS_TOOL_SPEC(1)
AKANTU_PLANE_STRESS_TOOL_SPEC(3)
} // namespace akantu
#include "plane_stress_toolbox_tmpl.hh"
#endif /* __AKANTU_PLANE_STRESS_TOOLBOX_HH__ */
diff --git a/src/model/solid_mechanics/materials/random_internal_field.hh b/src/model/solid_mechanics/materials/random_internal_field.hh
index f3e6decda..ebb9c03c6 100644
--- a/src/model/solid_mechanics/materials/random_internal_field.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field.hh
@@ -1,108 +1,105 @@
/**
* @file random_internal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Dec 08 2015
*
* @brief Random internal material parameter
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_random_generator.hh"
#include "internal_field.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_RANDOM_INTERNAL_FIELD_HH__
#define __AKANTU_RANDOM_INTERNAL_FIELD_HH__
namespace akantu {
/**
* class for the internal fields of materials with a random
* distribution
*/
-template<typename T,
- template<typename> class BaseField = InternalField,
- template<typename> class Generator = RandomGenerator>
+template <typename T, template <typename> class BaseField = InternalField,
+ template <typename> class Generator = RandomGenerator>
class RandomInternalField : public BaseField<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
RandomInternalField(const ID & id, Material & material);
~RandomInternalField() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
RandomInternalField operator=(const RandomInternalField &) = delete;
public:
AKANTU_GET_MACRO(RandomParameter, random_parameter, const RandomParameter<T>);
/// initialize the field to a given number of component
void initialize(UInt nb_component) override;
/// set the field to a given value
void setDefaultValue(const T & value) override;
/// set the specified random distribution to a given parameter
void setRandomDistribution(const RandomParameter<T> & param);
/// print the content
void printself(std::ostream & stream, int indent = 0) const override;
protected:
void setArrayValues(T * begin, T * end) override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
inline operator Real() const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// random parameter containing the distribution and base value
RandomParameter<T> random_parameter;
};
-
/// standard output stream operator
-template<typename T>
-inline std::ostream & operator <<(std::ostream & stream, const RandomInternalField<T> & _this)
-{
+template <typename T>
+inline std::ostream & operator<<(std::ostream & stream,
+ const RandomInternalField<T> & _this) {
_this.printself(stream);
return stream;
}
} // akantu
#endif /* __AKANTU_RANDOM_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh b/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
index c5b3cb4bc..ed64c4371 100644
--- a/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
@@ -1,125 +1,125 @@
/**
* @file random_internal_field_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Tue Dec 08 2015
*
* @brief Random internal material parameter implementation
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_random_generator.hh"
#include "internal_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__
#define __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
RandomInternalField<T, BaseField, Generator>::RandomInternalField(
const ID & id, Material & material)
: BaseField<T>(id, material), random_parameter(T()) {}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
RandomInternalField<T, BaseField, Generator>::~RandomInternalField() = default;
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::initialize(
UInt nb_component) {
this->internalInitialize(nb_component);
}
/* ------------------------------------------------------------------------ */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::setDefaultValue(
const T & value) {
random_parameter.setBaseValue(value);
this->reset();
}
/* ------------------------------------------------------------------------ */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::setRandomDistribution(
const RandomParameter<T> & param) {
random_parameter = param;
this->reset();
}
/* ------------------------------------------------------------------------ */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::printself(
- std::ostream & stream, int indent [[gnu::unused]]) const {
+ std::ostream & stream, int indent[[gnu::unused]]) const {
stream << "RandomInternalField [ ";
random_parameter.printself(stream);
stream << " ]";
#if !defined(AKANTU_NDEBUG)
if (AKANTU_DEBUG_TEST(dblDump)) {
stream << std::endl;
InternalField<T>::printself(stream, indent);
}
#endif
}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
void RandomInternalField<T, BaseField, Generator>::setArrayValues(T * begin,
T * end) {
random_parameter.template setValues<Generator>(begin, end);
}
/* -------------------------------------------------------------------------- */
template <typename T, template <typename> class BaseField,
template <typename> class Generator>
inline RandomInternalField<T, BaseField, Generator>::operator Real() const {
return random_parameter.getBaseValue();
}
/* -------------------------------------------------------------------------- */
template <>
inline void ParameterTyped<RandomInternalField<Real>>::setAuto(
const ParserParameter & in_param) {
Parameter::setAuto(in_param);
RandomParameter<Real> r = in_param;
param.setRandomDistribution(r);
}
/* -------------------------------------------------------------------------- */
} // akantu
#endif /* __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
index 0c81aecfa..8752fe003 100644
--- a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
@@ -1,74 +1,75 @@
/**
* @file damaged_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
* @date creation: Mon Aug 24 2015
* @date last modification: Thu Oct 15 2015
*
* @brief Implementation of inline function of damaged weight function
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline Real DamagedWeightFunction::operator()(Real r,
- const __attribute__((unused)) IntegrationPoint & q1,
- const IntegrationPoint & q2) {
+ const __attribute__((unused))
+ IntegrationPoint & q1,
+ const IntegrationPoint & q2) {
/// compute the weight
UInt quad = q2.global_num;
Array<Real> & dam_array = (*this->damage)(q2.type, q2.ghost_type);
Real D = dam_array(quad);
Real Radius_t = 0;
Real Radius_init = this->R2;
// if(D <= 0.5)
// {
// Radius_t = 2*D*Radius_init;
// }
// else
// {
// Radius_t = 2*Radius_init*(1-D);
// }
//
- Radius_t = Radius_init*(1-D);
-
+ Radius_t = Radius_init * (1 - D);
Radius_init *= Radius_init;
Radius_t *= Radius_t;
- if(Radius_t < Math::getTolerance()) {
- Radius_t = 0.001*Radius_init;
+ if (Radius_t < Math::getTolerance()) {
+ Radius_t = 0.001 * Radius_init;
}
- Real expb = (2*std::log(0.51))/(std::log(1.0-0.49*Radius_t/Radius_init));
- Int expb_floor=std::floor(expb);
- Real b = expb_floor + expb_floor%2;
- Real alpha = std::max(0., 1. - r*r / Radius_init);
- Real w = std::pow(alpha,b);
+ Real expb =
+ (2 * std::log(0.51)) / (std::log(1.0 - 0.49 * Radius_t / Radius_init));
+ Int expb_floor = std::floor(expb);
+ Real b = expb_floor + expb_floor % 2;
+ Real alpha = std::max(0., 1. - r * r / Radius_init);
+ Real w = std::pow(alpha, b);
return w;
}
/* -------------------------------------------------------------------------- */
inline void DamagedWeightFunction::init() {
this->damage = &(this->manager.registerWeightFunctionInternal("damage"));
}
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
index 31eb2dbc8..e4664c861 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
@@ -1,83 +1,86 @@
/**
* @file remove_damaged_with_damage_rate_weight_function.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 15 2015
*
* @brief Removed damaged weight function for non local materials
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_RATE_WEIGHT_FUNCTION_HH__
#define __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_RATE_WEIGHT_FUNCTION_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
-/* Remove damaged with damage rate weight function */
+/* Remove damaged with damage rate weight function */
/* -------------------------------------------------------------------------- */
class RemoveDamagedWithDamageRateWeightFunction : public BaseWeightFunction {
public:
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
RemoveDamagedWithDamageRateWeightFunction(NonLocalManager & manager)
: BaseWeightFunction(manager, "remove_damage_with_damage_rate"),
damage_with_damage_rate(nullptr) {
- this->registerParam<Real>("damage_limit", this->damage_limit_with_damage_rate, 1, _pat_parsable, "Damage Threshold");
+ this->registerParam<Real>("damage_limit",
+ this->damage_limit_with_damage_rate, 1,
+ _pat_parsable, "Damage Threshold");
this->init();
}
- /* -------------------------------------------------------------------------- */
- /* Base Weight Function inherited methods */
- /* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Base Weight Function inherited methods */
+ /* --------------------------------------------------------------------------
+ */
inline Real operator()(Real r,
- const __attribute__((unused)) IntegrationPoint & q1,
- const IntegrationPoint & q2);
+ const __attribute__((unused)) IntegrationPoint & q1,
+ const IntegrationPoint & q2);
inline void init() override;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// limit at which a point is considered as complitely broken
Real damage_limit_with_damage_rate;
/// internal pointer to the current damage vector
ElementTypeMapReal * damage_with_damage_rate;
-
};
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "remove_damaged_with_damage_rate_weight_function_inline_impl.cc"
+#if defined(AKANTU_INCLUDE_INLINE_IMPL)
+#include "remove_damaged_with_damage_rate_weight_function_inline_impl.cc"
#endif
} // akantu
#endif /* __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
index 918813435..2c9b3d939 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
@@ -1,60 +1,62 @@
/**
* @file remove_damaged_with_damage_rate_weight_function_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
* @date creation: Mon Aug 24 2015
* @date last modification: Thu Oct 15 2015
*
* @brief Implementation of inline function of remove damaged with
* damage rate weight function
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline void RemoveDamagedWithDamageRateWeightFunction::init() {
- this->damage_with_damage_rate = &(this->manager.registerWeightFunctionInternal("damage-rate"));
+ this->damage_with_damage_rate =
+ &(this->manager.registerWeightFunctionInternal("damage-rate"));
}
/* -------------------------------------------------------------------------- */
-inline Real RemoveDamagedWithDamageRateWeightFunction::operator()(Real r,
- const __attribute__((unused)) IntegrationPoint & q1,
+inline Real RemoveDamagedWithDamageRateWeightFunction::
+operator()(Real r, const __attribute__((unused)) IntegrationPoint & q1,
- const IntegrationPoint & q2) {
+ const IntegrationPoint & q2) {
/// compute the weight
UInt quad = q2.global_num;
- if(q1.global_num == quad) return 1.;
+ if (q1.global_num == quad)
+ return 1.;
- Array<Real> & dam_array = (*this->damage_with_damage_rate)(q2.type, q2.ghost_type);
+ Array<Real> & dam_array =
+ (*this->damage_with_damage_rate)(q2.type, q2.ghost_type);
Real D = dam_array(quad);
Real w = 0.;
Real alphaexp = 1.;
Real betaexp = 2.;
- if(D < damage_limit_with_damage_rate) {
- Real alpha = std::max(0., 1. - pow((r*r / this->R2),alphaexp));
+ if (D < damage_limit_with_damage_rate) {
+ Real alpha = std::max(0., 1. - pow((r * r / this->R2), alphaexp));
w = pow(alpha, betaexp);
}
return w;
}
-
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
index 714f57229..992297710 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
@@ -1,117 +1,123 @@
/**
* @file stress_based_weight_function.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Aug 24 2015
* @date last modification: Wed Oct 07 2015
*
* @brief implementation of the stres based weight function classes
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "stress_based_weight_function.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
-StressBasedWeightFunction::StressBasedWeightFunction(NonLocalManager & manager) :
- BaseWeightFunction(manager, "stress_based")
- // stress_diag("stress_diag", material), selected_stress_diag(NULL),
- // stress_base("stress_base", material), selected_stress_base(NULL),
- // characteristic_size("lc", material), selected_characteristic_size(NULL)
+StressBasedWeightFunction::StressBasedWeightFunction(NonLocalManager & manager)
+ : BaseWeightFunction(manager, "stress_based")
+// stress_diag("stress_diag", material), selected_stress_diag(NULL),
+// stress_base("stress_base", material), selected_stress_base(NULL),
+// characteristic_size("lc", material), selected_characteristic_size(NULL)
{
// this->registerParam("ft", this->ft, 0., _pat_parsable, "Tensile strength");
// stress_diag.initialize(spatial_dimension);
// stress_base.initialize(spatial_dimension * spatial_dimension);
// characteristic_size.initialize(1);
}
/* -------------------------------------------------------------------------- */
/// During intialization the characteristic sizes for all quadrature
/// points are computed
void StressBasedWeightFunction::init() {
// const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
// for (UInt g = _not_ghost; g <= _ghost; ++g) {
// GhostType gt = GhostType(g);
// Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt);
// Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt);
// for(; it != last_type; ++it) {
// UInt nb_quadrature_points =
// this->material.getModel().getFEEngine().getNbQuadraturePoints(*it, gt);
- // const Array<UInt> & element_filter = this->material.getElementFilter(*it, gt);
+ // const Array<UInt> & element_filter =
+ // this->material.getElementFilter(*it, gt);
// UInt nb_element = element_filter.size();
// Array<Real> ones(nb_element*nb_quadrature_points, 1, 1.);
// Array<Real> & lc = characteristic_size(*it, gt);
// this->material.getModel().getFEEngine().integrateOnQuadraturePoints(ones,
// lc,
// 1,
// *it,
// gt,
// element_filter);
// for (UInt q = 0; q < nb_quadrature_points * nb_element; q++) {
// lc(q) = pow(lc(q), 1./ Real(spatial_dimension));
// }
// }
// }
}
-
/* -------------------------------------------------------------------------- */
/// computation of principals stresses and principal directions
-void StressBasedWeightFunction::updatePrincipalStress(__attribute__((unused)) GhostType ghost_type) {
-// AKANTU_DEBUG_IN();
+void StressBasedWeightFunction::updatePrincipalStress(__attribute__((unused))
+ GhostType ghost_type) {
+ // AKANTU_DEBUG_IN();
-// const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
+ // const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
-// Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
-// Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
-// for(; it != last_type; ++it) {
-// Array<Real>::const_matrix_iterator sigma =
-// this->material.getStress(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
-// auto eigenvalues =
-// stress_diag(*it, ghost_type).begin(spatial_dimension);
-// auto eigenvalues_end =
-// stress_diag(*it, ghost_type).end(spatial_dimension);
-// Array<Real>::matrix_iterator eigenvector =
-// stress_base(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
+ // Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+ // Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
+ // ghost_type);
+ // for(; it != last_type; ++it) {
+ // Array<Real>::const_matrix_iterator sigma =
+ // this->material.getStress(*it, ghost_type).begin(spatial_dimension,
+ // spatial_dimension);
+ // auto eigenvalues =
+ // stress_diag(*it, ghost_type).begin(spatial_dimension);
+ // auto eigenvalues_end =
+ // stress_diag(*it, ghost_type).end(spatial_dimension);
+ // Array<Real>::matrix_iterator eigenvector =
+ // stress_base(*it, ghost_type).begin(spatial_dimension,
+ // spatial_dimension);
-// #ifndef __trick__
-// auto cl = characteristic_size(*it, ghost_type).begin();
-// #endif
-// UInt q = 0;
-// for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues, ++eigenvector, ++cl, ++q) {
-// sigma->eig(*eigenvalues, *eigenvector);
-// *eigenvalues /= ft;
-// #ifndef __trick__
-// // specify a lower bound for principal stress based on the size of the element
-// for (UInt i = 0; i < spatial_dimension; ++i) {
-// (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
-// }
-// #endif
-// }
-// }
-// AKANTU_DEBUG_OUT();
+ // #ifndef __trick__
+ // auto cl = characteristic_size(*it, ghost_type).begin();
+ // #endif
+ // UInt q = 0;
+ // for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues,
+ // ++eigenvector, ++cl, ++q) {
+ // sigma->eig(*eigenvalues, *eigenvector);
+ // *eigenvalues /= ft;
+ // #ifndef __trick__
+ // // specify a lower bound for principal stress based on the size of
+ // the element
+ // for (UInt i = 0; i < spatial_dimension; ++i) {
+ // (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
+ // }
+ // #endif
+ // }
+ // }
+ // AKANTU_DEBUG_OUT();
}
} // akantu
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
index 07a742faa..a2e1debd7 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
@@ -1,104 +1,101 @@
/**
* @file stress_based_weight_function.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
* @date creation: Mon Aug 24 2015
* @date last modification: Thu Oct 15 2015
*
* @brief Removed damaged weight function for non local materials
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "base_weight_function.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__
#define __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
-/* Stress Based Weight */
+/* Stress Based Weight */
/* -------------------------------------------------------------------------- */
/// based on based on Giry et al.: Stress-based nonlocal damage model,
/// IJSS, 48, 2011
class StressBasedWeightFunction : public BaseWeightFunction {
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
StressBasedWeightFunction(NonLocalManager & manager);
- /* -------------------------------------------------------------------------- */
- /* Base Weight Function inherited methods */
- /* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Base Weight Function inherited methods */
+ /* --------------------------------------------------------------------------
+ */
void init() override;
inline void updateInternals() override;
void updatePrincipalStress(GhostType ghost_type);
- inline void updateQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates);
+ inline void updateQuadraturePointsCoordinates(
+ ElementTypeMapArray<Real> & quadrature_points_coordinates);
-
- inline Real operator()(Real r,
- const IntegrationPoint & q1,
- const IntegrationPoint & q2);
+ inline Real operator()(Real r, const IntegrationPoint & q1,
+ const IntegrationPoint & q2);
/// computation of ellipsoid
- inline Real computeRhoSquare(Real r,
- Vector<Real> & eigs,
- Matrix<Real> & eigenvects,
- Vector<Real> & x_s);
+ inline Real computeRhoSquare(Real r, Vector<Real> & eigs,
+ Matrix<Real> & eigenvects, Vector<Real> & x_s);
protected:
inline void setInternal();
private:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// tensile strength
Real ft;
/// prinicipal stresses
ElementTypeMapReal * stress_diag;
/// for preselection of types (optimization)
ElementTypeMapReal * selected_stress_diag;
/// principal directions
ElementTypeMapReal * stress_base;
/// lenght intrinisic to the material
ElementTypeMapReal * characteristic_size;
-
};
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "stress_based_weight_function_inline_impl.cc"
+#if defined(AKANTU_INCLUDE_INLINE_IMPL)
+#include "stress_based_weight_function_inline_impl.cc"
#endif
} // akantu
#endif /* __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model.cc b/src/model/solid_mechanics/solid_mechanics_model.cc
index e534b46f2..ba8c9bcd2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model.cc
@@ -1,1219 +1,1212 @@
/**
* @file solid_mechanics_model.cc
*
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Tue Jan 19 2016
*
* @brief Implementation of the SolidMechanicsModel class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "integrator_gauss.hh"
#include "shape_lagrange.hh"
#include "solid_mechanics_model_tmpl.hh"
#include "communicator.hh"
#include "element_synchronizer.hh"
#include "sparse_matrix.hh"
#include "synchronizer_registry.hh"
#include "dumpable_inline_impl.hh"
#ifdef AKANTU_USE_IOHELPER
#include "dumper_iohelper_paraview.hh"
#endif
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/**
* A solid mechanics model need a mesh and a dimension to be created. the model
* by it self can not do a lot, the good init functions should be called in
* order to configure the model depending on what we want to do.
*
* @param mesh mesh representing the model we want to simulate
* @param dim spatial dimension of the problem, if dim = 0 (default value) the
* dimension of the problem is assumed to be the on of the mesh
* @param id an id to identify the model
*/
SolidMechanicsModel::SolidMechanicsModel(Mesh & mesh, UInt dim, const ID & id,
const MemoryID & memory_id,
const ModelType model_type)
: Model(mesh, model_type, dim, id, memory_id),
BoundaryCondition<SolidMechanicsModel>(), f_m2a(1.0),
displacement(nullptr), previous_displacement(nullptr),
displacement_increment(nullptr), mass(nullptr), velocity(nullptr),
acceleration(nullptr), external_force(nullptr), internal_force(nullptr),
blocked_dofs(nullptr), current_position(nullptr),
material_index("material index", id, memory_id),
material_local_numbering("material local numbering", id, memory_id),
increment_flag(false), are_materials_instantiated(false) {
AKANTU_DEBUG_IN();
this->registerFEEngineObject<MyFEEngineType>("SolidMechanicsFEEngine", mesh,
Model::spatial_dimension);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
this->mesh.addDumpMesh(mesh, Model::spatial_dimension, _not_ghost,
_ek_regular);
#endif
material_selector = std::make_shared<DefaultMaterialSelector>(material_index),
this->initDOFManager();
this->registerDataAccessor(*this);
if (this->mesh.isDistributed()) {
auto & synchronizer = this->mesh.getElementSynchronizer();
this->registerSynchronizer(synchronizer, _gst_material_id);
this->registerSynchronizer(synchronizer, _gst_smm_mass);
this->registerSynchronizer(synchronizer, _gst_smm_stress);
this->registerSynchronizer(synchronizer, _gst_smm_boundary);
this->registerSynchronizer(synchronizer, _gst_for_dump);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModel::~SolidMechanicsModel() {
AKANTU_DEBUG_IN();
for (auto & internal : this->registered_internals) {
delete internal.second;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::setTimeStep(Real time_step, const ID & solver_id) {
Model::setTimeStep(time_step, solver_id);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.getDumper().setTimeStep(time_step);
#endif
}
/* -------------------------------------------------------------------------- */
/* Initialization */
/* -------------------------------------------------------------------------- */
/**
* This function groups many of the initialization in on function. For most of
* basics case the function should be enough. The functions initialize the
* model, the internal vectors, set them to 0, and depending on the parameters
* it also initialize the explicit or implicit solver.
*
* @param material_file the file containing the materials to use
* @param method the analysis method wanted. See the akantu::AnalysisMethod for
* the different possibilities
*/
void SolidMechanicsModel::initFullImpl(const ModelOptions & options) {
material_index.initialize(mesh, _element_kind = _ek_not_defined,
_default_value = UInt(-1), _with_nb_element = true);
material_local_numbering.initialize(mesh, _element_kind = _ek_not_defined,
_with_nb_element = true);
Model::initFullImpl(options);
// initialize pbc
if (this->pbc_pair.size() != 0)
this->initPBC();
// initialize the materials
if (this->parser.getLastParsedFile() != "") {
this->instantiateMaterials();
}
this->initMaterials();
this->initBC(*this, *displacement, *displacement_increment, *external_force);
}
/* -------------------------------------------------------------------------- */
TimeStepSolverType SolidMechanicsModel::getDefaultSolverType() const {
return _tsst_dynamic_lumped;
}
/* -------------------------------------------------------------------------- */
ModelSolverOptions SolidMechanicsModel::getDefaultSolverOptions(
const TimeStepSolverType & type) const {
ModelSolverOptions options;
switch (type) {
case _tsst_dynamic_lumped: {
options.non_linear_solver_type = _nls_lumped;
options.integration_scheme_type["displacement"] = _ist_central_difference;
options.solution_type["displacement"] = IntegrationScheme::_acceleration;
break;
}
case _tsst_static: {
options.non_linear_solver_type = _nls_newton_raphson;
options.integration_scheme_type["displacement"] = _ist_pseudo_time;
options.solution_type["displacement"] = IntegrationScheme::_not_defined;
break;
}
case _tsst_dynamic: {
if (this->method == _explicit_consistent_mass) {
options.non_linear_solver_type = _nls_newton_raphson;
options.integration_scheme_type["displacement"] = _ist_central_difference;
options.solution_type["displacement"] = IntegrationScheme::_acceleration;
} else {
options.non_linear_solver_type = _nls_newton_raphson;
options.integration_scheme_type["displacement"] = _ist_trapezoidal_rule_2;
options.solution_type["displacement"] = IntegrationScheme::_displacement;
}
break;
}
default:
AKANTU_EXCEPTION(type << " is not a valid time step solver type");
}
return options;
}
/* -------------------------------------------------------------------------- */
std::tuple<ID, TimeStepSolverType>
SolidMechanicsModel::getDefaultSolverID(const AnalysisMethod & method) {
switch (method) {
case _explicit_lumped_mass: {
return std::make_tuple("explicit_lumped", _tsst_dynamic_lumped);
}
case _explicit_consistent_mass: {
return std::make_tuple("explicit", _tsst_dynamic);
}
case _static: {
return std::make_tuple("static", _tsst_static);
}
case _implicit_dynamic: {
return std::make_tuple("implicit", _tsst_dynamic);
}
default:
return std::make_tuple("unknown", _tsst_not_defined);
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initSolver(TimeStepSolverType time_step_solver_type,
NonLinearSolverType) {
auto & dof_manager = this->getDOFManager();
/* ------------------------------------------------------------------------ */
// for alloc type of solvers
this->allocNodalField(this->displacement, spatial_dimension, "displacement");
this->allocNodalField(this->previous_displacement, spatial_dimension,
"previous_displacement");
this->allocNodalField(this->displacement_increment, spatial_dimension,
"displacement_increment");
this->allocNodalField(this->internal_force, spatial_dimension,
"internal_force");
this->allocNodalField(this->external_force, spatial_dimension,
"external_force");
this->allocNodalField(this->blocked_dofs, spatial_dimension, "blocked_dofs");
this->allocNodalField(this->current_position, spatial_dimension,
"current_position");
// initialize the current positions
this->current_position->copy(this->mesh.getNodes());
/* ------------------------------------------------------------------------ */
if (!dof_manager.hasDOFs("displacement")) {
dof_manager.registerDOFs("displacement", *this->displacement, _dst_nodal);
dof_manager.registerBlockedDOFs("displacement", *this->blocked_dofs);
dof_manager.registerDOFsIncrement("displacement",
*this->displacement_increment);
dof_manager.registerDOFsPrevious("displacement",
*this->previous_displacement);
}
/* ------------------------------------------------------------------------ */
// for dynamic
if (time_step_solver_type == _tsst_dynamic ||
time_step_solver_type == _tsst_dynamic_lumped) {
this->allocNodalField(this->velocity, spatial_dimension, "velocity");
this->allocNodalField(this->acceleration, spatial_dimension,
"acceleration");
if (!dof_manager.hasDOFsDerivatives("displacement", 1)) {
dof_manager.registerDOFsDerivative("displacement", 1, *this->velocity);
dof_manager.registerDOFsDerivative("displacement", 2,
*this->acceleration);
}
}
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the model,basically it pre-compute the shapes, shapes derivatives
* and jacobian
*/
void SolidMechanicsModel::initModel() {
/// \todo add the current position as a parameter to initShapeFunctions for
/// large deformation
getFEEngine().initShapeFunctions(_not_ghost);
getFEEngine().initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleResidual() {
AKANTU_DEBUG_IN();
/* ------------------------------------------------------------------------ */
// computes the internal forces
this->assembleInternalForces();
/* ------------------------------------------------------------------------ */
this->getDOFManager().assembleToResidual("displacement",
*this->external_force, 1);
this->getDOFManager().assembleToResidual("displacement",
*this->internal_force, 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleResidual(const ID & residual_part) {
AKANTU_DEBUG_IN();
if ("external" == residual_part) {
this->getDOFManager().assembleToResidual("displacement",
*this->external_force, 1);
AKANTU_DEBUG_OUT();
return;
}
if ("internal" == residual_part) {
this->getDOFManager().assembleToResidual("displacement",
*this->internal_force, 1);
AKANTU_DEBUG_OUT();
return;
}
AKANTU_CUSTOM_EXCEPTION(
debug::SolverCallbackResidualPartUnknown(residual_part));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MatrixType SolidMechanicsModel::getMatrixType(const ID & matrix_id) {
// \TODO check the materials to know what is the correct answer
if (matrix_id == "C")
return _mt_not_defined;
return _symmetric;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMatrix(const ID & matrix_id) {
if (matrix_id == "K") {
this->assembleStiffnessMatrix();
} else if (matrix_id == "M") {
this->assembleMass();
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleLumpedMatrix(const ID & matrix_id) {
if (matrix_id == "M") {
this->assembleMassLumped();
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::beforeSolveStep() {
for (auto & material : materials)
material->beforeSolveStep();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::afterSolveStep() {
for (auto & material : materials)
material->afterSolveStep();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::predictor() { ++displacement_release; }
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::corrector() { ++displacement_release; }
/* -------------------------------------------------------------------------- */
/**
* This function computes the internal forces as F_{int} = \int_{\Omega} N
* \sigma d\Omega@f$
*/
void SolidMechanicsModel::assembleInternalForces() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the internal forces");
this->internal_force->clear();
// compute the stresses of local elements
AKANTU_DEBUG_INFO("Compute local stresses");
for (auto & material : materials) {
material->computeAllStresses(_not_ghost);
}
/* ------------------------------------------------------------------------ */
/* Computation of the non local part */
if (this->non_local_manager)
this->non_local_manager->computeAllNonLocalStresses();
// communicate the stresses
AKANTU_DEBUG_INFO("Send data for residual assembly");
this->asynchronousSynchronize(_gst_smm_stress);
// assemble the forces due to local stresses
AKANTU_DEBUG_INFO("Assemble residual for local elements");
for (auto & material : materials) {
material->assembleInternalForces(_not_ghost);
}
// finalize communications
AKANTU_DEBUG_INFO("Wait distant stresses");
this->waitEndSynchronize(_gst_smm_stress);
// assemble the stresses due to ghost elements
AKANTU_DEBUG_INFO("Assemble residual for ghost elements");
for (auto & material : materials) {
material->assembleInternalForces(_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
// Check if materials need to recompute the matrix
bool need_to_reassemble = false;
for (auto & material : materials) {
need_to_reassemble |= material->hasStiffnessMatrixChanged();
}
if (need_to_reassemble) {
this->getDOFManager().getMatrix("K").clear();
// call compute stiffness matrix on each local elements
for (auto & material : materials) {
material->assembleStiffnessMatrix(_not_ghost);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateCurrentPosition() {
if (this->current_position_release == this->displacement_release)
return;
this->current_position->copy(this->mesh.getNodes());
auto cpos_it = this->current_position->begin(Model::spatial_dimension);
auto cpos_end = this->current_position->end(Model::spatial_dimension);
auto disp_it = this->displacement->begin(Model::spatial_dimension);
for (; cpos_it != cpos_end; ++cpos_it, ++disp_it) {
*cpos_it += *disp_it;
}
this->current_position_release = this->displacement_release;
}
/* -------------------------------------------------------------------------- */
const Array<Real> & SolidMechanicsModel::getCurrentPosition() {
this->updateCurrentPosition();
return *this->current_position;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateDataForNonLocalCriterion(
ElementTypeMapReal & criterion) {
const ID field_name = criterion.getName();
for (auto & material : materials) {
if (!material->isInternal<Real>(field_name, _ek_regular))
continue;
for (auto ghost_type : ghost_types) {
material->flattenInternal(field_name, criterion, ghost_type, _ek_regular);
}
}
}
/* -------------------------------------------------------------------------- */
/* Information */
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getStableTimeStep() {
AKANTU_DEBUG_IN();
Real min_dt = getStableTimeStep(_not_ghost);
/// reduction min over all processors
mesh.getCommunicator().allReduce(min_dt, SynchronizerOperation::_min);
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getStableTimeStep(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Real min_dt = std::numeric_limits<Real>::max();
this->updateCurrentPosition();
Element elem;
elem.ghost_type = ghost_type;
for (auto type :
mesh.elementTypes(Model::spatial_dimension, ghost_type, _ek_regular)) {
elem.type = type;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(type);
auto mat_indexes = material_index(type, ghost_type).begin();
auto mat_loc_num = material_local_numbering(type, ghost_type).begin();
Array<Real> X(0, nb_nodes_per_element * Model::spatial_dimension);
FEEngine::extractNodalToElementField(mesh, *current_position, X, type,
_not_ghost);
auto X_el = X.begin(Model::spatial_dimension, nb_nodes_per_element);
for (UInt el = 0; el < nb_element;
++el, ++X_el, ++mat_indexes, ++mat_loc_num) {
elem.element = *mat_loc_num;
Real el_h = getFEEngine().getElementInradius(*X_el, type);
Real el_c = this->materials[*mat_indexes]->getCelerity(elem);
Real el_dt = el_h / el_c;
min_dt = std::min(min_dt, el_dt);
}
}
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getKineticEnergy() {
AKANTU_DEBUG_IN();
Real ekin = 0.;
UInt nb_nodes = mesh.getNbNodes();
if (this->getDOFManager().hasLumpedMatrix("M")) {
auto m_it = this->mass->begin(Model::spatial_dimension);
auto m_end = this->mass->end(Model::spatial_dimension);
auto v_it = this->velocity->begin(Model::spatial_dimension);
for (UInt n = 0; m_it != m_end; ++n, ++m_it, ++v_it) {
const Vector<Real> & v = *v_it;
const Vector<Real> & m = *m_it;
Real mv2 = 0;
bool is_local_node = mesh.isLocalOrMasterNode(n);
// bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
bool count_node = is_local_node; // && is_not_pbc_slave_node;
if (count_node) {
for (UInt i = 0; i < Model::spatial_dimension; ++i) {
if (m(i) > std::numeric_limits<Real>::epsilon())
mv2 += v(i) * v(i) * m(i);
}
}
ekin += mv2;
}
} else if (this->getDOFManager().hasMatrix("M")) {
Array<Real> Mv(nb_nodes, Model::spatial_dimension);
this->getDOFManager().getMatrix("M").matVecMul(*this->velocity, Mv);
auto mv_it = Mv.begin(Model::spatial_dimension);
auto mv_end = Mv.end(Model::spatial_dimension);
auto v_it = this->velocity->begin(Model::spatial_dimension);
for (; mv_it != mv_end; ++mv_it, ++v_it) {
ekin += v_it->dot(*mv_it);
}
} else {
AKANTU_ERROR("No function called to assemble the mass matrix.");
}
mesh.getCommunicator().allReduce(ekin, SynchronizerOperation::_sum);
AKANTU_DEBUG_OUT();
return ekin * .5;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getKineticEnergy(const ElementType & type,
UInt index) {
AKANTU_DEBUG_IN();
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
Array<Real> vel_on_quad(nb_quadrature_points, Model::spatial_dimension);
Array<UInt> filter_element(1, 1, index);
getFEEngine().interpolateOnIntegrationPoints(*velocity, vel_on_quad,
Model::spatial_dimension, type,
_not_ghost, filter_element);
- auto vit =
- vel_on_quad.begin(Model::spatial_dimension);
+ auto vit = vel_on_quad.begin(Model::spatial_dimension);
auto vend = vel_on_quad.end(Model::spatial_dimension);
Vector<Real> rho_v2(nb_quadrature_points);
Real rho = materials[material_index(type)(index)]->getRho();
for (UInt q = 0; vit != vend; ++vit, ++q) {
rho_v2(q) = rho * vit->dot(*vit);
}
AKANTU_DEBUG_OUT();
return .5 * getFEEngine().integrate(rho_v2, type, index);
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getExternalWork() {
AKANTU_DEBUG_IN();
auto ext_force_it = external_force->begin(Model::spatial_dimension);
auto int_force_it = internal_force->begin(Model::spatial_dimension);
auto boun_it = blocked_dofs->begin(Model::spatial_dimension);
decltype(ext_force_it) incr_or_velo_it;
if (this->method == _static) {
incr_or_velo_it =
this->displacement_increment->begin(Model::spatial_dimension);
} else {
incr_or_velo_it = this->velocity->begin(Model::spatial_dimension);
}
Real work = 0.;
UInt nb_nodes = this->mesh.getNbNodes();
for (UInt n = 0; n < nb_nodes;
++n, ++ext_force_it, ++int_force_it, ++boun_it, ++incr_or_velo_it) {
const auto & int_force = *int_force_it;
const auto & ext_force = *ext_force_it;
const auto & boun = *boun_it;
const auto & incr_or_velo = *incr_or_velo_it;
bool is_local_node = this->mesh.isLocalOrMasterNode(n);
// bool is_not_pbc_slave_node = !this->isPBCSlaveNode(n);
bool count_node = is_local_node; // && is_not_pbc_slave_node;
if (count_node) {
for (UInt i = 0; i < Model::spatial_dimension; ++i) {
if (boun(i))
work -= int_force(i) * incr_or_velo(i);
else
work += ext_force(i) * incr_or_velo(i);
}
}
}
mesh.getCommunicator().allReduce(work, SynchronizerOperation::_sum);
if (this->method != _static)
work *= this->getTimeStep();
AKANTU_DEBUG_OUT();
return work;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getEnergy(const std::string & energy_id) {
AKANTU_DEBUG_IN();
if (energy_id == "kinetic") {
return getKineticEnergy();
} else if (energy_id == "external work") {
return getExternalWork();
}
Real energy = 0.;
for (auto & material : materials)
energy += material->getEnergy(energy_id);
/// reduction sum over all processors
mesh.getCommunicator().allReduce(energy, SynchronizerOperation::_sum);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getEnergy(const std::string & energy_id,
const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
if (energy_id == "kinetic") {
return getKineticEnergy(type, index);
}
UInt mat_index = this->material_index(type, _not_ghost)(index);
UInt mat_loc_num = this->material_local_numbering(type, _not_ghost)(index);
Real energy =
this->materials[mat_index]->getEnergy(energy_id, type, mat_loc_num);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
this->material_index.initialize(mesh, _element_kind = _ek_not_defined,
_with_nb_element = true,
_default_value = UInt(-1));
this->material_local_numbering.initialize(
mesh, _element_kind = _ek_not_defined, _with_nb_element = true,
_default_value = UInt(-1));
ElementTypeMapArray<UInt> filter("new_element_filter", this->getID(),
this->getMemoryID());
for (auto & elem : element_list) {
if (!filter.exists(elem.type, elem.ghost_type))
filter.alloc(0, 1, elem.type, elem.ghost_type);
filter(elem.type, elem.ghost_type).push_back(elem.element);
}
this->assignMaterialToElements(&filter);
for (auto & material : materials)
material->onElementsAdded(element_list, event);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onElementsRemoved(
const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event) {
for (auto & material : materials) {
material->onElementsRemoved(element_list, new_numbering, event);
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event) {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
if (displacement) {
displacement->resize(nb_nodes, 0.);
++displacement_release;
}
if (mass)
mass->resize(nb_nodes, 0.);
if (velocity)
velocity->resize(nb_nodes, 0.);
if (acceleration)
acceleration->resize(nb_nodes, 0.);
if (external_force)
external_force->resize(nb_nodes, 0.);
if (internal_force)
internal_force->resize(nb_nodes, 0.);
if (blocked_dofs)
blocked_dofs->resize(nb_nodes, 0.);
if (current_position)
current_position->resize(nb_nodes, 0.);
if (previous_displacement)
previous_displacement->resize(nb_nodes, 0.);
if (displacement_increment)
displacement_increment->resize(nb_nodes, 0.);
for (auto & material : materials) {
material->onNodesAdded(nodes_list, event);
}
need_to_reassemble_lumped_mass = true;
need_to_reassemble_mass = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onNodesRemoved(const Array<UInt> & /*element_list*/,
const Array<UInt> & new_numbering,
const RemovedNodesEvent & /*event*/) {
if (displacement) {
mesh.removeNodesFromArray(*displacement, new_numbering);
++displacement_release;
}
if (mass)
mesh.removeNodesFromArray(*mass, new_numbering);
if (velocity)
mesh.removeNodesFromArray(*velocity, new_numbering);
if (acceleration)
mesh.removeNodesFromArray(*acceleration, new_numbering);
if (internal_force)
mesh.removeNodesFromArray(*internal_force, new_numbering);
if (external_force)
mesh.removeNodesFromArray(*external_force, new_numbering);
if (blocked_dofs)
mesh.removeNodesFromArray(*blocked_dofs, new_numbering);
// if (increment_acceleration)
// mesh.removeNodesFromArray(*increment_acceleration, new_numbering);
if (displacement_increment)
mesh.removeNodesFromArray(*displacement_increment, new_numbering);
if (previous_displacement)
mesh.removeNodesFromArray(*previous_displacement, new_numbering);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::printself(std::ostream & stream, int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "Solid Mechanics Model [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + spatial dimension : " << Model::spatial_dimension
<< std::endl;
stream << space << " + fem [" << std::endl;
getFEEngine().printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + nodals information [" << std::endl;
displacement->printself(stream, indent + 2);
if (velocity)
velocity->printself(stream, indent + 2);
if (acceleration)
acceleration->printself(stream, indent + 2);
if (mass)
mass->printself(stream, indent + 2);
external_force->printself(stream, indent + 2);
internal_force->printself(stream, indent + 2);
blocked_dofs->printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + material information [" << std::endl;
material_index.printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + materials [" << std::endl;
for (auto & material : materials) {
material->printself(stream, indent + 1);
}
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initializeNonLocal() {
this->non_local_manager->synchronize(*this, _gst_material_id);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::insertIntegrationPointsInNeighborhoods(
const GhostType & ghost_type) {
for (auto & mat : materials) {
MaterialNonLocalInterface * mat_non_local;
if ((mat_non_local =
dynamic_cast<MaterialNonLocalInterface *>(mat.get())) == nullptr)
continue;
ElementTypeMapArray<Real> quadrature_points_coordinates(
"quadrature_points_coordinates_tmp_nl", this->id, this->memory_id);
quadrature_points_coordinates.initialize(this->getFEEngine(),
_nb_component = spatial_dimension,
_ghost_type = ghost_type);
for (auto & type : quadrature_points_coordinates.elementTypes(
Model::spatial_dimension, ghost_type)) {
this->getFEEngine().computeIntegrationPointsCoordinates(
quadrature_points_coordinates(type, ghost_type), type, ghost_type);
}
mat_non_local->initMaterialNonLocal();
mat_non_local->insertIntegrationPointsInNeighborhoods(
ghost_type, quadrature_points_coordinates);
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::computeNonLocalStresses(
const GhostType & ghost_type) {
for (auto & mat : materials) {
if (dynamic_cast<MaterialNonLocalInterface *>(mat.get()) == nullptr)
continue;
auto & mat_non_local = dynamic_cast<MaterialNonLocalInterface &>(*mat);
mat_non_local.computeNonLocalStresses(ghost_type);
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateLocalInternal(
ElementTypeMapReal & internal_flat, const GhostType & ghost_type,
const ElementKind & kind) {
const ID field_name = internal_flat.getName();
for (auto & material : materials) {
if (material->isInternal<Real>(field_name, kind))
material->flattenInternal(field_name, internal_flat, ghost_type, kind);
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateNonLocalInternal(
ElementTypeMapReal & internal_flat, const GhostType & ghost_type,
const ElementKind & kind) {
const ID field_name = internal_flat.getName();
for (auto & mat : materials) {
if (dynamic_cast<MaterialNonLocalInterface *>(mat.get()) == nullptr)
continue;
auto & mat_non_local = dynamic_cast<MaterialNonLocalInterface &>(*mat);
mat_non_local.updateNonLocalInternals(internal_flat, field_name, ghost_type,
kind);
}
}
/* -------------------------------------------------------------------------- */
FEEngine & SolidMechanicsModel::getFEEngineBoundary(const ID & name) {
return dynamic_cast<FEEngine &>(
getFEEngineClassBoundary<MyFEEngineType>(name));
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::splitElementByMaterial(
const Array<Element> & elements,
std::vector<Array<Element>> & elements_per_mat) const {
ElementType current_element_type = _not_defined;
GhostType current_ghost_type = _casper;
const Array<UInt> * mat_indexes = nullptr;
const Array<UInt> * mat_loc_num = nullptr;
for (const auto & el : elements) {
if (el.type != current_element_type ||
el.ghost_type != current_ghost_type) {
current_element_type = el.type;
current_ghost_type = el.ghost_type;
mat_indexes = &(this->material_index(el.type, el.ghost_type));
mat_loc_num = &(this->material_local_numbering(el.type, el.ghost_type));
}
Element mat_el = el;
mat_el.element = (*mat_loc_num)(el.element);
elements_per_mat[(*mat_indexes)(el.element)].push_back(mat_el);
}
}
/* -------------------------------------------------------------------------- */
UInt SolidMechanicsModel::getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
UInt nb_nodes_per_element = 0;
for (const Element & el : elements) {
nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
}
switch (tag) {
case _gst_material_id: {
size += elements.size() * sizeof(UInt);
break;
}
case _gst_smm_mass: {
size += nb_nodes_per_element * sizeof(Real) *
Model::spatial_dimension; // mass vector
break;
}
case _gst_smm_for_gradu: {
size += nb_nodes_per_element * Model::spatial_dimension *
sizeof(Real); // displacement
break;
}
case _gst_smm_boundary: {
// force, displacement, boundary
size += nb_nodes_per_element * Model::spatial_dimension *
(2 * sizeof(Real) + sizeof(bool));
break;
}
case _gst_for_dump: {
// displacement, velocity, acceleration, residual, force
size += nb_nodes_per_element * Model::spatial_dimension * sizeof(Real) * 5;
break;
}
default: {}
}
if (tag != _gst_material_id) {
splitByMaterial(elements, [&](auto && mat, auto && elements) {
size += mat.getNbData(elements, tag);
});
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
switch (tag) {
case _gst_material_id: {
this->packElementalDataHelper(material_index, buffer, elements, false,
getFEEngine());
break;
}
case _gst_smm_mass: {
packNodalDataHelper(*mass, buffer, elements, mesh);
break;
}
case _gst_smm_for_gradu: {
packNodalDataHelper(*displacement, buffer, elements, mesh);
break;
}
case _gst_for_dump: {
packNodalDataHelper(*displacement, buffer, elements, mesh);
packNodalDataHelper(*velocity, buffer, elements, mesh);
packNodalDataHelper(*acceleration, buffer, elements, mesh);
packNodalDataHelper(*internal_force, buffer, elements, mesh);
packNodalDataHelper(*external_force, buffer, elements, mesh);
break;
}
case _gst_smm_boundary: {
packNodalDataHelper(*external_force, buffer, elements, mesh);
packNodalDataHelper(*velocity, buffer, elements, mesh);
packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
break;
}
default: {}
}
if (tag != _gst_material_id) {
splitByMaterial(elements, [&](auto && mat, auto && elements) {
mat.packData(buffer, elements, tag);
});
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
switch (tag) {
case _gst_material_id: {
for (auto && element : elements) {
UInt recv_mat_index;
buffer >> recv_mat_index;
UInt & mat_index = material_index(element);
if (mat_index != UInt(-1))
continue;
// add ghosts element to the correct material
mat_index = recv_mat_index;
UInt index = materials[mat_index]->addElement(element);
material_local_numbering(element) = index;
}
break;
}
case _gst_smm_mass: {
unpackNodalDataHelper(*mass, buffer, elements, mesh);
break;
}
case _gst_smm_for_gradu: {
unpackNodalDataHelper(*displacement, buffer, elements, mesh);
break;
}
case _gst_for_dump: {
unpackNodalDataHelper(*displacement, buffer, elements, mesh);
unpackNodalDataHelper(*velocity, buffer, elements, mesh);
unpackNodalDataHelper(*acceleration, buffer, elements, mesh);
unpackNodalDataHelper(*internal_force, buffer, elements, mesh);
unpackNodalDataHelper(*external_force, buffer, elements, mesh);
break;
}
case _gst_smm_boundary: {
unpackNodalDataHelper(*external_force, buffer, elements, mesh);
unpackNodalDataHelper(*velocity, buffer, elements, mesh);
unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
break;
}
default: {}
}
if (tag != _gst_material_id) {
splitByMaterial(elements, [&](auto && mat, auto && elements) {
mat.unpackData(buffer, elements, tag);
});
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
UInt SolidMechanicsModel::getNbData(const Array<UInt> & dofs,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
// UInt nb_nodes = mesh.getNbNodes();
switch (tag) {
case _gst_smm_uv: {
size += sizeof(Real) * Model::spatial_dimension * 2;
break;
}
case _gst_smm_res: {
size += sizeof(Real) * Model::spatial_dimension;
break;
}
case _gst_smm_mass: {
size += sizeof(Real) * Model::spatial_dimension;
break;
}
case _gst_for_dump: {
size += sizeof(Real) * Model::spatial_dimension * 5;
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
AKANTU_DEBUG_OUT();
return size * dofs.size();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
const SynchronizationTag & tag) const {
AKANTU_DEBUG_IN();
switch (tag) {
case _gst_smm_uv: {
packDOFDataHelper(*displacement, buffer, dofs);
packDOFDataHelper(*velocity, buffer, dofs);
break;
}
case _gst_smm_res: {
packDOFDataHelper(*internal_force, buffer, dofs);
break;
}
case _gst_smm_mass: {
packDOFDataHelper(*mass, buffer, dofs);
break;
}
case _gst_for_dump: {
packDOFDataHelper(*displacement, buffer, dofs);
packDOFDataHelper(*velocity, buffer, dofs);
packDOFDataHelper(*acceleration, buffer, dofs);
packDOFDataHelper(*internal_force, buffer, dofs);
packDOFDataHelper(*external_force, buffer, dofs);
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
const Array<UInt> & dofs,
const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
switch (tag) {
case _gst_smm_uv: {
unpackDOFDataHelper(*displacement, buffer, dofs);
unpackDOFDataHelper(*velocity, buffer, dofs);
break;
}
case _gst_smm_res: {
unpackDOFDataHelper(*internal_force, buffer, dofs);
break;
}
case _gst_smm_mass: {
unpackDOFDataHelper(*mass, buffer, dofs);
break;
}
case _gst_for_dump: {
unpackDOFDataHelper(*displacement, buffer, dofs);
unpackDOFDataHelper(*velocity, buffer, dofs);
unpackDOFDataHelper(*acceleration, buffer, dofs);
unpackDOFDataHelper(*internal_force, buffer, dofs);
unpackDOFDataHelper(*external_force, buffer, dofs);
break;
}
- default: {
- AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
- }
+ default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index f42929e96..57e489704 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,560 +1,559 @@
/**
* @file solid_mechanics_model.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Tue Jan 19 2016
*
* @brief Model of Solid Mechanics
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "boundary_condition.hh"
#include "data_accessor.hh"
#include "fe_engine.hh"
#include "model.hh"
#include "non_local_manager.hh"
#include "solid_mechanics_model_event_handler.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_HH__
namespace akantu {
class Material;
class MaterialSelector;
class DumperIOHelper;
class NonLocalManager;
template <ElementKind kind, class IntegrationOrderFunctor>
class IntegratorGauss;
template <ElementKind kind> class ShapeLagrange;
} // namespace akantu
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
class SolidMechanicsModel
: public Model,
public DataAccessor<Element>,
public DataAccessor<UInt>,
public BoundaryCondition<SolidMechanicsModel>,
public NonLocalManagerCallback,
public EventHandlerManager<SolidMechanicsModelEventHandler> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
class NewMaterialElementsEvent : public NewElementsEvent {
public:
AKANTU_GET_MACRO_NOT_CONST(MaterialList, material, Array<UInt> &);
AKANTU_GET_MACRO(MaterialList, material, const Array<UInt> &);
protected:
Array<UInt> material;
};
using MyFEEngineType = FEEngineTemplate<IntegratorGauss, ShapeLagrange>;
protected:
using EventManager = EventHandlerManager<SolidMechanicsModelEventHandler>;
public:
SolidMechanicsModel(
Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const ID & id = "solid_mechanics_model", const MemoryID & memory_id = 0,
const ModelType model_type = ModelType::_solid_mechanics_model);
~SolidMechanicsModel() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// initialize completely the model
void initFullImpl(
const ModelOptions & options = SolidMechanicsModelOptions()) override;
/// initialize all internal arrays for materials
virtual void initMaterials();
/// initialize the model
void initModel() override;
/// function to print the containt of the class
void printself(std::ostream & stream, int indent = 0) const override;
/// get some default values for derived classes
std::tuple<ID, TimeStepSolverType>
getDefaultSolverID(const AnalysisMethod & method) override;
/* ------------------------------------------------------------------------ */
/* Solver interface */
/* ------------------------------------------------------------------------ */
public:
/// assembles the stiffness matrix,
virtual void assembleStiffnessMatrix();
/// assembles the internal forces in the array internal_forces
virtual void assembleInternalForces();
protected:
/// callback for the solver, this adds f_{ext} - f_{int} to the residual
void assembleResidual() override;
/// callback for the solver, this adds f_{ext} or f_{int} to the residual
void assembleResidual(const ID & residual_part) override;
bool canSplitResidual() override { return true; }
/// get the type of matrix needed
MatrixType getMatrixType(const ID & matrix_id) override;
/// callback for the solver, this assembles different matrices
void assembleMatrix(const ID & matrix_id) override;
/// callback for the solver, this assembles the stiffness matrix
void assembleLumpedMatrix(const ID & matrix_id) override;
/// callback for the solver, this is called at beginning of solve
void predictor() override;
/// callback for the solver, this is called at end of solve
void corrector() override;
/// callback for the solver, this is called at beginning of solve
void beforeSolveStep() override;
/// callback for the solver, this is called at end of solve
void afterSolveStep() override;
/// Callback for the model to instantiate the matricees when needed
void initSolver(TimeStepSolverType time_step_solver_type,
NonLinearSolverType non_linear_solver_type) override;
protected:
/* ------------------------------------------------------------------------ */
TimeStepSolverType getDefaultSolverType() const override;
/* ------------------------------------------------------------------------ */
ModelSolverOptions
getDefaultSolverOptions(const TimeStepSolverType & type) const override;
public:
bool isDefaultSolverExplicit() {
return method == _explicit_lumped_mass ||
method == _explicit_consistent_mass;
}
protected:
/// update the current position vector
void updateCurrentPosition();
/* ------------------------------------------------------------------------ */
/* Materials (solid_mechanics_model_material.cc) */
/* ------------------------------------------------------------------------ */
public:
/// register an empty material of a given type
Material & registerNewMaterial(const ID & mat_name, const ID & mat_type,
const ID & opt_param);
/// reassigns materials depending on the material selector
virtual void reassignMaterial();
/// apply a constant eigen_grad_u on all quadrature points of a given material
virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
const ID & material_name,
const GhostType ghost_type = _not_ghost);
protected:
/// register a material in the dynamic database
Material & registerNewMaterial(const ParserSection & mat_section);
/// read the material files to instantiate all the materials
void instantiateMaterials();
/// set the element_id_by_material and add the elements to the good materials
virtual void
assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = nullptr);
/* ------------------------------------------------------------------------ */
/* Mass (solid_mechanics_model_mass.cc) */
/* ------------------------------------------------------------------------ */
public:
/// assemble the lumped mass matrix
void assembleMassLumped();
/// assemble the mass matrix for consistent mass resolutions
void assembleMass();
protected:
/// assemble the lumped mass matrix for local and ghost elements
void assembleMassLumped(GhostType ghost_type);
/// assemble the mass matrix for either _ghost or _not_ghost elements
void assembleMass(GhostType ghost_type);
/// fill a vector of rho
void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type);
/// compute the kinetic energy
Real getKineticEnergy();
Real getKineticEnergy(const ElementType & type, UInt index);
/// compute the external work (for impose displacement, the velocity should be
/// given too)
Real getExternalWork();
/* ------------------------------------------------------------------------ */
/* NonLocalManager inherited members */
/* ------------------------------------------------------------------------ */
protected:
void initializeNonLocal() override;
void updateDataForNonLocalCriterion(ElementTypeMapReal & criterion) override;
void computeNonLocalStresses(const GhostType & ghost_type) override;
void
insertIntegrationPointsInNeighborhoods(const GhostType & ghost_type) override;
/// update the values of the non local internal
void updateLocalInternal(ElementTypeMapReal & internal_flat,
const GhostType & ghost_type,
const ElementKind & kind) override;
/// copy the results of the averaging in the materials
void updateNonLocalInternal(ElementTypeMapReal & internal_flat,
const GhostType & ghost_type,
const ElementKind & kind) override;
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const override;
void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
const SynchronizationTag & tag) const override;
void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
const SynchronizationTag & tag) override;
UInt getNbData(const Array<UInt> & dofs,
const SynchronizationTag & tag) const override;
void packData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
const SynchronizationTag & tag) const override;
void unpackData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
const SynchronizationTag & tag) override;
protected:
void
splitElementByMaterial(const Array<Element> & elements,
std::vector<Array<Element>> & elements_per_mat) const;
template <typename Operation>
void splitByMaterial(const Array<Element> & elements, Operation && op) const;
/* ------------------------------------------------------------------------ */
/* Mesh Event Handler inherited members */
/* ------------------------------------------------------------------------ */
protected:
void onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event) override;
void onNodesRemoved(const Array<UInt> & element_list,
const Array<UInt> & new_numbering,
const RemovedNodesEvent & event) override;
void onElementsAdded(const Array<Element> & nodes_list,
const NewElementsEvent & event) override;
void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event) override;
void onElementsChanged(const Array<Element> &, const Array<Element> &,
const ElementTypeMapArray<UInt> &,
const ChangedElementsEvent &) override{};
/* ------------------------------------------------------------------------ */
/* Dumpable interface (kept for convenience) and dumper relative functions */
/* ------------------------------------------------------------------------ */
public:
virtual void onDump();
//! decide wether a field is a material internal or not
bool isInternal(const std::string & field_name,
const ElementKind & element_kind);
#ifndef SWIG
//! give the amount of data per element
virtual ElementTypeMap<UInt>
getInternalDataPerElem(const std::string & field_name,
const ElementKind & kind);
//! flatten a given material internal field
ElementTypeMapArray<Real> &
flattenInternal(const std::string & field_name, const ElementKind & kind,
const GhostType ghost_type = _not_ghost);
//! flatten all the registered material internals
void flattenAllRegisteredInternals(const ElementKind & kind);
#endif
dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) override;
dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) override;
dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & kind) override;
virtual void dump(const std::string & dumper_name);
virtual void dump(const std::string & dumper_name, UInt step);
virtual void dump(const std::string & dumper_name, Real time, UInt step);
void dump() override;
virtual void dump(UInt step);
virtual void dump(Real time, UInt step);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, Model::spatial_dimension, UInt);
/// set the value of the time step
void setTimeStep(Real time_step, const ID & solver_id = "") override;
/// get the value of the conversion from forces/ mass to acceleration
AKANTU_GET_MACRO(F_M2A, f_m2a, Real);
/// set the value of the conversion from forces/ mass to acceleration
AKANTU_SET_MACRO(F_M2A, f_m2a, Real);
/// get the SolidMechanicsModel::displacement vector
AKANTU_GET_MACRO(Displacement, *displacement, Array<Real> &);
/// get the SolidMechanicsModel::previous_displacement vector
AKANTU_GET_MACRO(PreviousDisplacement, *previous_displacement, Array<Real> &);
/// get the SolidMechanicsModel::current_position vector \warn only consistent
/// after a call to SolidMechanicsModel::updateCurrentPosition
const Array<Real> & getCurrentPosition();
/// get the SolidMechanicsModel::increment vector \warn only consistent if
/// SolidMechanicsModel::setIncrementFlagOn has been called before
AKANTU_GET_MACRO(Increment, *displacement_increment, Array<Real> &);
/// get the lumped SolidMechanicsModel::mass vector
AKANTU_GET_MACRO(Mass, *mass, Array<Real> &);
/// get the SolidMechanicsModel::velocity vector
AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
/// get the SolidMechanicsModel::acceleration vector, updated by
/// SolidMechanicsModel::updateAcceleration
AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
/// get the SolidMechanicsModel::force vector (external forces)
AKANTU_GET_MACRO(Force, *external_force, Array<Real> &);
/// get the SolidMechanicsModel::internal_force vector (internal forces)
AKANTU_GET_MACRO(InternalForce, *internal_force, Array<Real> &);
/// get the SolidMechanicsModel::blocked_dofs vector
AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
/// get the value of the SolidMechanicsModel::increment_flag
AKANTU_GET_MACRO(IncrementFlag, increment_flag, bool);
/// get a particular material (by material index)
inline Material & getMaterial(UInt mat_index);
/// get a particular material (by material index)
inline const Material & getMaterial(UInt mat_index) const;
/// get a particular material (by material name)
inline Material & getMaterial(const std::string & name);
/// get a particular material (by material name)
inline const Material & getMaterial(const std::string & name) const;
/// get a particular material id from is name
inline UInt getMaterialIndex(const std::string & name) const;
/// give the number of materials
inline UInt getNbMaterials() const { return materials.size(); }
/// give the material internal index from its id
Int getInternalIndexFromID(const ID & id) const;
/// compute the stable time step
Real getStableTimeStep();
/// get the energies
Real getEnergy(const std::string & energy_id);
/// compute the energy for energy
Real getEnergy(const std::string & energy_id, const ElementType & type,
UInt index);
AKANTU_GET_MACRO(MaterialByElement, material_index,
const ElementTypeMapArray<UInt> &);
/// vectors containing local material element index for each global element
/// index
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialByElement, material_index,
UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialByElement, material_index, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialLocalNumbering,
material_local_numbering, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialLocalNumbering,
material_local_numbering, UInt);
AKANTU_GET_MACRO_NOT_CONST(MaterialSelector, *material_selector,
MaterialSelector &);
AKANTU_SET_MACRO(MaterialSelector, material_selector,
std::shared_ptr<MaterialSelector>);
/// Access the non_local_manager interface
AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
/// get the FEEngine object to integrate or interpolate on the boundary
FEEngine & getFEEngineBoundary(const ID & name = "") override;
protected:
friend class Material;
protected:
-
/// compute the stable time step
Real getStableTimeStep(const GhostType & ghost_type);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// conversion coefficient form force/mass to acceleration
Real f_m2a;
/// displacements array
Array<Real> * displacement;
UInt displacement_release{0};
/// displacements array at the previous time step (used in finite deformation)
Array<Real> * previous_displacement{nullptr};
/// increment of displacement
Array<Real> * displacement_increment{nullptr};
/// lumped mass array
Array<Real> * mass{nullptr};
/// Check if materials need to recompute the mass array
bool need_to_reassemble_lumped_mass{true};
/// Check if materials need to recompute the mass matrix
bool need_to_reassemble_mass{true};
/// velocities array
Array<Real> * velocity{nullptr};
/// accelerations array
Array<Real> * acceleration{nullptr};
/// accelerations array
// Array<Real> * increment_acceleration;
/// external forces array
Array<Real> * external_force{nullptr};
/// internal forces array
Array<Real> * internal_force{nullptr};
/// array specifing if a degree of freedom is blocked or not
Array<bool> * blocked_dofs{nullptr};
/// array of current position used during update residual
Array<Real> * current_position{nullptr};
UInt current_position_release{0};
/// Arrays containing the material index for each element
ElementTypeMapArray<UInt> material_index;
/// Arrays containing the position in the element filter of the material
/// (material's local numbering)
ElementTypeMapArray<UInt> material_local_numbering;
/// list of used materials
std::vector<std::unique_ptr<Material>> materials;
/// mapping between material name and material internal id
std::map<std::string, UInt> materials_names_to_id;
/// class defining of to choose a material
std::shared_ptr<MaterialSelector> material_selector;
/// flag defining if the increment must be computed or not
bool increment_flag;
/// tells if the material are instantiated
bool are_materials_instantiated;
using flatten_internal_map = std::map<std::pair<std::string, ElementKind>,
ElementTypeMapArray<Real> *>;
/// map a registered internals to be flattened for dump purposes
flatten_internal_map registered_internals;
/// non local manager
std::unique_ptr<NonLocalManager> non_local_manager;
};
/* -------------------------------------------------------------------------- */
namespace BC {
namespace Neumann {
using FromStress = FromHigherDim;
using FromTraction = FromSameDim;
} // namespace Neumann
} // namespace BC
} // namespace akantu
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material.hh"
#include "parser.hh"
#include "solid_mechanics_model_inline_impl.cc"
#include "solid_mechanics_model_tmpl.hh"
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
index acf03716c..63396a1b8 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
@@ -1,615 +1,611 @@
/**
* @file fragment_manager.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Jan 23 2014
* @date last modification: Mon Dec 14 2015
*
* @brief Group manager to handle fragments
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fragment_manager.hh"
#include "aka_iterators.hh"
+#include "communicator.hh"
#include "material_cohesive.hh"
#include "mesh_iterators.hh"
#include "solid_mechanics_model_cohesive.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <functional>
#include <numeric>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
FragmentManager::FragmentManager(SolidMechanicsModelCohesive & model,
bool dump_data, const ID & id,
const MemoryID & memory_id)
: GroupManager(model.getMesh(), id, memory_id), model(model),
mass_center(0, model.getSpatialDimension(), "mass_center"),
mass(0, model.getSpatialDimension(), "mass"),
velocity(0, model.getSpatialDimension(), "velocity"),
inertia_moments(0, model.getSpatialDimension(), "inertia_moments"),
principal_directions(
0, model.getSpatialDimension() * model.getSpatialDimension(),
"principal_directions"),
quad_coordinates("quad_coordinates", id),
mass_density("mass_density", id),
nb_elements_per_fragment(0, 1, "nb_elements_per_fragment"),
dump_data(dump_data) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
/// compute quadrature points' coordinates
quad_coordinates.initialize(mesh, _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension,
_ghost_type = _not_ghost);
// mesh.initElementTypeMapArray(quad_coordinates, spatial_dimension,
// spatial_dimension, _not_ghost);
model.getFEEngine().interpolateOnIntegrationPoints(model.getMesh().getNodes(),
quad_coordinates);
/// store mass density per quadrature point
mass_density.initialize(mesh, _spatial_dimension = spatial_dimension,
_ghost_type = _not_ghost);
// mesh.initElementTypeMapArray(mass_density, 1, spatial_dimension,
// _not_ghost);
storeMassDensityPerIntegrationPoint();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
class CohesiveElementFilter : public GroupManager::ClusteringFilter {
public:
CohesiveElementFilter(const SolidMechanicsModelCohesive & model,
const Real max_damage = 1.)
: model(model), is_unbroken(max_damage) {}
bool operator()(const Element & el) const override {
if (Mesh::getKind(el.type) == _ek_regular)
return true;
const Array<UInt> & mat_indexes =
model.getMaterialByElement(el.type, el.ghost_type);
const Array<UInt> & mat_loc_num =
model.getMaterialLocalNumbering(el.type, el.ghost_type);
const auto & mat = static_cast<const MaterialCohesive &>(
model.getMaterial(mat_indexes(el.element)));
UInt el_index = mat_loc_num(el.element);
UInt nb_quad_per_element =
model.getFEEngine("CohesiveFEEngine")
.getNbIntegrationPoints(el.type, el.ghost_type);
const Array<Real> & damage_array = mat.getDamage(el.type, el.ghost_type);
AKANTU_DEBUG_ASSERT(nb_quad_per_element * el_index < damage_array.size(),
"This quadrature point is out of range");
const Real * element_damage =
damage_array.storage() + nb_quad_per_element * el_index;
UInt unbroken_quads = std::count_if(
element_damage, element_damage + nb_quad_per_element, is_unbroken);
if (unbroken_quads > 0)
return true;
return false;
}
private:
struct IsUnbrokenFunctor {
IsUnbrokenFunctor(const Real & max_damage) : max_damage(max_damage) {}
bool operator()(const Real & x) { return x < max_damage; }
const Real max_damage;
};
const SolidMechanicsModelCohesive & model;
const IsUnbrokenFunctor is_unbroken;
};
/* -------------------------------------------------------------------------- */
void FragmentManager::buildFragments(Real damage_limit) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
ElementSynchronizer * cohesive_synchronizer =
const_cast<ElementSynchronizer *>(model.getCohesiveSynchronizer());
if (cohesive_synchronizer) {
cohesive_synchronizer->computeBufferSize(model, _gst_smmc_damage);
cohesive_synchronizer->asynchronousSynchronize(model, _gst_smmc_damage);
cohesive_synchronizer->waitEndSynchronize(model, _gst_smmc_damage);
}
#endif
auto & mesh_facets = const_cast<Mesh &>(mesh.getMeshFacets());
UInt spatial_dimension = model.getSpatialDimension();
std::string fragment_prefix("fragment");
/// generate fragments
global_nb_fragment =
createClusters(spatial_dimension, mesh_facets, fragment_prefix,
CohesiveElementFilter(model, damage_limit));
nb_fragment = getNbElementGroups(spatial_dimension);
fragment_index.resize(nb_fragment);
UInt * fragment_index_it = fragment_index.storage();
/// loop over fragments
for (const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++fragment_index_it) {
/// get fragment index
std::string fragment_index_string =
it->first.substr(fragment_prefix.size() + 1);
std::stringstream sstr(fragment_index_string.c_str());
sstr >> *fragment_index_it;
AKANTU_DEBUG_ASSERT(!sstr.fail(), "fragment_index is not an integer");
}
/// compute fragments' mass
computeMass();
if (dump_data) {
createDumpDataArray(fragment_index, "fragments", true);
createDumpDataArray(mass, "fragments mass");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeMass() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
/// create a unit field per quadrature point, since to compute mass
/// it's neccessary to integrate only density
ElementTypeMapArray<Real> unit_field("unit_field", id);
unit_field.initialize(model.getFEEngine(), _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension,
_ghost_type = _not_ghost, _default_value = 1.);
// mesh.initElementTypeMapArray(unit_field, spatial_dimension,
// spatial_dimension,
// _not_ghost);
// ElementTypeMapArray<Real>::type_iterator it =
// unit_field.firstType(spatial_dimension, _not_ghost, _ek_regular);
// ElementTypeMapArray<Real>::type_iterator end =
// unit_field.lastType(spatial_dimension, _not_ghost, _ek_regular);
// for (; it != end; ++it) {
// ElementType type = *it;
// Array<Real> & field_array = unit_field(type);
// UInt nb_element = mesh.getNbElement(type);
// UInt nb_quad_per_element =
// model.getFEEngine().getNbIntegrationPoints(type);
// field_array.resize(nb_element * nb_quad_per_element);
// field_array.set(1.);
// }
integrateFieldOnFragments(unit_field, mass);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeCenterOfMass() {
AKANTU_DEBUG_IN();
/// integrate position multiplied by density
integrateFieldOnFragments(quad_coordinates, mass_center);
/// divide it by the fragments' mass
Real * mass_storage = mass.storage();
Real * mass_center_storage = mass_center.storage();
UInt total_components = mass_center.size() * mass_center.getNbComponent();
for (UInt i = 0; i < total_components; ++i)
mass_center_storage[i] /= mass_storage[i];
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeVelocity() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
/// compute velocity per quadrature point
ElementTypeMapArray<Real> velocity_field("velocity_field", id);
velocity_field.initialize(
model.getFEEngine(), _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension, _ghost_type = _not_ghost);
// mesh.initElementTypeMapArray(velocity_field, spatial_dimension,
// spatial_dimension, _not_ghost);
model.getFEEngine().interpolateOnIntegrationPoints(model.getVelocity(),
velocity_field);
/// integrate on fragments
integrateFieldOnFragments(velocity_field, velocity);
/// divide it by the fragments' mass
Real * mass_storage = mass.storage();
Real * velocity_storage = velocity.storage();
UInt total_components = velocity.size() * velocity.getNbComponent();
for (UInt i = 0; i < total_components; ++i)
velocity_storage[i] /= mass_storage[i];
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Given the distance @f$ \mathbf{r} @f$ between a quadrature point
* and its center of mass, the moment of inertia is computed as \f[
* I_\mathrm{CM} = \mathrm{tr}(\mathbf{r}\mathbf{r}^\mathrm{T})
* \mathbf{I} - \mathbf{r}\mathbf{r}^\mathrm{T} \f] for more
* information check Wikipedia
* (http://en.wikipedia.org/wiki/Moment_of_inertia#Identities_for_a_skew-symmetric_matrix)
*
*/
void FragmentManager::computeInertiaMoments() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
computeCenterOfMass();
/// compute local coordinates products with respect to the center of match
ElementTypeMapArray<Real> moments_coords("moments_coords", id);
moments_coords.initialize(model.getFEEngine(),
_nb_component =
spatial_dimension * spatial_dimension,
_spatial_dimension = spatial_dimension,
_ghost_type = _not_ghost, _default_value = 1.);
// mesh.initElementTypeMapArray(moments_coords,
// spatial_dimension * spatial_dimension,
// spatial_dimension, _not_ghost);
// /// resize the by element type
// ElementTypeMapArray<Real>::type_iterator it =
// moments_coords.firstType(spatial_dimension, _not_ghost, _ek_regular);
// ElementTypeMapArray<Real>::type_iterator end =
// moments_coords.lastType(spatial_dimension, _not_ghost, _ek_regular);
// for (; it != end; ++it) {
// ElementType type = *it;
// Array<Real> & field_array = moments_coords(type);
// UInt nb_element = mesh.getNbElement(type);
// UInt nb_quad_per_element =
// model.getFEEngine().getNbIntegrationPoints(type);
// field_array.resize(nb_element * nb_quad_per_element);
// }
/// compute coordinates
- auto mass_center_it =
- mass_center.begin(spatial_dimension);
+ auto mass_center_it = mass_center.begin(spatial_dimension);
/// loop over fragments
for (const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++mass_center_it) {
const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
/// loop over elements of the fragment
for (auto type :
el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
UInt nb_quad_per_element =
model.getFEEngine().getNbIntegrationPoints(type);
Array<Real> & moments_coords_array = moments_coords(type);
const Array<Real> & quad_coordinates_array = quad_coordinates(type);
const Array<UInt> & el_list_array = el_list(type);
Array<Real>::matrix_iterator moments_begin =
moments_coords_array.begin(spatial_dimension, spatial_dimension);
auto quad_coordinates_begin =
quad_coordinates_array.begin(spatial_dimension);
Vector<Real> relative_coords(spatial_dimension);
for (UInt el = 0; el < el_list_array.size(); ++el) {
UInt global_el = el_list_array(el);
/// loop over quadrature points
for (UInt q = 0; q < nb_quad_per_element; ++q) {
UInt global_q = global_el * nb_quad_per_element + q;
Matrix<Real> moments_matrix = moments_begin[global_q];
const Vector<Real> & quad_coord_vector =
quad_coordinates_begin[global_q];
/// to understand this read the documentation written just
/// before this function
relative_coords = quad_coord_vector;
relative_coords -= *mass_center_it;
moments_matrix.outerProduct(relative_coords, relative_coords);
Real trace = moments_matrix.trace();
moments_matrix *= -1.;
moments_matrix += Matrix<Real>::eye(spatial_dimension, trace);
}
}
}
}
/// integrate moments
Array<Real> integrated_moments(global_nb_fragment,
spatial_dimension * spatial_dimension);
integrateFieldOnFragments(moments_coords, integrated_moments);
/// compute and store principal moments
inertia_moments.resize(global_nb_fragment);
principal_directions.resize(global_nb_fragment);
Array<Real>::matrix_iterator integrated_moments_it =
integrated_moments.begin(spatial_dimension, spatial_dimension);
- auto inertia_moments_it =
- inertia_moments.begin(spatial_dimension);
+ auto inertia_moments_it = inertia_moments.begin(spatial_dimension);
Array<Real>::matrix_iterator principal_directions_it =
principal_directions.begin(spatial_dimension, spatial_dimension);
for (UInt frag = 0; frag < global_nb_fragment; ++frag,
++integrated_moments_it, ++inertia_moments_it,
++principal_directions_it) {
integrated_moments_it->eig(*inertia_moments_it, *principal_directions_it);
}
if (dump_data)
createDumpDataArray(inertia_moments, "moments of inertia");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeAllData() {
AKANTU_DEBUG_IN();
buildFragments();
computeVelocity();
computeInertiaMoments();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::storeMassDensityPerIntegrationPoint() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator end = mesh.lastType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
Array<Real> & mass_density_array = mass_density(type);
UInt nb_element = mesh.getNbElement(type);
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
mass_density_array.resize(nb_element * nb_quad_per_element);
const Array<UInt> & mat_indexes = model.getMaterialByElement(type);
Real * mass_density_it = mass_density_array.storage();
/// store mass_density for each element and quadrature point
for (UInt el = 0; el < nb_element; ++el) {
Material & mat = model.getMaterial(mat_indexes(el));
for (UInt q = 0; q < nb_quad_per_element; ++q, ++mass_density_it)
*mass_density_it = mat.getRho();
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::integrateFieldOnFragments(
ElementTypeMapArray<Real> & field, Array<Real> & output) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
UInt nb_component = output.getNbComponent();
/// integration part
output.resize(global_nb_fragment);
output.clear();
UInt * fragment_index_it = fragment_index.storage();
auto output_begin = output.begin(nb_component);
/// loop over fragments
for (const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++fragment_index_it) {
const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
/// loop over elements of the fragment
for (auto type :
el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
UInt nb_quad_per_element =
model.getFEEngine().getNbIntegrationPoints(type);
const Array<Real> & density_array = mass_density(type);
Array<Real> & field_array = field(type);
const Array<UInt> & elements = el_list(type);
UInt nb_element = elements.size();
/// generate array to be integrated by filtering fragment's elements
Array<Real> integration_array(elements.size() * nb_quad_per_element,
nb_component);
Array<Real>::matrix_iterator int_array_it =
integration_array.begin_reinterpret(nb_quad_per_element, nb_component,
nb_element);
Array<Real>::matrix_iterator int_array_end =
integration_array.end_reinterpret(nb_quad_per_element, nb_component,
nb_element);
Array<Real>::matrix_iterator field_array_begin =
field_array.begin_reinterpret(nb_quad_per_element, nb_component,
field_array.size() /
nb_quad_per_element);
- auto density_array_begin =
- density_array.begin_reinterpret(nb_quad_per_element,
- density_array.size() /
- nb_quad_per_element);
+ auto density_array_begin = density_array.begin_reinterpret(
+ nb_quad_per_element, density_array.size() / nb_quad_per_element);
for (UInt el = 0; int_array_it != int_array_end; ++int_array_it, ++el) {
UInt global_el = elements(el);
*int_array_it = field_array_begin[global_el];
/// multiply field by density
const Vector<Real> & density_vector = density_array_begin[global_el];
for (UInt i = 0; i < nb_quad_per_element; ++i) {
for (UInt j = 0; j < nb_component; ++j) {
(*int_array_it)(i, j) *= density_vector(i);
}
}
}
/// integrate the field over the fragment
Array<Real> integrated_array(elements.size(), nb_component);
model.getFEEngine().integrate(integration_array, integrated_array,
nb_component, type, _not_ghost, elements);
/// sum over all elements and store the result
Vector<Real> output_tmp(output_begin[*fragment_index_it]);
output_tmp += std::accumulate(integrated_array.begin(nb_component),
integrated_array.end(nb_component),
Vector<Real>(nb_component));
}
}
/// sum output over all processors
const Communicator & comm = mesh.getCommunicator();
comm.allReduce(output, SynchronizerOperation::_sum);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FragmentManager::computeNbElementsPerFragment() {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model.getSpatialDimension();
nb_elements_per_fragment.resize(global_nb_fragment);
nb_elements_per_fragment.clear();
UInt * fragment_index_it = fragment_index.storage();
/// loop over fragments
for (const_element_group_iterator it(element_group_begin());
it != element_group_end(); ++it, ++fragment_index_it) {
const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
/// loop over elements of the fragment
for (auto type :
el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
UInt nb_element = el_list(type).size();
nb_elements_per_fragment(*fragment_index_it) += nb_element;
}
}
/// sum values over all processors
const auto & comm = mesh.getCommunicator();
comm.allReduce(nb_elements_per_fragment, SynchronizerOperation::_sum);
if (dump_data)
createDumpDataArray(nb_elements_per_fragment, "elements per fragment");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T>
void FragmentManager::createDumpDataArray(Array<T> & data, std::string name,
bool fragment_index_output) {
AKANTU_DEBUG_IN();
if (data.size() == 0)
return;
auto & mesh_not_const = const_cast<Mesh &>(mesh);
auto && spatial_dimension = mesh.getSpatialDimension();
auto && nb_component = data.getNbComponent();
auto && data_begin = data.begin(nb_component);
auto fragment_index_it = fragment_index.begin();
/// loop over fragments
for (const auto & fragment : ElementGroupsIterable(*this)) {
const auto & fragment_idx = *fragment_index_it;
/// loop over cluster types
for (auto & type : fragment.elementTypes(spatial_dimension)) {
/// init mesh data
auto & mesh_data = mesh_not_const.getDataPointer<T>(
name, type, _not_ghost, nb_component);
auto mesh_data_begin = mesh_data.begin(nb_component);
/// fill mesh data
for (const auto & elem : fragment.getElements(type)) {
Vector<T> md_tmp = mesh_data_begin[elem];
if (fragment_index_output) {
md_tmp(0) = fragment_idx;
} else {
md_tmp = data_begin[fragment_idx];
}
}
}
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
index 704ade675..cfed39f0e 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
@@ -1,162 +1,159 @@
/**
* @file material_selector_cohesive.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Dec 11 2015
* @date last modification: Mon Dec 14 2015
*
* @brief Material selector for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_selector_cohesive.hh"
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
DefaultMaterialCohesiveSelector::DefaultMaterialCohesiveSelector(
const SolidMechanicsModelCohesive & model)
: facet_material(model.getFacetMaterial()), mesh(model.getMesh()) {
// backward compatibility v3: to get the former behavior back when the user
// creates its own selector
this->fallback_selector =
std::make_shared<DefaultMaterialSelector>(model.getMaterialByElement());
}
/* -------------------------------------------------------------------------- */
UInt DefaultMaterialCohesiveSelector::operator()(const Element & element) {
if (Mesh::getKind(element.type) == _ek_cohesive) {
try {
const Array<Element> & cohesive_el_to_facet =
mesh.getMeshFacets().getSubelementToElement(element.type,
element.ghost_type);
bool third_dimension = (mesh.getSpatialDimension() == 3);
const Element & facet =
cohesive_el_to_facet(element.element, third_dimension);
if (facet_material.exists(facet.type, facet.ghost_type)) {
return facet_material(facet.type, facet.ghost_type)(facet.element);
} else {
return fallback_value;
}
} catch (...) {
return fallback_value;
}
} else if (Mesh::getSpatialDimension(element.type) ==
mesh.getSpatialDimension() - 1) {
return facet_material(element.type, element.ghost_type)(element.element);
} else {
return MaterialSelector::operator()(element);
}
}
/* -------------------------------------------------------------------------- */
MeshDataMaterialCohesiveSelector::MeshDataMaterialCohesiveSelector(
const SolidMechanicsModelCohesive & model)
: model(model), mesh_facets(model.getMeshFacets()),
material_index(mesh_facets.getData<std::string>("physical_names")) {
third_dimension = (model.getSpatialDimension() == 3);
// backward compatibility v3: to get the former behavior back when the user
// creates its own selector
this->fallback_selector =
std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
model);
}
/* -------------------------------------------------------------------------- */
UInt MeshDataMaterialCohesiveSelector::operator()(const Element & element) {
if (Mesh::getKind(element.type) == _ek_cohesive) {
const auto & facet = mesh_facets.getSubelementToElement(
element.type, element.ghost_type)(element.element, third_dimension);
try {
std::string material_name = this->material_index(facet);
return this->model.getMaterialIndex(material_name);
- } catch(...) {
+ } catch (...) {
return fallback_value;
}
} else
return MaterialSelector::operator()(element);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
MaterialCohesiveRulesSelector::MaterialCohesiveRulesSelector(
const SolidMechanicsModelCohesive & model,
const MaterialCohesiveRules & rules,
ID mesh_data_id) // what we have here is the name of model and also
// the name of different materials
- : model(model),
- mesh_data_id(std::move(mesh_data_id)),
- mesh(model.getMesh()),
- mesh_facets(model.getMeshFacets()),
- spatial_dimension(model.getSpatialDimension()),
- rules(rules) {
+ : model(model), mesh_data_id(std::move(mesh_data_id)),
+ mesh(model.getMesh()), mesh_facets(model.getMeshFacets()),
+ spatial_dimension(model.getSpatialDimension()), rules(rules) {
// cohesive fallback
this->fallback_selector =
std::make_shared<DefaultMaterialCohesiveSelector>(model);
// non cohesive fallback
this->fallback_selector->setFallback(
std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
model));
}
/* -------------------------------------------------------------------------- */
UInt MaterialCohesiveRulesSelector::operator()(const Element & element) {
if (mesh_facets.getSpatialDimension(element.type) ==
(spatial_dimension - 1)) {
const std::vector<Element> & element_to_subelement =
mesh_facets.getElementToSubelement(element.type,
element.ghost_type)(element.element);
// Array<bool> & facets_check = model.getFacetsCheck();
const Element & el1 = element_to_subelement[0];
const Element & el2 = element_to_subelement[1];
ID id1 = mesh.getData<std::string>(mesh_data_id, el1.type,
el1.ghost_type)(el1.element);
ID id2 = id1;
if (el2 != ElementNull) {
id2 = mesh.getData<std::string>(mesh_data_id, el2.type,
el2.ghost_type)(el2.element);
}
auto rit = rules.find(std::make_pair(id1, id2));
if (rit == rules.end()) {
rit = rules.find(std::make_pair(id2, id1));
}
if (rit != rules.end()) {
return model.getMaterialIndex(rit->second);
}
}
return MaterialSelector::operator()(element);
}
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh
index 946884013..22e2c96dd 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh
@@ -1,71 +1,68 @@
/**
* @file cohesive_internal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Oct 08 2015
*
* @brief Internal field for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "internal_field.hh"
#ifndef __AKANTU_COHESIVE_INTERNAL_FIELD_HH__
#define __AKANTU_COHESIVE_INTERNAL_FIELD_HH__
namespace akantu {
/// internal field class for cohesive materials
-template<typename T>
-class CohesiveInternalField : public InternalField<T> {
+template <typename T> class CohesiveInternalField : public InternalField<T> {
public:
CohesiveInternalField(const ID & id, Material & material);
~CohesiveInternalField() override;
/// initialize the field to a given number of component
void initialize(UInt nb_component) override;
private:
- CohesiveInternalField operator=(__attribute__((unused)) const CohesiveInternalField & other) {};
-
+ CohesiveInternalField operator=(__attribute__((unused))
+ const CohesiveInternalField & other){};
};
-
/* -------------------------------------------------------------------------- */
/* Facet Internal Field */
/* -------------------------------------------------------------------------- */
-template<typename T>
-class FacetInternalField : public InternalField<T> {
+template <typename T> class FacetInternalField : public InternalField<T> {
public:
FacetInternalField(const ID & id, Material & material);
~FacetInternalField() override;
/// initialize the field to a given number of component
void initialize(UInt nb_component) override;
};
} // akantu
#endif /* __AKANTU_COHESIVE_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
index 1c936b9c7..1be65c688 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
@@ -1,219 +1,217 @@
/**
* @file material_cohesive_bilinear.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Feb 22 2012
* @date last modification: Thu Oct 15 2015
*
* @brief Bilinear cohesive constitutive law
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_bilinear.hh"
//#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialCohesiveBilinear<spatial_dimension>::MaterialCohesiveBilinear(
SolidMechanicsModel & model, const ID & id)
: MaterialCohesiveLinear<spatial_dimension>(model, id) {
AKANTU_DEBUG_IN();
this->registerParam("delta_0", delta_0, Real(0.),
_pat_parsable | _pat_readable,
"Elastic limit displacement");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
this->sigma_c_eff.setRandomDistribution(this->sigma_c.getRandomParameter());
MaterialCohesiveLinear<spatial_dimension>::initMaterial();
this->delta_max.setDefaultValue(delta_0);
this->insertion_stress.setDefaultValue(0);
this->delta_max.reset();
this->insertion_stress.reset();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::onElementsAdded(
const Array<Element> & element_list, const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
MaterialCohesiveLinear<spatial_dimension>::onElementsAdded(element_list,
event);
bool scale_traction = false;
// don't scale sigma_c if volume_s hasn't been specified by the user
if (!Math::are_float_equal(this->volume_s, 0.))
scale_traction = true;
Array<Element>::const_scalar_iterator el_it = element_list.begin();
Array<Element>::const_scalar_iterator el_end = element_list.end();
for (; el_it != el_end; ++el_it) {
// filter not ghost cohesive elements
if (el_it->ghost_type != _not_ghost ||
Mesh::getKind(el_it->type) != _ek_cohesive)
continue;
UInt index = el_it->element;
ElementType type = el_it->type;
UInt nb_element = this->model->getMesh().getNbElement(type);
UInt nb_quad_per_element = this->fem_cohesive.getNbIntegrationPoints(type);
- auto sigma_c_begin =
- this->sigma_c_eff(type).begin_reinterpret(nb_quad_per_element,
- nb_element);
+ auto sigma_c_begin = this->sigma_c_eff(type).begin_reinterpret(
+ nb_quad_per_element, nb_element);
Vector<Real> sigma_c_vec = sigma_c_begin[index];
- auto delta_c_begin =
- this->delta_c_eff(type).begin_reinterpret(nb_quad_per_element,
- nb_element);
+ auto delta_c_begin = this->delta_c_eff(type).begin_reinterpret(
+ nb_quad_per_element, nb_element);
Vector<Real> delta_c_vec = delta_c_begin[index];
if (scale_traction)
scaleTraction(*el_it, sigma_c_vec);
/**
* Recompute sigma_c as
* @f$ {\sigma_c}_\textup{new} =
* \frac{{\sigma_c}_\textup{old} \delta_c} {\delta_c - \delta_0} @f$
*/
for (UInt q = 0; q < nb_quad_per_element; ++q) {
delta_c_vec(q) = 2 * this->G_c / sigma_c_vec(q);
if (delta_c_vec(q) - delta_0 < Math::getTolerance())
- AKANTU_ERROR("delta_0 = "
- << delta_0 << " must be lower than delta_c = "
- << delta_c_vec(q) << ", modify your material file");
+ AKANTU_ERROR("delta_0 = " << delta_0 << " must be lower than delta_c = "
+ << delta_c_vec(q)
+ << ", modify your material file");
sigma_c_vec(q) *= delta_c_vec(q) / (delta_c_vec(q) - delta_0);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::scaleTraction(
const Element & el, Vector<Real> & sigma_c_vec) {
AKANTU_DEBUG_IN();
Real base_sigma_c = this->sigma_c_eff;
const Mesh & mesh_facets = this->model->getMeshFacets();
const FEEngine & fe_engine = this->model->getFEEngine();
auto coh_element_to_facet_begin =
mesh_facets.getSubelementToElement(el.type).begin(2);
const Vector<Element> & coh_element_to_facet =
coh_element_to_facet_begin[el.element];
// compute bounding volume
Real volume = 0;
// loop over facets
for (UInt f = 0; f < 2; ++f) {
const Element & facet = coh_element_to_facet(f);
const Array<std::vector<Element>> & facet_to_element =
mesh_facets.getElementToSubelement(facet.type, facet.ghost_type);
const std::vector<Element> & element_list = facet_to_element(facet.element);
auto elem = element_list.begin();
auto elem_end = element_list.end();
// loop over elements connected to each facet
for (; elem != elem_end; ++elem) {
// skip cohesive elements and dummy elements
if (*elem == ElementNull || Mesh::getKind(elem->type) == _ek_cohesive)
continue;
// unit vector for integration in order to obtain the volume
UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
Vector<Real> unit_vector(nb_quadrature_points, 1);
volume += fe_engine.integrate(unit_vector, elem->type, elem->element,
elem->ghost_type);
}
}
// scale sigma_c
sigma_c_vec -= base_sigma_c;
sigma_c_vec *= std::pow(this->volume_s / volume, 1. / this->m_s);
sigma_c_vec += base_sigma_c;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveBilinear<spatial_dimension>::computeTraction(
const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialCohesiveLinear<spatial_dimension>::computeTraction(normal, el_type,
ghost_type);
// adjust damage
Array<Real>::scalar_iterator delta_c_it =
this->delta_c_eff(el_type, ghost_type).begin();
Array<Real>::scalar_iterator delta_max_it =
this->delta_max(el_type, ghost_type).begin();
Array<Real>::scalar_iterator damage_it =
this->damage(el_type, ghost_type).begin();
Array<Real>::scalar_iterator damage_end =
this->damage(el_type, ghost_type).end();
for (; damage_it != damage_end; ++damage_it, ++delta_max_it, ++delta_c_it) {
*damage_it =
std::max((*delta_max_it - delta_0) / (*delta_c_it - delta_0), Real(0.));
*damage_it = std::min(*damage_it, Real(1.));
}
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(cohesive_bilinear, MaterialCohesiveBilinear);
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
index b31def0c0..4c5b6a09d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
@@ -1,112 +1,106 @@
/**
* @file material_cohesive_bilinear.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Bilinear cohesive constitutive law
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear.hh"
#ifndef __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__
#define __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
* Cohesive material bilinear
*
* parameters in the material files :
* - delta_0 : elastic limit displacement (default: 0)
* - sigma_c : critical stress sigma_c (default: 0)
- * - beta : weighting parameter for sliding and normal opening (default: 0)
+ * - beta : weighting parameter for sliding and normal opening (default:
+ * 0)
* - G_cI : fracture energy for mode I (default: 0)
* - G_cII : fracture energy for mode II (default: 0)
* - penalty : stiffness in compression to prevent penetration
*/
-template<UInt spatial_dimension>
-class MaterialCohesiveBilinear : public MaterialCohesiveLinear<spatial_dimension> {
+template <UInt spatial_dimension>
+class MaterialCohesiveBilinear
+ : public MaterialCohesiveLinear<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// initialize the material computed parameter
void initMaterial() override;
/// set material parameters for new elements
void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event) override;
protected:
-
/// constitutive law
void computeTraction(const Array<Real> & normal, ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/**
* Scale traction sigma_c according to the volume of the
* two elements surrounding an element
*/
void scaleTraction(const Element & el, Vector<Real> & sigma_c_vec);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// elastic limit displacement
Real delta_0;
-
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "material_cohesive_elastic_inline_impl.cc"
-
} // akantu
#endif /* __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
index 010024676..35ecec09e 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
@@ -1,358 +1,349 @@
/**
* @file material_cohesive_exponential.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Mon Jul 09 2012
* @date last modification: Tue Aug 04 2015
*
* @brief Exponential irreversible cohesive law of mixed mode loading
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_exponential.hh"
#include "dof_synchronizer.hh"
#include "solid_mechanics_model.hh"
#include "sparse_matrix.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialCohesiveExponential<spatial_dimension>::MaterialCohesiveExponential(
SolidMechanicsModel & model, const ID & id)
: MaterialCohesive(model, id) {
AKANTU_DEBUG_IN();
this->registerParam("beta", beta, Real(0.), _pat_parsable, "Beta parameter");
this->registerParam("exponential_penalty", exp_penalty, true, _pat_parsable,
"Is contact penalty following the exponential law?");
this->registerParam(
"contact_tangent", contact_tangent, Real(1.0), _pat_parsable,
"Ratio of contact tangent over the initial exponential tangent");
// this->initInternalArray(delta_max, 1, _ek_cohesive);
use_previous_delta_max = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialCohesive::initMaterial();
if ((exp_penalty) && (contact_tangent != 1)) {
contact_tangent = 1;
AKANTU_DEBUG_WARNING("The parsed paramter <contact_tangent> is forced to "
"1.0 when the contact penalty follows the exponential "
"law");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeTraction(
const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
- auto traction_it =
- tractions(el_type, ghost_type).begin(spatial_dimension);
+ auto traction_it = tractions(el_type, ghost_type).begin(spatial_dimension);
- auto opening_it =
- opening(el_type, ghost_type).begin(spatial_dimension);
+ auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
- auto normal_it =
- normal.begin(spatial_dimension);
+ auto normal_it = normal.begin(spatial_dimension);
- auto traction_end =
- tractions(el_type, ghost_type).end(spatial_dimension);
+ auto traction_end = tractions(el_type, ghost_type).end(spatial_dimension);
- auto delta_max_it =
- delta_max(el_type, ghost_type).begin();
+ auto delta_max_it = delta_max(el_type, ghost_type).begin();
- auto delta_max_prev_it =
- delta_max.previous(el_type, ghost_type).begin();
+ auto delta_max_prev_it = delta_max.previous(el_type, ghost_type).begin();
/// compute scalars
Real beta2 = beta * beta;
/// loop on each quadrature point
for (; traction_it != traction_end; ++traction_it, ++opening_it, ++normal_it,
++delta_max_it, ++delta_max_prev_it) {
/// compute normal and tangential opening vectors
Real normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening(spatial_dimension);
normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening = *opening_it;
tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
/**
* compute effective opening displacement
* @f$ \delta = \sqrt{
* \beta^2 \Delta_t^2 + \Delta_n^2 } @f$
*/
Real delta = tangential_opening_norm;
delta *= delta * beta2;
delta += normal_opening_norm * normal_opening_norm;
delta = sqrt(delta);
if ((normal_opening_norm < 0) &&
(std::abs(normal_opening_norm) > Math::getTolerance())) {
Vector<Real> op_n(*normal_it);
op_n *= normal_opening_norm;
Vector<Real> delta_s(*opening_it);
delta_s -= op_n;
delta = tangential_opening_norm * beta;
computeCoupledTraction(*traction_it, *normal_it, delta, delta_s,
*delta_max_it, *delta_max_prev_it);
computeCompressiveTraction(*traction_it, *normal_it, normal_opening_norm,
*opening_it);
} else
computeCoupledTraction(*traction_it, *normal_it, delta, *opening_it,
*delta_max_it, *delta_max_prev_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTraction(
Vector<Real> & tract, const Vector<Real> & normal, Real delta,
const Vector<Real> & opening, Real & delta_max_new, Real delta_max) {
AKANTU_DEBUG_IN();
/// full damage case
if (std::abs(delta) < Math::getTolerance()) {
/// set traction to zero
tract.clear();
} else { /// element not fully damaged
/**
* Compute traction loading @f$ \mathbf{T} =
* e \sigma_c \frac{\delta}{\delta_c} e^{-\delta/ \delta_c}@f$
*/
/**
* Compute traction unloading @f$ \mathbf{T} =
* \frac{t_{max}}{\delta_{max}} \delta @f$
*/
Real beta2 = beta * beta;
Real normal_open_norm = opening.dot(normal);
Vector<Real> op_n_n(spatial_dimension);
op_n_n = normal;
op_n_n *= (1 - beta2);
op_n_n *= normal_open_norm;
tract = beta2 * opening;
tract += op_n_n;
delta_max_new = std::max(delta_max, delta);
tract *= exp(1) * sigma_c * exp(-delta_max_new / delta_c) / delta_c;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCompressiveTraction(
Vector<Real> & tract, const Vector<Real> & normal, Real delta_n,
__attribute__((unused)) const Vector<Real> & opening) {
Vector<Real> temp_tract(normal);
if (exp_penalty) {
temp_tract *=
delta_n * exp(1) * sigma_c * exp(-delta_n / delta_c) / delta_c;
} else {
Real initial_tg = contact_tangent * exp(1) * sigma_c * delta_n / delta_c;
temp_tract *= initial_tg;
}
tract += temp_tract;
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeTangentTraction(
const ElementType & el_type, Array<Real> & tangent_matrix,
const Array<Real> & normal, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator tangent_it =
tangent_matrix.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator tangent_end =
tangent_matrix.end(spatial_dimension, spatial_dimension);
- auto normal_it =
- normal.begin(spatial_dimension);
+ auto normal_it = normal.begin(spatial_dimension);
- auto opening_it =
- opening(el_type, ghost_type).begin(spatial_dimension);
+ auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
- auto delta_max_it =
- delta_max.previous(el_type, ghost_type).begin();
+ auto delta_max_it = delta_max.previous(el_type, ghost_type).begin();
Real beta2 = beta * beta;
/**
* compute tangent matrix @f$ \frac{\partial \mathbf{t}}
* {\partial \delta} = \hat{\mathbf{t}} \otimes
* \frac{\partial (t/\delta)}{\partial \delta}
* \frac{\hat{\mathbf{t}}}{\delta}+ \frac{t}{\delta} [ \beta^2 \mathbf{I} +
* (1-\beta^2) (\mathbf{n} \otimes \mathbf{n})] @f$
**/
/**
* In which @f$
* \frac{\partial(t/ \delta)}{\partial \delta} =
* \left\{\begin{array} {l l}
* -e \frac{\sigma_c}{\delta_c^2 }e^{-\delta / \delta_c} & \quad if
* \delta \geq \delta_{max} \\
* 0 & \quad if \delta < \delta_{max}, \delta_n > 0
* \end{array}\right. @f$
**/
for (; tangent_it != tangent_end;
++tangent_it, ++normal_it, ++opening_it, ++delta_max_it) {
Real normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening(spatial_dimension);
normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening = *opening_it;
tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
Real delta = tangential_opening_norm;
delta *= delta * beta2;
delta += normal_opening_norm * normal_opening_norm;
delta = sqrt(delta);
if ((normal_opening_norm < 0) &&
(std::abs(normal_opening_norm) > Math::getTolerance())) {
Vector<Real> op_n(*normal_it);
op_n *= normal_opening_norm;
Vector<Real> delta_s(*opening_it);
delta_s -= op_n;
delta = tangential_opening_norm * beta;
computeCoupledTangent(*tangent_it, *normal_it, delta, delta_s,
*delta_max_it);
computeCompressivePenalty(*tangent_it, *normal_it, normal_opening_norm);
} else
computeCoupledTangent(*tangent_it, *normal_it, delta, *opening_it,
*delta_max_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTangent(
Matrix<Real> & tangent, const Vector<Real> & normal, Real delta,
const Vector<Real> & opening, Real) {
AKANTU_DEBUG_IN();
Real beta2 = beta * beta;
Matrix<Real> J(spatial_dimension, spatial_dimension);
J.eye(beta2);
if (std::abs(delta) < Math::getTolerance()) {
delta = Math::getTolerance();
}
Real opening_normal;
opening_normal = opening.dot(normal);
Vector<Real> delta_e(normal);
delta_e *= opening_normal;
delta_e *= (1 - beta2);
delta_e += (beta2 * opening);
Real exponent = exp(1 - delta / delta_c) * sigma_c / delta_c;
Matrix<Real> first_term(spatial_dimension, spatial_dimension);
first_term.outerProduct(normal, normal);
first_term *= (1 - beta2);
first_term += J;
Matrix<Real> second_term(spatial_dimension, spatial_dimension);
second_term.outerProduct(delta_e, delta_e);
second_term /= delta;
second_term /= delta_c;
Matrix<Real> diff(first_term);
diff -= second_term;
tangent = diff;
tangent *= exponent;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCompressivePenalty(
Matrix<Real> & tangent, const Vector<Real> & normal, Real delta_n) {
if (!exp_penalty)
delta_n = 0;
Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
n_outer_n.outerProduct(normal, normal);
Real normal_tg = contact_tangent * exp(1) * sigma_c *
exp(-delta_n / delta_c) * (1 - delta_n / delta_c) / delta_c;
n_outer_n *= normal_tg;
tangent += n_outer_n;
}
INSTANTIATE_MATERIAL(cohesive_exponential, MaterialCohesiveExponential);
} // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
index 7dbdcba15..3b2b569c0 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
@@ -1,128 +1,123 @@
/**
* @file material_cohesive_exponential.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Feb 06 2015
*
* @brief Exponential irreversible cohesive law of mixed mode loading
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "material_cohesive.hh"
#include "aka_common.hh"
+#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__
#define __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__
/* -------------------------------------------------------------------------- */
-
namespace akantu {
/**
* Cohesive material Exponential damage
*
* parameters in the material files :
* - sigma_c : critical stress sigma_c (default: 0)
- * - beta : weighting parameter for sliding and normal opening (default: 0)
+ * - beta : weighting parameter for sliding and normal opening (default:
+ * 0)
* - delta_c : critical opening (default: 0)
*/
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
class MaterialCohesiveExponential : public MaterialCohesive {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialCohesiveExponential(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// Initialization
void initMaterial() override;
/// constitutive law
void computeTraction(const Array<Real> & normal, ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/// compute the tangent stiffness matrix for an element type
void computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type = _not_ghost) override;
private:
-
void computeCoupledTraction(Vector<Real> & tract, const Vector<Real> & normal,
- Real delta, const Vector<Real> & opening,
- Real & delta_max_new, Real delta_max);
-
- void computeCompressiveTraction(Vector<Real> & tract, const Vector<Real> & normal,
- Real delta_n, const Vector<Real> & opening);
+ Real delta, const Vector<Real> & opening,
+ Real & delta_max_new, Real delta_max);
+
+ void computeCompressiveTraction(Vector<Real> & tract,
+ const Vector<Real> & normal, Real delta_n,
+ const Vector<Real> & opening);
void computeCoupledTangent(Matrix<Real> & tangent,
- const Vector<Real> & normal, Real delta,
- const Vector<Real> & opening, Real delta_max_new);
+ const Vector<Real> & normal, Real delta,
+ const Vector<Real> & opening, Real delta_max_new);
+
+ void computeCompressivePenalty(Matrix<Real> & tangent,
+ const Vector<Real> & normal, Real delta_n);
- void computeCompressivePenalty(Matrix<Real> & tangent, const Vector<Real> & normal,
- Real delta_n);
-
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
/// beta parameter
Real beta;
/// contact penalty = initial slope ?
bool exp_penalty;
/// Ratio of contact tangent over the initial exponential tangent
Real contact_tangent;
};
-
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
// #include "material_cohesive_exponential_inline_impl.cc"
-
} // akantu
#endif /* __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
index e38bd4c1b..432b7e673 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
@@ -1,296 +1,298 @@
/**
* @file material_cohesive_linear_fatigue.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Feb 20 2015
* @date last modification: Tue Jan 12 2016
*
* @brief See material_cohesive_linear_fatigue.hh for information
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear_fatigue.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
-MaterialCohesiveLinearFatigue<spatial_dimension>
-::MaterialCohesiveLinearFatigue(SolidMechanicsModel & model,
- const ID & id) :
- MaterialCohesiveLinear<spatial_dimension>(model, id),
- delta_prec("delta_prec", *this),
- K_plus("K_plus", *this),
- K_minus("K_minus", *this),
- T_1d("T_1d", *this),
- switches("switches", *this),
- delta_dot_prec("delta_dot_prec", *this),
- normal_regime("normal_regime", *this) {
-
- this->registerParam("delta_f", delta_f, Real(-1.) ,
- _pat_parsable | _pat_readable,
- "delta_f");
+MaterialCohesiveLinearFatigue<spatial_dimension>::MaterialCohesiveLinearFatigue(
+ SolidMechanicsModel & model, const ID & id)
+ : MaterialCohesiveLinear<spatial_dimension>(model, id),
+ delta_prec("delta_prec", *this), K_plus("K_plus", *this),
+ K_minus("K_minus", *this), T_1d("T_1d", *this),
+ switches("switches", *this), delta_dot_prec("delta_dot_prec", *this),
+ normal_regime("normal_regime", *this) {
+
+ this->registerParam("delta_f", delta_f, Real(-1.),
+ _pat_parsable | _pat_readable, "delta_f");
this->registerParam("progressive_delta_f", progressive_delta_f, false,
- _pat_parsable | _pat_readable,
- "Whether or not delta_f is equal to delta_max");
+ _pat_parsable | _pat_readable,
+ "Whether or not delta_f is equal to delta_max");
this->registerParam("count_switches", count_switches, false,
- _pat_parsable | _pat_readable,
- "Count the opening/closing switches per element");
+ _pat_parsable | _pat_readable,
+ "Count the opening/closing switches per element");
- this->registerParam("fatigue_ratio", fatigue_ratio, Real(1.),
- _pat_parsable | _pat_readable,
- "What portion of the cohesive law is subjected to fatigue");
+ this->registerParam(
+ "fatigue_ratio", fatigue_ratio, Real(1.), _pat_parsable | _pat_readable,
+ "What portion of the cohesive law is subjected to fatigue");
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearFatigue<spatial_dimension>::initMaterial() {
MaterialCohesiveLinear<spatial_dimension>::initMaterial();
// check that delta_f has a proper value or assign a defaul value
- if (delta_f < 0) delta_f = this->delta_c_eff;
+ if (delta_f < 0)
+ delta_f = this->delta_c_eff;
else if (delta_f < this->delta_c_eff)
AKANTU_ERROR("Delta_f must be greater or equal to delta_c");
delta_prec.initialize(1);
K_plus.initialize(1);
K_minus.initialize(1);
T_1d.initialize(1);
normal_regime.initialize(1);
if (count_switches) {
switches.initialize(1);
delta_dot_prec.initialize(1);
}
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialCohesiveLinearFatigue<spatial_dimension>
-::computeTraction(const Array<Real> & normal,
- ElementType el_type,
- GhostType ghost_type) {
+template <UInt spatial_dimension>
+void MaterialCohesiveLinearFatigue<spatial_dimension>::computeTraction(
+ const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
auto traction_it =
- this->tractions(el_type, ghost_type).begin(spatial_dimension);
+ this->tractions(el_type, ghost_type).begin(spatial_dimension);
- auto opening_it =
- this->opening(el_type, ghost_type).begin(spatial_dimension);
+ auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
auto contact_traction_it =
- this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
+ this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
auto contact_opening_it =
- this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
+ this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
auto normal_it = normal.begin(spatial_dimension);
auto traction_end =
- this->tractions(el_type, ghost_type).end(spatial_dimension);
+ this->tractions(el_type, ghost_type).end(spatial_dimension);
const Array<Real> & sigma_c_array = this->sigma_c_eff(el_type, ghost_type);
Array<Real> & delta_max_array = this->delta_max(el_type, ghost_type);
const Array<Real> & delta_c_array = this->delta_c_eff(el_type, ghost_type);
Array<Real> & damage_array = this->damage(el_type, ghost_type);
auto insertion_stress_it =
- this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
+ this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
Array<Real> & delta_prec_array = delta_prec(el_type, ghost_type);
Array<Real> & K_plus_array = K_plus(el_type, ghost_type);
Array<Real> & K_minus_array = K_minus(el_type, ghost_type);
Array<Real> & T_1d_array = T_1d(el_type, ghost_type);
Array<bool> & normal_regime_array = normal_regime(el_type, ghost_type);
Array<UInt> * switches_array = nullptr;
Array<Real> * delta_dot_prec_array = nullptr;
if (count_switches) {
switches_array = &switches(el_type, ghost_type);
delta_dot_prec_array = &delta_dot_prec(el_type, ghost_type);
}
auto * memory_space = new Real[2 * spatial_dimension];
Vector<Real> normal_opening(memory_space, spatial_dimension);
Vector<Real> tangential_opening(memory_space + spatial_dimension,
- spatial_dimension);
+ spatial_dimension);
Real tolerance = Math::getTolerance();
/// loop on each quadrature point
- for (UInt q = 0; traction_it != traction_end;
- ++traction_it, ++opening_it, ++normal_it,
- ++contact_traction_it, ++insertion_stress_it, ++contact_opening_it, ++q) {
+ for (UInt q = 0; traction_it != traction_end; ++traction_it, ++opening_it,
+ ++normal_it, ++contact_traction_it, ++insertion_stress_it,
+ ++contact_opening_it, ++q) {
/// compute normal and tangential opening vectors
Real normal_opening_norm = opening_it->dot(*normal_it);
- normal_opening = (*normal_it);
+ normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
- tangential_opening = *opening_it;
- tangential_opening -= normal_opening;
+ tangential_opening = *opening_it;
+ tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
/**
* compute effective opening displacement
* @f$ \delta = \sqrt{
* \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
*/
- Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
+ Real delta =
+ tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
bool penetration = normal_opening_norm < -tolerance;
- if (this->contact_after_breaking == false && Math::are_float_equal(damage_array(q), 1.))
+ if (this->contact_after_breaking == false &&
+ Math::are_float_equal(damage_array(q), 1.))
penetration = false;
if (penetration) {
/// use penalty coefficient in case of penetration
*contact_traction_it = normal_opening;
*contact_traction_it *= this->penalty;
*contact_opening_it = normal_opening;
/// don't consider penetration contribution for delta
*opening_it = tangential_opening;
normal_opening.clear();
- }
- else {
+ } else {
delta += normal_opening_norm * normal_opening_norm;
contact_traction_it->clear();
contact_opening_it->clear();
}
delta = std::sqrt(delta);
/**
* Compute traction @f$ \mathbf{T} = \left(
* \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
* \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
* \frac{\delta}{\delta_c} \right)@f$
*/
-
// update maximum displacement and damage
delta_max_array(q) = std::max(delta, delta_max_array(q));
damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
Real delta_dot = delta - delta_prec_array(q);
// count switches if asked
if (count_switches) {
- if ( (delta_dot > 0. && (*delta_dot_prec_array)(q) <= 0.) ||
- (delta_dot < 0. && (*delta_dot_prec_array)(q) >= 0.) )
- ++((*switches_array)(q));
+ if ((delta_dot > 0. && (*delta_dot_prec_array)(q) <= 0.) ||
+ (delta_dot < 0. && (*delta_dot_prec_array)(q) >= 0.))
+ ++((*switches_array)(q));
(*delta_dot_prec_array)(q) = delta_dot;
}
// set delta_f equal to delta_max if desired
- if (progressive_delta_f) delta_f = delta_max_array(q);
+ if (progressive_delta_f)
+ delta_f = delta_max_array(q);
// broken element case
if (Math::are_float_equal(damage_array(q), 1.))
traction_it->clear();
// just inserted element case
else if (Math::are_float_equal(damage_array(q), 0.)) {
if (penetration)
- traction_it->clear();
+ traction_it->clear();
else
- *traction_it = *insertion_stress_it;
+ *traction_it = *insertion_stress_it;
// initialize the 1d traction to sigma_c
T_1d_array(q) = sigma_c_array(q);
}
// normal case
else {
// if element is closed then there are zero tractions
if (delta <= tolerance)
- traction_it->clear();
+ traction_it->clear();
// otherwise compute new tractions if the new delta is different
// than the previous one
else if (std::abs(delta_dot) > tolerance) {
- // loading case
- if (delta_dot > 0.) {
- if (!normal_regime_array(q)) {
- // equation (4) of the article
- K_plus_array(q) *= 1. - delta_dot / delta_f;
- // equivalent to equation (2) of the article
- T_1d_array(q) += K_plus_array(q) * delta_dot;
-
- // in case of reloading, traction must not exceed that of the
- // envelop of the cohesive law
- Real max_traction = sigma_c_array(q) * (1 - delta / delta_c_array(q));
- bool max_traction_exceeded = T_1d_array(q) > max_traction;
- if (max_traction_exceeded) T_1d_array(q) = max_traction;
-
- // switch to standard linear cohesive law
- if (delta_max_array(q) > fatigue_ratio * delta_c_array(q)) {
- // reset delta_max to avoid big jumps in the traction
- delta_max_array(q) = sigma_c_array(q) / (T_1d_array(q) / delta + sigma_c_array(q) / delta_c_array(q));
- damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
- K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
- normal_regime_array(q) = true;
- } else {
- // equation (3) of the article
- K_minus_array(q) = T_1d_array(q) / delta;
-
- // if the traction is following the cohesive envelop, then
- // K_plus has to be reset
- if (max_traction_exceeded) K_plus_array(q) = K_minus_array(q);
- }
- } else {
- // compute stiffness according to the standard law
- K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
- }
- }
- // unloading case
- else if (!normal_regime_array(q)) {
- // equation (4) of the article
- K_plus_array(q) += (K_plus_array(q) - K_minus_array(q)) * delta_dot / delta_f;
- // equivalent to equation (2) of the article
- T_1d_array(q) = K_minus_array(q) * delta;
- }
-
- // applying the actual stiffness
- *traction_it = tangential_opening;
- *traction_it *= this->beta2_kappa;
- *traction_it += normal_opening;
- *traction_it *= K_minus_array(q);
+ // loading case
+ if (delta_dot > 0.) {
+ if (!normal_regime_array(q)) {
+ // equation (4) of the article
+ K_plus_array(q) *= 1. - delta_dot / delta_f;
+ // equivalent to equation (2) of the article
+ T_1d_array(q) += K_plus_array(q) * delta_dot;
+
+ // in case of reloading, traction must not exceed that of the
+ // envelop of the cohesive law
+ Real max_traction =
+ sigma_c_array(q) * (1 - delta / delta_c_array(q));
+ bool max_traction_exceeded = T_1d_array(q) > max_traction;
+ if (max_traction_exceeded)
+ T_1d_array(q) = max_traction;
+
+ // switch to standard linear cohesive law
+ if (delta_max_array(q) > fatigue_ratio * delta_c_array(q)) {
+ // reset delta_max to avoid big jumps in the traction
+ delta_max_array(q) =
+ sigma_c_array(q) /
+ (T_1d_array(q) / delta + sigma_c_array(q) / delta_c_array(q));
+ damage_array(q) =
+ std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
+ K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) *
+ (1. - damage_array(q));
+ normal_regime_array(q) = true;
+ } else {
+ // equation (3) of the article
+ K_minus_array(q) = T_1d_array(q) / delta;
+
+ // if the traction is following the cohesive envelop, then
+ // K_plus has to be reset
+ if (max_traction_exceeded)
+ K_plus_array(q) = K_minus_array(q);
+ }
+ } else {
+ // compute stiffness according to the standard law
+ K_minus_array(q) =
+ sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
+ }
+ }
+ // unloading case
+ else if (!normal_regime_array(q)) {
+ // equation (4) of the article
+ K_plus_array(q) +=
+ (K_plus_array(q) - K_minus_array(q)) * delta_dot / delta_f;
+ // equivalent to equation (2) of the article
+ T_1d_array(q) = K_minus_array(q) * delta;
+ }
+
+ // applying the actual stiffness
+ *traction_it = tangential_opening;
+ *traction_it *= this->beta2_kappa;
+ *traction_it += normal_opening;
+ *traction_it *= K_minus_array(q);
}
}
// update precendent delta
delta_prec_array(q) = delta;
}
- delete [] memory_space;
+ delete[] memory_space;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(cohesive_linear_fatigue, MaterialCohesiveLinearFatigue);
-
} // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
index 7d736f3f8..93d3329d2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
@@ -1,135 +1,133 @@
/**
* @file material_cohesive_linear_fatigue.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Thu Jun 25 2015
*
* @brief Linear irreversible cohesive law with dissipative
* unloading-reloading cycles
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__
#define __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
* Linear irreversible cohesive law with dissipative
* unloading-reloading cycles
*
* This law uses two different stiffnesses during unloading and
* reloading. The implementation is based on the article entitled "A
* cohesive model for fatigue crack growth" by Nguyen, Repetto, Ortiz
* and Radovitzky (2001). This law is identical to the
* MaterialCohesiveLinear one except for the unloading-reloading
* phase.
*
* input parameter:
*
* - delta_f : it must be greater than delta_c and it is inversely
* proportional to the dissipation in the unloading-reloading
* cycles (default: delta_c)
*/
template <UInt spatial_dimension>
-class MaterialCohesiveLinearFatigue : public MaterialCohesiveLinear<spatial_dimension> {
+class MaterialCohesiveLinearFatigue
+ : public MaterialCohesiveLinear<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- MaterialCohesiveLinearFatigue(SolidMechanicsModel & model, const ID & id = "");
+ MaterialCohesiveLinearFatigue(SolidMechanicsModel & model,
+ const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// initialize the material parameters
void initMaterial() override;
protected:
-
/// constitutive law
void computeTraction(const Array<Real> & normal, ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the switches
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Switches, switches, UInt);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
-
/// delta_f parameter
Real delta_f;
/// variable saying if delta_f is equal to delta_max for each
/// element when the traction is computed
bool progressive_delta_f;
/// count the opening/closing switches per element
bool count_switches;
/// delta of the previous step
CohesiveInternalField<Real> delta_prec;
/// stiffness for reloading
CohesiveInternalField<Real> K_plus;
/// stiffness for unloading
CohesiveInternalField<Real> K_minus;
/// 1D traction in the cohesive law
CohesiveInternalField<Real> T_1d;
/// Number of opening/closing switches
CohesiveInternalField<UInt> switches;
/// delta increment of the previous time step
CohesiveInternalField<Real> delta_dot_prec;
/// has the element passed to normal regime (not in fatigue anymore)
CohesiveInternalField<bool> normal_regime;
/// ratio indicating until what point fatigue is applied in the cohesive law
Real fatigue_ratio;
};
} // akantu
#endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
index 0d1a0e651..9de56ad9b 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
@@ -1,278 +1,277 @@
/**
* @file material_cohesive_linear_friction.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Tue Jan 12 2016
* @date last modification: Thu Jan 14 2016
*
* @brief Linear irreversible cohesive law of mixed mode loading with
* random stress definition for extrinsic type
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear_friction.hh"
#include "solid_mechanics_model_cohesive.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialCohesiveLinearFriction<spatial_dimension>::
MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id)
: MaterialParent(model, id), residual_sliding("residual_sliding", *this),
friction_force("friction_force", *this) {
AKANTU_DEBUG_IN();
this->registerParam("mu", mu_max, Real(0.), _pat_parsable | _pat_readable,
"Maximum value of the friction coefficient");
this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
_pat_parsable | _pat_readable,
"Penalty parameter for the friction behavior");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearFriction<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialParent::initMaterial();
friction_force.initialize(spatial_dimension);
residual_sliding.initialize(1);
residual_sliding.initializeHistory();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearFriction<spatial_dimension>::computeTraction(
__attribute__((unused)) const Array<Real> & normal, ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
residual_sliding.resize();
friction_force.resize();
/// define iterators
auto traction_it =
this->tractions(el_type, ghost_type).begin(spatial_dimension);
auto traction_end =
this->tractions(el_type, ghost_type).end(spatial_dimension);
auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
auto previous_opening_it =
this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
auto contact_traction_it =
this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
auto contact_opening_it =
this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
auto normal_it = this->normal.begin(spatial_dimension);
auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
auto delta_max_it = this->delta_max(el_type, ghost_type).begin();
auto delta_max_prev_it =
this->delta_max.previous(el_type, ghost_type).begin();
auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
auto damage_it = this->damage(el_type, ghost_type).begin();
auto insertion_stress_it =
this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
auto res_sliding_it = this->residual_sliding(el_type, ghost_type).begin();
auto res_sliding_prev_it =
this->residual_sliding.previous(el_type, ghost_type).begin();
auto friction_force_it =
this->friction_force(el_type, ghost_type).begin(spatial_dimension);
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
if (not this->model->isDefaultSolverExplicit())
this->delta_max(el_type, ghost_type)
.copy(this->delta_max.previous(el_type, ghost_type));
/// loop on each quadrature point
for (; traction_it != traction_end;
++traction_it, ++opening_it, ++normal_it, ++sigma_c_it, ++delta_max_it,
++delta_c_it, ++damage_it, ++contact_traction_it, ++insertion_stress_it,
++contact_opening_it, ++delta_max_prev_it, ++res_sliding_it,
++res_sliding_prev_it, ++friction_force_it, ++previous_opening_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
this->computeTractionOnQuad(
*traction_it, *opening_it, *normal_it, *delta_max_it, *delta_c_it,
*insertion_stress_it, *sigma_c_it, normal_opening, tangential_opening,
normal_opening_norm, tangential_opening_norm, *damage_it, penetration,
*contact_traction_it, *contact_opening_it);
if (penetration) {
/// the friction coefficient mu increases with the damage. It
/// equals the maximum value when damage = 1.
// Real damage = std::min(*delta_max_prev_it / *delta_c_it,
// Real(1.));
Real mu = mu_max; // * damage;
/// the definition of tau_max refers to the opening
/// (penetration) of the previous incremental step
Real normal_opening_prev_norm =
std::min(previous_opening_it->dot(*normal_it), Real(0.));
// Vector<Real> normal_opening_prev = (*normal_it);
// normal_opening_prev *= normal_opening_prev_norm;
Real tau_max = mu * this->penalty * (std::abs(normal_opening_prev_norm));
Real delta_sliding_norm =
std::abs(tangential_opening_norm - *res_sliding_prev_it);
/// tau is the norm of the friction force, acting tangentially to the
/// surface
Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
if ((tangential_opening_norm - *res_sliding_prev_it) < 0.0)
tau = -tau;
/// from tau get the x and y components of friction, to be added in the
/// force vector
Vector<Real> tangent_unit_vector(spatial_dimension);
tangent_unit_vector = tangential_opening / tangential_opening_norm;
*friction_force_it = tau * tangent_unit_vector;
/// update residual_sliding
*res_sliding_it =
tangential_opening_norm - (std::abs(tau) / friction_penalty);
} else {
friction_force_it->clear();
}
*traction_it += *friction_force_it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearFriction<spatial_dimension>::computeTangentTraction(
const ElementType & el_type, Array<Real> & tangent_matrix,
__attribute__((unused)) const Array<Real> & normal, GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
auto tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
auto tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
auto normal_it = this->normal.begin(spatial_dimension);
auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
auto previous_opening_it =
this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
/**
* NB: delta_max_it points on delta_max_previous, i.e. the
* delta_max related to the solution of the previous incremental
* step
*/
auto delta_max_it = this->delta_max.previous(el_type, ghost_type).begin();
auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
auto damage_it = this->damage(el_type, ghost_type).begin();
auto contact_opening_it =
this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
auto res_sliding_prev_it =
this->residual_sliding.previous(el_type, ghost_type).begin();
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
for (; tangent_it != tangent_end;
++tangent_it, ++normal_it, ++opening_it, ++previous_opening_it,
++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
++contact_opening_it, ++res_sliding_prev_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
this->computeTangentTractionOnQuad(
*tangent_it, *delta_max_it, *delta_c_it, *sigma_c_it, *opening_it,
*normal_it, normal_opening, tangential_opening, normal_opening_norm,
tangential_opening_norm, *damage_it, penetration, *contact_opening_it);
if (penetration) {
// Real damage = std::min(*delta_max_it / *delta_c_it, Real(1.));
Real mu = mu_max; // * damage;
Real normal_opening_prev_norm =
std::min(previous_opening_it->dot(*normal_it), Real(0.));
// Vector<Real> normal_opening_prev = (*normal_it);
// normal_opening_prev *= normal_opening_prev_norm;
- Real tau_max =
- mu * this->penalty * (std::abs(normal_opening_prev_norm));
+ Real tau_max = mu * this->penalty * (std::abs(normal_opening_prev_norm));
Real delta_sliding_norm =
std::abs(tangential_opening_norm - *res_sliding_prev_it);
// tau is the norm of the friction force, acting tangentially to the
// surface
Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
if (tau < tau_max && tau_max > Math::getTolerance()) {
Matrix<Real> I(spatial_dimension, spatial_dimension);
I.eye(1.);
Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
n_outer_n.outerProduct(*normal_it, *normal_it);
Matrix<Real> nn(n_outer_n);
I -= nn;
*tangent_it += I * friction_penalty;
}
}
// check if the tangential stiffness matrix is symmetric
// for (UInt h = 0; h < spatial_dimension; ++h){
// for (UInt l = h; l < spatial_dimension; ++l){
// if (l > h){
// Real k_ls = (*tangent_it)[spatial_dimension*h+l];
// Real k_us = (*tangent_it)[spatial_dimension*l+h];
// // std::cout << "k_ls = " << k_ls << std::endl;
// // std::cout << "k_us = " << k_us << std::endl;
// if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
// Real error = std::abs((k_ls - k_us) / k_us);
// if (error > 1e-10){
// std::cout << "non symmetric cohesive matrix" << std::endl;
// // std::cout << "error " << error << std::endl;
// }
// }
// }
// }
// }
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(cohesive_linear_friction, MaterialCohesiveLinearFriction);
} // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
index ee0d09fa2..f928863f1 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
@@ -1,107 +1,106 @@
/**
* @file material_cohesive_linear_friction.hh
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Jan 12 2016
*
* @brief Linear irreversible cohesive law of mixed mode loading with
* random stress definition for extrinsic type
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
#define __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
* Cohesive material linear with friction force
*
* parameters in the material files :
* - mu : friction coefficient
* - penalty_for_friction : Penalty parameter for the friction behavior
*/
-template<UInt spatial_dimension>
-class MaterialCohesiveLinearFriction : public MaterialCohesiveLinear<spatial_dimension> {
+template <UInt spatial_dimension>
+class MaterialCohesiveLinearFriction
+ : public MaterialCohesiveLinear<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
using MaterialParent = MaterialCohesiveLinear<spatial_dimension>;
public:
-
- MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id = "");
+ MaterialCohesiveLinearFriction(SolidMechanicsModel & model,
+ const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// initialize the material parameters
void initMaterial() override;
protected:
/// constitutive law
void computeTraction(const Array<Real> & normal, ElementType el_type,
GhostType ghost_type = _not_ghost) override;
/// compute tangent stiffness matrix
void computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type) override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// maximum value of the friction coefficient
Real mu_max;
/// penalty parameter for the friction law
Real friction_penalty;
/// history parameter for the friction law
CohesiveInternalField<Real> residual_sliding;
/// friction force
CohesiveInternalField<Real> friction_force;
};
} // akantu
#endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
index 49e9c5a22..08322ed07 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
@@ -1,265 +1,264 @@
/**
* @file material_cohesive_linear_inline_impl.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Apr 22 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Inline functions of the MaterialCohesiveLinear
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear.hh"
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
#define __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline Real MaterialCohesiveLinear<dim>::computeEffectiveNorm(
const Matrix<Real> & stress, const Vector<Real> & normal,
const Vector<Real> & tangent, Vector<Real> & normal_traction) const {
normal_traction.mul<false>(stress, normal);
Real normal_contrib = normal_traction.dot(normal);
/// in 3D tangential components must be summed
Real tangent_contrib = 0;
if (dim == 2) {
Real tangent_contrib_tmp = normal_traction.dot(tangent);
tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
} else if (dim == 3) {
for (UInt s = 0; s < dim - 1; ++s) {
const Vector<Real> tangent_v(tangent.storage() + s * dim, dim);
Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
}
}
tangent_contrib = std::sqrt(tangent_contrib);
normal_contrib = std::max(Real(0.), normal_contrib);
return std::sqrt(normal_contrib * normal_contrib +
tangent_contrib * tangent_contrib * beta2_inv);
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialCohesiveLinear<dim>::computeTractionOnQuad(
Vector<Real> & traction, Vector<Real> & opening,
- const Vector<Real> & normal, Real & delta_max,
- const Real & delta_c, const Vector<Real> & insertion_stress,
- const Real & sigma_c, Vector<Real> & normal_opening,
- Vector<Real> & tangential_opening, Real & normal_opening_norm,
- Real & tangential_opening_norm, Real & damage, bool & penetration,
- Vector<Real> & contact_traction, Vector<Real> & contact_opening) {
+ const Vector<Real> & normal, Real & delta_max, const Real & delta_c,
+ const Vector<Real> & insertion_stress, const Real & sigma_c,
+ Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
+ Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
+ bool & penetration, Vector<Real> & contact_traction,
+ Vector<Real> & contact_opening) {
/// compute normal and tangential opening vectors
normal_opening_norm = opening.dot(normal);
normal_opening = normal;
normal_opening *= normal_opening_norm;
tangential_opening = opening;
tangential_opening -= normal_opening;
tangential_opening_norm = tangential_opening.norm();
/**
* compute effective opening displacement
* @f$ \delta = \sqrt{
* \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
*/
Real delta =
tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
penetration = normal_opening_norm / delta_c < -Math::getTolerance();
- //penetration = normal_opening_norm < 0.;
+ // penetration = normal_opening_norm < 0.;
if (this->contact_after_breaking == false &&
Math::are_float_equal(damage, 1.))
penetration = false;
if (penetration) {
/// use penalty coefficient in case of penetration
contact_traction = normal_opening;
contact_traction *= this->penalty;
contact_opening = normal_opening;
/// don't consider penetration contribution for delta
opening = tangential_opening;
normal_opening.clear();
} else {
delta += normal_opening_norm * normal_opening_norm;
contact_traction.clear();
contact_opening.clear();
}
delta = std::sqrt(delta);
/// update maximum displacement and damage
delta_max = std::max(delta_max, delta);
damage = std::min(delta_max / delta_c, Real(1.));
/**
* Compute traction @f$ \mathbf{T} = \left(
* \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
* \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
* \frac{\delta}{\delta_c} \right)@f$
*/
if (Math::are_float_equal(damage, 1.))
traction.clear();
else if (Math::are_float_equal(damage, 0.)) {
if (penetration)
traction.clear();
else
traction = insertion_stress;
} else {
traction = tangential_opening;
traction *= this->beta2_kappa;
traction += normal_opening;
AKANTU_DEBUG_ASSERT(delta_max != 0.,
"Division by zero, tolerance might be too low");
traction *= sigma_c / delta_max * (1. - damage);
}
}
/* -------------------------------------------------------------------------- */
template <UInt dim>
inline void MaterialCohesiveLinear<dim>::computeTangentTractionOnQuad(
Matrix<Real> & tangent, Real & delta_max, const Real & delta_c,
const Real & sigma_c, Vector<Real> & opening, const Vector<Real> & normal,
Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
- bool & penetration,
- Vector<Real> & contact_opening) {
+ bool & penetration, Vector<Real> & contact_opening) {
/**
* During the update of the residual the interpenetrations are
* stored in the array "contact_opening", therefore, in the case
* of penetration, in the array "opening" there are only the
* tangential components.
*/
opening += contact_opening;
/// compute normal and tangential opening vectors
normal_opening_norm = opening.dot(normal);
normal_opening = normal;
normal_opening *= normal_opening_norm;
tangential_opening = opening;
tangential_opening -= normal_opening;
tangential_opening_norm = tangential_opening.norm();
Real delta =
tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
penetration = normal_opening_norm < 0.0;
if (this->contact_after_breaking == false &&
Math::are_float_equal(damage, 1.))
penetration = false;
Real derivative = 0; // derivative = d(t/delta)/ddelta
Real t = 0;
Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
n_outer_n.outerProduct(normal, normal);
if (penetration) {
/// stiffness in compression given by the penalty parameter
tangent += n_outer_n;
tangent *= penalty;
opening = tangential_opening;
normal_opening_norm = opening.dot(normal);
normal_opening = normal;
normal_opening *= normal_opening_norm;
} else {
delta += normal_opening_norm * normal_opening_norm;
}
delta = std::sqrt(delta);
/**
* Delta has to be different from 0 to have finite values of
* tangential stiffness. At the element insertion, delta =
* 0. Therefore, a fictictious value is defined, for the
* evaluation of the first value of K.
*/
if (delta < Math::getTolerance())
delta = delta_c / 1000.;
if (delta >= delta_max) {
if (delta <= delta_c) {
derivative = -sigma_c / (delta * delta);
t = sigma_c * (1 - delta / delta_c);
} else {
derivative = 0.;
t = 0.;
}
} else if (delta < delta_max) {
Real tmax = sigma_c * (1 - delta_max / delta_c);
t = tmax / delta_max * delta;
}
/// computation of the derivative of the constitutive law (dT/ddelta)
Matrix<Real> I(spatial_dimension, spatial_dimension);
I.eye(this->beta2_kappa);
Matrix<Real> nn(n_outer_n);
nn *= (1. - this->beta2_kappa);
nn += I;
nn *= t / delta;
Vector<Real> t_tilde(normal_opening);
t_tilde *= (1. - this->beta2_kappa2);
Vector<Real> mm(opening);
mm *= this->beta2_kappa2;
t_tilde += mm;
Vector<Real> t_hat(normal_opening);
t_hat += this->beta2_kappa * tangential_opening;
Matrix<Real> prov(spatial_dimension, spatial_dimension);
prov.outerProduct(t_hat, t_tilde);
prov *= derivative / delta;
prov += nn;
Matrix<Real> prov_t = prov.transpose();
tangent += prov_t;
}
/* -------------------------------------------------------------------------- */
} // akantu
/* -------------------------------------------------------------------------- */
#endif //__AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
index 7cf36d8f1..f31411171 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
@@ -1,415 +1,414 @@
/**
* @file material_cohesive_linear_uncoupled.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Wed Feb 22 2012
* @date last modification: Thu Jan 14 2016
*
* @brief Linear irreversible cohesive law of mixed mode loading with
* random stress definition for extrinsic type
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <numeric>
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear_uncoupled.hh"
#include "solid_mechanics_model_cohesive.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
MaterialCohesiveLinearUncoupled<spatial_dimension>::
MaterialCohesiveLinearUncoupled(SolidMechanicsModel & model, const ID & id)
: MaterialCohesiveLinear<spatial_dimension>(model, id),
delta_n_max("delta_n_max", *this), delta_t_max("delta_t_max", *this),
damage_n("damage_n", *this), damage_t("damage_t", *this) {
AKANTU_DEBUG_IN();
this->registerParam(
"roughness", R, Real(1.), _pat_parsable | _pat_readable,
"Roughness to define coupling between mode II and mode I");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearUncoupled<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialCohesiveLinear<spatial_dimension>::initMaterial();
delta_n_max.initialize(1);
delta_t_max.initialize(1);
damage_n.initialize(1);
damage_t.initialize(1);
delta_n_max.initializeHistory();
delta_t_max.initializeHistory();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTraction(
const Array<Real> &, ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
delta_n_max.resize();
delta_t_max.resize();
damage_n.resize();
damage_t.resize();
/// define iterators
auto traction_it =
this->tractions(el_type, ghost_type).begin(spatial_dimension);
auto traction_end =
this->tractions(el_type, ghost_type).end(spatial_dimension);
auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
auto contact_traction_it =
this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
auto contact_opening_it =
this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
auto normal_it = this->normal.begin(spatial_dimension);
auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
auto delta_n_max_it = delta_n_max(el_type, ghost_type).begin();
auto delta_t_max_it = delta_t_max(el_type, ghost_type).begin();
auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
auto damage_n_it = damage_n(el_type, ghost_type).begin();
auto damage_t_it = damage_t(el_type, ghost_type).begin();
auto insertion_stress_it =
this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
/// loop on each quadrature point
for (; traction_it != traction_end;
- ++traction_it, ++opening_it, ++contact_traction_it,
- ++contact_opening_it, ++normal_it, ++sigma_c_it, ++delta_n_max_it,
- ++delta_t_max_it, ++delta_c_it, ++damage_n_it, ++damage_t_it,
- ++insertion_stress_it) {
+ ++traction_it, ++opening_it, ++contact_traction_it, ++contact_opening_it,
+ ++normal_it, ++sigma_c_it, ++delta_n_max_it, ++delta_t_max_it,
+ ++delta_c_it, ++damage_n_it, ++damage_t_it, ++insertion_stress_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
/// compute normal and tangential opening vectors
normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening = *normal_it;
normal_opening *= normal_opening_norm;
// std::cout<< "normal_opening_norm = " << normal_opening_norm
// <<std::endl;
Vector<Real> tangential_opening = *opening_it;
tangential_opening -= normal_opening;
tangential_opening_norm = tangential_opening.norm();
/// compute effective opening displacement
Real delta_n =
tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
Real delta_t =
tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
penetration = normal_opening_norm < 0.0;
if (this->contact_after_breaking == false &&
Math::are_float_equal(*damage_n_it, 1.))
penetration = false;
if (penetration) {
/// use penalty coefficient in case of penetration
*contact_traction_it = normal_opening;
*contact_traction_it *= this->penalty;
*contact_opening_it = normal_opening;
/// don't consider penetration contribution for delta
//*opening_it = tangential_opening;
normal_opening.clear();
} else {
delta_n += normal_opening_norm * normal_opening_norm;
delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
contact_traction_it->clear();
contact_opening_it->clear();
}
delta_n = std::sqrt(delta_n);
delta_t = std::sqrt(delta_t);
/// update maximum displacement and damage
*delta_n_max_it = std::max(*delta_n_max_it, delta_n);
*damage_n_it = std::min(*delta_n_max_it / *delta_c_it, Real(1.));
*delta_t_max_it = std::max(*delta_t_max_it, delta_t);
*damage_t_it = std::min(*delta_t_max_it / *delta_c_it, Real(1.));
Vector<Real> normal_traction(spatial_dimension);
Vector<Real> shear_traction(spatial_dimension);
/// NORMAL TRACTIONS
if (Math::are_float_equal(*damage_n_it, 1.))
normal_traction.clear();
else if (Math::are_float_equal(*damage_n_it, 0.)) {
if (penetration)
normal_traction.clear();
else
normal_traction = *insertion_stress_it;
} else {
// the following formulation holds both in loading and in
// unloading-reloading
normal_traction = normal_opening;
AKANTU_DEBUG_ASSERT(*delta_n_max_it != 0.,
"Division by zero, tolerance might be too low");
normal_traction *= *sigma_c_it / (*delta_n_max_it) * (1. - *damage_n_it);
}
/// SHEAR TRACTIONS
if (Math::are_float_equal(*damage_t_it, 1.))
shear_traction.clear();
else if (Math::are_float_equal(*damage_t_it, 0.)) {
shear_traction.clear();
} else {
shear_traction = tangential_opening;
AKANTU_DEBUG_ASSERT(*delta_t_max_it != 0.,
"Division by zero, tolerance might be too low");
shear_traction *= this->beta2_kappa;
shear_traction *= *sigma_c_it / (*delta_t_max_it) * (1. - *damage_t_it);
}
*traction_it = normal_traction;
*traction_it += shear_traction;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTangentTraction(
const ElementType & el_type, Array<Real> & tangent_matrix,
const Array<Real> &, GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
auto tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
auto tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
auto normal_it = this->normal.begin(spatial_dimension);
auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
/// NB: delta_max_it points on delta_max_previous, i.e. the
/// delta_max related to the solution of the previous incremental
/// step
auto delta_n_max_it = delta_n_max.previous(el_type, ghost_type).begin();
auto delta_t_max_it = delta_t_max.previous(el_type, ghost_type).begin();
auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
auto damage_n_it = damage_n(el_type, ghost_type).begin();
auto contact_opening_it =
this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
Vector<Real> normal_opening(spatial_dimension);
Vector<Real> tangential_opening(spatial_dimension);
for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it,
++sigma_c_it, ++delta_c_it,
++delta_n_max_it, ++delta_t_max_it,
++damage_n_it, ++contact_opening_it) {
Real normal_opening_norm, tangential_opening_norm;
bool penetration;
Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
/**
* During the update of the residual the interpenetrations are
* stored in the array "contact_opening", therefore, in the case
* of penetration, in the array "opening" there are only the
* tangential components.
*/
*opening_it += *contact_opening_it;
/// compute normal and tangential opening vectors
normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening = *normal_it;
normal_opening *= normal_opening_norm;
Vector<Real> tangential_opening = *opening_it;
tangential_opening -= normal_opening;
tangential_opening_norm = tangential_opening.norm();
Real delta_n =
tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
Real delta_t =
tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
penetration = normal_opening_norm < 0.0;
if (this->contact_after_breaking == false &&
Math::are_float_equal(*damage_n_it, 1.))
penetration = false;
Real derivative = 0; // derivative = d(t/delta)/ddelta
Real T = 0;
/// TANGENT STIFFNESS FOR NORMAL TRACTIONS
Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
n_outer_n.outerProduct(*normal_it, *normal_it);
if (penetration) {
/// stiffness in compression given by the penalty parameter
*tangent_it = n_outer_n;
*tangent_it *= this->penalty;
//*opening_it = tangential_opening;
normal_opening.clear();
} else {
delta_n += normal_opening_norm * normal_opening_norm;
delta_n = std::sqrt(delta_n);
delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
/**
* Delta has to be different from 0 to have finite values of
* tangential stiffness. At the element insertion, delta =
* 0. Therefore, a fictictious value is defined, for the
* evaluation of the first value of K.
*/
if (delta_n < Math::getTolerance())
delta_n = *delta_c_it / 1000.;
// loading
if (delta_n >= *delta_n_max_it) {
if (delta_n <= *delta_c_it) {
derivative = -(*sigma_c_it) / (delta_n * delta_n);
T = *sigma_c_it * (1 - delta_n / *delta_c_it);
} else {
derivative = 0.;
T = 0.;
}
// unloading-reloading
} else if (delta_n < *delta_n_max_it) {
Real T_max = *sigma_c_it * (1 - *delta_n_max_it / *delta_c_it);
derivative = 0.;
T = T_max / *delta_n_max_it * delta_n;
}
/// computation of the derivative of the constitutive law (dT/ddelta)
Matrix<Real> nn(n_outer_n);
nn *= T / delta_n;
Vector<Real> Delta_tilde(normal_opening);
Delta_tilde *= (1. - this->beta2_kappa2);
Vector<Real> mm(*opening_it);
mm *= this->beta2_kappa2;
Delta_tilde += mm;
const Vector<Real> & Delta_hat(normal_opening);
Matrix<Real> prov(spatial_dimension, spatial_dimension);
prov.outerProduct(Delta_hat, Delta_tilde);
prov *= derivative / delta_n;
prov += nn;
Matrix<Real> prov_t = prov.transpose();
*tangent_it = prov_t;
}
derivative = 0.;
T = 0.;
/// TANGENT STIFFNESS FOR SHEAR TRACTIONS
delta_t = std::sqrt(delta_t);
/**
* Delta has to be different from 0 to have finite values of
* tangential stiffness. At the element insertion, delta =
* 0. Therefore, a fictictious value is defined, for the
* evaluation of the first value of K.
*/
if (delta_t < Math::getTolerance())
delta_t = *delta_c_it / 1000.;
// loading
if (delta_t >= *delta_t_max_it) {
if (delta_t <= *delta_c_it) {
derivative = -(*sigma_c_it) / (delta_t * delta_t);
T = *sigma_c_it * (1 - delta_t / *delta_c_it);
} else {
derivative = 0.;
T = 0.;
}
// unloading-reloading
} else if (delta_t < *delta_t_max_it) {
Real T_max = *sigma_c_it * (1 - *delta_t_max_it / *delta_c_it);
derivative = 0.;
T = T_max / *delta_t_max_it * delta_t;
}
/// computation of the derivative of the constitutive law (dT/ddelta)
Matrix<Real> I(spatial_dimension, spatial_dimension);
I.eye();
Matrix<Real> nn(n_outer_n);
I -= nn;
I *= T / delta_t;
Vector<Real> Delta_tilde(normal_opening);
Delta_tilde *= (delta_c2_R2 - this->beta2_kappa2);
Vector<Real> mm(*opening_it);
mm *= this->beta2_kappa2;
Delta_tilde += mm;
Vector<Real> Delta_hat(tangential_opening);
Delta_hat *= this->beta2_kappa;
Matrix<Real> prov(spatial_dimension, spatial_dimension);
prov.outerProduct(Delta_hat, Delta_tilde);
prov *= derivative / delta_t;
prov += I;
Matrix<Real> prov_t = prov.transpose();
*tangent_it += prov_t;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(cohesive_linear_uncoupled,
MaterialCohesiveLinearUncoupled);
} // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
index 130bf7a92..4d55b04ce 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
@@ -1,572 +1,573 @@
/**
* @file material_cohesive.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Feb 22 2012
* @date last modification: Tue Jan 12 2016
*
* @brief Specialization of the material class for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive.hh"
#include "aka_random_generator.hh"
#include "dof_synchronizer.hh"
#include "fe_engine_template.hh"
#include "integrator_gauss.hh"
#include "shape_cohesive.hh"
#include "solid_mechanics_model_cohesive.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
MaterialCohesive::MaterialCohesive(SolidMechanicsModel & model, const ID & id)
: Material(model, id),
facet_filter("facet_filter", id, this->getMemoryID()),
fem_cohesive(
model.getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine")),
reversible_energy("reversible_energy", *this),
total_energy("total_energy", *this), opening("opening", *this),
tractions("tractions", *this),
contact_tractions("contact_tractions", *this),
contact_opening("contact_opening", *this), delta_max("delta max", *this),
use_previous_delta_max(false), use_previous_opening(false),
damage("damage", *this), sigma_c("sigma_c", *this),
normal(0, spatial_dimension, "normal") {
AKANTU_DEBUG_IN();
this->model = dynamic_cast<SolidMechanicsModelCohesive *>(&model);
this->registerParam("sigma_c", sigma_c, _pat_parsable | _pat_readable,
"Critical stress");
this->registerParam("delta_c", delta_c, Real(0.),
_pat_parsable | _pat_readable, "Critical displacement");
this->element_filter.initialize(this->model->getMesh(),
_spatial_dimension = spatial_dimension,
_element_kind = _ek_cohesive);
// this->model->getMesh().initElementTypeMapArray(
// this->element_filter, 1, spatial_dimension, false, _ek_cohesive);
if (this->model->getIsExtrinsic())
this->facet_filter.initialize(this->model->getMeshFacets(),
_spatial_dimension = spatial_dimension - 1,
_element_kind = _ek_regular);
// this->model->getMeshFacets().initElementTypeMapArray(facet_filter, 1,
// spatial_dimension -
// 1);
this->reversible_energy.initialize(1);
this->total_energy.initialize(1);
this->tractions.initialize(spatial_dimension);
this->tractions.initializeHistory();
this->contact_tractions.initialize(spatial_dimension);
this->contact_opening.initialize(spatial_dimension);
this->opening.initialize(spatial_dimension);
this->opening.initializeHistory();
this->delta_max.initialize(1);
this->damage.initialize(1);
if (this->model->getIsExtrinsic())
this->sigma_c.initialize(1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MaterialCohesive::~MaterialCohesive() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
if (this->use_previous_delta_max)
this->delta_max.initializeHistory();
if (this->use_previous_opening)
this->opening.initializeHistory();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::assembleInternalForces(GhostType ghost_type) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(debug::_dm_material_cohesive,
"Cohesive Tractions", tractions);
#endif
auto & internal_force = const_cast<Array<Real> &>(model->getInternalForce());
for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type,
_ek_cohesive)) {
auto & elem_filter = element_filter(type, ghost_type);
UInt nb_element = elem_filter.size();
if (nb_element == 0)
continue;
const auto & shapes = fem_cohesive.getShapes(type, ghost_type);
auto & traction = tractions(type, ghost_type);
auto & contact_traction = contact_tractions(type, ghost_type);
UInt size_of_shapes = shapes.getNbComponent();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points =
fem_cohesive.getNbIntegrationPoints(type, ghost_type);
/// compute @f$t_i N_a@f$
Array<Real> * traction_cpy = new Array<Real>(
nb_element * nb_quadrature_points, spatial_dimension * size_of_shapes);
auto traction_it = traction.begin(spatial_dimension, 1);
auto contact_traction_it = contact_traction.begin(spatial_dimension, 1);
auto shapes_filtered_begin = shapes.begin(1, size_of_shapes);
auto traction_cpy_it =
traction_cpy->begin(spatial_dimension, size_of_shapes);
Matrix<Real> traction_tmp(spatial_dimension, 1);
for (UInt el = 0; el < nb_element; ++el) {
UInt current_quad = elem_filter(el) * nb_quadrature_points;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++traction_it,
++contact_traction_it, ++current_quad, ++traction_cpy_it) {
const Matrix<Real> & shapes_filtered =
shapes_filtered_begin[current_quad];
traction_tmp.copy(*traction_it);
traction_tmp += *contact_traction_it;
traction_cpy_it->mul<false, false>(traction_tmp, shapes_filtered);
}
}
/**
* compute @f$\int t \cdot N\, dS@f$ by @f$ \sum_q \mathbf{N}^t
* \mathbf{t}_q \overline w_q J_q@f$
*/
Array<Real> * int_t_N = new Array<Real>(
nb_element, spatial_dimension * size_of_shapes, "int_t_N");
fem_cohesive.integrate(*traction_cpy, *int_t_N,
spatial_dimension * size_of_shapes, type, ghost_type,
elem_filter);
delete traction_cpy;
int_t_N->extendComponentsInterlaced(2, int_t_N->getNbComponent());
Real * int_t_N_val = int_t_N->storage();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < size_of_shapes * spatial_dimension; ++n)
int_t_N_val[n] *= -1.;
int_t_N_val += nb_nodes_per_element * spatial_dimension;
}
/// assemble
model->getDOFManager().assembleElementalArrayLocalArray(
*int_t_N, internal_force, type, ghost_type, -1, elem_filter);
delete int_t_N;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::assembleStiffnessMatrix(GhostType ghost_type) {
AKANTU_DEBUG_IN();
for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type,
_ek_cohesive)) {
UInt nb_quadrature_points =
fem_cohesive.getNbIntegrationPoints(type, ghost_type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<Real> & shapes = fem_cohesive.getShapes(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
UInt nb_element = elem_filter.size();
if (!nb_element)
continue;
UInt size_of_shapes = shapes.getNbComponent();
Array<Real> * shapes_filtered = new Array<Real>(
nb_element * nb_quadrature_points, size_of_shapes, "filtered shapes");
Real * shapes_filtered_val = shapes_filtered->storage();
UInt * elem_filter_val = elem_filter.storage();
for (UInt el = 0; el < nb_element; ++el) {
auto shapes_val =
shapes.storage() +
elem_filter_val[el] * size_of_shapes * nb_quadrature_points;
memcpy(shapes_filtered_val, shapes_val,
size_of_shapes * nb_quadrature_points * sizeof(Real));
shapes_filtered_val += size_of_shapes * nb_quadrature_points;
}
/**
* compute A matrix @f$ \mathbf{A} = \left[\begin{array}{c c c c c c c c c c
*c c}
* 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 \\
* 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 \\
* 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\
* 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 \\
* 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 \\
* 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1
* \end{array} \right]@f$
**/
// UInt size_of_A =
// spatial_dimension*size_of_shapes*spatial_dimension*nb_nodes_per_element;
// Real * A = new Real[size_of_A];
// memset(A, 0, size_of_A*sizeof(Real));
Matrix<Real> A(spatial_dimension * size_of_shapes,
spatial_dimension * nb_nodes_per_element);
for (UInt i = 0; i < spatial_dimension * size_of_shapes; ++i) {
A(i, i) = 1;
A(i, i + spatial_dimension * size_of_shapes) = -1;
}
// compute traction. This call is not necessary for the linear
// cohesive law that, currently, is the only one used for the
// extrinsic approach.
// if (!model->getIsExtrinsic()){
// computeTraction(ghost_type);
//}
/// get the tangent matrix @f$\frac{\partial{(t/\delta)}}{\partial{\delta}}
/// @f$
Array<Real> * tangent_stiffness_matrix = new Array<Real>(
nb_element * nb_quadrature_points,
spatial_dimension * spatial_dimension, "tangent_stiffness_matrix");
// Array<Real> * normal = new Array<Real>(nb_element *
// nb_quadrature_points, spatial_dimension, "normal");
normal.resize(nb_quadrature_points);
computeNormal(model->getCurrentPosition(), normal, type, ghost_type);
/// compute openings @f$\mathbf{\delta}@f$
// computeOpening(model->getDisplacement(), opening(type, ghost_type), type,
// ghost_type);
tangent_stiffness_matrix->clear();
computeTangentTraction(type, *tangent_stiffness_matrix, normal, ghost_type);
// delete normal;
UInt size_at_nt_d_n_a = spatial_dimension * nb_nodes_per_element *
spatial_dimension * nb_nodes_per_element;
Array<Real> * at_nt_d_n_a = new Array<Real>(
nb_element * nb_quadrature_points, size_at_nt_d_n_a, "A^t*N^t*D*N*A");
Array<Real>::iterator<Vector<Real>> shapes_filt_it =
shapes_filtered->begin(size_of_shapes);
Array<Real>::matrix_iterator D_it =
tangent_stiffness_matrix->begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator At_Nt_D_N_A_it =
at_nt_d_n_a->begin(spatial_dimension * nb_nodes_per_element,
spatial_dimension * nb_nodes_per_element);
Array<Real>::matrix_iterator At_Nt_D_N_A_end =
at_nt_d_n_a->end(spatial_dimension * nb_nodes_per_element,
spatial_dimension * nb_nodes_per_element);
Matrix<Real> N(spatial_dimension, spatial_dimension * size_of_shapes);
Matrix<Real> N_A(spatial_dimension,
spatial_dimension * nb_nodes_per_element);
Matrix<Real> D_N_A(spatial_dimension,
spatial_dimension * nb_nodes_per_element);
for (; At_Nt_D_N_A_it != At_Nt_D_N_A_end;
++At_Nt_D_N_A_it, ++D_it, ++shapes_filt_it) {
N.clear();
/**
* store the shapes in voigt notations matrix @f$\mathbf{N} =
* \begin{array}{cccccc} N_0(\xi) & 0 & N_1(\xi) &0 & N_2(\xi) & 0 \\
* 0 & * N_0(\xi)& 0 &N_1(\xi)& 0 & N_2(\xi) \end{array} @f$
**/
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt n = 0; n < size_of_shapes; ++n)
N(i, i + spatial_dimension * n) = (*shapes_filt_it)(n);
/**
* compute stiffness matrix @f$ \mathbf{K} = \delta \mathbf{U}^T
* \int_{\Gamma_c} {\mathbf{P}^t \frac{\partial{\mathbf{t}}}
*{\partial{\delta}}
* \mathbf{P} d\Gamma \Delta \mathbf{U}} @f$
**/
N_A.mul<false, false>(N, A);
D_N_A.mul<false, false>(*D_it, N_A);
(*At_Nt_D_N_A_it).mul<true, false>(D_N_A, N_A);
}
delete tangent_stiffness_matrix;
delete shapes_filtered;
Array<Real> * K_e = new Array<Real>(nb_element, size_at_nt_d_n_a, "K_e");
fem_cohesive.integrate(*at_nt_d_n_a, *K_e, size_at_nt_d_n_a, type,
ghost_type, elem_filter);
delete at_nt_d_n_a;
model->getDOFManager().assembleElementalMatricesToMatrix(
"K", "displacement", *K_e, type, ghost_type, _unsymmetric, elem_filter);
delete K_e;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- *
* Compute traction from displacements
*
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void MaterialCohesive::computeTraction(GhostType ghost_type) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(debug::_dm_material_cohesive,
"Cohesive Openings", opening);
#endif
for (auto & type : element_filter.elementTypes(spatial_dimension, ghost_type,
_ek_cohesive)) {
Array<UInt> & elem_filter = element_filter(type, ghost_type);
UInt nb_element = elem_filter.size();
if (nb_element == 0)
continue;
UInt nb_quadrature_points =
nb_element * fem_cohesive.getNbIntegrationPoints(type, ghost_type);
normal.resize(nb_quadrature_points);
/// compute normals @f$\mathbf{n}@f$
computeNormal(model->getCurrentPosition(), normal, type, ghost_type);
/// compute openings @f$\mathbf{\delta}@f$
computeOpening(model->getDisplacement(), opening(type, ghost_type), type,
ghost_type);
/// compute traction @f$\mathbf{t}@f$
computeTraction(normal, type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::computeNormal(const Array<Real> & position,
Array<Real> & normal, ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
auto & fem_cohesive =
this->model->getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine");
#define COMPUTE_NORMAL(type) \
fem_cohesive.getShapeFunctions() \
.computeNormalsOnIntegrationPoints<type, CohesiveReduceFunctionMean>( \
position, normal, ghost_type, element_filter(type, ghost_type));
- AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_NORMAL);
+ AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_NORMAL);
#undef COMPUTE_NORMAL
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MaterialCohesive::computeOpening(const Array<Real> & displacement,
Array<Real> & opening, ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
auto & fem_cohesive =
this->model->getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine");
#define COMPUTE_OPENING(type) \
fem_cohesive.getShapeFunctions() \
.interpolateOnIntegrationPoints<type, CohesiveReduceFunctionOpening>( \
displacement, opening, spatial_dimension, ghost_type, \
element_filter(type, ghost_type));
AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_OPENING);
#undef COMPUTE_OPENING
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void MaterialCohesive::updateEnergies(ElementType type,
- GhostType ghost_type) {
+void MaterialCohesive::updateEnergies(ElementType type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
- if(Mesh::getKind(type) != _ek_cohesive) return;
+ if (Mesh::getKind(type) != _ek_cohesive)
+ return;
Vector<Real> b(spatial_dimension);
Vector<Real> h(spatial_dimension);
auto erev = reversible_energy(type, ghost_type).begin();
auto etot = total_energy(type, ghost_type).begin();
auto traction_it = tractions(type, ghost_type).begin(spatial_dimension);
auto traction_old_it =
tractions.previous(type, ghost_type).begin(spatial_dimension);
auto opening_it = opening(type, ghost_type).begin(spatial_dimension);
- auto opening_old_it = opening.previous(type, ghost_type).begin(spatial_dimension);
+ auto opening_old_it =
+ opening.previous(type, ghost_type).begin(spatial_dimension);
auto traction_end = tractions(type, ghost_type).end(spatial_dimension);
/// loop on each quadrature point
for (; traction_it != traction_end; ++traction_it, ++traction_old_it,
++opening_it, ++opening_old_it, ++erev,
++etot) {
/// trapezoidal integration
b = *opening_it;
b -= *opening_old_it;
h = *traction_old_it;
h += *traction_it;
*etot += .5 * b.dot(h);
*erev = .5 * traction_it->dot(*opening_it);
}
/// update old values
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getReversibleEnergy() {
AKANTU_DEBUG_IN();
Real erev = 0.;
/// integrate reversible energy for each type of elements
for (auto & type : element_filter.elementTypes(spatial_dimension, _not_ghost,
_ek_cohesive)) {
erev +=
fem_cohesive.integrate(reversible_energy(type, _not_ghost), type,
_not_ghost, element_filter(type, _not_ghost));
}
AKANTU_DEBUG_OUT();
return erev;
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getDissipatedEnergy() {
AKANTU_DEBUG_IN();
Real edis = 0.;
/// integrate dissipated energy for each type of elements
for (auto & type : element_filter.elementTypes(spatial_dimension, _not_ghost,
_ek_cohesive)) {
Array<Real> dissipated_energy(total_energy(type, _not_ghost));
dissipated_energy -= reversible_energy(type, _not_ghost);
edis += fem_cohesive.integrate(dissipated_energy, type, _not_ghost,
element_filter(type, _not_ghost));
}
AKANTU_DEBUG_OUT();
return edis;
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getContactEnergy() {
AKANTU_DEBUG_IN();
Real econ = 0.;
/// integrate contact energy for each type of elements
for (auto & type : element_filter.elementTypes(spatial_dimension, _not_ghost,
_ek_cohesive)) {
auto & el_filter = element_filter(type, _not_ghost);
UInt nb_quad_per_el = fem_cohesive.getNbIntegrationPoints(type, _not_ghost);
UInt nb_quad_points = el_filter.size() * nb_quad_per_el;
Array<Real> contact_energy(nb_quad_points);
auto contact_traction_it =
contact_tractions(type, _not_ghost).begin(spatial_dimension);
auto contact_opening_it =
contact_opening(type, _not_ghost).begin(spatial_dimension);
/// loop on each quadrature point
for (UInt q = 0; q < nb_quad_points;
++contact_traction_it, ++contact_opening_it, ++q) {
contact_energy(q) = .5 * contact_traction_it->dot(*contact_opening_it);
}
econ += fem_cohesive.integrate(contact_energy, type, _not_ghost, el_filter);
}
AKANTU_DEBUG_OUT();
return econ;
}
/* -------------------------------------------------------------------------- */
Real MaterialCohesive::getEnergy(const std::string & type) {
AKANTU_DEBUG_IN();
if (type == "reversible")
return getReversibleEnergy();
else if (type == "dissipated")
return getDissipatedEnergy();
else if (type == "cohesive contact")
return getContactEnergy();
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
index 166121c90..2f854eb40 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
@@ -1,238 +1,238 @@
/**
* @file material_cohesive.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Jan 12 2016
*
* @brief Specialization of the material class for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material.hh"
/* -------------------------------------------------------------------------- */
#include "cohesive_internal_field.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_HH__
#define __AKANTU_MATERIAL_COHESIVE_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class SolidMechanicsModelCohesive;
}
namespace akantu {
class MaterialCohesive : public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
using MyFEEngineCohesiveType =
FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>;
public:
MaterialCohesive(SolidMechanicsModel & model, const ID & id = "");
~MaterialCohesive() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
void initMaterial() override;
/// compute tractions (including normals and openings)
void computeTraction(GhostType ghost_type = _not_ghost);
/// assemble residual
void assembleInternalForces(GhostType ghost_type = _not_ghost) override;
/// check stress for cohesive elements' insertion, by default it
/// also updates the cohesive elements' data
virtual void checkInsertion(bool /*check_only*/ = false) {
AKANTU_TO_IMPLEMENT();
}
/// interpolate stress on given positions for each element (empty
/// implemantation to avoid the generic call to be done on cohesive elements)
virtual void interpolateStress(const ElementType /*type*/,
- Array<Real> & /*result*/){}
+ Array<Real> & /*result*/) {}
/// compute the stresses
void computeAllStresses(GhostType /*ghost_type*/ = _not_ghost) override{};
// add the facet to be handled by the material
UInt addFacet(const Element & element);
protected:
virtual void computeTangentTraction(const ElementType & /*el_type*/,
Array<Real> & /*tangent_matrix*/,
const Array<Real> & /*normal*/,
GhostType /*ghost_type*/ = _not_ghost) {
AKANTU_TO_IMPLEMENT();
}
/// compute the normal
void computeNormal(const Array<Real> & position, Array<Real> & normal,
ElementType type, GhostType ghost_type);
/// compute the opening
void computeOpening(const Array<Real> & displacement, Array<Real> & opening,
ElementType type, GhostType ghost_type);
template <ElementType type>
void computeNormal(const Array<Real> & position, Array<Real> & normal,
GhostType ghost_type);
/// assemble stiffness
void assembleStiffnessMatrix(GhostType ghost_type) override;
/// constitutive law
virtual void computeTraction(const Array<Real> & normal, ElementType el_type,
GhostType ghost_type = _not_ghost) = 0;
/// parallelism functions
inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
protected:
void updateEnergies(ElementType el_type, GhostType ghost_type) override;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the opening
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Opening, opening, Real);
/// get the traction
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Traction, tractions, Real);
/// get damage
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
/// get facet filter
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetFilter, facet_filter, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetFilter, facet_filter, UInt);
AKANTU_GET_MACRO(FacetFilter, facet_filter,
const ElementTypeMapArray<UInt> &);
// AKANTU_GET_MACRO(ElementFilter, element_filter, const
// ElementTypeMapArray<UInt> &);
/// compute reversible energy
Real getReversibleEnergy();
/// compute dissipated energy
Real getDissipatedEnergy();
/// compute contact energy
Real getContactEnergy();
/// get energy
Real getEnergy(const std::string & type) override;
/// return the energy (identified by id) for the provided element
Real getEnergy(const std::string & energy_id, ElementType type,
UInt index) override {
return Material::getEnergy(energy_id, type, index);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// list of facets assigned to this material
ElementTypeMapArray<UInt> facet_filter;
/// Link to the cohesive fem object in the model
FEEngine & fem_cohesive;
private:
/// reversible energy by quadrature point
CohesiveInternalField<Real> reversible_energy;
/// total energy by quadrature point
CohesiveInternalField<Real> total_energy;
protected:
/// opening in all elements and quadrature points
CohesiveInternalField<Real> opening;
/// traction in all elements and quadrature points
CohesiveInternalField<Real> tractions;
/// traction due to contact
CohesiveInternalField<Real> contact_tractions;
/// normal openings for contact tractions
CohesiveInternalField<Real> contact_opening;
/// maximum displacement
CohesiveInternalField<Real> delta_max;
/// tell if the previous delta_max state is needed (in iterative schemes)
bool use_previous_delta_max;
/// tell if the previous opening state is needed (in iterative schemes)
bool use_previous_opening;
/// damage
CohesiveInternalField<Real> damage;
/// pointer to the solid mechanics model for cohesive elements
SolidMechanicsModelCohesive * model;
/// critical stress
RandomInternalField<Real, FacetInternalField> sigma_c;
/// critical displacement
Real delta_c;
/// array to temporarily store the normals
Array<Real> normal;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_cohesive_inline_impl.cc"
} // namespace akantu
#include "cohesive_internal_field_tmpl.hh"
#endif /* __AKANTU_MATERIAL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh
index 4ad8a634d..6548a282c 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh
@@ -1,49 +1,49 @@
/**
* @file material_cohesive_includes.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 26 2010
* @date last modification: Tue Jan 12 2016
*
* @brief List of includes for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef AKANTU_CMAKE_LIST_MATERIALS
#include "material_cohesive.hh"
+#include "material_cohesive_bilinear.hh"
+#include "material_cohesive_exponential.hh"
#include "material_cohesive_linear.hh"
#include "material_cohesive_linear_fatigue.hh"
#include "material_cohesive_linear_friction.hh"
#include "material_cohesive_linear_uncoupled.hh"
-#include "material_cohesive_bilinear.hh"
-#include "material_cohesive_exponential.hh"
#endif
-#define AKANTU_COHESIVE_MATERIAL_LIST \
- ((2, (cohesive_linear, MaterialCohesiveLinear ))) \
- ((2, (cohesive_linear_fatigue, MaterialCohesiveLinearFatigue ))) \
- ((2, (cohesive_linear_friction, MaterialCohesiveLinearFriction))) \
- ((2, (cohesive_linear_uncoupled, MaterialCohesiveLinearUncoupled))) \
- ((2, (cohesive_bilinear , MaterialCohesiveBilinear ))) \
- ((2, (cohesive_exponential , MaterialCohesiveExponential )))
+#define AKANTU_COHESIVE_MATERIAL_LIST \
+ ((2, (cohesive_linear, MaterialCohesiveLinear)))( \
+ (2, (cohesive_linear_fatigue, MaterialCohesiveLinearFatigue)))( \
+ (2, (cohesive_linear_friction, MaterialCohesiveLinearFriction)))( \
+ (2, (cohesive_linear_uncoupled, MaterialCohesiveLinearUncoupled)))( \
+ (2, (cohesive_bilinear, MaterialCohesiveBilinear)))( \
+ (2, (cohesive_exponential, MaterialCohesiveExponential)))
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
index b7de4e93c..9e2a9eb12 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
@@ -1,713 +1,713 @@
/**
* @file solid_mechanics_model_cohesive.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Wed Jan 13 2016
*
* @brief Solid mechanics model for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
#include "aka_iterators.hh"
#include "cohesive_element_inserter.hh"
#include "element_synchronizer.hh"
#include "facet_synchronizer.hh"
#include "fe_engine_template.hh"
#include "integrator_gauss.hh"
#include "material_cohesive.hh"
#include "parser.hh"
#include "shape_cohesive.hh"
#include "dumpable_inline_impl.hh"
#ifdef AKANTU_USE_IOHELPER
#include "dumper_iohelper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
#include <algorithm>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(
Mesh & mesh, UInt dim, const ID & id, const MemoryID & memory_id)
: SolidMechanicsModel(mesh, dim, id, memory_id,
ModelType::_solid_mechanics_model_cohesive),
tangents("tangents", id), facet_stress("facet_stress", id),
facet_material("facet_material", id) {
AKANTU_DEBUG_IN();
registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh,
Model::spatial_dimension);
auto && tmp_material_selector =
std::make_shared<DefaultMaterialCohesiveSelector>(*this);
tmp_material_selector->setFallback(this->material_selector);
this->material_selector = tmp_material_selector;
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
this->mesh.addDumpMeshToDumper("cohesive elements", mesh,
Model::spatial_dimension, _not_ghost,
_ek_cohesive);
#endif
if (this->mesh.isDistributed()) {
/// create the distributed synchronizer for cohesive elements
this->cohesive_synchronizer = std::make_unique<ElementSynchronizer>(
mesh, "cohesive_distributed_synchronizer");
auto & synchronizer = mesh.getElementSynchronizer();
this->cohesive_synchronizer->split(synchronizer, [](auto && el) {
return Mesh::getKind(el.type) == _ek_cohesive;
});
this->registerSynchronizer(*cohesive_synchronizer, _gst_material_id);
this->registerSynchronizer(*cohesive_synchronizer, _gst_smm_stress);
this->registerSynchronizer(*cohesive_synchronizer, _gst_smm_boundary);
}
this->inserter = std::make_unique<CohesiveElementInserter>(
this->mesh, id + ":cohesive_element_inserter");
registerFEEngineObject<MyFEEngineFacetType>(
"FacetsFEEngine", mesh.getMeshFacets(), Model::spatial_dimension - 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModelCohesive::~SolidMechanicsModelCohesive() = default;
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::setTimeStep(Real time_step,
const ID & solver_id) {
SolidMechanicsModel::setTimeStep(time_step, solver_id);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
#endif
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initFullImpl(const ModelOptions & options) {
AKANTU_DEBUG_IN();
const auto & smmc_options =
dynamic_cast<const SolidMechanicsModelCohesiveOptions &>(options);
this->is_extrinsic = smmc_options.extrinsic;
inserter->setIsExtrinsic(is_extrinsic);
if (mesh.isDistributed()) {
auto & mesh_facets = inserter->getMeshFacets();
auto & synchronizer =
dynamic_cast<FacetSynchronizer &>(mesh_facets.getElementSynchronizer());
this->registerSynchronizer(synchronizer, _gst_smmc_facets);
this->registerSynchronizer(synchronizer, _gst_smmc_facets_conn);
synchronizeGhostFacetsConnectivity();
/// create the facet synchronizer for extrinsic simulations
if (is_extrinsic) {
facet_stress_synchronizer = std::make_unique<ElementSynchronizer>(
synchronizer, id + ":facet_stress_synchronizer");
this->registerSynchronizer(*facet_stress_synchronizer,
_gst_smmc_facets_stress);
}
inserter->initParallel(*cohesive_synchronizer);
}
ParserSection section;
bool is_empty;
std::tie(section, is_empty) = this->getParserSection();
if (not is_empty) {
auto inserter_section =
section.getSubSections(ParserType::_cohesive_inserter);
if (inserter_section.begin() != inserter_section.end()) {
inserter->parseSection(*inserter_section.begin());
}
}
SolidMechanicsModel::initFullImpl(options);
AKANTU_DEBUG_OUT();
} // namespace akantu
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initMaterials() {
AKANTU_DEBUG_IN();
// make sure the material are instantiated
if (!are_materials_instantiated)
instantiateMaterials();
/// find the first cohesive material
UInt cohesive_index = UInt(-1);
for (auto && material : enumerate(materials)) {
if (dynamic_cast<MaterialCohesive *>(std::get<1>(material).get())) {
cohesive_index = std::get<0>(material);
break;
}
}
if (cohesive_index == UInt(-1))
AKANTU_EXCEPTION("No cohesive materials in the material input file");
material_selector->setFallback(cohesive_index);
// set the facet information in the material in case of dynamic insertion
// to know what material to call for stress checks
if (is_extrinsic) {
this->initExtrinsicMaterials();
} else {
this->initIntrinsicMaterials();
}
AKANTU_DEBUG_OUT();
} // namespace akantu
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initExtrinsicMaterials() {
const Mesh & mesh_facets = inserter->getMeshFacets();
facet_material.initialize(
mesh_facets, _spatial_dimension = spatial_dimension - 1,
_with_nb_element = true,
_default_value = material_selector->getFallbackValue());
for_each_element(
mesh_facets,
[&](auto && element) {
auto mat_index = (*material_selector)(element);
auto & mat = dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
facet_material(element) = mat_index;
mat.addFacet(element);
},
_spatial_dimension = spatial_dimension - 1, _ghost_type = _not_ghost);
SolidMechanicsModel::initMaterials();
this->initAutomaticInsertion();
}
/* -------------------------------------------------------------------------- */
#if 0
void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(
const std::string & cohesive_surfaces) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
if (facet_synchronizer != nullptr)
inserter->initParallel(facet_synchronizer, cohesive_element_synchronizer);
// inserter->initParallel(facet_synchronizer, synch_parallel);
#endif
std::istringstream split(cohesive_surfaces);
std::string physname;
while (std::getline(split, physname, ',')) {
AKANTU_DEBUG_INFO(
"Pre-inserting cohesive elements along facets from physical surface: "
<< physname);
insertElementsFromMeshData(physname);
}
synchronizeInsertionData();
SolidMechanicsModel::initMaterials();
auto && tmp = std::make_shared<MeshDataMaterialCohesiveSelector>(*this);
tmp->setFallback(material_selector->getFallbackValue());
tmp->setFallback(material_selector->getFallbackSelector());
material_selector = tmp;
// UInt nb_new_elements =
inserter->insertElements();
// if (nb_new_elements > 0) {
// this->reinitializeSolver();
// }
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::synchronizeInsertionData() {
if (inserter->getMeshFacets().isDistributed()) {
inserter->getMeshFacets().getElementSynchronizer().synchronizeOnce(
*inserter, _gst_ce_groups);
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initIntrinsicMaterials() {
AKANTU_DEBUG_IN();
SolidMechanicsModel::initMaterials();
this->insertIntrinsicElements();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the model,basically it pre-compute the shapes, shapes derivatives
* and jacobian
*/
void SolidMechanicsModelCohesive::initModel() {
AKANTU_DEBUG_IN();
SolidMechanicsModel::initModel();
/// add cohesive type connectivity
ElementType type = _not_defined;
for (auto && type_ghost : ghost_types) {
for (const auto & tmp_type :
mesh.elementTypes(spatial_dimension, type_ghost)) {
const auto & connectivity = mesh.getConnectivity(tmp_type, type_ghost);
if (connectivity.size() == 0)
continue;
type = tmp_type;
auto type_facet = Mesh::getFacetType(type);
auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
mesh.addConnectivityType(type_cohesive, type_ghost);
}
}
AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
if (is_extrinsic) {
getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::insertIntrinsicElements() {
AKANTU_DEBUG_IN();
inserter->insertIntrinsicElements();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initAutomaticInsertion() {
AKANTU_DEBUG_IN();
this->inserter->limitCheckFacets();
this->updateFacetStressSynchronizer();
this->resizeFacetStress();
/// compute normals on facets
this->computeNormals();
this->initStressInterpolation();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
AKANTU_DEBUG_IN();
this->inserter->limitCheckFacets();
this->updateFacetStressSynchronizer();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::initStressInterpolation() {
Mesh & mesh_facets = inserter->getMeshFacets();
/// compute quadrature points coordinates on facets
Array<Real> & position = mesh.getNodes();
ElementTypeMapArray<Real> quad_facets("quad_facets", id);
quad_facets.initialize(mesh_facets, _nb_component = Model::spatial_dimension,
_spatial_dimension = Model::spatial_dimension - 1);
// mesh_facets.initElementTypeMapArray(quad_facets, Model::spatial_dimension,
// Model::spatial_dimension - 1);
getFEEngine("FacetsFEEngine")
.interpolateOnIntegrationPoints(position, quad_facets);
/// compute elements quadrature point positions and build
/// element-facet quadrature points data structure
ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
elements_quad_facets.initialize(
mesh, _nb_component = Model::spatial_dimension,
_spatial_dimension = Model::spatial_dimension);
// mesh.initElementTypeMapArray(elements_quad_facets,
// Model::spatial_dimension,
// Model::spatial_dimension);
for (auto elem_gt : ghost_types) {
for (auto & type : mesh.elementTypes(Model::spatial_dimension, elem_gt)) {
UInt nb_element = mesh.getNbElement(type, elem_gt);
if (nb_element == 0)
continue;
/// compute elements' quadrature points and list of facet
/// quadrature points positions by element
const auto & facet_to_element =
mesh_facets.getSubelementToElement(type, elem_gt);
auto & el_q_facet = elements_quad_facets(type, elem_gt);
auto facet_type = Mesh::getFacetType(type);
auto nb_quad_per_facet =
getFEEngine("FacetsFEEngine").getNbIntegrationPoints(facet_type);
auto nb_facet_per_elem = facet_to_element.getNbComponent();
// small hack in the loop to skip boundary elements, they are silently
// initialized to NaN to see if this causes problems
el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet,
std::numeric_limits<Real>::quiet_NaN());
for (auto && data :
zip(make_view(facet_to_element),
make_view(el_q_facet, spatial_dimension, nb_quad_per_facet))) {
const auto & global_facet = std::get<0>(data);
auto & el_q = std::get<1>(data);
if (global_facet == ElementNull)
continue;
Matrix<Real> quad_f =
make_view(quad_facets(global_facet.type, global_facet.ghost_type),
spatial_dimension, nb_quad_per_facet)
.begin()[global_facet.element];
el_q = quad_f;
// for (UInt q = 0; q < nb_quad_per_facet; ++q) {
// for (UInt s = 0; s < Model::spatial_dimension; ++s) {
// el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
// f * nb_quad_per_facet + q,
// s) = quad_f(global_facet * nb_quad_per_facet + q,
// s);
// }
// }
//}
}
}
}
/// loop over non cohesive materials
for (auto && material : materials) {
if (dynamic_cast<MaterialCohesive *>(material.get()))
continue;
/// initialize the interpolation function
material->initElementalFieldInterpolation(elements_quad_facets);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::assembleInternalForces() {
AKANTU_DEBUG_IN();
// f_int += f_int_cohe
for (auto & material : this->materials) {
try {
auto & mat = dynamic_cast<MaterialCohesive &>(*material);
mat.computeTraction(_not_ghost);
} catch (std::bad_cast & bce) {
}
}
SolidMechanicsModel::assembleInternalForces();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::computeNormals() {
AKANTU_DEBUG_IN();
Mesh & mesh_facets = this->inserter->getMeshFacets();
this->getFEEngine("FacetsFEEngine")
.computeNormalsOnIntegrationPoints(_not_ghost);
/**
* @todo store tangents while computing normals instead of
* recomputing them as follows:
*/
/* ------------------------------------------------------------------------ */
UInt tangent_components =
Model::spatial_dimension * (Model::spatial_dimension - 1);
tangents.initialize(mesh_facets, _nb_component = tangent_components,
_spatial_dimension = Model::spatial_dimension - 1);
// mesh_facets.initElementTypeMapArray(tangents, tangent_components,
// Model::spatial_dimension - 1);
for (auto facet_type :
mesh_facets.elementTypes(Model::spatial_dimension - 1)) {
const Array<Real> & normals =
this->getFEEngine("FacetsFEEngine")
.getNormalsOnIntegrationPoints(facet_type);
Array<Real> & tangents = this->tangents(facet_type);
Math::compute_tangents(normals, tangents);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::interpolateStress() {
ElementTypeMapArray<Real> by_elem_result("temporary_stress_by_facets", id);
for (auto & material : materials) {
auto * mat = dynamic_cast<MaterialCohesive *>(material.get());
if (mat == nullptr)
/// interpolate stress on facet quadrature points positions
material->interpolateStressOnFacets(facet_stress, by_elem_result);
}
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(
debug::_dm_model_cohesive, "Interpolated stresses before", facet_stress);
#endif
this->synchronize(_gst_smmc_facets_stress);
#if defined(AKANTU_DEBUG_TOOLS)
debug::element_manager.printData(debug::_dm_model_cohesive,
"Interpolated stresses", facet_stress);
#endif
}
/* -------------------------------------------------------------------------- */
UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
AKANTU_DEBUG_IN();
interpolateStress();
for (auto & mat : materials) {
auto * mat_cohesive = dynamic_cast<MaterialCohesive *>(mat.get());
- if(mat_cohesive) {
+ if (mat_cohesive) {
/// check which not ghost cohesive elements are to be created
mat_cohesive->checkInsertion();
}
}
/// communicate data among processors
this->synchronize(_gst_smmc_facets);
/// insert cohesive elements
UInt nb_new_elements = inserter->insertElements();
// if (nb_new_elements > 0) {
// this->reinitializeSolver();
// }
AKANTU_DEBUG_OUT();
return nb_new_elements;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onElementsAdded(
const Array<Element> & element_list, const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
updateCohesiveSynchronizers();
SolidMechanicsModel::onElementsAdded(element_list, event);
if (cohesive_synchronizer != nullptr)
cohesive_synchronizer->computeAllBufferSizes(*this);
if (is_extrinsic)
resizeFacetStress();
/// if (method != _explicit_lumped_mass) {
/// this->initSolver();
/// }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & new_nodes,
const NewNodesEvent & event) {
AKANTU_DEBUG_IN();
// Array<UInt> nodes_list(nb_new_nodes);
// for (UInt n = 0; n < nb_new_nodes; ++n)
// nodes_list(n) = doubled_nodes(n, 1);
SolidMechanicsModel::onNodesAdded(new_nodes, event);
UInt new_node, old_node;
try {
const auto & cohesive_event =
dynamic_cast<const CohesiveNewNodesEvent &>(event);
const auto & old_nodes = cohesive_event.getOldNodesList();
auto copy = [this, &new_node, &old_node](auto & arr) {
for (UInt s = 0; s < spatial_dimension; ++s) {
arr(new_node, s) = arr(old_node, s);
}
};
for (auto && pair : zip(new_nodes, old_nodes)) {
std::tie(new_node, old_node) = pair;
copy(*displacement);
copy(*blocked_dofs);
if (velocity)
copy(*velocity);
if (acceleration)
copy(*acceleration);
if (current_position)
copy(*current_position);
if (previous_displacement)
copy(*previous_displacement);
}
// if (this->getDOFManager().hasMatrix("M")) {
// this->assembleMass(old_nodes);
// }
// if (this->getDOFManager().hasLumpedMatrix("M")) {
// this->assembleMassLumped(old_nodes);
// }
} catch (std::bad_cast &) {
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onEndSolveStep(const AnalysisMethod &) {
AKANTU_DEBUG_IN();
/*
* This is required because the Cauchy stress is the stress measure that
* is used to check the insertion of cohesive elements
*/
for (auto & mat : materials) {
if (mat->isFiniteDeformation())
mat->computeAllCauchyStresses(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::printself(std::ostream & stream,
int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "SolidMechanicsModelCohesive [" << std::endl;
SolidMechanicsModel::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::resizeFacetStress() {
AKANTU_DEBUG_IN();
this->facet_stress.initialize(getFEEngine("FacetsFEEngine"),
_nb_component =
2 * spatial_dimension * spatial_dimension,
_spatial_dimension = spatial_dimension - 1);
// for (auto && ghost_type : ghost_types) {
// for (const auto & type :
// mesh_facets.elementTypes(spatial_dimension - 1, ghost_type)) {
// UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
// UInt nb_quadrature_points = getFEEngine("FacetsFEEngine")
// .getNbIntegrationPoints(type,
// ghost_type);
// UInt new_size = nb_facet * nb_quadrature_points;
// facet_stress(type, ghost_type).resize(new_size);
// }
// }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(
const std::string & dumper_name, const std::string & field_id,
const std::string & group_name, const ElementKind & element_kind,
bool padding_flag) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = Model::spatial_dimension;
ElementKind _element_kind = element_kind;
if (dumper_name == "cohesive elements") {
_element_kind = _ek_cohesive;
} else if (dumper_name == "facets") {
spatial_dimension = Model::spatial_dimension - 1;
}
SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id,
group_name, spatial_dimension,
_element_kind, padding_flag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModelCohesive::onDump() {
this->flattenAllRegisteredInternals(_ek_cohesive);
SolidMechanicsModel::onDump();
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
index a4f9a9d81..cf149d7b2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
@@ -1,319 +1,320 @@
/**
* @file solid_mechanics_model_cohesive.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Mon Dec 14 2015
*
* @brief Solid mechanics model for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "cohesive_element_inserter.hh"
#include "material_selector_cohesive.hh"
#include "random_internal_field.hh" // included to have the specialization of
#include "solid_mechanics_model.hh"
#include "solid_mechanics_model_event_handler.hh"
// ParameterTyped::operator Real()
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class FacetSynchronizer;
class FacetStressSynchronizer;
class ElementSynchronizer;
} // namespace akantu
namespace akantu {
/* -------------------------------------------------------------------------- */
struct FacetsCohesiveIntegrationOrderFunctor {
- template <ElementType type, ElementType cohesive_type =
- CohesiveFacetProperty<type>::cohesive_type>
+ template <ElementType type,
+ ElementType cohesive_type =
+ CohesiveFacetProperty<type>::cohesive_type>
struct _helper {
static constexpr int get() {
return ElementClassProperty<cohesive_type>::polynomial_degree;
}
};
template <ElementType type> struct _helper<type, _not_defined> {
static constexpr int get() {
return ElementClassProperty<type>::polynomial_degree;
}
};
template <ElementType type> static inline constexpr int getOrder() {
return _helper<type>::get();
}
};
/* -------------------------------------------------------------------------- */
/* Solid Mechanics Model for Cohesive elements */
/* -------------------------------------------------------------------------- */
class SolidMechanicsModelCohesive : public SolidMechanicsModel,
public SolidMechanicsModelEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
class NewCohesiveNodesEvent : public NewNodesEvent {
public:
AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
protected:
Array<UInt> old_nodes;
};
using MyFEEngineCohesiveType =
FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>;
using MyFEEngineFacetType =
FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular,
FacetsCohesiveIntegrationOrderFunctor>;
SolidMechanicsModelCohesive(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "solid_mechanics_model_cohesive",
const MemoryID & memory_id = 0);
~SolidMechanicsModelCohesive() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// initialize the cohesive model
void initFullImpl(const ModelOptions & options) override;
public:
/// set the value of the time step
void setTimeStep(Real time_step, const ID & solver_id = "") override;
/// assemble the residual for the explicit scheme
void assembleInternalForces() override;
/// function to perform a stress check on each facet and insert
/// cohesive elements if needed (returns the number of new cohesive
/// elements)
UInt checkCohesiveStress();
/// interpolate stress on facets
void interpolateStress();
/// update automatic insertion after a change in the element inserter
void updateAutomaticInsertion();
/// insert intrinsic cohesive elements
void insertIntrinsicElements();
// template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria
// criteria> bool solveStepCohesive(Real tolerance, Real & error, UInt
// max_iteration = 100,
// bool load_reduction = false,
// Real tol_increase_factor = 1.0,
// bool do_not_factorize = false);
protected:
/// initialize stress interpolation
void initStressInterpolation();
/// initialize the model
void initModel() override;
/// initialize cohesive material
void initMaterials() override;
/// init facet filters for cohesive materials
void initFacetFilter();
// synchronize facets physical data before insertion along physical surfaces
void synchronizeInsertionData();
/// function to print the contain of the class
void printself(std::ostream & stream, int indent = 0) const override;
private:
/// initialize cohesive material with extrinsic insertion
void initExtrinsicMaterials();
/// initialize cohesive material with intrinsic insertion
void initIntrinsicMaterials();
/// insert cohesive elements along a given physical surface of the mesh
void insertElementsFromMeshData(const std::string & physical_name);
/// initialize completely the model for extrinsic elements
void initAutomaticInsertion();
/// compute facets' normals
void computeNormals();
/// resize facet stress
void resizeFacetStress();
/// init facets_check array
void initFacetsCheck();
/* ------------------------------------------------------------------------ */
/* Mesh Event Handler inherited members */
/* ------------------------------------------------------------------------ */
protected:
void onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event) override;
void onElementsAdded(const Array<Element> & nodes_list,
const NewElementsEvent & event) override;
/* ------------------------------------------------------------------------ */
/* SolidMechanicsModelEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
void onEndSolveStep(const AnalysisMethod & method) override;
/* ------------------------------------------------------------------------ */
/* Dumpable interface */
/* ------------------------------------------------------------------------ */
public:
void onDump() override;
void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag) override;
public:
/// register the tags associated with the parallel synchronizer for
/// cohesive elements
// void initParallel(MeshPartition * partition,
// DataAccessor * data_accessor = NULL,
// bool extrinsic = false);
protected:
void synchronizeGhostFacetsConnectivity();
void updateCohesiveSynchronizers();
void updateFacetStressSynchronizer();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const override;
void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
const SynchronizationTag & tag) const override;
void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
const SynchronizationTag & tag) override;
protected:
UInt getNbQuadsForFacetCheck(const Array<Element> & elements) const;
template <typename T>
void packFacetStressDataHelper(const ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & elements) const;
template <typename T>
void unpackFacetStressDataHelper(ElementTypeMapArray<T> & data_to_unpack,
CommunicationBuffer & buffer,
const Array<Element> & elements) const;
template <typename T, bool pack_helper>
void packUnpackFacetStressDataHelper(ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & element) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get facet mesh
AKANTU_GET_MACRO(MeshFacets, mesh.getMeshFacets(), const Mesh &);
/// get stress on facets vector
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressOnFacets, facet_stress, Real);
/// get facet material
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetMaterial, facet_material, UInt);
/// get facet material
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetMaterial, facet_material, UInt);
/// get facet material
AKANTU_GET_MACRO(FacetMaterial, facet_material,
const ElementTypeMapArray<UInt> &);
/// @todo THIS HAS TO BE CHANGED
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Tangents, tangents, Real);
/// get element inserter
AKANTU_GET_MACRO_NOT_CONST(ElementInserter, *inserter,
CohesiveElementInserter &);
/// get is_extrinsic boolean
AKANTU_GET_MACRO(IsExtrinsic, is_extrinsic, bool);
/// get cohesive elements synchronizer
AKANTU_GET_MACRO(CohesiveSynchronizer, *cohesive_synchronizer,
const ElementSynchronizer &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// @todo store tangents when normals are computed:
ElementTypeMapArray<Real> tangents;
/// stress on facets on the two sides by quadrature point
ElementTypeMapArray<Real> facet_stress;
/// material to use if a cohesive element is created on a facet
ElementTypeMapArray<UInt> facet_material;
bool is_extrinsic;
/// cohesive element inserter
std::unique_ptr<CohesiveElementInserter> inserter;
/// facet stress synchronizer
std::unique_ptr<ElementSynchronizer> facet_stress_synchronizer;
/// cohesive elements synchronizer
std::unique_ptr<ElementSynchronizer> cohesive_synchronizer;
/// global connectivity
ElementTypeMapArray<UInt> * global_connectivity;
};
} // namespace akantu
#include "solid_mechanics_model_cohesive_inline_impl.cc"
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
index 922bb5ab6..bf3a809e3 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
@@ -1,303 +1,305 @@
/**
* @file solid_mechanics_model_cohesive_inline_impl.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jan 18 2013
* @date last modification: Thu Jan 14 2016
*
* @brief Implementation of inline functions for the Cohesive element model
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
#define __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
// template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
// bool SolidMechanicsModelCohesive::solveStepCohesive(
// Real tolerance, Real & error, UInt max_iteration, bool load_reduction,
// Real tol_increase_factor, bool do_not_factorize) {
- // // EventManager::sendEvent(
- // // SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
- // // this->implicitPred();
-
- // // bool insertion_new_element = true;
- // // bool converged = false;
- // // Array<Real> * displacement_tmp = NULL;
- // // Array<Real> * velocity_tmp = NULL;
- // // Array<Real> * acceleration_tmp = NULL;
- // // StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- // // Int prank = comm.whoAmI();
-
- // // /// Loop for the insertion of new cohesive elements
- // // while (insertion_new_element) {
-
- // // if (is_extrinsic) {
- // // /**
- // // * If in extrinsic the solution of the previous incremental step
- // // * is saved in temporary arrays created for displacements,
- // // * velocities and accelerations. Such arrays are used to find
- // // * the solution with the Newton-Raphson scheme (this is done by
- // // * pointing the pointer "displacement" to displacement_tmp). In
- // // * this way, inside the array "displacement" is kept the
- // // * solution of the previous incremental step, and in
- // // * "displacement_tmp" is saved the current solution.
- // // */
-
- // // if (!displacement_tmp)
- // // displacement_tmp = new Array<Real>(0, spatial_dimension);
-
- // // displacement_tmp->copy(*(this->displacement));
-
- // // if (!velocity_tmp)
- // // velocity_tmp = new Array<Real>(0, spatial_dimension);
-
- // // velocity_tmp->copy(*(this->velocity));
-
- // // if (!acceleration_tmp) {
- // // acceleration_tmp = new Array<Real>(0, spatial_dimension);
- // // }
-
- // // acceleration_tmp->copy(*(this->acceleration));
-
- // // std::swap(displacement, displacement_tmp);
- // // std::swap(velocity, velocity_tmp);
- // // std::swap(acceleration, acceleration_tmp);
- // // }
-
- // // this->updateResidual();
-
- // // AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
- // // "You should first initialize the implicit solver and "
- // // "assemble the stiffness matrix");
-
- // // bool need_factorize = !do_not_factorize;
-
- // // if (method == _implicit_dynamic) {
- // // AKANTU_DEBUG_ASSERT(mass_matrix != NULL, "You should first initialize "
- // // "the implicit solver and "
- // // "assemble the mass matrix");
- // // }
-
- // // switch (cmethod) {
- // // case _scm_newton_raphson_tangent:
- // // case _scm_newton_raphson_tangent_not_computed:
- // // break;
- // // case _scm_newton_raphson_tangent_modified:
- // // this->assembleStiffnessMatrix();
- // // break;
- // // default:
- // // AKANTU_ERROR("The resolution method "
- // // << cmethod << " has not been implemented!");
- // // }
-
- // // UInt iter = 0;
- // // converged = false;
- // // error = 0.;
- // // if (criteria == _scc_residual) {
- // // converged = this->testConvergence<criteria>(tolerance, error);
- // // if (converged)
- // // return converged;
- // // }
-
- // // /// Loop to solve the nonlinear system
- // // do {
- // // if (cmethod == _scm_newton_raphson_tangent)
- // // this->assembleStiffnessMatrix();
-
- // // solve<NewmarkBeta::_displacement_corrector>(*increment, 1.,
- // // need_factorize);
-
- // // this->implicitCorr();
-
- // // this->updateResidual();
-
- // // converged = this->testConvergence<criteria>(tolerance, error);
-
- // // iter++;
- // // AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
- // // << std::setw(std::log10(max_iteration)) << iter
- // // << ": error " << error
- // // << (converged ? " < " : " > ") << tolerance);
-
- // // switch (cmethod) {
- // // case _scm_newton_raphson_tangent:
- // // need_factorize = true;
- // // break;
- // // case _scm_newton_raphson_tangent_not_computed:
- // // case _scm_newton_raphson_tangent_modified:
- // // need_factorize = false;
- // // break;
- // // default:
- // // AKANTU_ERROR("The resolution method "
- // // << cmethod << " has not been implemented!");
- // // }
-
- // // } while (!converged && iter < max_iteration);
-
- // // /**
- // // * This is to save the obtained result and proceed with the
- // // * simulation even if the error is higher than the pre-fixed
- // // * tolerance. This is done only after loading reduction
- // // * (load_reduction = true).
- // // */
- // // // if (load_reduction && (error < tolerance * tol_increase_factor))
- // // // converged = true;
- // // if ((error < tolerance * tol_increase_factor))
- // // converged = true;
-
- // // if (converged) {
-
- // // } else if (iter == max_iteration) {
- // // if (prank == 0) {
- // // AKANTU_DEBUG_WARNING(
- // // "[" << criteria << "] Convergence not reached after "
- // // << std::setw(std::log10(max_iteration)) << iter << " iteration"
- // // << (iter == 1 ? "" : "s") << "!" << std::endl);
- // // }
- // // }
-
- // // if (is_extrinsic) {
- // // /**
- // // * If is extrinsic the pointer "displacement" is moved back to
- // // * the array displacement. In this way, the array displacement is
- // // * correctly resized during the checkCohesiveStress function (in
- // // * case new cohesive elements are added). This is possible
- // // * because the procedure called by checkCohesiveStress does not
- // // * use the displacement field (the correct one is now stored in
- // // * displacement_tmp), but directly the stress field that is
- // // * already computed.
- // // */
- // // Array<Real> * tmp_swap;
-
- // // tmp_swap = displacement_tmp;
- // // displacement_tmp = this->displacement;
- // // this->displacement = tmp_swap;
-
- // // tmp_swap = velocity_tmp;
- // // velocity_tmp = this->velocity;
- // // this->velocity = tmp_swap;
-
- // // tmp_swap = acceleration_tmp;
- // // acceleration_tmp = this->acceleration;
- // // this->acceleration = tmp_swap;
-
- // // /// If convergence is reached, call checkCohesiveStress in order
- // // /// to check if cohesive elements have to be introduced
- // // if (converged) {
-
- // // UInt new_cohesive_elements = checkCohesiveStress();
-
- // // if (new_cohesive_elements == 0) {
- // // insertion_new_element = false;
- // // } else {
- // // insertion_new_element = true;
- // // }
- // // }
- // // }
-
- // // if (!converged && load_reduction)
- // // insertion_new_element = false;
-
- // // /**
- // // * If convergence is not reached, there is the possibility to
- // // * return back to the main file and reduce the load. Before doing
- // // * this, a pre-fixed value as to be defined for the parameter
- // // * delta_max of the cohesive elements introduced in the current
- // // * incremental step. This is done by calling the function
- // // * checkDeltaMax.
- // // */
- // // if (!converged) {
- // // insertion_new_element = false;
-
- // // for (UInt m = 0; m < materials.size(); ++m) {
- // // try {
- // // MaterialCohesive & mat =
- // // dynamic_cast<MaterialCohesive &>(*materials[m]);
- // // mat.checkDeltaMax(_not_ghost);
- // // } catch (std::bad_cast &) {
- // // }
- // // }
- // // }
-
- // // } // end loop for the insertion of new cohesive elements
-
- // // /**
- // // * When the solution to the current incremental step is computed (no
- // // * more cohesive elements have to be introduced), call the function
- // // * to compute the energies.
- // // */
- // // if ((is_extrinsic && converged)) {
-
- // // for (UInt m = 0; m < materials.size(); ++m) {
- // // try {
- // // MaterialCohesive & mat =
- // // dynamic_cast<MaterialCohesive &>(*materials[m]);
- // // mat.computeEnergies();
- // // } catch (std::bad_cast & bce) {
- // // }
- // // }
-
- // // EventManager::sendEvent(
- // // SolidMechanicsModelEvent::AfterSolveStepEvent(method));
-
- // // /**
- // // * The function resetVariables is necessary to correctly set a
- // // * variable that permit to decrease locally the penalty parameter
- // // * for compression.
- // // */
- // // for (UInt m = 0; m < materials.size(); ++m) {
- // // try {
- // // MaterialCohesive & mat =
- // // dynamic_cast<MaterialCohesive &>(*materials[m]);
- // // mat.resetVariables(_not_ghost);
- // // } catch (std::bad_cast &) {
- // // }
- // // }
-
- // // /// The correct solution is saved
- // // this->displacement->copy(*displacement_tmp);
- // // this->velocity->copy(*velocity_tmp);
- // // this->acceleration->copy(*acceleration_tmp);
- // // }
-
- // // delete displacement_tmp;
- // // delete velocity_tmp;
- // // delete acceleration_tmp;
-
- // // return insertion_new_element;
+// // EventManager::sendEvent(
+// // SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
+// // this->implicitPred();
+
+// // bool insertion_new_element = true;
+// // bool converged = false;
+// // Array<Real> * displacement_tmp = NULL;
+// // Array<Real> * velocity_tmp = NULL;
+// // Array<Real> * acceleration_tmp = NULL;
+// // StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+// // Int prank = comm.whoAmI();
+
+// // /// Loop for the insertion of new cohesive elements
+// // while (insertion_new_element) {
+
+// // if (is_extrinsic) {
+// // /**
+// // * If in extrinsic the solution of the previous incremental step
+// // * is saved in temporary arrays created for displacements,
+// // * velocities and accelerations. Such arrays are used to find
+// // * the solution with the Newton-Raphson scheme (this is done by
+// // * pointing the pointer "displacement" to displacement_tmp). In
+// // * this way, inside the array "displacement" is kept the
+// // * solution of the previous incremental step, and in
+// // * "displacement_tmp" is saved the current solution.
+// // */
+
+// // if (!displacement_tmp)
+// // displacement_tmp = new Array<Real>(0, spatial_dimension);
+
+// // displacement_tmp->copy(*(this->displacement));
+
+// // if (!velocity_tmp)
+// // velocity_tmp = new Array<Real>(0, spatial_dimension);
+
+// // velocity_tmp->copy(*(this->velocity));
+
+// // if (!acceleration_tmp) {
+// // acceleration_tmp = new Array<Real>(0, spatial_dimension);
+// // }
+
+// // acceleration_tmp->copy(*(this->acceleration));
+
+// // std::swap(displacement, displacement_tmp);
+// // std::swap(velocity, velocity_tmp);
+// // std::swap(acceleration, acceleration_tmp);
+// // }
+
+// // this->updateResidual();
+
+// // AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
+// // "You should first initialize the implicit solver and
+// "
+// // "assemble the stiffness matrix");
+
+// // bool need_factorize = !do_not_factorize;
+
+// // if (method == _implicit_dynamic) {
+// // AKANTU_DEBUG_ASSERT(mass_matrix != NULL, "You should first initialize
+// "
+// // "the implicit solver and "
+// // "assemble the mass matrix");
+// // }
+
+// // switch (cmethod) {
+// // case _scm_newton_raphson_tangent:
+// // case _scm_newton_raphson_tangent_not_computed:
+// // break;
+// // case _scm_newton_raphson_tangent_modified:
+// // this->assembleStiffnessMatrix();
+// // break;
+// // default:
+// // AKANTU_ERROR("The resolution method "
+// // << cmethod << " has not been implemented!");
+// // }
+
+// // UInt iter = 0;
+// // converged = false;
+// // error = 0.;
+// // if (criteria == _scc_residual) {
+// // converged = this->testConvergence<criteria>(tolerance, error);
+// // if (converged)
+// // return converged;
+// // }
+
+// // /// Loop to solve the nonlinear system
+// // do {
+// // if (cmethod == _scm_newton_raphson_tangent)
+// // this->assembleStiffnessMatrix();
+
+// // solve<NewmarkBeta::_displacement_corrector>(*increment, 1.,
+// // need_factorize);
+
+// // this->implicitCorr();
+
+// // this->updateResidual();
+
+// // converged = this->testConvergence<criteria>(tolerance, error);
+
+// // iter++;
+// // AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
+// // << std::setw(std::log10(max_iteration)) << iter
+// // << ": error " << error
+// // << (converged ? " < " : " > ") << tolerance);
+
+// // switch (cmethod) {
+// // case _scm_newton_raphson_tangent:
+// // need_factorize = true;
+// // break;
+// // case _scm_newton_raphson_tangent_not_computed:
+// // case _scm_newton_raphson_tangent_modified:
+// // need_factorize = false;
+// // break;
+// // default:
+// // AKANTU_ERROR("The resolution method "
+// // << cmethod << " has not been implemented!");
+// // }
+
+// // } while (!converged && iter < max_iteration);
+
+// // /**
+// // * This is to save the obtained result and proceed with the
+// // * simulation even if the error is higher than the pre-fixed
+// // * tolerance. This is done only after loading reduction
+// // * (load_reduction = true).
+// // */
+// // // if (load_reduction && (error < tolerance * tol_increase_factor))
+// // // converged = true;
+// // if ((error < tolerance * tol_increase_factor))
+// // converged = true;
+
+// // if (converged) {
+
+// // } else if (iter == max_iteration) {
+// // if (prank == 0) {
+// // AKANTU_DEBUG_WARNING(
+// // "[" << criteria << "] Convergence not reached after "
+// // << std::setw(std::log10(max_iteration)) << iter << "
+// iteration"
+// // << (iter == 1 ? "" : "s") << "!" << std::endl);
+// // }
+// // }
+
+// // if (is_extrinsic) {
+// // /**
+// // * If is extrinsic the pointer "displacement" is moved back to
+// // * the array displacement. In this way, the array displacement is
+// // * correctly resized during the checkCohesiveStress function (in
+// // * case new cohesive elements are added). This is possible
+// // * because the procedure called by checkCohesiveStress does not
+// // * use the displacement field (the correct one is now stored in
+// // * displacement_tmp), but directly the stress field that is
+// // * already computed.
+// // */
+// // Array<Real> * tmp_swap;
+
+// // tmp_swap = displacement_tmp;
+// // displacement_tmp = this->displacement;
+// // this->displacement = tmp_swap;
+
+// // tmp_swap = velocity_tmp;
+// // velocity_tmp = this->velocity;
+// // this->velocity = tmp_swap;
+
+// // tmp_swap = acceleration_tmp;
+// // acceleration_tmp = this->acceleration;
+// // this->acceleration = tmp_swap;
+
+// // /// If convergence is reached, call checkCohesiveStress in order
+// // /// to check if cohesive elements have to be introduced
+// // if (converged) {
+
+// // UInt new_cohesive_elements = checkCohesiveStress();
+
+// // if (new_cohesive_elements == 0) {
+// // insertion_new_element = false;
+// // } else {
+// // insertion_new_element = true;
+// // }
+// // }
+// // }
+
+// // if (!converged && load_reduction)
+// // insertion_new_element = false;
+
+// // /**
+// // * If convergence is not reached, there is the possibility to
+// // * return back to the main file and reduce the load. Before doing
+// // * this, a pre-fixed value as to be defined for the parameter
+// // * delta_max of the cohesive elements introduced in the current
+// // * incremental step. This is done by calling the function
+// // * checkDeltaMax.
+// // */
+// // if (!converged) {
+// // insertion_new_element = false;
+
+// // for (UInt m = 0; m < materials.size(); ++m) {
+// // try {
+// // MaterialCohesive & mat =
+// // dynamic_cast<MaterialCohesive &>(*materials[m]);
+// // mat.checkDeltaMax(_not_ghost);
+// // } catch (std::bad_cast &) {
+// // }
+// // }
+// // }
+
+// // } // end loop for the insertion of new cohesive elements
+
+// // /**
+// // * When the solution to the current incremental step is computed (no
+// // * more cohesive elements have to be introduced), call the function
+// // * to compute the energies.
+// // */
+// // if ((is_extrinsic && converged)) {
+
+// // for (UInt m = 0; m < materials.size(); ++m) {
+// // try {
+// // MaterialCohesive & mat =
+// // dynamic_cast<MaterialCohesive &>(*materials[m]);
+// // mat.computeEnergies();
+// // } catch (std::bad_cast & bce) {
+// // }
+// // }
+
+// // EventManager::sendEvent(
+// // SolidMechanicsModelEvent::AfterSolveStepEvent(method));
+
+// // /**
+// // * The function resetVariables is necessary to correctly set a
+// // * variable that permit to decrease locally the penalty parameter
+// // * for compression.
+// // */
+// // for (UInt m = 0; m < materials.size(); ++m) {
+// // try {
+// // MaterialCohesive & mat =
+// // dynamic_cast<MaterialCohesive &>(*materials[m]);
+// // mat.resetVariables(_not_ghost);
+// // } catch (std::bad_cast &) {
+// // }
+// // }
+
+// // /// The correct solution is saved
+// // this->displacement->copy(*displacement_tmp);
+// // this->velocity->copy(*velocity_tmp);
+// // this->acceleration->copy(*acceleration_tmp);
+// // }
+
+// // delete displacement_tmp;
+// // delete velocity_tmp;
+// // delete acceleration_tmp;
+
+// // return insertion_new_element;
//}
} // akantu
-
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
index e376a4ba7..f961c7a7c 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
@@ -1,179 +1,179 @@
/**
* @file embedded_interface_intersector.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri May 01 2015
* @date last modification: Mon Jan 04 2016
*
* @brief Class that loads the interface from mesh and computes intersections
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "embedded_interface_intersector.hh"
#include "mesh_segment_intersector.hh"
/// Helper macro for types in the mesh. Creates an intersector and computes
/// intersection queries
#define INTERFACE_INTERSECTOR_CASE(dim, type) \
do { \
MeshSegmentIntersector<dim, type> intersector(this->mesh, interface_mesh); \
name_to_primitives_it = name_to_primitives_map.begin(); \
for (; name_to_primitives_it != name_to_primitives_end; \
++name_to_primitives_it) { \
intersector.setPhysicalName(name_to_primitives_it->first); \
intersector.buildResultFromQueryList(name_to_primitives_it->second); \
} \
} while (0)
#define INTERFACE_INTERSECTOR_CASE_2D(type) INTERFACE_INTERSECTOR_CASE(2, type)
#define INTERFACE_INTERSECTOR_CASE_3D(type) INTERFACE_INTERSECTOR_CASE(3, type)
namespace akantu {
EmbeddedInterfaceIntersector::EmbeddedInterfaceIntersector(
Mesh & mesh, const Mesh & primitive_mesh)
: MeshGeomAbstract(mesh),
interface_mesh(mesh.getSpatialDimension(), "interface_mesh"),
primitive_mesh(primitive_mesh) {
// Initiating mesh connectivity and data
interface_mesh.addConnectivityType(_segment_2, _not_ghost);
interface_mesh.addConnectivityType(_segment_2, _ghost);
interface_mesh.registerData<Element>("associated_element")
.alloc(0, 1, _segment_2);
interface_mesh.registerData<std::string>("physical_names")
.alloc(0, 1, _segment_2);
}
EmbeddedInterfaceIntersector::~EmbeddedInterfaceIntersector() {}
void EmbeddedInterfaceIntersector::constructData(GhostType /*ghost_type*/) {
AKANTU_DEBUG_IN();
const UInt dim = this->mesh.getSpatialDimension();
if (dim == 1)
AKANTU_ERROR(
"No embedded model in 1D. Deactivate intersection initialization");
Array<std::string> * physical_names = NULL;
try {
physical_names = &const_cast<Array<std::string> &>(
this->primitive_mesh.getData<std::string>("physical_names",
_segment_2));
} catch (debug::Exception & e) {
AKANTU_ERROR("You must define physical names to reinforcements in "
- "order to use the embedded model");
+ "order to use the embedded model");
throw e;
}
const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_segment_2);
Array<UInt>::const_vector_iterator connectivity =
primitive_mesh.getConnectivity(_segment_2).begin(nb_nodes_per_element);
Array<std::string>::scalar_iterator names_it = physical_names->begin(),
names_end = physical_names->end();
std::map<std::string, std::list<K::Segment_3>> name_to_primitives_map;
// Loop over the physical names and register segment lists in
// name_to_primitives_map
for (; names_it != names_end; ++names_it) {
UInt element_id = names_it - physical_names->begin();
const Vector<UInt> el_connectivity = connectivity[element_id];
K::Segment_3 segment = this->createSegment(el_connectivity);
name_to_primitives_map[*names_it].push_back(segment);
}
// Loop over the background types of the mesh
Mesh::type_iterator type_it = this->mesh.firstType(dim, _not_ghost),
type_end = this->mesh.lastType(dim, _not_ghost);
std::map<std::string, std::list<K::Segment_3>>::iterator
name_to_primitives_it,
name_to_primitives_end = name_to_primitives_map.end();
for (; type_it != type_end; ++type_it) {
// Used in AKANTU_BOOST_ELEMENT_SWITCH
ElementType type = *type_it;
AKANTU_DEBUG_INFO("Computing intersections with background element type "
<< type);
switch (dim) {
case 1:
break;
case 2:
// Compute intersections for supported 2D elements
AKANTU_BOOST_ELEMENT_SWITCH(INTERFACE_INTERSECTOR_CASE_2D,
(_triangle_3)(_triangle_6));
break;
case 3:
// Compute intersections for supported 3D elements
AKANTU_BOOST_ELEMENT_SWITCH(INTERFACE_INTERSECTOR_CASE_3D,
(_tetrahedron_4));
break;
}
}
AKANTU_DEBUG_OUT();
}
K::Segment_3
EmbeddedInterfaceIntersector::createSegment(const Vector<UInt> & connectivity) {
AKANTU_DEBUG_IN();
K::Point_3 *source = NULL, *target = NULL;
const Array<Real> & nodes = this->primitive_mesh.getNodes();
if (this->mesh.getSpatialDimension() == 2) {
source = new K::Point_3(nodes(connectivity(0), 0),
nodes(connectivity(0), 1), 0.);
target = new K::Point_3(nodes(connectivity(1), 0),
nodes(connectivity(1), 1), 0.);
} else if (this->mesh.getSpatialDimension() == 3) {
source =
new K::Point_3(nodes(connectivity(0), 0), nodes(connectivity(0), 1),
nodes(connectivity(0), 2));
target =
new K::Point_3(nodes(connectivity(1), 0), nodes(connectivity(1), 1),
nodes(connectivity(1), 2));
}
K::Segment_3 segment(*source, *target);
delete source;
delete target;
AKANTU_DEBUG_OUT();
return segment;
}
} // namespace akantu
#undef INTERFACE_INTERSECTOR_CASE
#undef INTERFACE_INTERSECTOR_CASE_2D
#undef INTERFACE_INTERSECTOR_CASE_3D
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
index 60492c373..03bf41fb0 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
@@ -1,93 +1,98 @@
/**
* @file embedded_interface_intersector.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri May 01 2015
* @date last modification: Mon Dec 14 2015
*
* @brief Class that loads the interface from mesh and computes intersections
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
#define __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
#include "aka_common.hh"
-#include "mesh_geom_common.hh"
#include "mesh_geom_abstract.hh"
+#include "mesh_geom_common.hh"
#include "mesh_segment_intersector.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
namespace {
using K = cgal::Cartesian;
}
/**
- * @brief Computes the intersections of the reinforcements defined in the primitive mesh
+ * @brief Computes the intersections of the reinforcements defined in the
+ * primitive mesh
*
- * The purpose of this class is to look for reinforcements in the primitive mesh, which
- * should be defined by physical groups with the same names as the reinforcement materials
+ * The purpose of this class is to look for reinforcements in the primitive
+ * mesh, which
+ * should be defined by physical groups with the same names as the reinforcement
+ * materials
* in the model.
*
- * It then constructs the CGAL primitives from the elements of those reinforcements
- * and computes the intersections with the background mesh, to create an `interface_mesh`,
+ * It then constructs the CGAL primitives from the elements of those
+ * reinforcements
+ * and computes the intersections with the background mesh, to create an
+ * `interface_mesh`,
* which is in turn used by the EmbeddedInterfaceModel.
*
* @see MeshSegmentIntersector, MeshGeomAbstract
* @see EmbeddedInterfaceModel
*/
class EmbeddedInterfaceIntersector : public MeshGeomAbstract {
public:
/// Construct from mesh and a reinforcement mesh
- explicit EmbeddedInterfaceIntersector(Mesh & mesh, const Mesh & primitive_mesh);
+ explicit EmbeddedInterfaceIntersector(Mesh & mesh,
+ const Mesh & primitive_mesh);
/// Destructor
virtual ~EmbeddedInterfaceIntersector();
public:
/// Generate the interface mesh
virtual void constructData(GhostType ghost_type = _not_ghost);
/// Create a segment with an element connectivity
K::Segment_3 createSegment(const Vector<UInt> & connectivity);
/// Getter for interface mesh
AKANTU_GET_MACRO_NOT_CONST(InterfaceMesh, interface_mesh, Mesh &);
protected:
/// Resulting mesh of intersection
Mesh interface_mesh;
/// Mesh used for primitive construction
const Mesh & primitive_mesh;
-
};
} // akantu
#endif // __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
index 39e0c4939..c951110c8 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
@@ -1,176 +1,173 @@
/**
* @file embedded_interface_model.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Mar 13 2015
* @date last modification: Mon Dec 14 2015
*
* @brief Model of Solid Mechanics with embedded interfaces
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "embedded_interface_model.hh"
-#include "material_reinforcement.hh"
+#include "integrator_gauss.hh"
#include "material_elastic.hh"
+#include "material_reinforcement.hh"
#include "mesh_iterators.hh"
-#include "integrator_gauss.hh"
#include "shape_lagrange.hh"
#ifdef AKANTU_USE_IOHELPER
-# include "dumper_iohelper_paraview.hh"
-# include "dumpable_inline_impl.hh"
+#include "dumpable_inline_impl.hh"
+#include "dumper_iohelper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
EmbeddedInterfaceModel::EmbeddedInterfaceModel(Mesh & mesh,
Mesh & primitive_mesh,
UInt spatial_dimension,
const ID & id,
- const MemoryID & memory_id) :
- SolidMechanicsModel(mesh, spatial_dimension, id, memory_id),
- intersector(mesh, primitive_mesh),
- interface_mesh(nullptr),
- primitive_mesh(primitive_mesh),
- interface_material_selector(nullptr)
-{
+ const MemoryID & memory_id)
+ : SolidMechanicsModel(mesh, spatial_dimension, id, memory_id),
+ intersector(mesh, primitive_mesh), interface_mesh(nullptr),
+ primitive_mesh(primitive_mesh), interface_material_selector(nullptr) {
this->model_type = ModelType::_embedded_model;
// This pointer should be deleted by ~SolidMechanicsModel()
auto mat_sel_pointer =
std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
*this);
this->setMaterialSelector(mat_sel_pointer);
interface_mesh = &(intersector.getInterfaceMesh());
// Create 1D FEEngine on the interface mesh
registerFEEngineObject<MyFEEngineType>("EmbeddedInterfaceFEEngine",
*interface_mesh, 1);
// Registering allocator for material reinforcement
MaterialFactory::getInstance().registerAllocator(
"reinforcement",
[&](UInt dim, const ID & constitutive, SolidMechanicsModel &,
const ID & id) -> std::unique_ptr<Material> {
if (constitutive == "elastic") {
using mat = MaterialElastic<1>;
switch (dim) {
case 2:
return std::make_unique<MaterialReinforcement<mat, 2>>(*this, id);
case 3:
return std::make_unique<MaterialReinforcement<mat, 3>>(*this, id);
default:
AKANTU_EXCEPTION("Dimension 1 is invalid for reinforcements");
}
} else {
AKANTU_EXCEPTION("Reinforcement type" << constitutive
<< " is not recognized");
}
});
}
/* -------------------------------------------------------------------------- */
EmbeddedInterfaceModel::~EmbeddedInterfaceModel() {
delete interface_material_selector;
}
/* -------------------------------------------------------------------------- */
void EmbeddedInterfaceModel::initFullImpl(const ModelOptions & options) {
const auto & eim_options =
dynamic_cast<const EmbeddedInterfaceModelOptions &>(options);
// Do no initialize interface_mesh if told so
if (eim_options.has_intersections)
intersector.constructData();
SolidMechanicsModel::initFullImpl(options);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("reinforcement", id);
- this->mesh.addDumpMeshToDumper("reinforcement", *interface_mesh,
- 1, _not_ghost, _ek_regular);
+ this->mesh.addDumpMeshToDumper("reinforcement", *interface_mesh, 1,
+ _not_ghost, _ek_regular);
#endif
}
void EmbeddedInterfaceModel::initModel() {
// Initialize interface FEEngine
SolidMechanicsModel::initModel();
FEEngine & engine = getFEEngine("EmbeddedInterfaceFEEngine");
engine.initShapeFunctions(_not_ghost);
engine.initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
void EmbeddedInterfaceModel::assignMaterialToElements(
const ElementTypeMapArray<UInt> * filter) {
delete interface_material_selector;
interface_material_selector =
new InterfaceMeshDataMaterialSelector<std::string>("physical_names",
*this);
for_each_element(getInterfaceMesh(),
[&](auto && element) {
auto mat_index = (*interface_material_selector)(element);
// material_index(element) = mat_index;
materials[mat_index]->addElement(element);
- // this->material_local_numbering(element) = index;
+ // this->material_local_numbering(element) = index;
},
- _element_filter = filter,
- _spatial_dimension = 1);
+ _element_filter = filter, _spatial_dimension = 1);
SolidMechanicsModel::assignMaterialToElements(filter);
}
/* -------------------------------------------------------------------------- */
-void EmbeddedInterfaceModel::addDumpGroupFieldToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind,
- bool padding_flag) {
+void EmbeddedInterfaceModel::addDumpGroupFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id,
+ const std::string & group_name, const ElementKind & element_kind,
+ bool padding_flag) {
#ifdef AKANTU_USE_IOHELPER
dumper::Field * field = NULL;
// If dumper is reinforcement, create a 1D elemental field
if (dumper_name == "reinforcement")
- field = this->createElementalField(field_id, group_name, padding_flag, 1, element_kind);
+ field = this->createElementalField(field_id, group_name, padding_flag, 1,
+ element_kind);
else {
try {
- SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id, group_name, element_kind, padding_flag);
- } catch (...) {}
+ SolidMechanicsModel::addDumpGroupFieldToDumper(
+ dumper_name, field_id, group_name, element_kind, padding_flag);
+ } catch (...) {
+ }
}
if (field) {
- DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name,group_name);
- Model::addDumpGroupFieldToDumper(field_id,field,dumper);
+ DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name, group_name);
+ Model::addDumpGroupFieldToDumper(field_id, field, dumper);
}
#endif
}
} // akantu
-
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
index fab1f94fe..836661b31 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
@@ -1,150 +1,154 @@
/**
* @file embedded_interface_model.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Mon Dec 14 2015
*
* @brief Model of Solid Mechanics with embedded interfaces
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
#define __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
#include "aka_common.hh"
-#include "solid_mechanics_model.hh"
#include "mesh.hh"
+#include "solid_mechanics_model.hh"
#include "embedded_interface_intersector.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/**
* @brief Solid mechanics model using the embedded model.
*
* This SolidMechanicsModel subclass implements the embedded model,
* a method used to represent 1D elements in a finite elements model
* (eg. reinforcements in concrete).
*
* In addition to the SolidMechanicsModel properties, this model has
* a mesh of the 1D elements embedded in the model, and an instance of the
- * EmbeddedInterfaceIntersector class for the computation of the intersections of the
+ * EmbeddedInterfaceIntersector class for the computation of the intersections
+ * of the
* 1D elements with the background (bulk) mesh.
*
* @see MaterialReinforcement
*/
class EmbeddedInterfaceModel : public SolidMechanicsModel {
using MyFEEngineType = SolidMechanicsModel::MyFEEngineType;
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/**
* @brief Constructor
*
* @param mesh main mesh (concrete)
* @param primitive_mesh mesh of the embedded reinforcement
*/
- EmbeddedInterfaceModel(Mesh & mesh,
- Mesh & primitive_mesh,
+ EmbeddedInterfaceModel(Mesh & mesh, Mesh & primitive_mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "embedded_interface_model",
const MemoryID & memory_id = 0);
/// Destructor
~EmbeddedInterfaceModel() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// Initialise the model
void initFullImpl(
const ModelOptions & options = EmbeddedInterfaceModelOptions()) override;
/// Initialise the materials
void
assignMaterialToElements(const ElementTypeMapArray<UInt> * filter) override;
/// Initialize the embedded shape functions
void initModel() override;
/// Allows filtering of dump fields which need to be dumpes on interface mesh
void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag) override;
- // virtual ElementTypeMap<UInt> getInternalDataPerElem(const std::string & field_name,
- // const ElementKind & kind);
+ // virtual ElementTypeMap<UInt> getInternalDataPerElem(const std::string &
+ // field_name,
+ // const ElementKind &
+ // kind);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get interface mesh
AKANTU_GET_MACRO(InterfaceMesh, *interface_mesh, Mesh &);
/// Get associated elements
- AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InterfaceAssociatedElements,
- interface_mesh->getData<Element>("associated_element"),
- Element);
+ AKANTU_GET_MACRO_BY_ELEMENT_TYPE(
+ InterfaceAssociatedElements,
+ interface_mesh->getData<Element>("associated_element"), Element);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Intersector object to build the interface mesh
EmbeddedInterfaceIntersector intersector;
/// Interface mesh (weak reference)
Mesh * interface_mesh;
/// Mesh used to create the CGAL primitives for intersections
Mesh & primitive_mesh;
/// Material selector for interface
MaterialSelector * interface_material_selector;
};
/// Material selector based on mesh data for interface elements
-template<typename T>
-class InterfaceMeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
+template <typename T>
+class InterfaceMeshDataMaterialSelector
+ : public ElementDataMaterialSelector<T> {
public:
- InterfaceMeshDataMaterialSelector(const std::string & name, const EmbeddedInterfaceModel & model, UInt first_index = 1) :
- ElementDataMaterialSelector<T>(model.getInterfaceMesh().getData<T>(name), model, first_index)
- {}
+ InterfaceMeshDataMaterialSelector(const std::string & name,
+ const EmbeddedInterfaceModel & model,
+ UInt first_index = 1)
+ : ElementDataMaterialSelector<T>(
+ model.getInterfaceMesh().getData<T>(name), model, first_index) {}
};
} // akantu
#endif // __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh b/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
index c59446298..ff5d8538c 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
@@ -1,127 +1,127 @@
/**
* @file solid_mechanics_model_event_handler.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Dec 18 2015
*
* @brief EventHandler implementation for SolidMechanicsEvents
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__
namespace akantu {
/// akantu::SolidMechanicsModelEvent is the base event for model
namespace SolidMechanicsModelEvent {
-struct BeforeSolveStepEvent {
- BeforeSolveStepEvent(AnalysisMethod & method) : method(method) {}
- AnalysisMethod method;
-};
-struct AfterSolveStepEvent {
- AfterSolveStepEvent(AnalysisMethod & method) : method(method) {}
- AnalysisMethod method;
-};
-struct BeforeDumpEvent {
- BeforeDumpEvent() = default;
-};
-struct BeginningOfDamageIterationEvent {
- BeginningOfDamageIterationEvent() = default;
-};
-struct AfterDamageEvent {
- AfterDamageEvent() = default;
-};
+ struct BeforeSolveStepEvent {
+ BeforeSolveStepEvent(AnalysisMethod & method) : method(method) {}
+ AnalysisMethod method;
+ };
+ struct AfterSolveStepEvent {
+ AfterSolveStepEvent(AnalysisMethod & method) : method(method) {}
+ AnalysisMethod method;
+ };
+ struct BeforeDumpEvent {
+ BeforeDumpEvent() = default;
+ };
+ struct BeginningOfDamageIterationEvent {
+ BeginningOfDamageIterationEvent() = default;
+ };
+ struct AfterDamageEvent {
+ AfterDamageEvent() = default;
+ };
}
/// akantu::SolidMechanicsModelEvent
class SolidMechanicsModelEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
virtual ~SolidMechanicsModelEventHandler() = default;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
/// Send what is before the solve step to the beginning of solve step through
/// EventManager
inline void
sendEvent(const SolidMechanicsModelEvent::BeforeSolveStepEvent & event) {
onBeginningSolveStep(event.method);
}
/// Send what is after the solve step to the end of solve step through
/// EventManager
inline void
sendEvent(const SolidMechanicsModelEvent::AfterSolveStepEvent & event) {
onEndSolveStep(event.method);
}
/// Send what is before dump to current dump through EventManager
inline void
sendEvent(__attribute__((unused))
const SolidMechanicsModelEvent::BeforeDumpEvent & event) {
onDump();
}
/// Send what is at the beginning of damage iteration to Damage iteration
/// through EventManager
inline void sendEvent(
__attribute__((unused))
const SolidMechanicsModelEvent::BeginningOfDamageIterationEvent & event) {
onDamageIteration();
}
/// Send what is after damage for the damage update through EventManager
inline void
sendEvent(__attribute__((unused))
const SolidMechanicsModelEvent::AfterDamageEvent & event) {
onDamageUpdate();
}
template <class EventHandler> friend class EventHandlerManager;
/* ------------------------------------------------------------------------ */
/* Interface */
/* ------------------------------------------------------------------------ */
public:
/// function to implement to react on akantu::BeforeSolveStepEvent
virtual void onBeginningSolveStep(__attribute__((unused))
const AnalysisMethod & method) {}
/// function to implement to react on akantu::AfterSolveStepEvent
virtual void onEndSolveStep(__attribute__((unused))
const AnalysisMethod & method) {}
/// function to implement to react on akantu::BeforeDumpEvent
virtual void onDump() {}
/// function to implement to react on akantu::BeginningOfDamageIterationEvent
virtual void onDamageIteration() {}
/// function to implement to react on akantu::AfterDamageEvent
virtual void onDamageUpdate() {}
};
} // akantu
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_mass.cc b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
index 792a26cb2..e0f5392a6 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_mass.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
@@ -1,159 +1,159 @@
/**
* @file solid_mechanics_model_mass.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Oct 05 2010
* @date last modification: Fri Oct 16 2015
*
* @brief function handling mass computation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "integrator_gauss.hh"
#include "material.hh"
#include "model_solver.hh"
#include "shape_lagrange.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class ComputeRhoFunctor {
public:
explicit ComputeRhoFunctor(const SolidMechanicsModel & model)
: model(model){};
void operator()(Matrix<Real> & rho, const Element & element) const {
const Array<UInt> & mat_indexes =
model.getMaterialByElement(element.type, element.ghost_type);
Real mat_rho =
model.getMaterial(mat_indexes(element.element)).getParam("rho");
rho.set(mat_rho);
}
private:
const SolidMechanicsModel & model;
};
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMassLumped() {
AKANTU_DEBUG_IN();
- if(not need_to_reassemble_lumped_mass) return;
+ if (not need_to_reassemble_lumped_mass)
+ return;
UInt nb_nodes = mesh.getNbNodes();
if (this->mass == nullptr) {
std::stringstream sstr_mass;
sstr_mass << id << ":mass";
mass =
&(alloc<Real>(sstr_mass.str(), nb_nodes, Model::spatial_dimension, 0));
} else {
mass->clear();
}
if (!this->getDOFManager().hasLumpedMatrix("M")) {
this->getDOFManager().getNewLumpedMatrix("M");
}
this->getDOFManager().clearLumpedMatrix("M");
assembleMassLumped(_not_ghost);
assembleMassLumped(_ghost);
this->getDOFManager().getLumpedMatrixPerDOFs("displacement", "M",
*(this->mass));
/// for not connected nodes put mass to one in order to avoid
#if !defined(AKANTU_NDEBUG)
bool has_unconnected_nodes = false;
- auto mass_it =
- mass->begin_reinterpret(mass->size() * mass->getNbComponent());
- auto mass_end =
- mass->end_reinterpret(mass->size() * mass->getNbComponent());
+ auto mass_it = mass->begin_reinterpret(mass->size() * mass->getNbComponent());
+ auto mass_end = mass->end_reinterpret(mass->size() * mass->getNbComponent());
for (; mass_it != mass_end; ++mass_it) {
if (std::abs(*mass_it) < std::numeric_limits<Real>::epsilon() ||
Math::isnan(*mass_it)) {
has_unconnected_nodes = true;
break;
}
}
if (has_unconnected_nodes)
AKANTU_DEBUG_WARNING("There are nodes that seem to not be connected to any "
"elements, beware that they have lumped mass of 0.");
#endif
this->synchronize(_gst_smm_mass);
need_to_reassemble_lumped_mass = false;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass() {
AKANTU_DEBUG_IN();
- if(not need_to_reassemble_mass) return;
+ if (not need_to_reassemble_mass)
+ return;
this->getDOFManager().clearMatrix("M");
assembleMass(_not_ghost);
need_to_reassemble_mass = false;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMassLumped(GhostType ghost_type) {
AKANTU_DEBUG_IN();
auto & fem = getFEEngineClass<MyFEEngineType>();
ComputeRhoFunctor compute_rho(*this);
for (auto type : mesh.elementTypes(Model::spatial_dimension, ghost_type)) {
fem.assembleFieldLumped(compute_rho, "M", "displacement",
this->getDOFManager(), type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass(GhostType ghost_type) {
AKANTU_DEBUG_IN();
auto & fem = getFEEngineClass<MyFEEngineType>();
ComputeRhoFunctor compute_rho(*this);
for (auto type : mesh.elementTypes(Model::spatial_dimension, ghost_type)) {
fem.assembleFieldMatrix(compute_rho, "M", "displacement",
this->getDOFManager(), type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_material.cc b/src/model/solid_mechanics/solid_mechanics_model_material.cc
index ece2d8d99..74ce922a9 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_material.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_material.cc
@@ -1,256 +1,254 @@
/**
* @file solid_mechanics_model_material.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Nov 26 2010
* @date last modification: Mon Nov 16 2015
*
* @brief instatiation of materials
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_factory.hh"
#include "aka_math.hh"
#include "material_non_local.hh"
#include "mesh_iterators.hh"
#include "non_local_manager.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
Material &
SolidMechanicsModel::registerNewMaterial(const ParserSection & section) {
std::string mat_name;
std::string mat_type = section.getName();
std::string opt_param = section.getOption();
try {
std::string tmp = section.getParameter("name");
mat_name = tmp; /** this can seam weird, but there is an ambiguous operator
* overload that i couldn't solve. @todo remove the
* weirdness of this code
*/
} catch (debug::Exception &) {
- AKANTU_ERROR(
- "A material of type \'"
- << mat_type << "\' in the input file has been defined without a name!");
+ AKANTU_ERROR("A material of type \'"
+ << mat_type
+ << "\' in the input file has been defined without a name!");
}
Material & mat = this->registerNewMaterial(mat_name, mat_type, opt_param);
mat.parseSection(section);
return mat;
}
/* -------------------------------------------------------------------------- */
Material & SolidMechanicsModel::registerNewMaterial(const ID & mat_name,
const ID & mat_type,
const ID & opt_param) {
AKANTU_DEBUG_ASSERT(materials_names_to_id.find(mat_name) ==
materials_names_to_id.end(),
"A material with this name '"
<< mat_name << "' has already been registered. "
<< "Please use unique names for materials");
UInt mat_count = materials.size();
materials_names_to_id[mat_name] = mat_count;
std::stringstream sstr_mat;
sstr_mat << this->id << ":" << mat_count << ":" << mat_type;
ID mat_id = sstr_mat.str();
std::unique_ptr<Material> material = MaterialFactory::getInstance().allocate(
mat_type, spatial_dimension, opt_param, *this, mat_id);
materials.push_back(std::move(material));
return *(materials.back());
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::instantiateMaterials() {
ParserSection model_section;
bool is_empty;
std::tie(model_section, is_empty) = this->getParserSection();
- if(not is_empty) {
+ if (not is_empty) {
auto model_materials = model_section.getSubSections(ParserType::_material);
for (const auto & section : model_materials) {
this->registerNewMaterial(section);
}
}
auto sub_sections = this->parser.getSubSections(ParserType::_material);
for (const auto & section : sub_sections) {
this->registerNewMaterial(section);
}
-
-
#ifdef AKANTU_DAMAGE_NON_LOCAL
for (auto & material : materials) {
if (dynamic_cast<MaterialNonLocalInterface *>(material.get()) == nullptr)
continue;
this->non_local_manager = std::make_unique<NonLocalManager>(
*this, *this, id + ":non_local_manager", memory_id);
break;
}
#endif
- if(materials.empty())
- AKANTU_EXCEPTION("No materials where instantiated for the model" << getID());
+ if (materials.empty())
+ AKANTU_EXCEPTION("No materials where instantiated for the model"
+ << getID());
are_materials_instantiated = true;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assignMaterialToElements(
const ElementTypeMapArray<UInt> * filter) {
for_each_element(
mesh,
[&](auto && element) {
UInt mat_index = (*material_selector)(element);
AKANTU_DEBUG_ASSERT(
mat_index < materials.size(),
"The material selector returned an index that does not exists");
material_index(element) = mat_index;
},
_element_filter = filter, _ghost_type = _not_ghost);
if (non_local_manager)
non_local_manager->synchronize(*this, _gst_material_id);
- for_each_element(
- mesh,
- [&](auto && element) {
- auto mat_index = material_index(element);
- auto index = materials[mat_index]->addElement(element);
- material_local_numbering(element) = index;
- },
- _element_filter = filter, _ghost_type = _not_ghost);
+ for_each_element(mesh,
+ [&](auto && element) {
+ auto mat_index = material_index(element);
+ auto index = materials[mat_index]->addElement(element);
+ material_local_numbering(element) = index;
+ },
+ _element_filter = filter, _ghost_type = _not_ghost);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initMaterials() {
AKANTU_DEBUG_ASSERT(materials.size() != 0, "No material to initialize !");
if (!are_materials_instantiated)
instantiateMaterials();
this->assignMaterialToElements();
// synchronize the element material arrays
this->synchronize(_gst_material_id);
for (auto & material : materials) {
/// init internals properties
material->initMaterial();
}
this->synchronize(_gst_smm_init_mat);
if (this->non_local_manager) {
this->non_local_manager->initialize();
}
}
/* -------------------------------------------------------------------------- */
Int SolidMechanicsModel::getInternalIndexFromID(const ID & id) const {
AKANTU_DEBUG_IN();
auto it = materials.begin();
auto end = materials.end();
for (; it != end; ++it)
if ((*it)->getID() == id) {
AKANTU_DEBUG_OUT();
return (it - materials.begin());
}
AKANTU_DEBUG_OUT();
return -1;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::reassignMaterial() {
AKANTU_DEBUG_IN();
std::vector<Array<Element>> element_to_add(materials.size());
std::vector<Array<Element>> element_to_remove(materials.size());
Element element;
for (auto ghost_type : ghost_types) {
element.ghost_type = ghost_type;
for (auto type :
mesh.elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
element.type = type;
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<UInt> & mat_indexes = material_index(type, ghost_type);
for (UInt el = 0; el < nb_element; ++el) {
element.element = el;
UInt old_material = mat_indexes(el);
UInt new_material = (*material_selector)(element);
if (old_material != new_material) {
element_to_add[new_material].push_back(element);
element_to_remove[old_material].push_back(element);
}
}
}
}
UInt mat_index = 0;
for (auto mat_it = materials.begin(); mat_it != materials.end();
++mat_it, ++mat_index) {
(*mat_it)->removeElements(element_to_remove[mat_index]);
(*mat_it)->addElements(element_to_add[mat_index]);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::applyEigenGradU(
const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name,
const GhostType ghost_type) {
AKANTU_DEBUG_ASSERT(prescribed_eigen_grad_u.size() ==
spatial_dimension * spatial_dimension,
"The prescribed grad_u is not of the good size");
for (auto & material : materials) {
if (material->getName() == material_name)
material->applyEigenGradU(prescribed_eigen_grad_u, ghost_type);
}
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
index 26850f2c7..afb0de79a 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
@@ -1,63 +1,62 @@
/**
* @file solid_mechanics_model_tmpl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Nov 13 2015
*
* @brief template part of solid mechanics model
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_TMPL_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_TMPL_HH__
namespace akantu {
#define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
/* -------------------------------------------------------------------------- */
template <typename Operation>
-void
-SolidMechanicsModel::splitByMaterial(const Array<Element> & elements,
- Operation && op) const {
+void SolidMechanicsModel::splitByMaterial(const Array<Element> & elements,
+ Operation && op) const {
std::vector<Array<Element>> elements_per_mat(materials.size());
this->splitElementByMaterial(elements, elements_per_mat);
for (auto && mat : zip(materials, elements_per_mat)) {
FWD(op)(FWD(*std::get<0>(mat)), FWD(std::get<1>(mat)));
}
}
#undef FWD
/* -------------------------------------------------------------------------- */
} // namespace akantu
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_TMPL_HH__ */
diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh
index 9ac8e1c10..d59f608e5 100644
--- a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh
+++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh
@@ -1,134 +1,134 @@
/**
* @file structural_element_bernoulli_beam_2.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation Tue Sep 19 2017
*
* @brief Specific functions for bernoulli beam 2d
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "structural_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__
#define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <>
inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_2>() {
AKANTU_DEBUG_IN();
constexpr ElementType type = _bernoulli_beam_2;
auto & fem = getFEEngineClass<MyFEEngineType>();
auto nb_element = mesh.getNbElement(type);
auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
auto nb_quadrature_points = fem.getNbIntegrationPoints(type);
auto nb_fields_to_interpolate = ElementClass<type>::getNbStressComponents();
auto nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
Array<Real> n(nb_element * nb_quadrature_points,
nb_fields_to_interpolate * nt_n_field_size, "N");
Array<Real> * rho_field =
new Array<Real>(nb_element * nb_quadrature_points, 1, "Rho");
rho_field->clear();
computeRho(*rho_field, type, _not_ghost);
#if 0
bool sign = true;
for (auto && ghost_type : ghost_types) {
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
0, 0, 0, sign, ghost_type); // Ni ui -> u
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
1, 1, 1, sign, ghost_type); // Mi vi -> v
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
2, 2, 1, sign, ghost_type); // Li Theta_i -> v
fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n,
rotation_matrix, type, ghost_type);
}
#endif
delete rho_field;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <>
void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_2>(
Array<Real> & rotations) {
auto type = _bernoulli_beam_2;
- auto nodes_it = mesh.getNodes().begin(this->spatial_dimension);
+ auto nodes_it = mesh.getNodes().begin(this->spatial_dimension);
for (auto && tuple :
zip(make_view(mesh.getConnectivity(type), 2),
make_view(rotations, nb_degree_of_freedom, nb_degree_of_freedom))) {
auto & connec = std::get<0>(tuple);
auto & R = std::get<1>(tuple);
Vector<Real> x2 = nodes_it[connec(1)]; // X2
Vector<Real> x1 = nodes_it[connec(0)]; // X1
auto le = x1.distance(x2);
auto c = (x2(0) - x1(0)) / le;
auto s = (x2(1) - x1(1)) / le;
/// Definition of the rotation matrix
R = {{c, s, 0.}, {-s, c, 0.}, {0., 0., 1.}};
}
}
/* -------------------------------------------------------------------------- */
template <>
void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_2>(
Array<Real> & tangent_moduli) {
// auto nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2);
auto nb_quadrature_points =
getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2);
auto tangent_size = 2;
tangent_moduli.clear();
auto D_it = tangent_moduli.begin(tangent_size, tangent_size);
auto el_mat = element_material(_bernoulli_beam_2, _not_ghost).begin();
for (auto & mat : element_material(_bernoulli_beam_2, _not_ghost)) {
auto E = materials[mat].E;
auto A = materials[mat].A;
auto I = materials[mat].I;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
auto & D = *D_it;
D(0, 0) = E * A;
D(1, 1) = E * I;
}
}
}
} // namespace akantu
#endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__ */
diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
index f4c3c121d..16616689c 100644
--- a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
+++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
@@ -1,190 +1,187 @@
/**
* @file structural_element_bernoulli_beam_3.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation Tue Sep 19 2017
*
* @brief Specific functions for bernoulli beam 3d
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__
#define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__
#include "structural_mechanics_model.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <>
inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_3>() {
AKANTU_DEBUG_IN();
#if 0
GhostType ghost_type = _not_ghost;
ElementType type = _bernoulli_beam_3;
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_element = getFEEngine().getMesh().getNbElement(type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
UInt nb_fields_to_interpolate =
getTangentStiffnessVoigtSize<_bernoulli_beam_3>();
UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
Array<Real> * n =
new Array<Real>(nb_element * nb_quadrature_points,
nb_fields_to_interpolate * nt_n_field_size, "N");
n->clear();
Array<Real> * rho_field =
new Array<Real>(nb_element * nb_quadrature_points, "Rho");
rho_field->clear();
computeRho(*rho_field, type, _not_ghost);
/* --------------------------------------------------------------------------
*/
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
0, 0, 0, true, ghost_type); // Ni ui -> u
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
1, 1, 1, true, ghost_type); // Mi vi -> v
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
2, 5, 1, true, ghost_type); // Li Theta_z_i -> v
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
1, 2, 2, true, ghost_type); // Mi wi -> w
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
2, 4, 2, false, ghost_type); // -Li Theta_y_i -> w
fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
0, 3, 3, true, ghost_type); // Ni Theta_x_i->Theta_x
/* --------------------------------------------------------------------------
*/
fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n,
rotation_matrix, type, ghost_type);
delete n;
delete rho_field;
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <>
void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_3>(
Array<Real> & rotations) {
ElementType type = _bernoulli_beam_3;
Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
- auto n_it =
- mesh.getNormals(type).begin(spatial_dimension);
- Array<UInt>::iterator<Vector<UInt> > connec_it =
+ auto n_it = mesh.getNormals(type).begin(spatial_dimension);
+ Array<UInt>::iterator<Vector<UInt>> connec_it =
mesh.getConnectivity(type).begin(2);
- auto nodes_it =
- mesh.getNodes().begin(spatial_dimension);
+ auto nodes_it = mesh.getNodes().begin(spatial_dimension);
Matrix<Real> Pe(spatial_dimension, spatial_dimension);
Matrix<Real> Pg(spatial_dimension, spatial_dimension);
Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension);
Vector<Real> x_n(spatial_dimension); // x vect n
Array<Real>::matrix_iterator R_it =
rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e = 0; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) {
Vector<Real> & n = *n_it;
Matrix<Real> & R = *R_it;
Vector<UInt> & connec = *connec_it;
Vector<Real> x;
x = nodes_it[connec(1)]; // X2
Vector<Real> y;
y = nodes_it[connec(0)]; // X1
Real l = x.distance(y);
x -= y; // X2 - X1
x_n.crossProduct(x, n);
Pe.eye();
Pe(0, 0) *= l;
Pe(1, 1) *= -l;
Pg(0, 0) = x(0);
Pg(0, 1) = x_n(0);
Pg(0, 2) = n(0);
Pg(1, 0) = x(1);
Pg(1, 1) = x_n(1);
Pg(1, 2) = n(1);
Pg(2, 0) = x(2);
Pg(2, 1) = x_n(2);
Pg(2, 2) = n(2);
inv_Pg.inverse(Pg);
Pe *= inv_Pg;
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
R(i, j) = Pe(i, j);
R(i + spatial_dimension, j + spatial_dimension) = Pe(i, j);
}
}
}
}
/* -------------------------------------------------------------------------- */
template <>
void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>(
Array<Real> & tangent_moduli) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3);
UInt nb_quadrature_points =
getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3);
UInt tangent_size = 4;
tangent_moduli.clear();
Array<Real>::matrix_iterator D_it =
tangent_moduli.begin(tangent_size, tangent_size);
for (UInt e = 0; e < nb_element; ++e) {
UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e);
Real E = materials[mat].E;
Real A = materials[mat].A;
Real Iz = materials[mat].Iz;
Real Iy = materials[mat].Iy;
Real GJ = materials[mat].GJ;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
Matrix<Real> & D = *D_it;
D(0, 0) = E * A;
D(1, 1) = E * Iz;
D(2, 2) = E * Iy;
D(3, 3) = GJ;
}
}
}
-
-} // akantu
+} // akantu
#endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__ */
diff --git a/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh b/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh
index 885a0a1a5..30a4d44b4 100644
--- a/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh
+++ b/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh
@@ -1,76 +1,77 @@
/**
* @file structural_element_bernoulli_kirchhoff_shell.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation Tue Sep 19 2017
*
* @brief Specific functions for bernoulli kirchhoff shell
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_KIRCHHOFF_SHELL_HH__
#define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_KIRCHHOFF_SHELL_HH__
#include "structural_mechanics_model.hh"
namespace akantu {
/* -------------------------------------------------------------------------- */
template <>
inline void
StructuralMechanicsModel::assembleMass<_discrete_kirchhoff_triangle_18>() {
AKANTU_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template <>
void StructuralMechanicsModel::computeTangentModuli<
_discrete_kirchhoff_triangle_18>(Array<Real> & tangent_moduli) {
auto tangent_size =
- ElementClass<_discrete_kirchhoff_triangle_18>::getNbStressComponents();
+ ElementClass<_discrete_kirchhoff_triangle_18>::getNbStressComponents();
auto nb_quad =
getFEEngine().getNbIntegrationPoints(_discrete_kirchhoff_triangle_18);
auto H_it = tangent_moduli.begin(tangent_size, tangent_size);
for (UInt mat :
element_material(_discrete_kirchhoff_triangle_18, _not_ghost)) {
auto & m = materials[mat];
for (UInt q = 0; q < nb_quad; ++q, ++H_it) {
auto & H = *H_it;
H.clear();
Matrix<Real> D = {{1, m.nu, 0}, {m.nu, 1, 0}, {0, 0, (1 - m.nu) / 2}};
D *= m.E * m.t / (1 - m.nu * m.nu);
H.block(D, 0, 0); // in plane membrane behavior
H.block(D * Math::pow<3>(m.t) / 12., 3, 3); // bending behavior
}
}
}
-} // akantu
+} // akantu
-#endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_DISCRETE_KIRCHHOFF_TRIANGLE_18_HH__ */
+#endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_DISCRETE_KIRCHHOFF_TRIANGLE_18_HH__ \
+ */
diff --git a/src/model/structural_mechanics/structural_mechanics_model.cc b/src/model/structural_mechanics/structural_mechanics_model.cc
index d093d45c6..f1ea3fff0 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model.cc
@@ -1,489 +1,483 @@
/**
* @file structural_mechanics_model.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Thu Oct 15 2015
*
* @brief Model implementation for StucturalMechanics elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "structural_mechanics_model.hh"
#include "dof_manager.hh"
#include "integrator_gauss.hh"
#include "mesh.hh"
#include "shape_structural.hh"
#include "sparse_matrix.hh"
#include "time_step_solver.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
#include "dumpable_inline_impl.hh"
#include "dumper_elemental_field.hh"
#include "dumper_iohelper_paraview.hh"
#include "group_manager_inline_impl.cc"
#endif
/* -------------------------------------------------------------------------- */
#include "structural_mechanics_model_inline_impl.cc"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::StructuralMechanicsModel(Mesh & mesh, UInt dim,
const ID & id,
const MemoryID & memory_id)
: Model(mesh, ModelType::_structural_mechanics_model, dim, id, memory_id),
time_step(NAN), f_m2a(1.0), stress("stress", id, memory_id),
element_material("element_material", id, memory_id),
set_ID("beam sets", id, memory_id),
rotation_matrix("rotation_matices", id, memory_id) {
AKANTU_DEBUG_IN();
registerFEEngineObject<MyFEEngineType>("StructuralMechanicsFEEngine", mesh,
spatial_dimension);
if (spatial_dimension == 2)
nb_degree_of_freedom = 3;
else if (spatial_dimension == 3)
nb_degree_of_freedom = 6;
else {
AKANTU_TO_IMPLEMENT();
}
#ifdef AKANTU_USE_IOHELPER
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
#endif
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_structural);
this->initDOFManager();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::~StructuralMechanicsModel() = default;
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initFullImpl(const ModelOptions & options) {
// <<<< This is the SolidMechanicsModel implementation for future ref >>>>
// material_index.initialize(mesh, _element_kind = _ek_not_defined,
// _default_value = UInt(-1), _with_nb_element =
// true);
// material_local_numbering.initialize(mesh, _element_kind = _ek_not_defined,
// _with_nb_element = true);
// Model::initFullImpl(options);
// // initialize pbc
// if (this->pbc_pair.size() != 0)
// this->initPBC();
// // initialize the materials
// if (this->parser.getLastParsedFile() != "") {
// this->instantiateMaterials();
// }
// this->initMaterials();
// this->initBC(*this, *displacement, *displacement_increment,
// *external_force);
// <<<< END >>>>
Model::initFullImpl(options);
// Initializing stresses
ElementTypeMap<UInt> stress_components;
/// TODO this is ugly af, maybe add a function to FEEngine
for (auto & type : mesh.elementTypes(_spatial_dimension = _all_dimensions,
- _element_kind = _ek_structural)) {
+ _element_kind = _ek_structural)) {
UInt nb_components = 0;
- // Getting number of components for each element type
+// Getting number of components for each element type
#define GET_(type) nb_components = ElementClass<type>::getNbStressComponents()
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_);
#undef GET_
stress_components(nb_components, type);
}
stress.initialize(getFEEngine(), _spatial_dimension = _all_dimensions,
- _element_kind = _ek_structural,
- _all_ghost_types = true,
+ _element_kind = _ek_structural, _all_ghost_types = true,
_nb_component = [&stress_components](
const ElementType & type, const GhostType &) -> UInt {
return stress_components(type);
});
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initFEEngineBoundary() {
/// TODO: this function should not be reimplemented
/// we're just avoiding a call to Model::initFEEngineBoundary()
}
/* -------------------------------------------------------------------------- */
// void StructuralMechanicsModel::setTimeStep(Real time_step) {
// this->time_step = time_step;
// #if defined(AKANTU_USE_IOHELPER)
// this->mesh.getDumper().setTimeStep(time_step);
// #endif
// }
/* -------------------------------------------------------------------------- */
/* Initialisation */
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initSolver(
TimeStepSolverType time_step_solver_type, NonLinearSolverType) {
AKANTU_DEBUG_IN();
this->allocNodalField(displacement_rotation, nb_degree_of_freedom,
"displacement");
- this->allocNodalField(external_force, nb_degree_of_freedom,
- "external_force");
- this->allocNodalField(internal_force, nb_degree_of_freedom,
- "internal_force");
+ this->allocNodalField(external_force, nb_degree_of_freedom, "external_force");
+ this->allocNodalField(internal_force, nb_degree_of_freedom, "internal_force");
this->allocNodalField(blocked_dofs, nb_degree_of_freedom, "blocked_dofs");
auto & dof_manager = this->getDOFManager();
if (!dof_manager.hasDOFs("displacement")) {
dof_manager.registerDOFs("displacement", *displacement_rotation,
_dst_nodal);
dof_manager.registerBlockedDOFs("displacement", *this->blocked_dofs);
}
if (time_step_solver_type == _tsst_dynamic ||
time_step_solver_type == _tsst_dynamic_lumped) {
this->allocNodalField(velocity, spatial_dimension, "velocity");
this->allocNodalField(acceleration, spatial_dimension, "acceleration");
if (!dof_manager.hasDOFsDerivatives("displacement", 1)) {
dof_manager.registerDOFsDerivative("displacement", 1, *this->velocity);
dof_manager.registerDOFsDerivative("displacement", 2,
*this->acceleration);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initModel() {
for (auto && type : mesh.elementTypes(_element_kind = _ek_structural)) {
// computeRotationMatrix(type);
element_material.alloc(mesh.getNbElement(type), 1, type);
}
getFEEngine().initShapeFunctions(_not_ghost);
getFEEngine().initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
getDOFManager().getMatrix("K").clear();
for (auto & type :
mesh.elementTypes(spatial_dimension, _not_ghost, _ek_structural)) {
#define ASSEMBLE_STIFFNESS_MATRIX(type) assembleStiffnessMatrix<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_STIFFNESS_MATRIX);
#undef ASSEMBLE_STIFFNESS_MATRIX
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::computeStresses() {
AKANTU_DEBUG_IN();
for (auto & type :
mesh.elementTypes(spatial_dimension, _not_ghost, _ek_structural)) {
#define COMPUTE_STRESS_ON_QUAD(type) computeStressOnQuad<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_STRESS_ON_QUAD);
#undef COMPUTE_STRESS_ON_QUAD
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::computeRotationMatrix(const ElementType & type) {
Mesh & mesh = getFEEngine().getMesh();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(type);
if (!rotation_matrix.exists(type)) {
rotation_matrix.alloc(nb_element,
nb_degree_of_freedom * nb_nodes_per_element *
nb_degree_of_freedom * nb_nodes_per_element,
type);
} else {
rotation_matrix(type).resize(nb_element);
}
rotation_matrix(type).clear();
Array<Real> rotations(nb_element,
nb_degree_of_freedom * nb_degree_of_freedom);
rotations.clear();
#define COMPUTE_ROTATION_MATRIX(type) computeRotationMatrix<type>(rotations);
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_ROTATION_MATRIX);
#undef COMPUTE_ROTATION_MATRIX
auto R_it = rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
auto T_it =
rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
nb_degree_of_freedom * nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el, ++R_it, ++T_it) {
auto & T = *T_it;
auto & R = *R_it;
for (UInt k = 0; k < nb_nodes_per_element; ++k) {
for (UInt i = 0; i < nb_degree_of_freedom; ++i)
for (UInt j = 0; j < nb_degree_of_freedom; ++j)
T(k * nb_degree_of_freedom + i, k * nb_degree_of_freedom + j) =
R(i, j);
}
}
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel::createNodalFieldBool(
const std::string & field_name, const std::string & group_name,
__attribute__((unused)) bool padding_flag) {
std::map<std::string, Array<bool> *> uint_nodal_fields;
uint_nodal_fields["blocked_dofs"] = blocked_dofs;
dumper::Field * field = NULL;
field = mesh.createNodalField(uint_nodal_fields[field_name], group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field *
StructuralMechanicsModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
UInt n;
if (spatial_dimension == 2) {
n = 2;
} else {
n = 3;
}
if (field_name == "displacement") {
return mesh.createStridedNodalField(displacement_rotation, group_name, n, 0,
padding_flag);
}
if (field_name == "rotation") {
return mesh.createStridedNodalField(displacement_rotation, group_name,
nb_degree_of_freedom - n, n,
padding_flag);
}
if (field_name == "force") {
- return mesh.createStridedNodalField(external_force, group_name, n,
- 0, padding_flag);
+ return mesh.createStridedNodalField(external_force, group_name, n, 0,
+ padding_flag);
}
if (field_name == "momentum") {
- return mesh.createStridedNodalField(external_force, group_name,
- nb_degree_of_freedom - n, n,
- padding_flag);
+ return mesh.createStridedNodalField(
+ external_force, group_name, nb_degree_of_freedom - n, n, padding_flag);
}
if (field_name == "internal_force") {
- return mesh.createStridedNodalField(internal_force, group_name, n,
- 0, padding_flag);
+ return mesh.createStridedNodalField(internal_force, group_name, n, 0,
+ padding_flag);
}
if (field_name == "internal_momentum") {
- return mesh.createStridedNodalField(internal_force, group_name,
- nb_degree_of_freedom - n, n,
- padding_flag);
+ return mesh.createStridedNodalField(
+ internal_force, group_name, nb_degree_of_freedom - n, n, padding_flag);
}
return nullptr;
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel::createElementalField(
const std::string & field_name, const std::string & group_name, bool,
const ElementKind & kind, const std::string &) {
dumper::Field * field = NULL;
if (field_name == "element_index_by_material")
field = mesh.createElementalField<UInt, Vector, dumper::ElementalField>(
field_name, group_name, this->spatial_dimension, kind);
return field;
}
/* -------------------------------------------------------------------------- */
/* Virtual methods from SolverCallback */
/* -------------------------------------------------------------------------- */
/// get the type of matrix needed
MatrixType StructuralMechanicsModel::getMatrixType(const ID & /*id*/) {
return _symmetric;
}
/// callback to assemble a Matrix
void StructuralMechanicsModel::assembleMatrix(const ID & id) {
if (id == "K")
assembleStiffnessMatrix();
}
/// callback to assemble a lumped Matrix
void StructuralMechanicsModel::assembleLumpedMatrix(const ID & /*id*/) {}
/// callback to assemble the residual StructuralMechanicsModel::(rhs)
void StructuralMechanicsModel::assembleResidual() {
AKANTU_DEBUG_IN();
auto & dof_manager = getDOFManager();
internal_force->clear();
computeStresses();
assembleInternalForce();
dof_manager.assembleToResidual("displacement", *internal_force, -1);
dof_manager.assembleToResidual("displacement", *external_force, 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Virtual methods from MeshEventHandler */
/* -------------------------------------------------------------------------- */
/// function to implement to react on akantu::NewNodesEvent
void StructuralMechanicsModel::onNodesAdded(const Array<UInt> & /*nodes_list*/,
const NewNodesEvent & /*event*/) {}
/// function to implement to react on akantu::RemovedNodesEvent
void StructuralMechanicsModel::onNodesRemoved(
const Array<UInt> & /*nodes_list*/, const Array<UInt> & /*new_numbering*/,
const RemovedNodesEvent & /*event*/) {}
/// function to implement to react on akantu::NewElementsEvent
void StructuralMechanicsModel::onElementsAdded(
const Array<Element> & /*elements_list*/,
const NewElementsEvent & /*event*/) {}
/// function to implement to react on akantu::RemovedElementsEvent
void StructuralMechanicsModel::onElementsRemoved(
const Array<Element> & /*elements_list*/,
const ElementTypeMapArray<UInt> & /*new_numbering*/,
const RemovedElementsEvent & /*event*/) {}
/// function to implement to react on akantu::ChangedElementsEvent
void StructuralMechanicsModel::onElementsChanged(
const Array<Element> & /*old_elements_list*/,
const Array<Element> & /*new_elements_list*/,
const ElementTypeMapArray<UInt> & /*new_numbering*/,
const ChangedElementsEvent & /*event*/) {}
/* -------------------------------------------------------------------------- */
/* Virtual methods from Model */
/* -------------------------------------------------------------------------- */
/// get some default values for derived classes
std::tuple<ID, TimeStepSolverType>
StructuralMechanicsModel::getDefaultSolverID(const AnalysisMethod & method) {
switch (method) {
case _static: {
return std::make_tuple("static", _tsst_static);
}
case _implicit_dynamic: {
return std::make_tuple("implicit", _tsst_dynamic);
}
default:
return std::make_tuple("unknown", _tsst_not_defined);
}
}
/* ------------------------------------------------------------------------ */
ModelSolverOptions StructuralMechanicsModel::getDefaultSolverOptions(
const TimeStepSolverType & type) const {
ModelSolverOptions options;
switch (type) {
case _tsst_static: {
options.non_linear_solver_type = _nls_linear;
options.integration_scheme_type["displacement"] = _ist_pseudo_time;
options.solution_type["displacement"] = IntegrationScheme::_not_defined;
break;
}
default:
AKANTU_EXCEPTION(type << " is not a valid time step solver type");
}
return options;
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::assembleInternalForce() {
for (auto type : mesh.elementTypes(_spatial_dimension = _all_dimensions,
- _element_kind = _ek_structural)) {
+ _element_kind = _ek_structural)) {
assembleInternalForce(type, _not_ghost);
// assembleInternalForce(type, _ghost);
}
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::assembleInternalForce(const ElementType & type,
GhostType gt) {
auto & fem = getFEEngine();
auto & sigma = stress(type, gt);
auto ndof = getNbDegreeOfFreedom(type);
auto nb_nodes = mesh.getNbNodesPerElement(type);
auto ndof_per_elem = ndof * nb_nodes;
Array<Real> BtSigma(fem.getNbIntegrationPoints(type) *
mesh.getNbElement(type),
ndof_per_elem, "BtSigma");
fem.computeBtD(sigma, BtSigma, type, gt);
- Array<Real> intBtSigma(0, ndof_per_elem,
- "intBtSigma");
+ Array<Real> intBtSigma(0, ndof_per_elem, "intBtSigma");
fem.integrate(BtSigma, intBtSigma, ndof_per_elem, type, gt);
BtSigma.resize(0);
getDOFManager().assembleElementalArrayLocalArray(intBtSigma, *internal_force,
type, gt, 1);
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/structural_mechanics/structural_mechanics_model.hh b/src/model/structural_mechanics/structural_mechanics_model.hh
index b06e1ea41..baa53daa2 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.hh
+++ b/src/model/structural_mechanics/structural_mechanics_model.hh
@@ -1,333 +1,332 @@
/**
* @file structural_mechanics_model.hh
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Thu Jan 21 2016
*
* @brief Particular implementation of the structural elements in the
* StructuralMechanicsModel
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_named_argument.hh"
#include "boundary_condition.hh"
#include "model.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
#define __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class Material;
class MaterialSelector;
class DumperIOHelper;
class NonLocalManager;
template <ElementKind kind, class IntegrationOrderFunctor>
class IntegratorGauss;
template <ElementKind kind> class ShapeStructural;
} // namespace akantu
namespace akantu {
struct StructuralMaterial {
Real E{0};
Real A{1};
Real I{0};
Real Iz{0};
Real Iy{0};
Real GJ{0};
Real rho{0};
Real t{0};
Real nu{0};
};
class StructuralMechanicsModel : public Model {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
using MyFEEngineType =
FEEngineTemplate<IntegratorGauss, ShapeStructural, _ek_structural>;
StructuralMechanicsModel(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "structural_mechanics_model",
const MemoryID & memory_id = 0);
virtual ~StructuralMechanicsModel();
/// Init full model
void initFullImpl(const ModelOptions & options) override;
/// Init boundary FEEngine
void initFEEngineBoundary() override;
-
/* ------------------------------------------------------------------------ */
/* Virtual methods from SolverCallback */
/* ------------------------------------------------------------------------ */
/// get the type of matrix needed
MatrixType getMatrixType(const ID &) override;
/// callback to assemble a Matrix
void assembleMatrix(const ID &) override;
/// callback to assemble a lumped Matrix
void assembleLumpedMatrix(const ID &) override;
/// callback to assemble the residual (rhs)
void assembleResidual() override;
/* ------------------------------------------------------------------------ */
/* Virtual methods from MeshEventHandler */
/* ------------------------------------------------------------------------ */
/// function to implement to react on akantu::NewNodesEvent
void onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event) override;
/// function to implement to react on akantu::RemovedNodesEvent
void onNodesRemoved(const Array<UInt> & nodes_list,
const Array<UInt> & new_numbering,
const RemovedNodesEvent & event) override;
/// function to implement to react on akantu::NewElementsEvent
void onElementsAdded(const Array<Element> & elements_list,
const NewElementsEvent & event) override;
/// function to implement to react on akantu::RemovedElementsEvent
void onElementsRemoved(const Array<Element> & elements_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event) override;
/// function to implement to react on akantu::ChangedElementsEvent
void onElementsChanged(const Array<Element> & old_elements_list,
const Array<Element> & new_elements_list,
const ElementTypeMapArray<UInt> & new_numbering,
const ChangedElementsEvent & event) override;
/* ------------------------------------------------------------------------ */
/* Virtual methods from Model */
/* ------------------------------------------------------------------------ */
protected:
/// get some default values for derived classes
std::tuple<ID, TimeStepSolverType>
getDefaultSolverID(const AnalysisMethod & method) override;
ModelSolverOptions
getDefaultSolverOptions(const TimeStepSolverType & type) const override;
UInt getNbDegreeOfFreedom(const ElementType & type) const;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
void initSolver(TimeStepSolverType, NonLinearSolverType) override;
/// initialize the model
void initModel() override;
/// compute the stresses per elements
void computeStresses();
/// compute the nodal forces
void assembleInternalForce();
/// compute the nodal forces for an element type
void assembleInternalForce(const ElementType & type, GhostType gt);
/// assemble the stiffness matrix
void assembleStiffnessMatrix();
/// assemble the mass matrix for consistent mass resolutions
void assembleMass();
/// TODO remove
void computeRotationMatrix(const ElementType & type);
protected:
/// compute Rotation Matrices
template <const ElementType type>
void computeRotationMatrix(__attribute__((unused)) Array<Real> & rotations) {}
/* ------------------------------------------------------------------------ */
/* Mass (structural_mechanics_model_mass.cc) */
/* ------------------------------------------------------------------------ */
/// assemble the mass matrix for either _ghost or _not_ghost elements
void assembleMass(GhostType ghost_type);
/// computes rho
void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type);
/// finish the computation of residual to solve in increment
void updateResidualInternal();
/* ------------------------------------------------------------------------ */
private:
template <ElementType type> void assembleStiffnessMatrix();
template <ElementType type> void assembleMass();
template <ElementType type> void computeStressOnQuad();
template <ElementType type>
void computeTangentModuli(Array<Real> & tangent_moduli);
/* ------------------------------------------------------------------------ */
/* Dumpable interface */
/* ------------------------------------------------------------------------ */
public:
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field *
createElementalField(const std::string & field_name,
const std::string & group_name, bool padding_flag,
const ElementKind & kind,
const std::string & fe_engine_id = "");
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// set the value of the time step
// void setTimeStep(Real time_step, const ID & solver_id = "") override;
/// return the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the StructuralMechanicsModel::displacement vector
AKANTU_GET_MACRO(Displacement, *displacement_rotation, Array<Real> &);
/// get the StructuralMechanicsModel::velocity vector
AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
/// get the StructuralMechanicsModel::acceleration vector, updated
/// by
/// StructuralMechanicsModel::updateAcceleration
AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
/// get the StructuralMechanicsModel::external_force vector
AKANTU_GET_MACRO(ExternalForce, *external_force, Array<Real> &);
/// get the StructuralMechanicsModel::internal_force vector (boundary forces)
AKANTU_GET_MACRO(InternalForce, *internal_force, Array<Real> &);
/// get the StructuralMechanicsModel::boundary vector
AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(RotationMatrix, rotation_matrix, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementMaterial, element_material, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Set_ID, set_ID, UInt);
void addMaterial(StructuralMaterial & material) {
materials.push_back(material);
}
const StructuralMaterial & getMaterial(const Element & element) const {
return materials[element_material(element)];
}
/* ------------------------------------------------------------------------ */
/* Boundaries (structural_mechanics_model_boundary.cc) */
/* ------------------------------------------------------------------------ */
public:
/// Compute Linear load function set in global axis
template <ElementType type>
void computeForcesByGlobalTractionArray(const Array<Real> & tractions);
/// Compute Linear load function set in local axis
template <ElementType type>
void computeForcesByLocalTractionArray(const Array<Real> & tractions);
/// compute force vector from a function(x,y,momentum) that describe stresses
// template <ElementType type>
// void computeForcesFromFunction(BoundaryFunction in_function,
// BoundaryFunctionType function_type);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// time step
Real time_step;
/// conversion coefficient form force/mass to acceleration
Real f_m2a;
/// displacements array
Array<Real> * displacement_rotation{nullptr};
/// velocities array
Array<Real> * velocity{nullptr};
/// accelerations array
Array<Real> * acceleration{nullptr};
/// forces array
Array<Real> * internal_force{nullptr};
/// forces array
Array<Real> * external_force{nullptr};
/// lumped mass array
Array<Real> * mass{nullptr};
/// boundaries array
Array<bool> * blocked_dofs{nullptr};
/// stress array
ElementTypeMapArray<Real> stress;
ElementTypeMapArray<UInt> element_material;
// Define sets of beams
ElementTypeMapArray<UInt> set_ID;
/// number of degre of freedom
UInt nb_degree_of_freedom;
// Rotation matrix
ElementTypeMapArray<Real> rotation_matrix;
// /// analysis method check the list in akantu::AnalysisMethod
// AnalysisMethod method;
/// flag defining if the increment must be computed or not
bool increment_flag;
/* ------------------------------------------------------------------------ */
std::vector<StructuralMaterial> materials;
};
} // namespace akantu
#endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__ */
diff --git a/src/model/structural_mechanics/structural_mechanics_model_boundary.cc b/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
index 850717a74..10f0b31f2 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
@@ -1,47 +1,47 @@
/**
* @file structural_mechanics_model_boundary.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Damien Spielmann <damien.spielmann@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Sun Oct 19 2014
*
- * @brief Implementation of the boundary conditions for StructuralMechanicsModel
+ * @brief Implementation of the boundary conditions for
+ * StructuralMechanicsModel
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "model.hh"
-#include "structural_mechanics_model.hh"
#include "integrator_gauss.hh"
+#include "model.hh"
#include "shape_structural.hh"
+#include "structural_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-
} // akantu
diff --git a/src/model/structural_mechanics/structural_mechanics_model_mass.cc b/src/model/structural_mechanics/structural_mechanics_model_mass.cc
index d3908068b..b24eeb0d2 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_mass.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_mass.cc
@@ -1,77 +1,76 @@
/**
* @file structural_mechanics_model_mass.cc
*
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
*
* @date creation: Mon Jul 07 2014
* @date last modification: Thu Oct 15 2015
*
* @brief function handling mass computation
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "structural_mechanics_model.hh"
-#include "material.hh"
#include "integrator_gauss.hh"
+#include "material.hh"
#include "shape_structural.hh"
+#include "structural_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class ComputeRhoFunctorStruct {
public:
explicit ComputeRhoFunctorStruct(const StructuralMechanicsModel & model)
: model(model){};
void operator()(Matrix<Real> & rho, const Element & element) const {
- Real mat_rho =
- model.getMaterial(element).rho;
+ Real mat_rho = model.getMaterial(element).rho;
rho.set(mat_rho);
}
private:
const StructuralMechanicsModel & model;
};
-
/* -------------------------------------------------------------------------- */
-void StructuralMechanicsModel::assembleMass(){
+void StructuralMechanicsModel::assembleMass() {
AKANTU_DEBUG_IN();
assembleMass(_not_ghost);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::assembleMass(GhostType ghost_type) {
AKANTU_DEBUG_IN();
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
ComputeRhoFunctorStruct compute_rho(*this);
- for (auto type : mesh.elementTypes(spatial_dimension, ghost_type, _ek_structural)) {
+ for (auto type :
+ mesh.elementTypes(spatial_dimension, ghost_type, _ek_structural)) {
fem.assembleFieldMatrix(compute_rho, "M", "displacement",
this->getDOFManager(), type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
} // akantu
diff --git a/src/model/time_step_solver.hh b/src/model/time_step_solver.hh
index 07fab9115..dfef977ca 100644
--- a/src/model/time_step_solver.hh
+++ b/src/model/time_step_solver.hh
@@ -1,136 +1,137 @@
/**
* @file time_step_solver.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Aug 24 12:42:04 2015
*
* @brief This corresponding to the time step evolution solver
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "aka_memory.hh"
#include "integration_scheme.hh"
#include "parameter_registry.hh"
#include "solver_callback.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TIME_STEP_SOLVER_HH__
#define __AKANTU_TIME_STEP_SOLVER_HH__
namespace akantu {
class DOFManager;
class NonLinearSolver;
}
namespace akantu {
class TimeStepSolver : public Memory,
public ParameterRegistry,
public SolverCallback {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
TimeStepSolver(DOFManager & dof_manager, const TimeStepSolverType & type,
NonLinearSolver & non_linear_solver, const ID & id,
UInt memory_id);
~TimeStepSolver() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// solves on step
virtual void solveStep(SolverCallback & solver_callback) = 0;
/// register an integration scheme for a given dof
virtual void
setIntegrationScheme(const ID & dof_id, const IntegrationSchemeType & type,
IntegrationScheme::SolutionType solution_type =
- IntegrationScheme::_not_defined) = 0;
+ IntegrationScheme::_not_defined) = 0;
/// replies if a integration scheme has been set
virtual bool hasIntegrationScheme(const ID & dof_id) const = 0;
/* ------------------------------------------------------------------------ */
/* Solver Callback interface */
/* ------------------------------------------------------------------------ */
public:
/// implementation of the SolverCallback::getMatrixType()
MatrixType getMatrixType(const ID &) final { return _mt_not_defined; }
/// implementation of the SolverCallback::predictor()
void predictor() override;
/// implementation of the SolverCallback::corrector()
void corrector() override;
/// implementation of the SolverCallback::assembleJacobian()
void assembleMatrix(const ID & matrix_id) override;
/// implementation of the SolverCallback::assembleJacobian()
void assembleLumpedMatrix(const ID & matrix_id) final;
/// implementation of the SolverCallback::assembleResidual()
void assembleResidual() override;
/// implementation of the SolverCallback::assembleResidual()
void assembleResidual(const ID & residual_part) override;
void beforeSolveStep() override;
void afterSolveStep() override;
bool canSplitResidual() { return solver_callback->canSplitResidual(); }
/* ------------------------------------------------------------------------ */
/* Accessor */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(TimeStep, time_step, Real);
AKANTU_SET_MACRO(TimeStep, time_step, Real);
AKANTU_GET_MACRO(NonLinearSolver, non_linear_solver, const NonLinearSolver &);
AKANTU_GET_MACRO_NOT_CONST(NonLinearSolver, non_linear_solver,
NonLinearSolver &);
+
protected:
MatrixType getCommonMatrixType();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Underlying dof manager containing the dof to treat
DOFManager & _dof_manager;
/// Type of solver
TimeStepSolverType type;
/// The time step for this solver
Real time_step;
/// Temporary storage for solver callback
SolverCallback * solver_callback;
/// NonLinearSolver used by this tome step solver
NonLinearSolver & non_linear_solver;
/// List of required matrices
std::map<std::string, MatrixType> needed_matrices;
};
} // akantu
#endif /* __AKANTU_TIME_STEP_SOLVER_HH__ */
diff --git a/src/model/time_step_solvers/time_step_solver.cc b/src/model/time_step_solvers/time_step_solver.cc
index 1cb645ef3..d936db10b 100644
--- a/src/model/time_step_solvers/time_step_solver.cc
+++ b/src/model/time_step_solvers/time_step_solver.cc
@@ -1,176 +1,177 @@
/**
* @file time_step_solver.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Oct 12 16:56:43 2015
*
* @brief Implementation of common part of TimeStepSolvers
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "time_step_solver.hh"
#include "dof_manager.hh"
#include "non_linear_solver.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
TimeStepSolver::TimeStepSolver(DOFManager & dof_manager,
const TimeStepSolverType & type,
NonLinearSolver & non_linear_solver,
const ID & id, UInt memory_id)
: Memory(id, memory_id), SolverCallback(dof_manager),
_dof_manager(dof_manager), type(type), time_step(0.),
solver_callback(nullptr), non_linear_solver(non_linear_solver) {
this->registerSubRegistry("non_linear_solver", non_linear_solver);
}
/* -------------------------------------------------------------------------- */
TimeStepSolver::~TimeStepSolver() = default;
/* -------------------------------------------------------------------------- */
MatrixType TimeStepSolver::getCommonMatrixType() {
MatrixType common_type = _mt_not_defined;
for (auto & pair : needed_matrices) {
auto & type = pair.second;
if (type == _mt_not_defined) {
type = this->solver_callback->getMatrixType(pair.first);
}
common_type = std::min(common_type, type);
}
AKANTU_DEBUG_ASSERT(common_type != _mt_not_defined,
"No type defined for the matrices");
return common_type;
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::predictor() {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
this->solver_callback->predictor();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::corrector() {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
this->solver_callback->corrector();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::beforeSolveStep() {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
this->solver_callback->beforeSolveStep();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::afterSolveStep() {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
this->solver_callback->afterSolveStep();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::assembleLumpedMatrix(const ID & matrix_id) {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
if (not _dof_manager.hasLumpedMatrix(matrix_id))
_dof_manager.getNewLumpedMatrix(matrix_id);
this->solver_callback->assembleLumpedMatrix(matrix_id);
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::assembleMatrix(const ID & matrix_id) {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
auto common_type = this->getCommonMatrixType();
if (matrix_id != "J") {
auto type = needed_matrices[matrix_id];
- if (type == _mt_not_defined) return;
+ if (type == _mt_not_defined)
+ return;
if (not _dof_manager.hasMatrix(matrix_id)) {
_dof_manager.getNewMatrix(matrix_id, type);
}
this->solver_callback->assembleMatrix(matrix_id);
return;
}
if (not _dof_manager.hasMatrix("J"))
_dof_manager.getNewMatrix("J", common_type);
for (auto & pair : needed_matrices) {
auto type = pair.second;
if (type == _mt_not_defined)
continue;
auto name = pair.first;
if (not _dof_manager.hasMatrix(name))
_dof_manager.getNewMatrix(name, type);
this->solver_callback->assembleMatrix(name);
}
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::assembleResidual() {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
this->_dof_manager.clearResidual();
this->solver_callback->assembleResidual();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolver::assembleResidual(const ID & residual_part) {
AKANTU_DEBUG_ASSERT(
this->solver_callback != nullptr,
"This function cannot be called if the solver_callback is not set");
this->solver_callback->assembleResidual(residual_part);
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/time_step_solvers/time_step_solver_default.cc b/src/model/time_step_solvers/time_step_solver_default.cc
index 41fe9bce9..371050e61 100644
--- a/src/model/time_step_solvers/time_step_solver_default.cc
+++ b/src/model/time_step_solvers/time_step_solver_default.cc
@@ -1,309 +1,309 @@
/**
* @file time_step_solver_default.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Sep 16 10:20:55 2015
*
* @brief Default implementation of the time step solver
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "time_step_solver_default.hh"
#include "dof_manager_default.hh"
#include "integration_scheme_1st_order.hh"
#include "integration_scheme_2nd_order.hh"
#include "mesh.hh"
#include "non_linear_solver.hh"
#include "pseudo_time.hh"
#include "sparse_matrix_aij.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
TimeStepSolverDefault::TimeStepSolverDefault(
DOFManagerDefault & dof_manager, const TimeStepSolverType & type,
NonLinearSolver & non_linear_solver, const ID & id, UInt memory_id)
: TimeStepSolver(dof_manager, type, non_linear_solver, id, memory_id),
dof_manager(dof_manager), is_mass_lumped(false) {
switch (type) {
case _tsst_dynamic:
break;
case _tsst_dynamic_lumped:
this->is_mass_lumped = true;
break;
case _tsst_static:
/// initialize a static time solver for callback dofs
break;
default:
AKANTU_TO_IMPLEMENT();
}
}
/* -------------------------------------------------------------------------- */
void TimeStepSolverDefault::setIntegrationScheme(
const ID & dof_id, const IntegrationSchemeType & type,
IntegrationScheme::SolutionType solution_type) {
if (this->integration_schemes.find(dof_id) !=
this->integration_schemes.end()) {
AKANTU_EXCEPTION("Their DOFs "
<< dof_id
<< " have already an integration scheme associated");
}
std::unique_ptr<IntegrationScheme> integration_scheme;
if (this->is_mass_lumped) {
switch (type) {
case _ist_forward_euler: {
integration_scheme = std::make_unique<ForwardEuler>(dof_manager, dof_id);
break;
}
case _ist_central_difference: {
integration_scheme =
std::make_unique<CentralDifference>(dof_manager, dof_id);
break;
}
default:
AKANTU_EXCEPTION(
"This integration scheme cannot be used in lumped dynamic");
}
} else {
switch (type) {
case _ist_pseudo_time: {
integration_scheme = std::make_unique<PseudoTime>(dof_manager, dof_id);
break;
}
case _ist_forward_euler: {
integration_scheme = std::make_unique<ForwardEuler>(dof_manager, dof_id);
break;
}
case _ist_trapezoidal_rule_1: {
integration_scheme =
std::make_unique<TrapezoidalRule1>(dof_manager, dof_id);
break;
}
case _ist_backward_euler: {
integration_scheme = std::make_unique<BackwardEuler>(dof_manager, dof_id);
break;
}
case _ist_central_difference: {
integration_scheme =
std::make_unique<CentralDifference>(dof_manager, dof_id);
break;
}
case _ist_fox_goodwin: {
integration_scheme = std::make_unique<FoxGoodwin>(dof_manager, dof_id);
break;
}
case _ist_trapezoidal_rule_2: {
integration_scheme =
std::make_unique<TrapezoidalRule2>(dof_manager, dof_id);
break;
}
case _ist_linear_acceleration: {
integration_scheme =
std::make_unique<LinearAceleration>(dof_manager, dof_id);
break;
}
case _ist_generalized_trapezoidal: {
integration_scheme =
std::make_unique<GeneralizedTrapezoidal>(dof_manager, dof_id);
break;
}
case _ist_newmark_beta:
integration_scheme = std::make_unique<NewmarkBeta>(dof_manager, dof_id);
break;
}
}
AKANTU_DEBUG_ASSERT(integration_scheme,
"No integration scheme was found for the provided types");
auto && matrices_names = integration_scheme->getNeededMatrixList();
for (auto && name : matrices_names) {
needed_matrices.insert({name, _mt_not_defined});
}
this->integration_schemes[dof_id] = std::move(integration_scheme);
this->solution_types[dof_id] = solution_type;
this->integration_schemes_owner.insert(dof_id);
}
/* -------------------------------------------------------------------------- */
bool TimeStepSolverDefault::hasIntegrationScheme(const ID & dof_id) const {
return this->integration_schemes.find(dof_id) !=
this->integration_schemes.end();
}
/* -------------------------------------------------------------------------- */
TimeStepSolverDefault::~TimeStepSolverDefault() = default;
/* -------------------------------------------------------------------------- */
void TimeStepSolverDefault::solveStep(SolverCallback & solver_callback) {
this->solver_callback = &solver_callback;
this->solver_callback->beforeSolveStep();
this->non_linear_solver.solve(*this);
this->solver_callback->afterSolveStep();
this->solver_callback = nullptr;
}
/* -------------------------------------------------------------------------- */
void TimeStepSolverDefault::predictor() {
AKANTU_DEBUG_IN();
TimeStepSolver::predictor();
for (auto & pair : this->integration_schemes) {
auto & dof_id = pair.first;
auto & integration_scheme = pair.second;
if (this->dof_manager.hasPreviousDOFs(dof_id)) {
this->dof_manager.savePreviousDOFs(dof_id);
}
/// integrator predictor
integration_scheme->predictor(this->time_step);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolverDefault::corrector() {
AKANTU_DEBUG_IN();
TimeStepSolver::corrector();
for (auto & pair : this->integration_schemes) {
auto & dof_id = pair.first;
auto & integration_scheme = pair.second;
const auto & solution_type = this->solution_types[dof_id];
integration_scheme->corrector(solution_type, this->time_step);
/// computing the increment of dof if needed
if (this->dof_manager.hasDOFsIncrement(dof_id)) {
if (!this->dof_manager.hasPreviousDOFs(dof_id)) {
AKANTU_DEBUG_WARNING("In order to compute the increment of "
<< dof_id << " a 'previous' has to be registered");
continue;
}
Array<Real> & increment = this->dof_manager.getDOFsIncrement(dof_id);
Array<Real> & previous = this->dof_manager.getPreviousDOFs(dof_id);
UInt dof_array_comp = this->dof_manager.getDOFs(dof_id).getNbComponent();
auto prev_dof_it = previous.begin(dof_array_comp);
auto incr_it = increment.begin(dof_array_comp);
auto incr_end = increment.end(dof_array_comp);
increment.copy(this->dof_manager.getDOFs(dof_id));
for (; incr_it != incr_end; ++incr_it, ++prev_dof_it) {
*incr_it -= *prev_dof_it;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolverDefault::assembleMatrix(const ID & matrix_id) {
AKANTU_DEBUG_IN();
TimeStepSolver::assembleMatrix(matrix_id);
if (matrix_id != "J")
return;
for (auto & pair : this->integration_schemes) {
auto & dof_id = pair.first;
auto & integration_scheme = pair.second;
const auto & solution_type = this->solution_types[dof_id];
integration_scheme->assembleJacobian(solution_type, this->time_step);
}
this->dof_manager.applyBoundary("J");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolverDefault::assembleResidual() {
AKANTU_DEBUG_IN();
if (this->needed_matrices.find("M") != needed_matrices.end()) {
if (this->is_mass_lumped) {
this->assembleLumpedMatrix("M");
} else {
this->assembleMatrix("M");
}
}
TimeStepSolver::assembleResidual();
for (auto & pair : this->integration_schemes) {
auto & integration_scheme = pair.second;
integration_scheme->assembleResidual(this->is_mass_lumped);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void TimeStepSolverDefault::assembleResidual(const ID & residual_part) {
AKANTU_DEBUG_IN();
if (this->needed_matrices.find("M") != needed_matrices.end()) {
if (this->is_mass_lumped) {
this->assembleLumpedMatrix("M");
} else {
this->assembleMatrix("M");
}
}
if (residual_part != "inertial") {
TimeStepSolver::assembleResidual(residual_part);
}
- if(residual_part == "inertial") {
+ if (residual_part == "inertial") {
for (auto & pair : this->integration_schemes) {
auto & integration_scheme = pair.second;
integration_scheme->assembleResidual(this->is_mass_lumped);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/model/time_step_solvers/time_step_solver_default.hh b/src/model/time_step_solvers/time_step_solver_default.hh
index 7513f2526..9996f657f 100644
--- a/src/model/time_step_solvers/time_step_solver_default.hh
+++ b/src/model/time_step_solvers/time_step_solver_default.hh
@@ -1,110 +1,112 @@
/**
* @file time_step_solver_default.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Aug 24 17:10:29 2015
*
* @brief Default implementation for the time stepper
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "integration_scheme.hh"
#include "time_step_solver.hh"
/* -------------------------------------------------------------------------- */
#include <map>
#include <set>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TIME_STEP_SOLVER_DEFAULT_HH__
#define __AKANTU_TIME_STEP_SOLVER_DEFAULT_HH__
namespace akantu {
class DOFManagerDefault;
}
namespace akantu {
class TimeStepSolverDefault : public TimeStepSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
TimeStepSolverDefault(DOFManagerDefault & dof_manager,
const TimeStepSolverType & type,
NonLinearSolver & non_linear_solver, const ID & id,
UInt memory_id);
~TimeStepSolverDefault() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// registers an integration scheme for a given dof
void setIntegrationScheme(const ID & dof_id,
const IntegrationSchemeType & type,
IntegrationScheme::SolutionType solution_type =
IntegrationScheme::_not_defined) override;
bool hasIntegrationScheme(const ID & dof_id) const override;
/// implementation of the TimeStepSolver::predictor()
void predictor() override;
/// implementation of the TimeStepSolver::corrector()
void corrector() override;
/// implementation of the TimeStepSolver::assembleMatrix()
void assembleMatrix(const ID & matrix_id) override;
/// implementation of the TimeStepSolver::assembleResidual()
void assembleResidual() override;
void assembleResidual(const ID & residual_part) override;
/// implementation of the generic TimeStepSolver::solveStep()
void solveStep(SolverCallback & solver_callback) override;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
- using DOFsIntegrationSchemes = std::map<ID, std::unique_ptr<IntegrationScheme>>;
- using DOFsIntegrationSchemesSolutionTypes = std::map<ID, IntegrationScheme::SolutionType>;
+ using DOFsIntegrationSchemes =
+ std::map<ID, std::unique_ptr<IntegrationScheme>>;
+ using DOFsIntegrationSchemesSolutionTypes =
+ std::map<ID, IntegrationScheme::SolutionType>;
using DOFsIntegrationSchemesOwner = std::set<ID>;
/// DOFManager with its real type
DOFManagerDefault & dof_manager;
/// Underlying integration scheme per dof, \todo check what happens in dynamic
/// in case of coupled equations
DOFsIntegrationSchemes integration_schemes;
/// defines if the solver is owner of the memory or not
DOFsIntegrationSchemesOwner integration_schemes_owner;
/// Type of corrector to use
DOFsIntegrationSchemesSolutionTypes solution_types;
/// define if the mass matrix is lumped or not
bool is_mass_lumped;
};
} // namespace akantu
#endif /* __AKANTU_TIME_STEP_SOLVER_DEFAULT_HH__ */
diff --git a/src/model/time_step_solvers/time_step_solver_default_explicit.hh b/src/model/time_step_solvers/time_step_solver_default_explicit.hh
index cceb0d50d..d23c30d3b 100644
--- a/src/model/time_step_solvers/time_step_solver_default_explicit.hh
+++ b/src/model/time_step_solvers/time_step_solver_default_explicit.hh
@@ -1,78 +1,77 @@
/**
* @file time_step_solver_default_explicit.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Aug 24 14:21:44 2015
*
* @brief Default solver for explicit resolution
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TIME_STEP_SOLVER_DEFAULT_EXPLICIT_HH__
#define __AKANTU_TIME_STEP_SOLVER_DEFAULT_EXPLICIT_HH__
namespace akantu {
class TimeStepSolverDefaultExplicit : public TimeStepSolverDefault {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
TimeStepSolverDefaultExplicit();
virtual ~TimeStepSolverDefaultExplicit();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
void solveStep();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "time_step_solver_default_explicit_inline_impl.cc"
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const TimeStepSolverDefaultExplicit & _this) {
_this.printself(stream);
return stream;
}
} // akantu
#endif /* __AKANTU_TIME_STEP_SOLVER_DEFAULT_EXPLICIT_HH__ */
diff --git a/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh b/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh
index 2a4cac0f8..9e0552b82 100644
--- a/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh
+++ b/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh
@@ -1,63 +1,63 @@
/**
* @file time_step_solver_default_solver_callback.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Sep 28 18:58:07 2015
*
- * @brief Implementation of the NonLinearSolverCallback for the time step solver
+ * @brief Implementation of the NonLinearSolverCallback for the time step
+ * solver
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "non_linear_solver_callback.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TIME_STEP_SOLVER_DEFAULT_SOLVER_CALLBACK_HH__
#define __AKANTU_TIME_STEP_SOLVER_DEFAULT_SOLVER_CALLBACK_HH__
namespace akantu {
class TimeStepSolverCallback : public NonLinearSolverCallback {
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// callback to assemble the Jacobian Matrix
virtual void assembleJacobian();
/// callback to assemble the residual (rhs)
virtual void assembleResidual();
/* ------------------------------------------------------------------------ */
/* Dynamic simulations part */
/* ------------------------------------------------------------------------ */
/// callback for the predictor (in case of dynamic simulation)
virtual void predictor();
/// callback for the corrector (in case of dynamic simulation)
virtual void corrector();
};
} // akantu
-
#endif /* __AKANTU_TIME_STEP_SOLVER_DEFAULT_SOLVER_CALLBACK_HH__ */
diff --git a/src/python/python_functor.hh b/src/python/python_functor.hh
index 22bc4a2c5..effa1fc8f 100644
--- a/src/python/python_functor.hh
+++ b/src/python/python_functor.hh
@@ -1,143 +1,146 @@
/**
* @file python_functor.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Sun Nov 15 2015
*
* @brief Python Functor interface
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "internal_field.hh"
#include "element_group.hh"
+#include "internal_field.hh"
/* -------------------------------------------------------------------------- */
#include <Python.h>
#include <map>
#include <vector>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PYTHON_FUNCTOR_HH__
#define __AKANTU_PYTHON_FUNCTOR_HH__
namespace akantu {
class PythonFunctor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PythonFunctor(PyObject * obj);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
/// call the python functor
PyObject * callFunctor(PyObject * functor, PyObject * args,
PyObject * kwargs) const;
/// call the python functor from variadic types
template <typename return_type, typename... Params>
return_type callFunctor(const std::string & functor_name,
Params &... parameters) const;
/// empty function to cose the recursive template loop
static inline void packArguments(std::vector<PyObject *> & pArgs);
/// get the python function object
inline PyObject * getPythonFunction(const std::string & functor_name) const;
/// variadic template for unknown number of arguments to unpack
template <typename T, typename... Args>
static inline void packArguments(std::vector<PyObject *> & pArgs, T & p,
Args &... params);
/// convert an akantu object to python
template <typename T>
static inline PyObject * convertToPython(const T & akantu_obj);
/// convert a stl vector to python
template <typename T>
static inline PyObject * convertToPython(const std::vector<T> & akantu_obj);
/// convert a stl vector to python
template <typename T>
- static inline PyObject * convertToPython(const std::vector<Array<T> *> & akantu_obj);
+ static inline PyObject *
+ convertToPython(const std::vector<Array<T> *> & akantu_obj);
/// convert a stl vector to python
template <typename T>
- static inline PyObject * convertToPython(const std::unique_ptr<T> & akantu_obj);
-
+ static inline PyObject *
+ convertToPython(const std::unique_ptr<T> & akantu_obj);
+
/// convert a stl vector to python
template <typename T1, typename T2>
static inline PyObject * convertToPython(const std::map<T1, T2> & akantu_obj);
-
+
/// convert an akantu vector to python
template <typename T>
static inline PyObject * convertToPython(const Vector<T> & akantu_obj);
/// convert an akantu internal to python
template <typename T>
static inline PyObject * convertToPython(const InternalField<T> & akantu_obj);
/// convert an akantu vector to python
template <typename T>
- static inline PyObject * convertToPython(const ElementTypeMapArray<T> & akantu_obj);
-
+ static inline PyObject *
+ convertToPython(const ElementTypeMapArray<T> & akantu_obj);
+
/// convert an akantu vector to python
template <typename T>
static inline PyObject * convertToPython(const Array<T> & akantu_obj);
/// convert an akantu vector to python
template <typename T>
static inline PyObject * convertToPython(Array<T> * akantu_obj);
/// convert a akantu matrix to python
template <typename T>
static inline PyObject * convertToPython(const Matrix<T> & akantu_obj);
/// convert a python object to an akantu object
template <typename return_type>
static inline return_type convertToAkantu(PyObject * python_obj);
/// convert a python object to an akantu object
template <typename T>
static inline std::vector<T> convertListToAkantu(PyObject * python_obj);
/// returns the numpy data type code
template <typename T> static inline int getPythonDataTypeCode();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
PyObject * python_obj;
};
} // akantu
#endif /* __AKANTU_PYTHON_FUNCTOR_HH__ */
#include "python_functor_inline_impl.cc"
diff --git a/src/python/python_functor_inline_impl.cc b/src/python/python_functor_inline_impl.cc
index 27ea3b174..e573bdabe 100644
--- a/src/python/python_functor_inline_impl.cc
+++ b/src/python/python_functor_inline_impl.cc
@@ -1,463 +1,462 @@
/**
* @file python_functor_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Fri Nov 13 2015
* @date last modification: Wed Nov 18 2015
*
* @brief Python functor interface
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "integration_point.hh"
#include "internal_field.hh"
/* -------------------------------------------------------------------------- */
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <Python.h>
#include <numpy/arrayobject.h>
#include <typeinfo>
#if PY_MAJOR_VERSION >= 3
#include <codecvt>
#endif
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
#define __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename T> inline int PythonFunctor::getPythonDataTypeCode() {
AKANTU_EXCEPTION("undefined type: " << debug::demangle(typeid(T).name()));
}
/* -------------------------------------------------------------------------- */
template <> inline int PythonFunctor::getPythonDataTypeCode<bool>() {
int data_typecode = NPY_NOTYPE;
size_t s = sizeof(bool);
switch (s) {
case 1:
data_typecode = NPY_BOOL;
break;
case 2:
data_typecode = NPY_UINT16;
break;
case 4:
data_typecode = NPY_UINT32;
break;
case 8:
data_typecode = NPY_UINT64;
break;
}
return data_typecode;
}
/* -------------------------------------------------------------------------- */
template <> inline int PythonFunctor::getPythonDataTypeCode<double>() {
return NPY_DOUBLE;
}
/* -------------------------------------------------------------------------- */
template <> inline int PythonFunctor::getPythonDataTypeCode<UInt>() {
return NPY_UINT;
}
-
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *
PythonFunctor::convertToPython<double>(const double & akantu_object) {
return PyFloat_FromDouble(akantu_object);
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *
PythonFunctor::convertToPython<UInt>(const UInt & akantu_object) {
#if PY_MAJOR_VERSION >= 3
return PyLong_FromLong(akantu_object);
#else
return PyInt_FromLong(akantu_object);
#endif
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *
PythonFunctor::convertToPython<int>(const int & akantu_object) {
#if PY_MAJOR_VERSION >= 3
return PyLong_FromLong(akantu_object);
#else
return PyInt_FromLong(akantu_object);
#endif
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *
PythonFunctor::convertToPython<bool>(const bool & akantu_object) {
return PyBool_FromLong(long(akantu_object));
}
/* -------------------------------------------------------------------------- */
template <>
inline PyObject *
PythonFunctor::convertToPython<std::string>(const std::string & str) {
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromString(str.c_str());
#else
return PyString_FromString(str.c_str());
#endif
}
/* --------------------------------------------------------------------------
*/
template <>
inline PyObject *
PythonFunctor::convertToPython<NodeGroup>(const NodeGroup & group) {
return PythonFunctor::convertToPython(group.getNodes());
}
/* --------------------------------------------------------------------------
*/
template <>
inline PyObject *
PythonFunctor::convertToPython<ElementGroup>(const ElementGroup & group) {
PyObject * res = PyDict_New();
PyDict_SetItem(res,
PythonFunctor::convertToPython(std::string("element_group")),
PythonFunctor::convertToPython(group.getElements()));
PyDict_SetItem(res, PythonFunctor::convertToPython(std::string("node_group")),
PythonFunctor::convertToPython(group.getNodeGroup()));
return res;
}
/* --------------------------------------------------------------------------
*/
template <>
inline PyObject *
PythonFunctor::convertToPython<ElementGroup *>(ElementGroup * const & group) {
return PythonFunctor::convertToPython(*group);
}
/* --------------------------------------------------------------------------
*/
template <>
inline PyObject *
PythonFunctor::convertToPython<ElementType>(const ElementType & type) {
// std::stringstream sstr;
// sstr << type;
// return PythonFunctor::convertToPython(sstr.str());
return PythonFunctor::convertToPython(int(type));
}
/* --------------------------------------------------------------------------
*/
template <typename T>
inline PyObject *
PythonFunctor::convertToPython(const ElementTypeMapArray<T> & map) {
std::map<std::string, Array<T> *> res;
for (const auto & type : map.elementTypes()) {
std::stringstream sstr;
sstr << type;
res[sstr.str()] = const_cast<Array<T> *>(&map(type));
}
return PythonFunctor::convertToPython(res);
}
/* --------------------------------------------------------------------------
*/
template <typename T> PyObject * PythonFunctor::convertToPython(const T &) {
AKANTU_EXCEPTION(__PRETTY_FUNCTION__ << " : not implemented yet !"
<< std::endl
<< debug::demangle(typeid(T).name()));
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline PyObject * PythonFunctor::convertToPython(const std::vector<T> & array) {
int data_typecode = getPythonDataTypeCode<T>();
npy_intp dims[1] = {int(array.size())};
PyObject * obj = PyArray_SimpleNewFromData(1, dims, data_typecode,
const_cast<T *>(&array[0]));
auto * res = (PyArrayObject *)obj;
return (PyObject *)res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline PyObject *
PythonFunctor::convertToPython(const std::vector<Array<T> *> & array) {
PyObject * res = PyDict_New();
for (auto a : array) {
PyObject * obj = PythonFunctor::convertToPython(*a);
PyObject * name = PythonFunctor::convertToPython(a->getID());
PyDict_SetItem(res, name, obj);
}
return (PyObject *)res;
}
/* -------------------------------------------------------------------------- */
template <typename T1, typename T2>
inline PyObject * PythonFunctor::convertToPython(const std::map<T1, T2> & map) {
PyObject * res = PyDict_New();
for (auto && a : map) {
PyObject * key = PythonFunctor::convertToPython(a.first);
PyObject * value = PythonFunctor::convertToPython(a.second);
PyDict_SetItem(res, key, value);
}
return (PyObject *)res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
PyObject * PythonFunctor::convertToPython(const Vector<T> & array) {
int data_typecode = getPythonDataTypeCode<T>();
npy_intp dims[1] = {array.size()};
PyObject * obj =
PyArray_SimpleNewFromData(1, dims, data_typecode, array.storage());
auto * res = (PyArrayObject *)obj;
return (PyObject *)res;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline PyObject *
PythonFunctor::convertToPython(const InternalField<T> & internals) {
return convertToPython(
static_cast<const ElementTypeMapArray<T> &>(internals));
}
/* --------------------------------------------------------------------- */
template <typename T>
inline PyObject * PythonFunctor::convertToPython(const std::unique_ptr<T> & u) {
return convertToPython(*u);
}
/* --------------------------------------------------------------------- */
template <typename T>
PyObject * PythonFunctor::convertToPython(const Array<T> & array) {
int data_typecode = getPythonDataTypeCode<T>();
npy_intp dims[2] = {array.size(), array.getNbComponent()};
PyObject * obj =
PyArray_SimpleNewFromData(2, dims, data_typecode, array.storage());
auto * res = (PyArrayObject *)obj;
return (PyObject *)res;
}
/* ---------------------------------------------------------------------- */
template <typename T>
PyObject * PythonFunctor::convertToPython(Array<T> * array) {
return PythonFunctor::convertToPython(*array);
}
/* ---------------------------------------------------------------------- */
template <typename T>
PyObject * PythonFunctor::convertToPython(const Matrix<T> & mat) {
int data_typecode = getPythonDataTypeCode<T>();
npy_intp dims[2] = {mat.size(0), mat.size(1)};
PyObject * obj =
PyArray_SimpleNewFromData(2, dims, data_typecode, mat.storage());
auto * res = (PyArrayObject *)obj;
return (PyObject *)res;
}
/* ---------------------------------------------------------------------- */
template <>
inline PyObject *
PythonFunctor::convertToPython<IntegrationPoint>(const IntegrationPoint & qp) {
PyObject * input = PyDict_New();
PyObject * num_point = PythonFunctor::convertToPython(qp.num_point);
PyObject * global_num = PythonFunctor::convertToPython(qp.global_num);
PyObject * material_id = PythonFunctor::convertToPython(qp.material_id);
PyObject * position = PythonFunctor::convertToPython(qp.getPosition());
PyDict_SetItemString(input, "num_point", num_point);
PyDict_SetItemString(input, "global_num", global_num);
PyDict_SetItemString(input, "material_id", material_id);
PyDict_SetItemString(input, "position", position);
return input;
}
/* --------------------------------------------------------------------------
*/
inline PyObject *
PythonFunctor::getPythonFunction(const std::string & functor_name) const {
#if PY_MAJOR_VERSION < 3
if (!PyInstance_Check(this->python_obj))
AKANTU_EXCEPTION("Python object is not an instance");
#else
// does not make sense to check everything is an instance of object in python 3
#endif
if (not PyObject_HasAttrString(this->python_obj, functor_name.c_str()))
AKANTU_EXCEPTION("Python dictionary has no " << functor_name << " entry");
PyObject * pFunctor =
PyObject_GetAttrString(this->python_obj, functor_name.c_str());
return pFunctor;
}
/* --------------------------------------------------------------------------
*/
inline void PythonFunctor::packArguments(__attribute__((unused))
std::vector<PyObject *> & p_args) {}
/* --------------------------------------------------------------------------
*/
template <typename T, typename... Args>
inline void PythonFunctor::packArguments(std::vector<PyObject *> & p_args,
T & p, Args &... params) {
p_args.push_back(PythonFunctor::convertToPython(p));
if (sizeof...(params) != 0)
PythonFunctor::packArguments(p_args, params...);
}
/* --------------------------------------------------------------------------
*/
template <typename return_type, typename... Params>
return_type PythonFunctor::callFunctor(const std::string & functor_name,
Params &... parameters) const {
_import_array();
std::vector<PyObject *> arg_vector;
this->packArguments(arg_vector, parameters...);
PyObject * pArgs = PyTuple_New(arg_vector.size());
for (UInt i = 0; i < arg_vector.size(); ++i) {
PyTuple_SetItem(pArgs, i, arg_vector[i]);
}
PyObject * kwargs = PyDict_New();
PyObject * pFunctor = this->getPythonFunction(functor_name);
PyObject * res = this->callFunctor(pFunctor, pArgs, kwargs);
Py_XDECREF(pArgs);
Py_XDECREF(kwargs);
return this->convertToAkantu<return_type>(res);
}
/* --------------------------------------------------------------------------
*/
template <typename return_type>
inline return_type PythonFunctor::convertToAkantu(PyObject * python_obj) {
if (PyList_Check(python_obj)) {
return PythonFunctor::convertListToAkantu<typename return_type::value_type>(
python_obj);
}
AKANTU_TO_IMPLEMENT();
}
/* --------------------------------------------------------------------------
*/
template <>
inline void PythonFunctor::convertToAkantu<void>(PyObject * python_obj) {
if (python_obj != Py_None)
AKANTU_DEBUG_WARNING(
"functor return a value while none was expected: ignored");
}
/* --------------------------------------------------------------------------
*/
template <>
inline std::string
PythonFunctor::convertToAkantu<std::string>(PyObject * python_obj) {
#if PY_MAJOR_VERSION >= 3
if (!PyUnicode_Check(python_obj))
AKANTU_EXCEPTION("cannot convert object to string");
std::wstring unicode_str(PyUnicode_AsWideCharString(python_obj, NULL));
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
return converter.to_bytes(unicode_str);
#else
if (!PyString_Check(python_obj))
AKANTU_EXCEPTION("cannot convert object to string");
return PyString_AsString(python_obj);
#endif
}
/* --------------------------------------------------------------------------
*/
template <>
inline Real PythonFunctor::convertToAkantu<Real>(PyObject * python_obj) {
if (!PyFloat_Check(python_obj))
AKANTU_EXCEPTION("cannot convert object to float");
return PyFloat_AsDouble(python_obj);
}
/* --------------------------------------------------------------------------
*/
template <>
inline UInt PythonFunctor::convertToAkantu<UInt>(PyObject * python_obj) {
#if PY_MAJOR_VERSION >= 3
if (!PyLong_Check(python_obj))
AKANTU_EXCEPTION("cannot convert object to integer");
return PyLong_AsLong(python_obj);
#else
if (!PyInt_Check(python_obj))
AKANTU_EXCEPTION("cannot convert object to integer");
return PyInt_AsLong(python_obj);
#endif
}
/* --------------------------------------------------------------------------
*/
template <typename T>
inline std::vector<T>
PythonFunctor::convertListToAkantu(PyObject * python_obj) {
std::vector<T> res;
UInt size = PyList_Size(python_obj);
for (UInt i = 0; i < size; ++i) {
PyObject * item = PyList_GET_ITEM(python_obj, i);
res.push_back(PythonFunctor::convertToAkantu<T>(item));
}
return res;
}
/* --------------------------------------------------------------------------
*/
} // akantu
#endif /* __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__ */
diff --git a/src/solver/petsc_wrapper.hh b/src/solver/petsc_wrapper.hh
index 0a36e6a0b..dab92ca0d 100644
--- a/src/solver/petsc_wrapper.hh
+++ b/src/solver/petsc_wrapper.hh
@@ -1,77 +1,79 @@
/**
* @file petsc_wrapper.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Wed Oct 07 2015
*
* @brief Wrapper of PETSc structures
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PETSC_WRAPPER_HH__
#define __AKANTU_PETSC_WRAPPER_HH__
/* -------------------------------------------------------------------------- */
#include <mpi.h>
-#include <petscmat.h>
-#include <petscvec.h>
#include <petscao.h>
#include <petscis.h>
#include <petscksp.h>
+#include <petscmat.h>
+#include <petscvec.h>
namespace akantu {
/* -------------------------------------------------------------------------- */
struct PETScMatrixWrapper {
Mat mat;
AO ao;
ISLocalToGlobalMapping mapping;
/// MPI communicator for PETSc commands
MPI_Comm communicator;
};
/* -------------------------------------------------------------------------- */
struct PETScSolverWrapper {
KSP ksp;
Vec solution;
Vec rhs;
// MPI communicator for PETSc commands
MPI_Comm communicator;
};
#if not defined(PETSC_CLANGUAGE_CXX)
extern int aka_PETScError(int ierr);
#define CHKERRXX(x) \
do { \
int error = aka_PETScError(x); \
- if (error != 0) { AKANTU_EXCEPTION("Error in PETSC"); } \
+ if (error != 0) { \
+ AKANTU_EXCEPTION("Error in PETSC"); \
+ } \
} while (0)
#endif
} // akantu
#endif /* __AKANTU_PETSC_WRAPPER_HH__ */
diff --git a/src/solver/solver_petsc.cc b/src/solver/solver_petsc.cc
index d43cf704e..b32a28b4c 100644
--- a/src/solver/solver_petsc.cc
+++ b/src/solver/solver_petsc.cc
@@ -1,1107 +1,1106 @@
/**
* @file solver_petsc.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue May 13 2014
* @date last modification: Tue Jan 19 2016
*
* @brief Solver class implementation for the petsc solver
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solver_petsc.hh"
#include "dof_manager_petsc.hh"
-#include "sparse_matrix_petsc.hh"
#include "mpi_type_wrapper.hh"
+#include "sparse_matrix_petsc.hh"
/* -------------------------------------------------------------------------- */
#include <petscksp.h>
//#include <petscsys.h>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
SolverPETSc::SolverPETSc(DOFManagerPETSc & dof_manager, const ID & matrix_id,
const ID & id, const MemoryID & memory_id)
: SparseSolver(dof_manager, matrix_id, id, memory_id),
- dof_manager(dof_manager),
- matrix(dof_manager.getMatrix(matrix_id)),
+ dof_manager(dof_manager), matrix(dof_manager.getMatrix(matrix_id)),
is_petsc_data_initialized(false) {
PetscErrorCode ierr;
/// create a solver context
ierr = KSPCreate(PETSC_COMM_WORLD, &this->ksp);
CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
SolverPETSc::~SolverPETSc() {
AKANTU_DEBUG_IN();
this->destroyInternalData();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::destroyInternalData() {
AKANTU_DEBUG_IN();
if (this->is_petsc_data_initialized) {
PetscErrorCode ierr;
ierr = KSPDestroy(&(this->ksp));
CHKERRXX(ierr);
this->is_petsc_data_initialized = false;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::initialize() {
AKANTU_DEBUG_IN();
this->is_petsc_data_initialized = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::solve() {
AKANTU_DEBUG_IN();
Vec & rhs = this->dof_manager.getResidual();
Vec & solution = this->dof_manager.getGlobalSolution();
PetscErrorCode ierr;
ierr = KSPSolve(this->ksp, rhs, solution);
CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// void SolverPETSc::solve(Array<Real> & solution) {
// AKANTU_DEBUG_IN();
// this->solution = &solution;
// this->solve();
// PetscErrorCode ierr;
// PETScMatrix * petsc_matrix = static_cast<PETScMatrix *>(this->matrix);
// // ierr = VecGetOwnershipRange(this->petsc_solver_wrapper->solution,
// // solution_begin, solution_end); CHKERRXX(ierr);
// // ierr = VecGetArray(this->petsc_solver_wrapper->solution, PetscScalar
// // **array); CHKERRXX(ierr);
// UInt nb_component = solution.getNbComponent();
// UInt size = solution.size();
// for (UInt i = 0; i < size; ++i) {
// for (UInt j = 0; j < nb_component; ++j) {
// UInt i_local = i * nb_component + j;
// if (this->matrix->getDOFSynchronizer().isLocalOrMasterDOF(i_local)) {
// Int i_global =
// this->matrix->getDOFSynchronizer().getDOFGlobalID(i_local);
-// ierr = AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao,
+// ierr =
+// AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao,
// 1, &(i_global));
// CHKERRXX(ierr);
-// ierr = VecGetValues(this->petsc_solver_wrapper->solution, 1, &i_global,
+// ierr = VecGetValues(this->petsc_solver_wrapper->solution, 1,
+// &i_global,
// &solution(i, j));
// CHKERRXX(ierr);
// }
// }
// }
// synch_registry->synchronize(_gst_solver_solution);
// AKANTU_DEBUG_OUT();
// }
/* -------------------------------------------------------------------------- */
void SolverPETSc::setOperators() {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
- /// set the matrix that defines the linear system and the matrix for
- /// preconditioning (here they are the same)
+/// set the matrix that defines the linear system and the matrix for
+/// preconditioning (here they are the same)
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
- ierr = KSPSetOperators(this->ksp,
- this->matrix.getPETScMat(),
+ ierr = KSPSetOperators(this->ksp, this->matrix.getPETScMat(),
this->matrix.getPETScMat());
CHKERRXX(ierr);
#else
- ierr = KSPSetOperators(this->ksp,
- this->matrix.getPETScMat(),
- this->matrix.getPETScMat(),
- SAME_NONZERO_PATTERN);
+ ierr = KSPSetOperators(this->ksp, this->matrix.getPETScMat(),
+ this->matrix.getPETScMat(), SAME_NONZERO_PATTERN);
CHKERRXX(ierr);
#endif
/// If this is not called the solution vector is zeroed in the call to
/// KSPSolve().
ierr = KSPSetInitialGuessNonzero(this->ksp, PETSC_TRUE);
KSPSetFromOptions(this->ksp);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
// void finalize_petsc() {
// static bool finalized = false;
// if (!finalized) {
// cout<<"*** INFO *** PETSc is finalizing..."<<endl;
// // finalize PETSc
// PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
// finalized = true;
// }
// }
// SolverPETSc::sparse_vector_type
// SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& AA,
// const SolverPETSc::sparse_vector_type& bb) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside PETSc solver: "<<timer<<endl;
// #endif
// #ifdef CPPUTILS_VERBOSE
// out<<" Inside operator()(const sparse_matrix_type&, const
// sparse_vector_type&)... "<<timer<<endl;
// #endif
// assert(AA.rows() == bb.size());
// // KSP ksp; //!< linear solver context
// Vec b; /* RHS */
// PC pc; /* preconditioner context */
// PetscErrorCode ierr;
// PetscInt nlocal;
// PetscInt n = bb.size();
// VecScatter ctx;
// /*
// Create vectors. Note that we form 1 vector from scratch and
// then duplicate as needed. For this simple case let PETSc decide how
// many elements of the vector are stored on each processor. The second
// argument to VecSetSizes() below causes PETSc to decide.
// */
// ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(b);CHKERRCONTINUE(ierr);
// if (!allocated_) {
// ierr = VecDuplicate(b,&x_);CHKERRCONTINUE(ierr);
// } else
// VecZeroEntries(x_);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// /* Set hight-hand-side vector */
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(b, 1, &row, &it->second, ADD_VALUES);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Right hand side set... "<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(b);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(b);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Right-hand-side vector assembled... "<<timer<<endl;
// ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// Vec b_all;
// ierr = VecScatterCreateToAll(b, &ctx, &b_all);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterBegin(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterEnd(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// value_type nrm;
// VecNorm(b_all,NORM_2,&nrm);
// out<<" Norm of right hand side... "<<nrm<<endl;
// #endif
// /* Identify the starting and ending mesh points on each
// processor for the interior part of the mesh. We let PETSc decide
// above. */
// // PetscInt rstart,rend;
// // ierr = VecGetOwnershipRange(x_,&rstart,&rend);CHKERRCONTINUE(ierr);
// ierr = VecGetLocalSize(x_,&nlocal);CHKERRCONTINUE(ierr);
// /*
// Create matrix. When using MatCreate(), the matrix format can
// be specified at runtime.
// Performance tuning note: For problems of substantial size,
// preallocation of matrix memory is crucial for attaining good
// performance. See the matrix chapter of the users manual for details.
// We pass in nlocal as the "local" size of the matrix to force it
// to have the same parallel layout as the vector created above.
// */
// if (!allocated_) {
// ierr = MatCreate(PETSC_COMM_WORLD,&A_);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(A_,nlocal,nlocal,n,n);CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(A_);CHKERRCONTINUE(ierr);
// ierr = MatSetUp(A_);CHKERRCONTINUE(ierr);
// } else {
// // zero-out matrix
// MatZeroEntries(A_);
// }
// /*
// Assemble matrix.
// The linear system is distributed across the processors by
// chunks of contiguous rows, which correspond to contiguous
// sections of the mesh on which the problem is discretized.
// For matrix assembly, each processor contributes entries for
// the part that it owns locally.
// */
// #ifdef CPPUTILS_VERBOSE
// out<<" Zeroed-out sparse matrix entries... "<<timer<<endl;
// #endif
// for (sparse_matrix_type::const_hash_iterator it = AA.map_.begin(); it !=
// AA.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = AA.unhash(it->first);
// PetscInt row = subs.first;
// PetscInt col = subs.second;
// ierr = MatSetValues(A_, 1, &row, 1, &col, &it->second,
// ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Filled sparse matrix... "<<timer<<endl;
// #endif
// /* Assemble the matrix */
// ierr = MatAssemblyBegin(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// if (!allocated_) {
// // set after the first MatAssemblyEnd
// // ierr = MatSetOption(A_, MAT_NEW_NONZERO_LOCATIONS,
// PETSC_FALSE);CHKERRCONTINUE(ierr);
// ierr = MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR,
// PETSC_FALSE);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Sparse matrix assembled... "<<timer<<endl;
// // view matrix
// MatView(A_, PETSC_VIEWER_STDOUT_WORLD);
// MatNorm(A_,NORM_FROBENIUS,&nrm);
// out<<" Norm of stiffness matrix... "<<nrm<<endl;
// #endif
// /*
// Set operators. Here the matrix that defines the linear system
// also serves as the preconditioning matrix.
// */
// // ierr =
// KSPSetOperators(ksp,A_,A_,DIFFERENT_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
// ierr =
// KSPSetOperators(ksp_,A_,A_,SAME_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
// //
// // /*
// // Set runtime options, e.g.,
// // -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
// // These options will override those specified above as long as
// // KSPSetFromOptions() is called _after_ any other customization
// // routines.
// // */
// // ierr = KSPSetFromOptions(ksp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Solving system... "<<timer<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Solve the linear system
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// /*
// Solve linear system
// */
// ierr = KSPSolve(ksp_,b,x_);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// /*
// View solver info; we could instead use the option -ksp_view to
// print this info to the screen at the conclusion of KSPSolve().
// */
// ierr = KSPView(ksp_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// int iter;
// KSPGetIterationNumber(ksp_, &iter);
// out<<" System solved in "<<iter<<" iterations... "<<timer<<endl;
// KSPConvergedReason reason;
// ierr = KSPGetConvergedReason(ksp_,&reason);CHKERRCONTINUE(ierr);
// if (reason < 0)
// out<<"*** WARNING *** PETSc solver diverged with flag ";
// else
// out<<"*** INFO *** PETSc solver converged with flag ";
// if (reason == KSP_CONVERGED_RTOL)
// out<<"KSP_CONVERGED_RTOL"<<endl;
// else if (reason == KSP_CONVERGED_ATOL)
// out<<"KSP_CONVERGED_ATOL"<<endl;
// else if (reason == KSP_CONVERGED_ITS)
// out<<"KSP_CONVERGED_ITS"<<endl;
// else if (reason == KSP_CONVERGED_CG_NEG_CURVE)
// out<<"KSP_CONVERGED_CG_NEG_CURVE"<<endl;
// else if (reason == KSP_CONVERGED_CG_CONSTRAINED)
// out<<"KSP_CONVERGED_CG_CONSTRAINED"<<endl;
// else if (reason == KSP_CONVERGED_STEP_LENGTH)
// out<<"KSP_CONVERGED_STEP_LENGTH"<<endl;
// else if (reason == KSP_CONVERGED_HAPPY_BREAKDOWN)
// out<<"KSP_CONVERGED_HAPPY_BREAKDOWN"<<endl;
// else if (reason == KSP_DIVERGED_NULL)
// out<<"KSP_DIVERGED_NULL"<<endl;
// else if (reason == KSP_DIVERGED_ITS)
// out<<"KSP_DIVERGED_ITS"<<endl;
// else if (reason == KSP_DIVERGED_DTOL)
// out<<"KSP_DIVERGED_DTOL"<<endl;
// else if (reason == KSP_DIVERGED_BREAKDOWN)
// out<<"KSP_DIVERGED_BREAKDOWN"<<endl;
// else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
// out<<"KSP_DIVERGED_BREAKDOWN_BICG"<<endl;
// else if (reason == KSP_DIVERGED_NONSYMMETRIC)
// out<<"KSP_DIVERGED_NONSYMMETRIC"<<endl;
// else if (reason == KSP_DIVERGED_INDEFINITE_PC)
// out<<"KSP_DIVERGED_INDEFINITE_PC"<<endl;
// else if (reason == KSP_DIVERGED_NAN)
// out<<"KSP_DIVERGED_NAN"<<endl;
// else if (reason == KSP_DIVERGED_INDEFINITE_MAT)
// out<<"KSP_DIVERGED_INDEFINITE_MAT"<<endl;
// else if (reason == KSP_CONVERGED_ITERATING)
// out<<"KSP_CONVERGED_ITERATING"<<endl;
// PetscReal rnorm;
// ierr = KSPGetResidualNorm(ksp_,&rnorm);CHKERRCONTINUE(ierr);
// out<<"PETSc last residual norm computed: "<<rnorm<<endl;
// ierr = VecView(x_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// VecNorm(x_,NORM_2,&nrm);
// out<<" Norm of solution vector... "<<nrm<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check solution and clean up
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// Vec x_all;
// ierr = VecScatterCreateToAll(x_, &ctx, &x_all);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterBegin(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterEnd(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Solution vector scattered... "<<timer<<endl;
// VecNorm(x_all,NORM_2,&nrm);
// out<<" Norm of scattered vector... "<<nrm<<endl;
// // ierr = VecView(x_all,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get values from solution and store them in the object that will be
// returned
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// sparse_vector_type xx(bb.size());
// /* Set solution vector */
// double zero = 0.;
// double val;
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(x_all, 1, &row, &val);
// if (val != zero)
// xx[row] = val;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Solution vector copied... "<<timer<<endl;
// // out<<" Norm of copied solution vector... "<<norm(xx,
// Insert_t)<<endl;
// #endif
// /*
// Free work space. All PETSc objects should be destroyed when they
// are no longer needed.
// */
// ierr = VecDestroy(&b);CHKERRCONTINUE(ierr);
// // ierr = KSPDestroy(&ksp);CHKERRCONTINUE(ierr);
// // set allocated flag
// if (!allocated_) {
// allocated_ = true;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return xx;
// }
// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const
// SolverPETSc::sparse_matrix_type& KKpf, const SolverPETSc::sparse_matrix_type&
// KKpp, const SolverPETSc::sparse_vector_type& UUp) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::operator()(const sparse_matrix&, const
// sparse_matrix&, const sparse_vector&). "<<timer<<endl;
// #endif
// Mat Kpf, Kpp;
// Vec Up, Pf, Pp;
// PetscErrorCode ierr =
// MatCreate(PETSC_COMM_WORLD,&Kpf);CHKERRCONTINUE(ierr);
// ierr = MatCreate(PETSC_COMM_WORLD,&Kpp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Allocating memory... "<<timer<<endl;
// #endif
// ierr = MatSetFromOptions(Kpf);CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(Kpp);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(Kpf,PETSC_DECIDE,PETSC_DECIDE, KKpf.rows(),
// KKpf.columns());CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(Kpp,PETSC_DECIDE,PETSC_DECIDE, KKpp.rows(),
// KKpp.columns());CHKERRCONTINUE(ierr);
// // get number of non-zeros in both diagonal and non-diagonal portions of
// the matrix
// std::pair<size_t,size_t> Kpf_nz = KKpf.non_zero_off_diagonal();
// std::pair<size_t,size_t> Kpp_nz = KKpp.non_zero_off_diagonal();
// ierr = MatMPIAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL,
// Kpf_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
// ierr = MatMPIAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL,
// Kpp_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
// ierr = MatSeqAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL);
// CHKERRCONTINUE(ierr);
// ierr = MatSeqAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL);
// CHKERRCONTINUE(ierr);
// for (sparse_matrix_type::const_hash_iterator it = KKpf.map_.begin(); it !=
// KKpf.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = KKpf.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second,
// ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// for (sparse_matrix_type::const_hash_iterator it = KKpp.map_.begin(); it !=
// KKpp.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = KKpp.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second,
// ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Filled sparse matrices... "<<timer<<endl;
// #endif
// /*
// Assemble matrix, using the 2-step process:
// MatAssemblyBegin(), MatAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = MatAssemblyBegin(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyBegin(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Sparse matrices assembled... "<<timer<<endl;
// #endif
// ierr = VecCreate(PETSC_COMM_WORLD,&Up);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(Up,PETSC_DECIDE, UUp.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(Up);CHKERRCONTINUE(ierr);
// ierr = VecCreate(PETSC_COMM_WORLD,&Pf);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(Pf,PETSC_DECIDE, KKpf.rows());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(Pf);CHKERRCONTINUE(ierr);
// ierr = VecDuplicate(Pf,&Pp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// /* Set hight-hand-side vector */
// for (sparse_vector_type::const_hash_iterator it = UUp.map_.begin(); it !=
// UUp.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(Up, 1, &row, &it->second, ADD_VALUES);
// }
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(Up);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(Up);CHKERRCONTINUE(ierr);
// // add Kpf*Uf
// ierr = MatMult(Kpf, x_, Pf);
// // add Kpp*Up
// ierr = MatMultAdd(Kpp, Up, Pf, Pp);
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrices multiplied... "<<timer<<endl;
// #endif
// VecScatter ctx;
// Vec Pp_all;
// ierr = VecScatterCreateToAll(Pp, &ctx, &Pp_all);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterBegin(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterEnd(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector scattered... "<<timer<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get values from solution and store them in the object that will be
// returned
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// sparse_vector_type pp(KKpf.rows());
// // get reaction vector
// for (int i=0; i<KKpf.rows(); ++i) {
// PetscScalar v;
// ierr = VecGetValues(Pp_all, 1, &i, &v);
// if (v != PetscScalar())
// pp[i] = v;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector copied... "<<timer<<endl;
// #endif
// ierr = MatDestroy(&Kpf);CHKERRCONTINUE(ierr);
// ierr = MatDestroy(&Kpp);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Up);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pf);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pp);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pp_all);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return pp;
// }
// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const
// SolverPETSc::sparse_vector_type& aa, const SolverPETSc::sparse_vector_type&
// bb) {
// assert(aa.size() == bb.size());
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::operator()(const sparse_vector&, const
// sparse_vector&). "<<timer<<endl;
// #endif
// Vec r;
// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// }
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// }
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
// sparse_vector_type rr(aa.size());
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(r, 1, &row, &rr[row]);
// }
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(r, 1, &row, &rr[row]);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector copied... "<<timer<<endl;
// #endif
// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return rr;
// }
// SolverPETSc::value_type SolverPETSc::norm(const
// SolverPETSc::sparse_matrix_type& aa, Element_insertion_type flag) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::norm(const sparse_matrix&). "<<timer<<endl;
// #endif
// Mat r;
// PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(r,PETSC_DECIDE,PETSC_DECIDE, aa.rows(),
// aa.columns());CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrix created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = aa.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// if (flag == Add_t)
// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, ADD_VALUES);
// else if (flag == Insert_t)
// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, INSERT_VALUES);
// CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrix filled..."<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = MatAssemblyBegin(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// value_type nrm;
// MatNorm(r,NORM_FROBENIUS,&nrm);
// #ifdef CPPUTILS_VERBOSE
// out<<" Norm computed... "<<timer<<endl;
// #endif
// ierr = MatDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return nrm;
// }
// SolverPETSc::value_type SolverPETSc::norm(const
// SolverPETSc::sparse_vector_type& aa, Element_insertion_type flag) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::norm(const sparse_vector&). "<<timer<<endl;
// #endif
// Vec r;
// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// int row = it->first;
// if (flag == Add_t)
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// else if (flag == Insert_t)
// ierr = VecSetValues(r, 1, &row, &it->second, INSERT_VALUES);
// CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector filled..."<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
// value_type nrm;
// VecNorm(r,NORM_2,&nrm);
// #ifdef CPPUTILS_VERBOSE
// out<<" Norm computed... "<<timer<<endl;
// #endif
// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return nrm;
// }
// //
// ///*
// -------------------------------------------------------------------------- */
// //SolverMumps::SolverMumps(SparseMatrix & matrix,
// // const ID & id,
// // const MemoryID & memory_id) :
// //Solver(matrix, id, memory_id), is_mumps_data_initialized(false),
// rhs_is_local(true) {
// // AKANTU_DEBUG_IN();
// //
// //#ifdef AKANTU_USE_MPI
// // parallel_method = SolverMumpsOptions::_fully_distributed;
// //#else //AKANTU_USE_MPI
// // parallel_method = SolverMumpsOptions::_master_slave_distributed;
// //#endif //AKANTU_USE_MPI
// //
// // CommunicatorEventHandler & comm_event_handler = *this;
// //
// // communicator.registerEventHandler(comm_event_handler);
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //SolverMumps::~SolverMumps() {
// // AKANTU_DEBUG_IN();
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::destroyMumpsData() {
// // AKANTU_DEBUG_IN();
// //
// // if(is_mumps_data_initialized) {
// // mumps_data.job = _smj_destroy; // destroy
// // dmumps_c(&mumps_data);
// // is_mumps_data_initialized = false;
// // }
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
// // AKANTU_DEBUG_IN();
// //
// // try{
// // const StaticCommunicatorMPI & comm_mpi =
// // dynamic_cast<const StaticCommunicatorMPI
// &>(comm.getRealStaticCommunicator());
// // if(mumps_data.comm_fortran ==
// MPI_Comm_c2f(comm_mpi.getMPICommunicator()))
// // destroyMumpsData();
// // } catch(...) {}
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::initMumpsData(SolverMumpsOptions::ParallelMethod
// parallel_method) {
// // switch(parallel_method) {
// // case SolverMumpsOptions::_fully_distributed:
// // icntl(18) = 3; //fully distributed
// // icntl(28) = 0; //automatic choice
// //
// // mumps_data.nz_loc = matrix->getNbNonZero();
// // mumps_data.irn_loc = matrix->getIRN().values;
// // mumps_data.jcn_loc = matrix->getJCN().values;
// // break;
// // case SolverMumpsOptions::_master_slave_distributed:
// // if(prank == 0) {
// // mumps_data.nz = matrix->getNbNonZero();
// // mumps_data.irn = matrix->getIRN().values;
// // mumps_data.jcn = matrix->getJCN().values;
// // } else {
// // mumps_data.nz = 0;
// // mumps_data.irn = NULL;
// // mumps_data.jcn = NULL;
// //
// // icntl(18) = 0; //centralized
// // icntl(28) = 0; //sequential analysis
// // }
// // break;
// // }
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::initialize(SolverOptions & options) {
// // AKANTU_DEBUG_IN();
// //
// // mumps_data.par = 1;
// //
// // if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions
// *>(&options)) {
// // if(opt->parallel_method ==
// SolverMumpsOptions::_master_slave_distributed) {
// // mumps_data.par = 0;
// // }
// // }
// //
// // mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
// // prank = communicator.whoAmI();
// //#ifdef AKANTU_USE_MPI
// // mumps_data.comm_fortran = MPI_Comm_c2f(dynamic_cast<const
// StaticCommunicatorMPI
// &>(communicator.getRealStaticCommunicator()).getMPICommunicator());
// //#endif
// //
// // if(AKANTU_DEBUG_TEST(dblTrace)) {
// // icntl(1) = 2;
// // icntl(2) = 2;
// // icntl(3) = 2;
// // icntl(4) = 4;
// // }
// //
// // mumps_data.job = _smj_initialize; //initialize
// // dmumps_c(&mumps_data);
// // is_mumps_data_initialized = true;
// //
// // /*
// ------------------------------------------------------------------------ */
// // UInt size = matrix->size();
// //
// // if(prank == 0) {
// // std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
// // rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, REAL_INIT_VALUE));
// // } else {
// // rhs = NULL;
// // }
// //
// // /// No outputs
// // icntl(1) = 0;
// // icntl(2) = 0;
// // icntl(3) = 0;
// // icntl(4) = 0;
// // mumps_data.nz_alloc = 0;
// //
// // if (AKANTU_DEBUG_TEST(dblDump)) icntl(4) = 4;
// //
// // mumps_data.n = size;
// //
// // if(AKANTU_DEBUG_TEST(dblDump)) {
// // strcpy(mumps_data.write_problem, "mumps_matrix.mtx");
// // }
// //
// // /*
// ------------------------------------------------------------------------ */
// // // Default Scaling
// // icntl(8) = 77;
// //
// // icntl(5) = 0; // Assembled matrix
// //
// // SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options);
// // if(opt)
// // parallel_method = opt->parallel_method;
// //
// // initMumpsData(parallel_method);
// //
// // mumps_data.job = _smj_analyze; //analyze
// // dmumps_c(&mumps_data);
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::setRHS(Array<Real> & rhs) {
// // if(prank == 0) {
// // matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
// // } else {
// // matrix->getDOFSynchronizer().gather(rhs, 0);
// // }
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::solve() {
// // AKANTU_DEBUG_IN();
// //
// // if(parallel_method == SolverMumpsOptions::_fully_distributed)
// // mumps_data.a_loc = matrix->getA().values;
// // else
// // if(prank == 0) {
// // mumps_data.a = matrix->getA().values;
// // }
// //
// // if(prank == 0) {
// // mumps_data.rhs = rhs->values;
// // }
// //
// // /// Default centralized dense second member
// // icntl(20) = 0;
// // icntl(21) = 0;
// //
// // mumps_data.job = _smj_factorize_solve; //solve
// // dmumps_c(&mumps_data);
// //
// // AKANTU_DEBUG_ASSERT(info(1) != -10, "Singular matrix");
// // AKANTU_DEBUG_ASSERT(info(1) == 0,
// // "Error in mumps during solve process, check mumps
// user guide INFO(1) ="
// // << info(1));
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::solve(Array<Real> & solution) {
// // AKANTU_DEBUG_IN();
// //
// // solve();
// //
// // if(prank == 0) {
// // matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
// // } else {
// // matrix->getDOFSynchronizer().scatter(solution, 0);
// // }
// //
// // AKANTU_DEBUG_OUT();
// //}
} // akantu
diff --git a/src/solver/solver_petsc.hh b/src/solver/solver_petsc.hh
index a992347cd..241884da4 100644
--- a/src/solver/solver_petsc.hh
+++ b/src/solver/solver_petsc.hh
@@ -1,182 +1,183 @@
/**
* @file solver_petsc.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue May 13 2014
* @date last modification: Wed Oct 07 2015
*
* @brief Solver class interface for the petsc solver
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "sparse_solver.hh"
/* -------------------------------------------------------------------------- */
#include <petscksp.h>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_PETSC_HH__
#define __AKANTU_SOLVER_PETSC_HH__
namespace akantu {
- class SparseMatrixPETSc;
- class DOFManagerPETSc;
+class SparseMatrixPETSc;
+class DOFManagerPETSc;
}
namespace akantu {
class SolverPETSc : public SparseSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SolverPETSc(DOFManagerPETSc & dof_manager, const ID & matrix_id,
const ID & id = "solver_petsc", const MemoryID & memory_id = 0);
virtual ~SolverPETSc();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// create the solver context and set the matrices
virtual void initialize();
virtual void setOperators();
virtual void setRHS(Array<Real> & rhs);
virtual void solve();
virtual void solve(Array<Real> & solution);
private:
/// clean the petsc data
virtual void destroyInternalData();
private:
/// DOFManager correctly typed
DOFManagerPETSc & dof_manager;
/// PETSc linear solver
KSP ksp;
/// Matrix defining the system of equations
SparseMatrixPETSc & matrix;
/// specify if the petsc_data is initialized or not
bool is_petsc_data_initialized;
};
// SolverPETSc(int argc, char *argv[]) : allocated_(false) {
// /*
// Set linear solver defaults for this problem (optional).
// - By extracting the KSP and PC contexts from the KSP context,
// we can then directly call any KSP and PC routines to set
// various options.
// - The following four statements are optional; all of these
// parameters could alternatively be specified at runtime via
// KSPSetFromOptions();
// */
// // ierr = KSPGetPC(ksp_,&pc);CHKERRCONTINUE(ierr);
// // ierr = PCSetType(pc,PCILU);CHKERRCONTINUE(ierr);
// // ierr = PCSetType(pc,PCJACOBI);CHKERRCONTINUE(ierr);
// ierr =
// KSPSetTolerances(ksp_,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRCONTINUE(ierr);
// }
// //! Overload operator() to solve system of linear equations
// sparse_vector_type operator()(const sparse_matrix_type& AA, const
// sparse_vector_type& bb);
// //! Overload operator() to obtain reaction vector
// sparse_vector_type operator()(const sparse_matrix_type& Kpf, const
// sparse_matrix_type& Kpp, const sparse_vector_type& Up);
// //! Overload operator() to obtain the addition two vectors
// sparse_vector_type operator()(const sparse_vector_type& aa, const
// sparse_vector_type& bb);
// value_type norm(const sparse_matrix_type& aa, Element_insertion_type it =
// Add_t);
// value_type norm(const sparse_vector_type& aa, Element_insertion_type it =
// Add_t);
// // NOTE: the destructor will return an error if it is called after
// MPI_Finalize is
// // called because it uses collect communication to free-up allocated
// memory.
// ~SolverPETSc() {
// static bool exit = false;
// if (!exit) {
// // add finalize PETSc function at exit
// atexit(finalize);
// exit = true;
// }
// if (allocated_) {
// PetscErrorCode ierr = MatDestroy(&A_);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&x_);CHKERRCONTINUE(ierr);
// ierr = KSPDestroy(&ksp_);CHKERRCONTINUE(ierr);
// }
// }
// /* from the PETSc library, these are the options that can be passed
// to the command line
// Options Database Keys
// -options_table - Calls PetscOptionsView()
// -options_left - Prints unused options that remain in the
// database
// -objects_left - Prints list of all objects that have not
// been freed
// -mpidump - Calls PetscMPIDump()
// -malloc_dump - Calls PetscMallocDump()
// -malloc_info - Prints total memory usage
// -malloc_log - Prints summary of memory usage
// Options Database Keys for Profiling
// -log_summary [filename] - Prints summary of flop and timing
// information to screen.
// If the filename is specified the summary is written to the file. See
// PetscLogView().
-// -log_summary_python [filename] - Prints data on of flop and timing usage
+// -log_summary_python [filename] - Prints data on of flop and timing
+// usage
// to a file or screen.
// -log_all [filename] - Logs extensive profiling information See
// PetscLogDump().
// -log [filename] - Logs basic profiline information See
// PetscLogDump().
// -log_sync - Log the synchronization in scatters,
// inner products and norms
// -log_mpe [filename] - Creates a logfile viewable by the utility
// Upshot/Nupshot (in MPICH distribution)
// }
// }
// };
} // akantu
#endif /* __AKANTU_SOLVER_PETSC_HH__ */
diff --git a/src/solver/sparse_matrix.cc b/src/solver/sparse_matrix.cc
index 08adfa791..593016ef0 100644
--- a/src/solver/sparse_matrix.cc
+++ b/src/solver/sparse_matrix.cc
@@ -1,80 +1,80 @@
/**
* @file sparse_matrix.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Mon Nov 16 2015
*
* @brief implementation of the SparseMatrix class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
+#include "communicator.hh"
#include "dof_manager.hh"
#include "sparse_matrix.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(DOFManager & dof_manager,
const MatrixType & matrix_type, const ID & id)
: id(id), _dof_manager(dof_manager), matrix_type(matrix_type),
size_(dof_manager.getSystemSize()), nb_non_zero(0) {
AKANTU_DEBUG_IN();
const auto & comm = _dof_manager.getCommunicator();
this->nb_proc = comm.getNbProc();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(const SparseMatrix & matrix, const ID & id)
: SparseMatrix(matrix._dof_manager, matrix.matrix_type, id) {
nb_non_zero = matrix.nb_non_zero;
}
/* -------------------------------------------------------------------------- */
SparseMatrix::~SparseMatrix() = default;
/* -------------------------------------------------------------------------- */
Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat) {
Array<Real> tmp(vect.size(), vect.getNbComponent(), 0.);
mat.matVecMul(vect, tmp);
vect.copy(tmp);
return vect;
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::add(const SparseMatrix & B, Real alpha) {
B.addMeTo(*this, alpha);
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/solver/sparse_matrix.hh b/src/solver/sparse_matrix.hh
index db9709e96..9dc5de8b3 100644
--- a/src/solver/sparse_matrix.hh
+++ b/src/solver/sparse_matrix.hh
@@ -1,159 +1,162 @@
/**
* @file sparse_matrix.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Fri Oct 16 2015
*
* @brief sparse matrix storage class (distributed assembled matrix)
* This is a COO format (Coordinate List)
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SPARSE_MATRIX_HH__
#define __AKANTU_SPARSE_MATRIX_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class DOFManager;
class TermsToAssemble;
}
namespace akantu {
class SparseMatrix {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseMatrix(DOFManager & dof_manager, const MatrixType & matrix_type,
const ID & id = "sparse_matrix");
SparseMatrix(const SparseMatrix & matrix, const ID & id = "sparse_matrix");
virtual ~SparseMatrix();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// remove the existing profile
virtual void clearProfile();
/// set the matrix to 0
virtual void clear() = 0;
/// add a non-zero element to the profile
virtual UInt add(UInt i, UInt j) = 0;
/// assemble a local matrix in the sparse one
virtual void add(UInt i, UInt j, Real value) = 0;
/// save the profil in a file using the MatrixMarket file format
virtual void saveProfile(__attribute__((unused)) const std::string &) const {
AKANTU_TO_IMPLEMENT();
}
/// save the matrix in a file using the MatrixMarket file format
virtual void saveMatrix(__attribute__((unused)) const std::string &) const {
AKANTU_TO_IMPLEMENT();
};
/// multiply the matrix by a coefficient
virtual void mul(Real alpha) = 0;
/// add matrices
virtual void add(const SparseMatrix & matrix, Real alpha = 1.);
/// Equivalent of *gemv in blas
virtual void matVecMul(const Array<Real> & x, Array<Real> & y,
Real alpha = 1., Real beta = 0.) const = 0;
/// modify the matrix to "remove" the blocked dof
virtual void applyBoundary(Real block_val = 1.) = 0;
/// operator *=
- SparseMatrix & operator*=(Real alpha) { this->mul(alpha); return *this; }
+ SparseMatrix & operator*=(Real alpha) {
+ this->mul(alpha);
+ return *this;
+ }
protected:
/// This is the revert of add B += \alpha * *this;
virtual void addMeTo(SparseMatrix & B, Real alpha) const = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the values at potition i, j
virtual inline Real operator()(__attribute__((unused)) UInt i,
__attribute__((unused)) UInt j) const {
AKANTU_TO_IMPLEMENT();
}
/// return the values at potition i, j
virtual inline Real & operator()(__attribute__((unused)) UInt i,
__attribute__((unused)) UInt j) {
AKANTU_TO_IMPLEMENT();
}
AKANTU_GET_MACRO(NbNonZero, nb_non_zero, UInt);
- UInt size() const { return size_;}
+ UInt size() const { return size_; }
AKANTU_GET_MACRO(MatrixType, matrix_type, const MatrixType &);
virtual UInt getRelease() const = 0;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
ID id;
/// Underlying dof manager
DOFManager & _dof_manager;
/// sparce matrix type
MatrixType matrix_type;
/// Size of the matrix
UInt size_;
/// number of processors
UInt nb_proc;
/// number of non zero element
UInt nb_non_zero;
};
Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
} // akantu
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "sparse_matrix_inline_impl.cc"
#endif /* __AKANTU_SPARSE_MATRIX_HH__ */
diff --git a/src/solver/sparse_matrix_aij.cc b/src/solver/sparse_matrix_aij.cc
index 3cb09925d..acf516e85 100644
--- a/src/solver/sparse_matrix_aij.cc
+++ b/src/solver/sparse_matrix_aij.cc
@@ -1,215 +1,215 @@
/**
* @file sparse_matrix_aij.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Aug 18 16:31:23 2015
*
* @brief Implementation of the AIJ sparse matrix
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "sparse_matrix_aij.hh"
+#include "aka_iterators.hh"
#include "dof_manager_default.hh"
#include "dof_synchronizer.hh"
#include "terms_to_assemble.hh"
-#include "aka_iterators.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
SparseMatrixAIJ::SparseMatrixAIJ(DOFManagerDefault & dof_manager,
const MatrixType & matrix_type, const ID & id)
: SparseMatrix(dof_manager, matrix_type, id), dof_manager(dof_manager),
irn(0, 1, id + ":irn"), jcn(0, 1, id + ":jcn"), a(0, 1, id + ":a") {}
/* -------------------------------------------------------------------------- */
SparseMatrixAIJ::SparseMatrixAIJ(const SparseMatrixAIJ & matrix, const ID & id)
: SparseMatrix(matrix, id), dof_manager(matrix.dof_manager),
irn(matrix.irn, true, id + ":irn"), jcn(matrix.jcn, true, id + ":jcn"),
a(matrix.a, true, id + ":a") {}
/* -------------------------------------------------------------------------- */
SparseMatrixAIJ::~SparseMatrixAIJ() = default;
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::applyBoundary(Real block_val) {
AKANTU_DEBUG_IN();
// clang-format off
const auto & blocked_dofs = this->dof_manager.getGlobalBlockedDOFs();
for (auto && ij_a : zip(irn, jcn, a)) {
UInt ni = this->dof_manager.globalToLocalEquationNumber(std::get<0>(ij_a) - 1);
UInt nj = this->dof_manager.globalToLocalEquationNumber(std::get<1>(ij_a) - 1);
if (blocked_dofs(ni) || blocked_dofs(nj)) {
std::get<2>(ij_a) =
std::get<0>(ij_a) != std::get<1>(ij_a) ? 0.
: this->dof_manager.isLocalOrMasterDOF(ni) ? block_val
: 0.;
}
}
this->value_release++;
// clang-format on
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::saveProfile(const std::string & filename) const {
AKANTU_DEBUG_IN();
std::ofstream outfile;
outfile.open(filename.c_str());
UInt m = this->size_;
outfile << "%%MatrixMarket matrix coordinate pattern";
if (this->matrix_type == _symmetric)
outfile << " symmetric";
else
outfile << " general";
outfile << std::endl;
outfile << m << " " << m << " " << this->nb_non_zero << std::endl;
for (UInt i = 0; i < this->nb_non_zero; ++i) {
outfile << this->irn.storage()[i] << " " << this->jcn.storage()[i] << " 1"
<< std::endl;
}
outfile.close();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::saveMatrix(const std::string & filename) const {
AKANTU_DEBUG_IN();
// open and set the properties of the stream
std::ofstream outfile;
outfile.open(filename.c_str());
outfile.precision(std::numeric_limits<Real>::digits10);
// write header
outfile << "%%MatrixMarket matrix coordinate real";
if (this->matrix_type == _symmetric)
outfile << " symmetric";
else
outfile << " general";
outfile << std::endl;
outfile << this->size_ << " " << this->size_ << " " << this->nb_non_zero
<< std::endl;
// write content
for (UInt i = 0; i < this->nb_non_zero; ++i) {
outfile << this->irn(i) << " " << this->jcn(i) << " " << this->a(i)
<< std::endl;
}
// time to end
outfile.close();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::matVecMul(const Array<Real> & x, Array<Real> & y,
Real alpha, Real beta) const {
AKANTU_DEBUG_IN();
y *= beta;
auto i_it = this->irn.begin();
auto j_it = this->jcn.begin();
auto a_it = this->a.begin();
auto a_end = this->a.end();
auto x_it = x.begin_reinterpret(x.size() * x.getNbComponent());
auto y_it = y.begin_reinterpret(x.size() * x.getNbComponent());
for (; a_it != a_end; ++i_it, ++j_it, ++a_it) {
Int i = this->dof_manager.globalToLocalEquationNumber(*i_it - 1);
Int j = this->dof_manager.globalToLocalEquationNumber(*j_it - 1);
const Real & A = *a_it;
y_it[i] += alpha * A * x_it[j];
if ((this->matrix_type == _symmetric) && (i != j))
y_it[j] += alpha * A * x_it[i];
}
if (this->dof_manager.hasSynchronizer())
this->dof_manager.getSynchronizer().reduceSynchronize<AddOperation>(y);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::copyContent(const SparseMatrix & matrix) {
AKANTU_DEBUG_IN();
const auto & mat = dynamic_cast<const SparseMatrixAIJ &>(matrix);
AKANTU_DEBUG_ASSERT(nb_non_zero == mat.getNbNonZero(),
"The to matrix don't have the same profiles");
memcpy(a.storage(), mat.getA().storage(), nb_non_zero * sizeof(Real));
this->value_release++;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class MatrixType>
void SparseMatrixAIJ::addMeToTemplated(MatrixType & B, Real alpha) const {
UInt i, j;
Real A_ij;
for (auto && tuple : zip(irn, jcn, a)) {
std::tie(i, j, A_ij) = tuple;
B.add(i - 1, j - 1, alpha * A_ij);
}
}
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::addMeTo(SparseMatrix & B, Real alpha) const {
if (auto * B_aij = dynamic_cast<SparseMatrixAIJ *>(&B)) {
this->addMeToTemplated<SparseMatrixAIJ>(*B_aij, alpha);
} else {
// this->addMeToTemplated<SparseMatrix>(*this, alpha);
}
}
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::mul(Real alpha) {
this->a *= alpha;
this->value_release++;
}
/* -------------------------------------------------------------------------- */
void SparseMatrixAIJ::clear() {
a.set(0.);
this->value_release++;
}
} // namespace akantu
diff --git a/src/solver/sparse_matrix_aij.hh b/src/solver/sparse_matrix_aij.hh
index 11d04b448..9c067be24 100644
--- a/src/solver/sparse_matrix_aij.hh
+++ b/src/solver/sparse_matrix_aij.hh
@@ -1,179 +1,180 @@
/**
* @file sparse_matrix_aij.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Aug 17 21:22:57 2015
*
* @brief AIJ implementation of the SparseMatrix (this the format used by Mumps)
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "aka_common.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
#include <unordered_map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SPARSE_MATRIX_AIJ_HH__
#define __AKANTU_SPARSE_MATRIX_AIJ_HH__
namespace akantu {
class DOFManagerDefault;
class TermsToAssemble;
}
namespace akantu {
class SparseMatrixAIJ : public SparseMatrix {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseMatrixAIJ(DOFManagerDefault & dof_manager,
const MatrixType & matrix_type,
const ID & id = "sparse_matrix_aij");
SparseMatrixAIJ(const SparseMatrixAIJ & matrix,
const ID & id = "sparse_matrix_aij");
~SparseMatrixAIJ() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// remove the existing profile
inline void clearProfile() override;
/// add a non-zero element
inline UInt add(UInt i, UInt j) override;
/// set the matrix to 0
void clear() override;
/// assemble a local matrix in the sparse one
inline void add(UInt i, UInt j, Real value) override;
/// set the size of the matrix
void resize(UInt size) { this->size_ = size; }
/// modify the matrix to "remove" the blocked dof
void applyBoundary(Real block_val = 1.) override;
/// save the profil in a file using the MatrixMarket file format
void saveProfile(const std::string & filename) const override;
/// save the matrix in a file using the MatrixMarket file format
void saveMatrix(const std::string & filename) const override;
/// copy assuming the profile are the same
virtual void copyContent(const SparseMatrix & matrix);
/// multiply the matrix by a scalar
void mul(Real alpha) override;
/// add matrix *this += B
// virtual void add(const SparseMatrix & matrix, Real alpha);
/// Equivalent of *gemv in blas
- void matVecMul(const Array<Real> & x, Array<Real> & y,
- Real alpha = 1., Real beta = 0.) const override;
+ void matVecMul(const Array<Real> & x, Array<Real> & y, Real alpha = 1.,
+ Real beta = 0.) const override;
/* ------------------------------------------------------------------------ */
/// accessor to A_{ij} - if (i, j) not present it returns 0
inline Real operator()(UInt i, UInt j) const override;
/// accessor to A_{ij} - if (i, j) not present it fails, (i, j) should be
/// first added to the profile
inline Real & operator()(UInt i, UInt j) override;
protected:
/// This is the revert of add B += \alpha * *this;
void addMeTo(SparseMatrix & B, Real alpha) const override;
private:
/// This is just to inline the addToMatrix function
template <class MatrixType>
void addMeToTemplated(MatrixType & B, Real alpha) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(IRN, irn, const Array<Int> &);
AKANTU_GET_MACRO(JCN, jcn, const Array<Int> &);
AKANTU_GET_MACRO(A, a, const Array<Real> &);
/// The release changes at each call of a function that changes the profile,
/// it in increasing but could overflow so it should be checked as
/// (my_release != release) and not as (my_release < release)
AKANTU_GET_MACRO(ProfileRelease, profile_release, UInt);
AKANTU_GET_MACRO(ValueRelease, value_release, UInt);
UInt getRelease() const override { return value_release; }
+
protected:
using KeyCOO = std::pair<UInt, UInt>;
using coordinate_list_map = std::unordered_map<KeyCOO, UInt>;
/// get the pair corresponding to (i, j)
inline KeyCOO key(UInt i, UInt j) const {
if (this->matrix_type == _symmetric && (i > j))
return std::make_pair(j, i);
return std::make_pair(i, j);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
DOFManagerDefault & dof_manager;
/// row indexes
Array<Int> irn;
/// column indexes
Array<Int> jcn;
/// values : A[k] = Matrix[irn[k]][jcn[k]]
Array<Real> a;
/// Profile release
UInt profile_release{1};
/// Value release
UInt value_release{1};
/// map for (i, j) -> k correspondence
coordinate_list_map irn_jcn_k;
};
} // akantu
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "sparse_matrix_aij_inline_impl.cc"
#endif /* __AKANTU_SPARSE_MATRIX_AIJ_HH__ */
diff --git a/src/solver/sparse_matrix_inline_impl.cc b/src/solver/sparse_matrix_inline_impl.cc
index 1ad017022..dc1a84948 100644
--- a/src/solver/sparse_matrix_inline_impl.cc
+++ b/src/solver/sparse_matrix_inline_impl.cc
@@ -1,39 +1,37 @@
/**
* @file sparse_matrix_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Tue Aug 18 2015
*
* @brief implementation of inline methods of the SparseMatrix class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
namespace akantu {
-inline void SparseMatrix::clearProfile() {
- this->nb_non_zero = 0;
-}
+inline void SparseMatrix::clearProfile() { this->nb_non_zero = 0; }
} // akantu
diff --git a/src/solver/sparse_matrix_petsc.cc b/src/solver/sparse_matrix_petsc.cc
index 7d357d9c9..906c4056e 100644
--- a/src/solver/sparse_matrix_petsc.cc
+++ b/src/solver/sparse_matrix_petsc.cc
@@ -1,404 +1,402 @@
/**
* @file petsc_matrix.cc
* @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Mon Jul 21 17:40:41 2014
*
* @brief Implementation of PETSc matrix class
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "sparse_matrix_petsc.hh"
-#include "mpi_type_wrapper.hh"
#include "dof_manager_petsc.hh"
+#include "mpi_type_wrapper.hh"
#include "static_communicator.hh"
/* -------------------------------------------------------------------------- */
#include <cstring>
#include <petscsys.h>
/* -------------------------------------------------------------------------- */
namespace akantu {
#if not defined(PETSC_CLANGUAGE_CXX)
int aka_PETScError(int ierr) {
CHKERRQ(ierr);
return 0;
}
#endif
/* -------------------------------------------------------------------------- */
SparseMatrixPETSc::SparseMatrixPETSc(DOFManagerPETSc & dof_manager,
- const MatrixType & sparse_matrix_type, const ID & id,
- const MemoryID & memory_id)
- : SparseMatrix(dof_manager, matrix_type, id, memory_id),
- dof_manager(dof_manager),
- d_nnz(0, 1, "dnnz"),
- o_nnz(0, 1, "onnz"), first_global_index(0) {
+ const MatrixType & sparse_matrix_type,
+ const ID & id, const MemoryID & memory_id)
+ : SparseMatrix(dof_manager, matrix_type, id, memory_id),
+ dof_manager(dof_manager), d_nnz(0, 1, "dnnz"), o_nnz(0, 1, "onnz"),
+ first_global_index(0) {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
// create the PETSc matrix object
ierr = MatCreate(PETSC_COMM_WORLD, &this->mat);
CHKERRXX(ierr);
/**
* Set the matrix type
* @todo PETSc does currently not support a straightforward way to
* apply Dirichlet boundary conditions for MPISBAIJ
* matrices. Therefore always the entire matrix is allocated. It
* would be possible to use MATSBAIJ for sequential matrices in case
* memory becomes critical. Also, block matrices would give a much
* better performance. Modify this in the future!
*/
ierr = MatSetType(this->mat, MATAIJ);
CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrixPETSc::~SparseMatrixPETSc() {
AKANTU_DEBUG_IN();
/// destroy all the PETSc data structures used for this matrix
PetscErrorCode ierr;
ierr = MatDestroy(&this->mat);
CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* With this method each processor computes the dimensions of the
* local matrix, i.e. the part of the global matrix it is storing.
* @param dof_synchronizer dof synchronizer that maps the local
* dofs to the global dofs and the equation numbers, i.e., the
* position at which the dof is assembled in the matrix
*/
void SparseMatrixPETSc::setSize() {
AKANTU_DEBUG_IN();
// PetscErrorCode ierr;
/// find the number of dofs corresponding to master or local nodes
UInt nb_dofs = this->dof_manager.getLocalSystemSize();
// UInt nb_local_master_dofs = 0;
/// create array to store the global equation number of all local and master
/// dofs
Array<Int> local_master_eq_nbs(nb_dofs);
Array<Int>::scalar_iterator it_eq_nb = local_master_eq_nbs.begin();
throw;
/// get the pointer to the global equation number array
- // Int * eq_nb_val =
-// this->dof_synchronizer->getGlobalDOFEquationNumbers().storage();
-
-// for (UInt i = 0; i < nb_dofs; ++i) {
-// if (this->dof_synchronizer->isLocalOrMasterDOF(i)) {
-// *it_eq_nb = eq_nb_val[i];
-// ++it_eq_nb;
-// ++nb_local_master_dofs;
-// }
-// }
+ // Int * eq_nb_val =
+ // this->dof_synchronizer->getGlobalDOFEquationNumbers().storage();
+
+ // for (UInt i = 0; i < nb_dofs; ++i) {
+ // if (this->dof_synchronizer->isLocalOrMasterDOF(i)) {
+ // *it_eq_nb = eq_nb_val[i];
+ // ++it_eq_nb;
+ // ++nb_local_master_dofs;
+ // }
+ // }
-// local_master_eq_nbs.resize(nb_local_master_dofs);
+ // local_master_eq_nbs.resize(nb_local_master_dofs);
-// /// set the local size
-// this->local_size = nb_local_master_dofs;
+ // /// set the local size
+ // this->local_size = nb_local_master_dofs;
-// /// resize PETSc matrix
-// #if defined(AKANTU_USE_MPI)
-// ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size,
-// this->local_size, this->size, this->size);
-// CHKERRXX(ierr);
-// #else
-// ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size,
-// this->local_size);
-// CHKERRXX(ierr);
-// #endif
+ // /// resize PETSc matrix
+ // #if defined(AKANTU_USE_MPI)
+ // ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size,
+ // this->local_size, this->size, this->size);
+ // CHKERRXX(ierr);
+ // #else
+ // ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size,
+ // this->local_size);
+ // CHKERRXX(ierr);
+ // #endif
-// /// create mapping from akantu global numbering to petsc global numbering
-// this->createGlobalAkantuToPETScMap(local_master_eq_nbs.storage());
+ // /// create mapping from akantu global numbering to petsc global numbering
+ // this->createGlobalAkantuToPETScMap(local_master_eq_nbs.storage());
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* This method generates a mapping from the global Akantu equation
* numbering to the global PETSc dof ordering
* @param local_master_eq_nbs_ptr Int pointer to the array of equation
* numbers of all local or master dofs, i.e. the row indices of the
* local matrix
*/
-void
-SparseMatrixPETSc::createGlobalAkantuToPETScMap(Int * local_master_eq_nbs_ptr) {
+void SparseMatrixPETSc::createGlobalAkantuToPETScMap(
+ Int * local_master_eq_nbs_ptr) {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt rank = comm.whoAmI();
// initialize vector to store the number of local and master nodes that are
// assigned to each processor
Vector<UInt> master_local_ndofs_per_proc(nb_proc);
/// store the nb of master and local dofs on each processor
master_local_ndofs_per_proc(rank) = this->local_size;
/// exchange the information among all processors
comm.allGather(master_local_ndofs_per_proc.storage(), 1);
/// each processor creates a map for his akantu global dofs to the
/// corresponding petsc global dofs
/// determine the PETSc-index for the first dof on each processor
for (UInt i = 0; i < rank; ++i) {
this->first_global_index += master_local_ndofs_per_proc(i);
}
/// create array for petsc ordering
Array<Int> petsc_dofs(this->local_size);
Array<Int>::scalar_iterator it_petsc_dofs = petsc_dofs.begin();
for (Int i = this->first_global_index;
i < this->first_global_index + this->local_size; ++i, ++it_petsc_dofs) {
*it_petsc_dofs = i;
}
- ierr = AOCreateBasic(PETSC_COMM_WORLD,
- this->local_size, local_master_eq_nbs_ptr,
- petsc_dofs.storage(), &(this->ao));
+ ierr =
+ AOCreateBasic(PETSC_COMM_WORLD, this->local_size, local_master_eq_nbs_ptr,
+ petsc_dofs.storage(), &(this->ao));
CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Method to save the nonzero pattern and the values stored at each position
* @param filename name of the file in which the information will be stored
*/
void SparseMatrixPETSc::saveMatrix(const std::string & filename) const {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
/// create Petsc viewer
PetscViewer viewer;
- ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,
- filename.c_str(), &viewer);
+ ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, filename.c_str(), &viewer);
CHKERRXX(ierr);
/// set the format
PetscViewerSetFormat(viewer, PETSC_VIEWER_DEFAULT);
CHKERRXX(ierr);
/// save the matrix
/// @todo Write should be done in serial -> might cause problems
ierr = MatView(this->mat, viewer);
CHKERRXX(ierr);
/// destroy the viewer
ierr = PetscViewerDestroy(&viewer);
CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Method to add an Akantu sparse matrix to the PETSc matrix
* @param matrix Akantu sparse matrix to be added
* @param alpha the factor specifying how many times the matrix should be added
*/
// void SparseMatrixPETSc::add(const SparseMatrix & matrix, Real alpha) {
// PetscErrorCode ierr;
// // AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
// // "The two matrix don't have the same profiles");
// Real val_to_add = 0;
// Array<Int> index(2);
// for (UInt n = 0; n < matrix.getNbNonZero(); ++n) {
// UInt mat_to_add_offset = matrix.getOffset();
// index(0) = matrix.getIRN()(n) - mat_to_add_offset;
// index(1) = matrix.getJCN()(n) - mat_to_add_offset;
// AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
// if (this->sparse_matrix_type == _symmetric && index(0) > index(1))
// std::swap(index(0), index(1));
// val_to_add = matrix.getA()(n) * alpha;
// /// MatSetValue might be very slow for MATBAIJ, might need to use
// /// MatSetValuesBlocked
// ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(0), index(1),
// val_to_add, ADD_VALUES);
// CHKERRXX(ierr);
// /// chek if sparse matrix to be added is symmetric. In this case
// /// the value also needs to be added at the transposed location in
-// /// the matrix because PETSc is using the full profile, also for symmetric
+// /// the matrix because PETSc is using the full profile, also for
+// symmetric
// /// matrices
// if (matrix.getSparseMatrixType() == _symmetric && index(0) != index(1))
// ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(1), index(0),
// val_to_add, ADD_VALUES);
// CHKERRXX(ierr);
// }
// this->performAssembly();
// }
/* -------------------------------------------------------------------------- */
/**
* Method to add another PETSc matrix to this PETSc matrix
* @param matrix PETSc matrix to be added
* @param alpha the factor specifying how many times the matrix should be added
*/
void SparseMatrixPETSc::add(const SparseMatrixPETSc & matrix, Real alpha) {
PetscErrorCode ierr;
- ierr = MatAXPY(this->mat, alpha,
- matrix.mat, SAME_NONZERO_PATTERN);
+ ierr = MatAXPY(this->mat, alpha, matrix.mat, SAME_NONZERO_PATTERN);
CHKERRXX(ierr);
this->performAssembly();
}
/* -------------------------------------------------------------------------- */
/**
* MatSetValues() generally caches the values. The matrix is ready to
* use only after MatAssemblyBegin() and MatAssemblyEnd() have been
* called. (http://www.mcs.anl.gov/petsc/)
*/
void SparseMatrixPETSc::performAssembly() {
this->beginAssembly();
this->endAssembly();
}
/* -------------------------------------------------------------------------- */
void SparseMatrixPETSc::beginAssembly() {
PetscErrorCode ierr;
ierr = MatAssemblyBegin(this->mat, MAT_FINAL_ASSEMBLY);
CHKERRXX(ierr);
ierr = MatAssemblyEnd(this->mat, MAT_FINAL_ASSEMBLY);
CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
void SparseMatrixPETSc::endAssembly() {
PetscErrorCode ierr;
ierr = MatAssemblyEnd(this->mat, MAT_FINAL_ASSEMBLY);
CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
/// access K(i, j). Works only for dofs on this processor!!!!
Real SparseMatrixPETSc::operator()(UInt i, UInt j) const {
AKANTU_DEBUG_IN();
// AKANTU_DEBUG_ASSERT(this->dof_synchronizer->isLocalOrMasterDOF(i) &&
// this->dof_synchronizer->isLocalOrMasterDOF(j),
// "Operator works only for dofs on this processor");
// Array<Int> index(2, 1);
// index(0) = this->dof_synchronizer->getDOFGlobalID(i);
// index(1) = this->dof_synchronizer->getDOFGlobalID(j);
// AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
// Real value = 0;
// PetscErrorCode ierr;
// /// @todo MatGetValue might be very slow for MATBAIJ, might need to use
// /// MatGetValuesBlocked
// ierr = MatGetValues(this->petsc_matrix_wrapper->mat, 1, &index(0), 1,
// &index(1), &value);
// CHKERRXX(ierr);
// AKANTU_DEBUG_OUT();
// return value;
return 0.;
}
/* -------------------------------------------------------------------------- */
/**
* Apply Dirichlet boundary conditions by zeroing the rows and columns which
* correspond to blocked dofs
* @param boundary array of booleans which are true if the dof at this position
* is blocked
* @param block_val the value in the diagonal entry of blocked rows
*/
void SparseMatrixPETSc::applyBoundary(const Array<bool> & boundary,
Real block_val) {
AKANTU_DEBUG_IN();
// PetscErrorCode ierr;
// /// get the global equation numbers to find the rows that need to be zeroed
// /// for the blocked dofs
- // Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
+ // Int * eq_nb_val =
+ // dof_synchronizer->getGlobalDOFEquationNumbers().storage();
- // /// every processor calls the MatSetZero() only for his local or master dofs.
+ // /// every processor calls the MatSetZero() only for his local or master
+ // dofs.
// /// This assures that not two processors or more try to zero the same row
// UInt nb_component = boundary.getNbComponent();
// UInt size = boundary.size();
// Int nb_blocked_local_master_eq_nb = 0;
// Array<Int> blocked_local_master_eq_nb(this->local_size);
// Int * blocked_lm_eq_nb_ptr = blocked_local_master_eq_nb.storage();
// for (UInt i = 0; i < size; ++i) {
// for (UInt j = 0; j < nb_component; ++j) {
// UInt local_dof = i * nb_component + j;
// if (boundary(i, j) == true &&
// this->dof_synchronizer->isLocalOrMasterDOF(local_dof)) {
// Int global_eq_nb = *eq_nb_val;
// *blocked_lm_eq_nb_ptr = global_eq_nb;
// ++nb_blocked_local_master_eq_nb;
// ++blocked_lm_eq_nb_ptr;
// }
// ++eq_nb_val;
// }
// }
// blocked_local_master_eq_nb.resize(nb_blocked_local_master_eq_nb);
// ierr = AOApplicationToPetsc(this->petsc_matrix_wrapper->ao,
// nb_blocked_local_master_eq_nb,
// blocked_local_master_eq_nb.storage());
// CHKERRXX(ierr);
// ierr = MatZeroRowsColumns(
// this->petsc_matrix_wrapper->mat, nb_blocked_local_master_eq_nb,
// blocked_local_master_eq_nb.storage(), block_val, 0, 0);
// CHKERRXX(ierr);
// this->performAssembly();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/// set all entries to zero while keeping the same nonzero pattern
-void SparseMatrixPETSc::clear() {
- MatZeroEntries(this->mat);
-}
+void SparseMatrixPETSc::clear() { MatZeroEntries(this->mat); }
} // akantu
diff --git a/src/solver/sparse_matrix_petsc.hh b/src/solver/sparse_matrix_petsc.hh
index 0fcb07f0d..fafa3b64c 100644
--- a/src/solver/sparse_matrix_petsc.hh
+++ b/src/solver/sparse_matrix_petsc.hh
@@ -1,142 +1,142 @@
/**
* @file petsc_matrix.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Aug 21 2015
*
* @brief Interface for PETSc matrices
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PETSC_MATRIX_HH__
#define __AKANTU_PETSC_MATRIX_HH__
/* -------------------------------------------------------------------------- */
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
-#include <petscmat.h>
#include <petscao.h>
+#include <petscmat.h>
/* -------------------------------------------------------------------------- */
namespace akantu {
- class DOFManagerPETSc;
+class DOFManagerPETSc;
}
namespace akantu {
-
class SparseMatrixPETSc : public SparseMatrix {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- SparseMatrixPETSc(DOFManagerPETSc & dof_manager, const MatrixType & matrix_type,
+ SparseMatrixPETSc(DOFManagerPETSc & dof_manager,
+ const MatrixType & matrix_type,
const ID & id = "sparse_matrix",
const MemoryID & memory_id = 0);
SparseMatrixPETSc(const SparseMatrix & matrix,
const ID & id = "sparse_matrix_petsc",
const MemoryID & memory_id = 0);
virtual ~SparseMatrixPETSc();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// set the matrix to 0
virtual void clear();
/// modify the matrix to "remove" the blocked dof
virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
/// save the matrix in a ASCII file format
virtual void saveMatrix(const std::string & filename) const;
/// add a sparse matrix assuming the profile are the same
virtual void add(const SparseMatrix & matrix, Real alpha);
/// add a petsc matrix assuming the profile are the same
virtual void add(const SparseMatrixPETSc & matrix, Real alpha);
Real operator()(UInt i, UInt j) const;
protected:
typedef std::pair<UInt, UInt> KeyCOO;
inline KeyCOO key(UInt i, UInt j) const { return std::make_pair(i, j); }
private:
virtual void destroyInternalData();
/// set the size of the PETSc matrix
void setSize();
void createGlobalAkantuToPETScMap(Int * local_master_eq_nbs_ptr);
void createLocalAkantuToPETScMap();
/// start to assemble the matrix
void beginAssembly();
/// finishes to assemble the matrix
void endAssembly();
/// perform the assembly stuff from petsc
void performAssembly();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(PETScMat, mat, const Mat &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
// DOFManagerPETSc that contains the numbering for petsc
DOFManagerPETSc & dof_manager;
/// store the PETSc matrix
Mat mat;
AO ao;
/// size of the diagonal part of the matrix partition
Int local_size;
/// number of nonzeros in every row of the diagonal part
Array<Int> d_nnz;
/// number of nonzeros in every row of the off-diagonal part
Array<Int> o_nnz;
/// the global index of the first local row
Int first_global_index;
/// bool to indicate if the matrix data has been initialized by calling
/// MatCreate
bool is_petsc_matrix_initialized;
};
} // akantu
#endif /* __AKANTU_PETSC_MATRIX_HH__ */
diff --git a/src/solver/sparse_solver.cc b/src/solver/sparse_solver.cc
index c4d16f64b..81e6a18f8 100644
--- a/src/solver/sparse_solver.cc
+++ b/src/solver/sparse_solver.cc
@@ -1,86 +1,85 @@
/**
* @file solver.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Tue Jan 19 2016
*
* @brief Solver interface class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh.hh"
-#include "dof_manager.hh"
#include "sparse_solver.hh"
#include "communicator.hh"
+#include "dof_manager.hh"
+#include "mesh.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
SparseSolver::SparseSolver(DOFManager & dof_manager, const ID & matrix_id,
const ID & id, const MemoryID & memory_id)
- : Memory(id, memory_id), Parsable(ParserType::_solver, id),
- _dof_manager(dof_manager), matrix_id(matrix_id), communicator(dof_manager.getCommunicator()) {
+ : Memory(id, memory_id), Parsable(ParserType::_solver, id),
+ _dof_manager(dof_manager), matrix_id(matrix_id),
+ communicator(dof_manager.getCommunicator()) {
AKANTU_DEBUG_IN();
// OK this is fishy...
this->communicator.registerEventHandler(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseSolver::~SparseSolver() {
AKANTU_DEBUG_IN();
- //this->destroyInternalData();
+ // this->destroyInternalData();
this->communicator.unregisterEventHandler(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolver::beforeStaticSolverDestroy() {
AKANTU_DEBUG_IN();
try {
this->destroyInternalData();
} catch (...) {
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolver::createSynchronizerRegistry() {
// this->synch_registry = new SynchronizerRegistry(this);
}
-void SparseSolver::onCommunicatorFinalize() {
- this->destroyInternalData();
-}
+void SparseSolver::onCommunicatorFinalize() { this->destroyInternalData(); }
} // akantu
diff --git a/src/solver/sparse_solver.hh b/src/solver/sparse_solver.hh
index 62053ca77..7c79df5a1 100644
--- a/src/solver/sparse_solver.hh
+++ b/src/solver/sparse_solver.hh
@@ -1,130 +1,130 @@
/**
* @file sparse_solver.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Jan 19 2016
*
* @brief interface for solvers
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
-#include "parsable.hh"
#include "communicator_event_handler.hh"
+#include "parsable.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_HH__
#define __AKANTU_SOLVER_HH__
namespace akantu {
enum SolverParallelMethod {
_not_parallel,
_fully_distributed,
_master_slave_distributed
};
class DOFManager;
}
namespace akantu {
class SparseSolver : protected Memory,
public Parsable,
public CommunicatorEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseSolver(DOFManager & dof_manager, const ID & matrix_id,
const ID & id = "solver", const MemoryID & memory_id = 0);
~SparseSolver() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the solver
virtual void initialize() = 0;
virtual void analysis(){};
virtual void factorize(){};
virtual void solve(){};
protected:
virtual void destroyInternalData(){};
public:
virtual void beforeStaticSolverDestroy();
void createSynchronizerRegistry();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
void onCommunicatorFinalize() override;
// inline virtual UInt getNbDataForDOFs(const Array<UInt> & dofs,
// SynchronizationTag tag) const;
// inline virtual void packDOFData(CommunicationBuffer & buffer,
// const Array<UInt> & dofs,
// SynchronizationTag tag) const;
// inline virtual void unpackDOFData(CommunicationBuffer & buffer,
// const Array<UInt> & dofs,
// SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// manager handling the dofs for this SparseMatrix solver
DOFManager & _dof_manager;
/// The id of the associated matrix
ID matrix_id;
/// How to parallelize the solve
SolverParallelMethod parallel_method;
/// Communicator used by the solver
Communicator & communicator;
};
namespace debug {
class SingularMatrixException : public Exception {
public:
SingularMatrixException(const SparseMatrix & matrix)
: Exception("Solver encountered singular matrix"), matrix(matrix) {}
const SparseMatrix & matrix;
};
}
} // akantu
#endif /* __AKANTU_SOLVER_HH__ */
diff --git a/src/solver/sparse_solver_inline_impl.cc b/src/solver/sparse_solver_inline_impl.cc
index da2ae4618..98e3a7bc9 100644
--- a/src/solver/sparse_solver_inline_impl.cc
+++ b/src/solver/sparse_solver_inline_impl.cc
@@ -1,81 +1,83 @@
/**
* @file solver_inline_impl.cc
* @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @date Thu Nov 13 14:43:41 2014
*
* @brief implementation of solver inline functions
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
// inline UInt Solver::getNbDataForDOFs(const Array<UInt> & dofs,
// SynchronizationTag tag) const {
// AKANTU_DEBUG_IN();
// UInt size = 0;
// switch(tag) {
// case _gst_solver_solution: {
// size += dofs.size() * sizeof(Real);
// break;
// }
// default: { }
// }
// AKANTU_DEBUG_OUT();
// return size;
// }
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// inline void Solver::packDOFData(CommunicationBuffer & buffer,
// const Array<UInt> & dofs,
// SynchronizationTag tag) const {
// AKANTU_DEBUG_IN();
// switch(tag) {
// case _gst_solver_solution: {
// packDOFDataHelper(*solution, buffer, dofs);
// break;
// }
// default: {
// }
// }
// AKANTU_DEBUG_OUT();
// }
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// inline void Solver::unpackDOFData(CommunicationBuffer & buffer,
// const Array<UInt> & dofs,
// SynchronizationTag tag) {
// AKANTU_DEBUG_IN();
// switch(tag) {
// case _gst_solver_solution: {
// unpackDOFDataHelper(*solution, buffer, dofs);
// break;
// }
// default: {
// }
// }
// AKANTU_DEBUG_OUT();
// }
diff --git a/src/solver/sparse_solver_mumps.cc b/src/solver/sparse_solver_mumps.cc
index de1b3e032..918d89f09 100644
--- a/src/solver/sparse_solver_mumps.cc
+++ b/src/solver/sparse_solver_mumps.cc
@@ -1,448 +1,446 @@
/**
* @file sparse_solver_mumps.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Tue Jan 19 2016
*
* @brief implem of SparseSolverMumps class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @subsection Ctrl_param Control parameters
*
* ICNTL(1),
* ICNTL(2),
* ICNTL(3) : output streams for error, diagnostics, and global messages
*
* ICNTL(4) : verbose level : 0 no message - 4 all messages
*
* ICNTL(5) : type of matrix, 0 assembled, 1 elementary
*
* ICNTL(6) : control the permutation and scaling(default 7) see mumps doc for
* more information
*
* ICNTL(7) : determine the pivot order (default 7) see mumps doc for more
* information
*
* ICNTL(8) : describe the scaling method used
*
* ICNTL(9) : 1 solve A x = b, 0 solve At x = b
*
* ICNTL(10) : number of iterative refinement when NRHS = 1
*
* ICNTL(11) : > 0 return statistics
*
* ICNTL(12) : only used for SYM = 2, ordering strategy
*
* ICNTL(13) :
*
* ICNTL(14) : percentage of increase of the estimated working space
*
* ICNTL(15-17) : not used
*
* ICNTL(18) : only used if ICNTL(5) = 0, 0 matrix centralized, 1 structure on
* host and mumps give the mapping, 2 structure on host and distributed matrix
* for facto, 3 distributed matrix
*
* ICNTL(19) : > 0, Shur complement returned
*
* ICNTL(20) : 0 rhs dense, 1 rhs sparse
*
* ICNTL(21) : 0 solution in rhs, 1 solution distributed in ISOL_loc and SOL_loc
* allocated by user
*
* ICNTL(22) : 0 in-core, 1 out-of-core
*
* ICNTL(23) : maximum memory allocatable by mumps pre proc
*
* ICNTL(24) : controls the detection of "null pivot rows"
*
* ICNTL(25) :
*
* ICNTL(26) :
*
* ICNTL(27) :
*
* ICNTL(28) : 0 automatic choice, 1 sequential analysis, 2 parallel analysis
*
* ICNTL(29) : 0 automatic choice, 1 PT-Scotch, 2 ParMetis
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "dof_manager_default.hh"
#include "dof_synchronizer.hh"
#include "sparse_matrix_aij.hh"
#if defined(AKANTU_USE_MPI)
#include "mpi_communicator_data.hh"
#endif
#include "sparse_solver_mumps.hh"
/* -------------------------------------------------------------------------- */
// static std::ostream & operator <<(std::ostream & stream, const DMUMPS_STRUC_C
// & _this) {
// stream << "DMUMPS Data [" << std::endl;
// stream << " + job : " << _this.job << std::endl;
// stream << " + par : " << _this.par << std::endl;
// stream << " + sym : " << _this.sym << std::endl;
// stream << " + comm_fortran : " << _this.comm_fortran << std::endl;
// stream << " + nz : " << _this.nz << std::endl;
// stream << " + irn : " << _this.irn << std::endl;
// stream << " + jcn : " << _this.jcn << std::endl;
// stream << " + nz_loc : " << _this.nz_loc << std::endl;
// stream << " + irn_loc : " << _this.irn_loc << std::endl;
// stream << " + jcn_loc : " << _this.jcn_loc << std::endl;
// stream << "]";
// return stream;
// }
namespace akantu {
/* -------------------------------------------------------------------------- */
SparseSolverMumps::SparseSolverMumps(DOFManagerDefault & dof_manager,
const ID & matrix_id, const ID & id,
const MemoryID & memory_id)
: SparseSolver(dof_manager, matrix_id, id, memory_id),
- dof_manager(dof_manager),
- master_rhs_solution(0, 1) {
+ dof_manager(dof_manager), master_rhs_solution(0, 1) {
AKANTU_DEBUG_IN();
this->prank = communicator.whoAmI();
#ifdef AKANTU_USE_MPI
this->parallel_method = _fully_distributed;
#else // AKANTU_USE_MPI
this->parallel_method = _not_parallel;
#endif // AKANTU_USE_MPI
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseSolverMumps::~SparseSolverMumps() {
AKANTU_DEBUG_IN();
mumpsDataDestroy();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::mumpsDataDestroy() {
if (this->is_initialized) {
this->mumps_data.job = _smj_destroy; // destroy
dmumps_c(&this->mumps_data);
this->is_initialized = false;
}
}
/* -------------------------------------------------------------------------- */
-void SparseSolverMumps::destroyInternalData() {
- mumpsDataDestroy();
-}
+void SparseSolverMumps::destroyInternalData() { mumpsDataDestroy(); }
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::checkInitialized() {
- if (this->is_initialized) return;
+ if (this->is_initialized)
+ return;
this->initialize();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::setOutputLevel() {
// Output setup
icntl(1) = 0; // error output
icntl(2) = 0; // diagnostics output
icntl(3) = 0; // information
icntl(4) = 0;
#if !defined(AKANTU_NDEBUG)
DebugLevel dbg_lvl = debug::debugger.getDebugLevel();
if (AKANTU_DEBUG_TEST(dblDump)) {
strcpy(this->mumps_data.write_problem, "mumps_matrix.mtx");
}
// clang-format off
icntl(1) = (dbg_lvl >= dblWarning) ? 6 : 0;
icntl(3) = (dbg_lvl >= dblInfo) ? 6 : 0;
icntl(2) = (dbg_lvl >= dblTrace) ? 6 : 0;
icntl(4) =
dbg_lvl >= dblDump ? 4 :
dbg_lvl >= dblTrace ? 3 :
dbg_lvl >= dblInfo ? 2 :
dbg_lvl >= dblWarning ? 1 :
0;
- // clang-format on
+// clang-format on
#endif
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::initMumpsData() {
auto & A = dof_manager.getMatrix(matrix_id);
// Default Scaling
icntl(8) = 77;
// Assembled matrix
icntl(5) = 0;
/// Default centralized dense second member
icntl(20) = 0;
icntl(21) = 0;
// automatic choice for analysis
icntl(28) = 0;
UInt size = A.size();
if (prank == 0) {
this->master_rhs_solution.resize(size);
}
this->mumps_data.nz_alloc = 0;
this->mumps_data.n = size;
switch (this->parallel_method) {
case _fully_distributed:
icntl(18) = 3; // fully distributed
this->mumps_data.nz_loc = A.getNbNonZero();
this->mumps_data.irn_loc = A.getIRN().storage();
this->mumps_data.jcn_loc = A.getJCN().storage();
break;
case _not_parallel:
case _master_slave_distributed:
icntl(18) = 0; // centralized
if (prank == 0) {
this->mumps_data.nz = A.getNbNonZero();
this->mumps_data.irn = A.getIRN().storage();
this->mumps_data.jcn = A.getJCN().storage();
} else {
this->mumps_data.nz = 0;
this->mumps_data.irn = nullptr;
this->mumps_data.jcn = nullptr;
}
break;
default:
AKANTU_ERROR("This case should not happen!!");
}
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::initialize() {
AKANTU_DEBUG_IN();
this->mumps_data.par = 1; // The host is part of computations
switch (this->parallel_method) {
case _not_parallel:
break;
case _master_slave_distributed:
this->mumps_data.par = 0; // The host is not part of the computations
- /* FALLTHRU */
- /* [[fallthrough]]; un-comment when compiler will get it */
+ /* FALLTHRU */
+ /* [[fallthrough]]; un-comment when compiler will get it */
case _fully_distributed:
#ifdef AKANTU_USE_MPI
const auto & mpi_data = dynamic_cast<const MPICommunicatorData &>(
communicator.getCommunicatorData());
MPI_Comm mpi_comm = mpi_data.getMPICommunicator();
this->mumps_data.comm_fortran = MPI_Comm_c2f(mpi_comm);
#else
AKANTU_ERROR(
"You cannot use parallel method to solve without activating MPI");
#endif
break;
}
const auto & A = dof_manager.getMatrix(matrix_id);
this->mumps_data.sym = 2 * (A.getMatrixType() == _symmetric);
this->prank = communicator.whoAmI();
this->setOutputLevel();
this->mumps_data.job = _smj_initialize; // initialize
dmumps_c(&this->mumps_data);
this->setOutputLevel();
this->is_initialized = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::analysis() {
AKANTU_DEBUG_IN();
initMumpsData();
this->mumps_data.job = _smj_analyze; // analyze
dmumps_c(&this->mumps_data);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::factorize() {
AKANTU_DEBUG_IN();
auto & A = dof_manager.getMatrix(matrix_id);
if (parallel_method == _fully_distributed)
this->mumps_data.a_loc = A.getA().storage();
else {
if (prank == 0)
this->mumps_data.a = A.getA().storage();
}
this->mumps_data.job = _smj_factorize; // factorize
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::solve(Array<Real> & x, const Array<Real> & b) {
auto & synch = this->dof_manager.getSynchronizer();
if (this->prank == 0) {
this->master_rhs_solution.resize(this->dof_manager.getSystemSize());
synch.gather(b, this->master_rhs_solution);
} else {
synch.gather(b);
}
this->solveInternal();
if (this->prank == 0) {
synch.scatter(x, this->master_rhs_solution);
} else {
synch.scatter(x);
}
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::solve() {
this->master_rhs_solution.copy(this->dof_manager.getGlobalResidual());
this->solveInternal();
this->dof_manager.setGlobalSolution(this->master_rhs_solution);
this->dof_manager.splitSolutionPerDOFs();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::solveInternal() {
AKANTU_DEBUG_IN();
this->checkInitialized();
const auto & A = dof_manager.getMatrix(matrix_id);
this->setOutputLevel();
if (this->last_profile_release != A.getProfileRelease()) {
this->analysis();
this->last_profile_release = A.getProfileRelease();
}
if (AKANTU_DEBUG_TEST(dblDump)) {
std::stringstream sstr;
sstr << prank << ".mtx";
A.saveMatrix("solver_mumps" + sstr.str());
}
if (this->last_value_release != A.getValueRelease()) {
this->factorize();
this->last_value_release = A.getValueRelease();
}
if (prank == 0) {
this->mumps_data.rhs = this->master_rhs_solution.storage();
}
this->mumps_data.job = _smj_solve; // solve
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::printError() {
Vector<Int> _info_v(2);
_info_v[0] = info(1); // to get errors
_info_v[1] = -info(1); // to get warnings
dof_manager.getCommunicator().allReduce(_info_v, SynchronizerOperation::_min);
_info_v[1] = -_info_v[1];
if (_info_v[0] < 0) { // < 0 is an error
switch (_info_v[0]) {
case -10:
AKANTU_CUSTOM_EXCEPTION(
debug::SingularMatrixException(dof_manager.getMatrix(matrix_id)));
break;
case -9: {
icntl(14) += 10;
if (icntl(14) != 90) {
// std::cout << "Dynamic memory increase of 10%" << std::endl;
AKANTU_DEBUG_WARNING("MUMPS dynamic memory is insufficient it will be "
"increased allowed to use 10% more");
// change releases to force a recompute
this->last_value_release--;
this->last_profile_release--;
this->solve();
} else {
AKANTU_ERROR("The MUMPS workarray is too small INFO(2)="
- << info(2) << "No further increase possible");
+ << info(2) << "No further increase possible");
}
break;
}
default:
AKANTU_ERROR("Error in mumps during solve process, check mumps "
- "user guide INFO(1) = "
- << _info_v[1]);
+ "user guide INFO(1) = "
+ << _info_v[1]);
}
} else if (_info_v[1] > 0) {
AKANTU_DEBUG_WARNING("Warning in mumps during solve process, check mumps "
"user guide INFO(1) = "
<< _info_v[1]);
}
}
} // akantu
diff --git a/src/solver/sparse_solver_mumps.hh b/src/solver/sparse_solver_mumps.hh
index 6be46c20c..23ec34a6b 100644
--- a/src/solver/sparse_solver_mumps.hh
+++ b/src/solver/sparse_solver_mumps.hh
@@ -1,160 +1,158 @@
/**
* @file sparse_solver_mumps.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Jan 19 2016
*
* @brief Solver class implementation for the mumps solver
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "sparse_solver.hh"
/* -------------------------------------------------------------------------- */
#include <dmumps_c.h>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_MUMPS_HH__
#define __AKANTU_SOLVER_MUMPS_HH__
namespace akantu {
- class DOFManagerDefault;
- class SparseMatrixAIJ;
+class DOFManagerDefault;
+class SparseMatrixAIJ;
}
-
namespace akantu {
class SparseSolverMumps : public SparseSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- SparseSolverMumps(DOFManagerDefault & dof_manager,
- const ID & matrix_id,
+ SparseSolverMumps(DOFManagerDefault & dof_manager, const ID & matrix_id,
const ID & id = "sparse_solver_mumps",
const MemoryID & memory_id = 0);
~SparseSolverMumps() override;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// build the profile and do the analysis part
void initialize() override;
/// analysis (symbolic facto + permutations)
void analysis() override;
/// factorize the matrix
void factorize() override;
/// solve the system
virtual void solve(Array<Real> & x, const Array<Real> & b);
/// solve using residual and solution from the dof_manager
void solve() override;
private:
/// print the error if any happened in mumps
void printError();
/// solve the system with master_rhs_solution as b and x
void solveInternal();
/// set internal values;
void initMumpsData();
/// set the level of verbosity of mumps based on the debug level of akantu
void setOutputLevel();
protected:
/// de-initialize the internal data
void destroyInternalData() override;
/// check if initialized and except if it is not the case
void checkInitialized();
-private:
+private:
void mumpsDataDestroy();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
private:
/// access the control variable
inline Int & icntl(UInt i) { return mumps_data.icntl[i - 1]; }
/// access the results info
inline Int & info(UInt i) { return mumps_data.info[i - 1]; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// DOFManager used by the Mumps implementation of the SparseSolver
DOFManagerDefault & dof_manager;
/// Full right hand side on the master processors and solution after solve
Array<Real> master_rhs_solution;
/// mumps data
DMUMPS_STRUC_C mumps_data;
/// Rank of the current process
UInt prank;
/// matrix release at last solve
UInt last_profile_release{UInt(-1)};
/// matrix release at last solve
UInt last_value_release{UInt(-1)};
/// check if the solver data are initialized
bool is_initialized{false};
/* ------------------------------------------------------------------------ */
/* Local types */
/* ------------------------------------------------------------------------ */
private:
SolverParallelMethod parallel_method;
// bool rhs_is_local;
enum SolverMumpsJob {
_smj_initialize = -1,
_smj_analyze = 1,
_smj_factorize = 2,
_smj_solve = 3,
_smj_analyze_factorize = 4,
_smj_factorize_solve = 5,
_smj_complete = 6, // analyze, factorize, solve
_smj_destroy = -2
};
};
} // akantu
#endif /* __AKANTU_SOLVER_MUMPS_HH__ */
diff --git a/src/synchronizer/communication_descriptor.hh b/src/synchronizer/communication_descriptor.hh
index 609218b86..373abd5b1 100644
--- a/src/synchronizer/communication_descriptor.hh
+++ b/src/synchronizer/communication_descriptor.hh
@@ -1,153 +1,153 @@
/**
* @file synchronizer_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Aug 3 13:49:36 2016
*
* @brief Implementation of the helper classes for the synchronizer
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
+#include "communication_request.hh"
#include "communication_tag.hh"
#include "data_accessor.hh"
-#include "communication_request.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COMMUNICATION_DESCRIPTOR_HH__
#define __AKANTU_COMMUNICATION_DESCRIPTOR_HH__
namespace akantu {
/* ------------------------------------------------------------------------ */
-enum CommunicationSendRecv { _send, _recv, _csr_not_defined };
+enum CommunicationSendRecv { _send, _recv, _csr_not_defined };
/* -------------------------------------------------------------------------- */
struct CommunicationSRType {
using type = CommunicationSendRecv;
static const type _begin_ = _send;
static const type _end_ = _csr_not_defined;
};
using send_recv_t = safe_enum<CommunicationSRType>;
namespace {
send_recv_t iterate_send_recv{};
}
/* ------------------------------------------------------------------------ */
class Communication {
public:
explicit Communication(const CommunicationSendRecv & type = _csr_not_defined)
: _type(type) {}
Communication(const Communication &) = delete;
Communication & operator=(const Communication &) = delete;
void resize(UInt size) {
this->_size = size;
this->_buffer.resize(size);
}
inline const CommunicationSendRecv & type() const { return this->_type; }
inline const UInt & size() const { return this->_size; }
inline const CommunicationRequest & request() const { return this->_request; }
inline CommunicationRequest & request() { return this->_request; }
inline const CommunicationBuffer & buffer() const { return this->_buffer; }
inline CommunicationBuffer & buffer() { return this->_buffer; }
private:
UInt _size{0};
CommunicationBuffer _buffer;
CommunicationRequest _request;
CommunicationSendRecv _type;
};
template <class Entity> class Communications;
/* ------------------------------------------------------------------------ */
template <class Entity> class CommunicationDescriptor {
public:
CommunicationDescriptor(Communication & communication, Array<Entity> & scheme,
Communications<Entity> & communications,
const SynchronizationTag & tag, UInt proc);
CommunicationDescriptor(const CommunicationDescriptor &) = default;
CommunicationDescriptor &
operator=(const CommunicationDescriptor &) = default;
/// get the quantity of data in the buffer
UInt getNbData() { return communication.size(); }
/// set the quantity of data in the buffer
void setNbData(UInt size) { communication.resize(size); }
/// get the corresponding tag
const SynchronizationTag & getTag() const { return tag; }
/// get the data buffer
CommunicationBuffer & getBuffer();
/// get the corresponding request
CommunicationRequest & getRequest();
/// get the communication scheme
const Array<Entity> & getScheme();
/// reset the buffer before pack or after unpack
void resetBuffer();
/// pack data for entities in the buffer
void packData(const DataAccessor<Entity> & accessor);
/// unpack data for entities from the buffer
void unpackData(DataAccessor<Entity> & accessor);
/// posts asynchronous send requests
void postSend(int hash_id);
/// posts asynchronous receive requests
void postRecv(int hash_id);
/// free the request
void freeRequest();
UInt getProc() { return proc; }
protected:
Communication & communication;
const Array<Entity> & scheme;
Communications<Entity> & communications;
const SynchronizationTag & tag;
UInt proc;
UInt rank;
UInt counter;
};
/* -------------------------------------------------------------------------- */
} // namespace akantu
#include "communication_descriptor_tmpl.hh"
#endif /* __AKANTU_COMMUNICATION_DESCRIPTOR_HH__ */
diff --git a/src/synchronizer/communication_descriptor_tmpl.hh b/src/synchronizer/communication_descriptor_tmpl.hh
index 8e6982fec..8b61411ec 100644
--- a/src/synchronizer/communication_descriptor_tmpl.hh
+++ b/src/synchronizer/communication_descriptor_tmpl.hh
@@ -1,152 +1,151 @@
/**
* @file communication_descriptor_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Sep 6 14:03:16 2016
*
* @brief implementation of CommunicationDescriptor
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communication_descriptor.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COMMUNICATION_DESCRIPTOR_TMPL_HH__
#define __AKANTU_COMMUNICATION_DESCRIPTOR_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
/* Implementations */
/* -------------------------------------------------------------------------- */
template <class Entity>
CommunicationDescriptor<Entity>::CommunicationDescriptor(
Communication & communication, Array<Entity> & scheme,
Communications<Entity> & communications, const SynchronizationTag & tag,
UInt proc)
: communication(communication), scheme(scheme),
communications(communications), tag(tag), proc(proc),
rank(communications.getCommunicator().whoAmI()) {
counter = communications.getCounter(tag);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
CommunicationBuffer & CommunicationDescriptor<Entity>::getBuffer() {
return communication.buffer();
}
/* -------------------------------------------------------------------------- */
template <class Entity>
CommunicationRequest & CommunicationDescriptor<Entity>::getRequest() {
return communication.request();
}
/* -------------------------------------------------------------------------- */
template <class Entity> void CommunicationDescriptor<Entity>::freeRequest() {
const auto & comm = communications.getCommunicator();
// comm.test(communication.request());
comm.freeCommunicationRequest(communication.request());
communications.decrementPending(tag, communication.type());
}
/* -------------------------------------------------------------------------- */
template <class Entity>
const Array<Entity> & CommunicationDescriptor<Entity>::getScheme() {
return scheme;
}
-template <class Entity>
-void CommunicationDescriptor<Entity>::resetBuffer() {
+template <class Entity> void CommunicationDescriptor<Entity>::resetBuffer() {
this->communication.buffer().reset();
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void CommunicationDescriptor<Entity>::packData(
const DataAccessor<Entity> & accessor) {
AKANTU_DEBUG_ASSERT(
communication.type() == _send,
"Cannot pack data on communication that is not of type _send");
accessor.packData(communication.buffer(), scheme, tag);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void CommunicationDescriptor<Entity>::unpackData(
DataAccessor<Entity> & accessor) {
AKANTU_DEBUG_ASSERT(
communication.type() == _recv,
"Cannot unpack data from communication that is not of type _recv");
accessor.unpackData(communication.buffer(), scheme, tag);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void CommunicationDescriptor<Entity>::postSend(int hash_id) {
AKANTU_DEBUG_ASSERT(communication.type() == _send,
"Cannot send a communication that is not of type _send");
Tag comm_tag = Tag::genTag(rank, counter, tag, hash_id);
AKANTU_DEBUG_ASSERT(communication.buffer().getPackedSize() ==
communication.size(),
"a problem have been introduced with "
<< "false sent sizes declaration "
<< communication.buffer().getPackedSize()
<< " != " << communication.size());
AKANTU_DEBUG_INFO("Posting send to proc " << proc << " (tag: " << tag << " - "
<< communication.size()
<< " data to send) "
<< " [ " << comm_tag << " ]");
CommunicationRequest & request = communication.request();
request = communications.getCommunicator().asyncSend(communication.buffer(),
proc, comm_tag);
communications.incrementPending(tag, communication.type());
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void CommunicationDescriptor<Entity>::postRecv(int hash_id) {
AKANTU_DEBUG_ASSERT(communication.type() == _recv,
"Cannot receive data for communication ("
<< communication.type()
<< ")that is not of type _recv");
Tag comm_tag = Tag::genTag(proc, counter, tag, hash_id);
AKANTU_DEBUG_INFO("Posting receive from proc "
<< proc << " (tag: " << tag << " - " << communication.size()
<< " data to receive) "
<< " [ " << comm_tag << " ]");
CommunicationRequest & request = communication.request();
request = communications.getCommunicator().asyncReceive(
communication.buffer(), proc, comm_tag);
communications.incrementPending(tag, communication.type());
}
} // akantu
#endif /* __AKANTU_COMMUNICATION_DESCRIPTOR_TMPL_HH__ */
diff --git a/src/synchronizer/communication_tag.hh b/src/synchronizer/communication_tag.hh
index f9a16291a..e6fb54a82 100644
--- a/src/synchronizer/communication_tag.hh
+++ b/src/synchronizer/communication_tag.hh
@@ -1,114 +1,116 @@
/**
* @file communication_tag.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Aug 24 12:40:55 2016
*
* @brief Description of the communication tags
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_COMMUNICATION_TAG_HH__
#define __AKANTU_COMMUNICATION_TAG_HH__
namespace akantu {
/**
* tag = |__________20_________|___8____|_4_|
* | proc | num mes| ct|
*/
class Tag {
public:
Tag() = default;
Tag(int val) : tag(val) {}
Tag(int val, int hash) : tag(val), hash(hash) {}
- operator int() const { return int(max_tag == 0 ? tag : (uint32_t(tag) % max_tag)); }
+ operator int() const {
+ return int(max_tag == 0 ? tag : (uint32_t(tag) % max_tag));
+ }
/// generates a tag
template <typename CommTag>
static inline Tag genTag(int proc, UInt msg_count, CommTag tag) {
int _tag = ((((proc & 0xFFFFF) << 12) + ((msg_count & 0xFF) << 4) +
((int)tag & 0xF)));
Tag t(_tag);
return t;
}
/// generates a tag and hashes it
template <typename CommTag>
static inline Tag genTag(int proc, UInt msg_count, CommTag tag, int hash) {
Tag t = genTag(proc, msg_count, tag);
t.tag = t.tag ^ hash;
t.hash = hash;
return t;
}
virtual void printself(std::ostream & stream, int) const {
int t = tag;
stream << "TAG(";
if (hash != 0)
t = t ^ hash;
- stream << (t >> 12) << ":" << (t >> 4 & 0xFF) << ":" << (t & 0xF)
- << " -> " << std::hex << "0x"<< int(*this);
+ stream << (t >> 12) << ":" << (t >> 4 & 0xFF) << ":" << (t & 0xF) << " -> "
+ << std::hex << "0x" << int(*this);
if (hash != 0)
stream << " {hash: 0x" << hash << "}";
stream << " [0x" << this->max_tag << "]";
stream << ")";
}
enum CommTags : int {
_SIZES = 1,
_CONNECTIVITY = 2,
_DATA = 3,
_PARTITIONS = 4,
_NB_NODES = 5,
_NODES = 6,
_COORDINATES = 7,
_NODES_TYPE = 8,
_MESH_DATA = 9,
_ELEMENT_GROUP = 10,
_NODE_GROUP = 11,
_MODIFY_SCHEME = 12,
_GATHER_INITIALIZATION = 1,
_GATHER = 2,
_SCATTER = 3,
_SYNCHRONIZE = 15,
};
private:
static void setMaxTag(int _max_tag) { max_tag = _max_tag; }
friend void initialize(const std::string &, int &, char **&);
private:
int tag{0};
int hash{0};
static int max_tag;
};
/* -------------------------------------------------------------------------- */
inline std::ostream & operator<<(std::ostream & stream, const Tag & _this) {
_this.printself(stream, 0);
return stream;
}
/* -------------------------------------------------------------------------- */
}
#endif /* __AKANTU_COMMUNICATION_TAG_HH__ */
diff --git a/src/synchronizer/communications.hh b/src/synchronizer/communications.hh
index 58f56ca01..8190e94ed 100644
--- a/src/synchronizer/communications.hh
+++ b/src/synchronizer/communications.hh
@@ -1,273 +1,272 @@
/**
* @file communications.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Aug 24 13:56:14 2016
*
* @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communication_descriptor.hh"
#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COMMUNICATIONS_HH__
#define __AKANTU_COMMUNICATIONS_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Entity> class Communications {
public:
using Scheme = Array<Entity>;
protected:
using CommunicationPerProcs = std::map<UInt, Communication>;
using CommunicationsPerTags =
std::map<SynchronizationTag, CommunicationPerProcs>;
using CommunicationSchemes = std::map<UInt, Scheme>;
using Request = std::map<UInt, std::vector<CommunicationRequest>>;
friend class CommunicationDescriptor<Entity>;
public:
using scheme_iterator = typename CommunicationSchemes::iterator;
using const_scheme_iterator = typename CommunicationSchemes::const_iterator;
/* ------------------------------------------------------------------------ */
class iterator;
class tag_iterator;
/* ------------------------------------------------------------------------ */
public:
CommunicationPerProcs & getCommunications(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
/* ------------------------------------------------------------------------ */
bool hasPending(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) const;
UInt getPending(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) const;
/* ------------------------------------------------------------------------ */
iterator begin(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
iterator end(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
/* ------------------------------------------------------------------------ */
iterator waitAny(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
/* ------------------------------------------------------------------------ */
void waitAll(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
void incrementPending(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
void decrementPending(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
void freeRequests(const SynchronizationTag & tag,
const CommunicationSendRecv & sr);
/* ------------------------------------------------------------------------ */
Scheme & createScheme(UInt proc, const CommunicationSendRecv & sr);
void resetSchemes(const CommunicationSendRecv & sr);
/* ------------------------------------------------------------------------ */
void setCommunicationSize(const SynchronizationTag & tag, UInt proc,
UInt size, const CommunicationSendRecv & sr);
public:
explicit Communications(const Communicator & communicator);
explicit Communications(const Communications & communications);
/* ------------------------------------------------------------------------ */
class IterableCommunicationDesc {
public:
IterableCommunicationDesc(Communications & communications,
- SynchronizationTag tag,
- CommunicationSendRecv sr)
- : communications(communications), tag(std::move(tag)), sr(std::move(sr)) {}
+ SynchronizationTag tag, CommunicationSendRecv sr)
+ : communications(communications), tag(std::move(tag)),
+ sr(std::move(sr)) {}
auto begin() { return communications.begin(tag, sr); }
auto end() { return communications.end(tag, sr); }
private:
Communications & communications;
SynchronizationTag tag;
CommunicationSendRecv sr;
};
auto iterateRecv(const SynchronizationTag & tag) {
return IterableCommunicationDesc(*this, tag, _recv);
}
auto iterateSend(const SynchronizationTag & tag) {
return IterableCommunicationDesc(*this, tag, _send);
}
/* ------------------------------------------------------------------------ */
// iterator begin_send(const SynchronizationTag & tag);
// iterator end_send(const SynchronizationTag & tag);
/* ------------------------------------------------------------------------ */
// iterator begin_recv(const SynchronizationTag & tag);
// iterator end_recv(const SynchronizationTag & tag);
/* ------------------------------------------------------------------------ */
class IterableTags {
public:
explicit IterableTags(Communications & communications)
: communications(communications) {}
decltype(auto) begin() { return communications.begin_tag(); }
decltype(auto) end() { return communications.end_tag(); }
private:
Communications & communications;
};
decltype(auto) iterateTags() { return IterableTags(*this); }
tag_iterator begin_tag();
tag_iterator end_tag();
/* ------------------------------------------------------------------------ */
bool hasCommunication(const SynchronizationTag & tag) const;
void incrementCounter(const SynchronizationTag & tag);
UInt getCounter(const SynchronizationTag & tag) const;
bool hasCommunicationSize(const SynchronizationTag & tag) const;
void invalidateSizes();
/* ------------------------------------------------------------------------ */
bool hasPendingRecv(const SynchronizationTag & tag) const;
bool hasPendingSend(const SynchronizationTag & tag) const;
const auto & getCommunicator() const;
/* ------------------------------------------------------------------------ */
iterator waitAnyRecv(const SynchronizationTag & tag);
iterator waitAnySend(const SynchronizationTag & tag);
void waitAllRecv(const SynchronizationTag & tag);
void waitAllSend(const SynchronizationTag & tag);
void freeSendRequests(const SynchronizationTag & tag);
void freeRecvRequests(const SynchronizationTag & tag);
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
class IterableSchemes {
public:
- IterableSchemes(Communications & communications,
- CommunicationSendRecv sr)
+ IterableSchemes(Communications & communications, CommunicationSendRecv sr)
: communications(communications), sr(std::move(sr)) {}
decltype(auto) begin() { return communications.begin_scheme(sr); }
decltype(auto) end() { return communications.end_scheme(sr); }
private:
Communications & communications;
CommunicationSendRecv sr;
};
class ConstIterableSchemes {
public:
ConstIterableSchemes(const Communications & communications,
CommunicationSendRecv sr)
: communications(communications), sr(std::move(sr)) {}
decltype(auto) begin() const { return communications.begin_scheme(sr); }
decltype(auto) end() const { return communications.end_scheme(sr); }
private:
const Communications & communications;
CommunicationSendRecv sr;
};
decltype(auto) iterateSchemes(const CommunicationSendRecv & sr) {
return IterableSchemes(*this, sr);
}
decltype(auto) iterateSchemes(const CommunicationSendRecv & sr) const {
return ConstIterableSchemes(*this, sr);
}
decltype(auto) iterateSendSchemes() { return IterableSchemes(*this, _send); }
decltype(auto) iterateSendSchemes() const {
return ConstIterableSchemes(*this, _send);
}
decltype(auto) iterateRecvSchemes() { return IterableSchemes(*this, _recv); }
decltype(auto) iterateRecvSchemes() const {
return ConstIterableSchemes(*this, _recv);
}
scheme_iterator begin_scheme(const CommunicationSendRecv & sr);
scheme_iterator end_scheme(const CommunicationSendRecv & sr);
const_scheme_iterator begin_scheme(const CommunicationSendRecv & sr) const;
const_scheme_iterator end_scheme(const CommunicationSendRecv & sr) const;
/* ------------------------------------------------------------------------ */
scheme_iterator begin_send_scheme();
scheme_iterator end_send_scheme();
const_scheme_iterator begin_send_scheme() const;
const_scheme_iterator end_send_scheme() const;
/* ------------------------------------------------------------------------ */
scheme_iterator begin_recv_scheme();
scheme_iterator end_recv_scheme();
const_scheme_iterator begin_recv_scheme() const;
const_scheme_iterator end_recv_scheme() const;
/* ------------------------------------------------------------------------ */
Scheme & createSendScheme(UInt proc);
Scheme & createRecvScheme(UInt proc);
/* ------------------------------------------------------------------------ */
Scheme & getScheme(UInt proc, const CommunicationSendRecv & sr);
const Scheme & getScheme(UInt proc, const CommunicationSendRecv & sr) const;
/* ------------------------------------------------------------------------ */
void resetSchemes();
/* ------------------------------------------------------------------------ */
void setSendCommunicationSize(const SynchronizationTag & tag, UInt proc,
UInt size);
void setRecvCommunicationSize(const SynchronizationTag & tag, UInt proc,
UInt size);
void initializeCommunications(const SynchronizationTag & tag);
protected:
CommunicationSchemes schemes[2];
CommunicationsPerTags communications[2];
std::map<SynchronizationTag, UInt> comm_counter;
std::map<SynchronizationTag, UInt> pending_communications[2];
std::map<SynchronizationTag, bool> comm_size_computed;
const Communicator & communicator;
};
} // namespace akantu
#include "communications_tmpl.hh"
#endif /* __AKANTU_COMMUNICATIONS_HH__ */
diff --git a/src/synchronizer/communications_tmpl.hh b/src/synchronizer/communications_tmpl.hh
index 10678c7ff..9b4f2aef9 100644
--- a/src/synchronizer/communications_tmpl.hh
+++ b/src/synchronizer/communications_tmpl.hh
@@ -1,550 +1,550 @@
/**
* @file communications_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Tue Sep 6 17:14:06 2016
*
* @brief Implementation of Communications
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communications.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COMMUNICATIONS_TMPL_HH__
#define __AKANTU_COMMUNICATIONS_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Entity>
Communications<Entity>::Communications(const Communicator & communicator)
: communicator(communicator) {}
/* -------------------------------------------------------------------------- */
template <class Entity>
Communications<Entity>::Communications(const Communications & other)
: communicator(other.communicator) {
- for(auto sr : iterate_send_recv) {
+ for (auto sr : iterate_send_recv) {
for (const auto & scheme_pair : other.iterateSchemes(sr)) {
auto proc = scheme_pair.first;
auto & other_scheme = scheme_pair.second;
auto & scheme = this->createScheme(proc, sr);
scheme.copy(other_scheme);
}
}
this->invalidateSizes();
}
/* -------------------------------------------------------------------------- */
template <class Entity> class Communications<Entity>::iterator {
using communication_iterator =
typename std::map<UInt, Communication>::iterator;
public:
iterator() : communications(nullptr) {}
iterator(scheme_iterator scheme_it, communication_iterator comm_it,
Communications<Entity> & communications,
const SynchronizationTag & tag)
: scheme_it(scheme_it), comm_it(comm_it), communications(&communications),
tag(tag) {}
iterator & operator=(const iterator & other) {
if (this != &other) {
this->scheme_it = other.scheme_it;
this->comm_it = other.comm_it;
this->communications = other.communications;
this->tag = other.tag;
}
return *this;
}
iterator & operator++() {
++scheme_it;
++comm_it;
return *this;
}
CommunicationDescriptor<Entity> operator*() {
AKANTU_DEBUG_ASSERT(
scheme_it->first == comm_it->first,
"The two iterators are not in phase, something wrong"
<< " happened, time to take out your favorite debugger ("
<< scheme_it->first << " != " << comm_it->first << ")");
return CommunicationDescriptor<Entity>(comm_it->second, scheme_it->second,
*communications, tag,
scheme_it->first);
}
bool operator==(const iterator & other) const {
return scheme_it == other.scheme_it && comm_it == other.comm_it;
}
bool operator!=(const iterator & other) const {
return scheme_it != other.scheme_it || comm_it != other.comm_it;
}
private:
scheme_iterator scheme_it;
communication_iterator comm_it;
Communications<Entity> * communications;
SynchronizationTag tag;
};
/* -------------------------------------------------------------------------- */
template <class Entity> class Communications<Entity>::tag_iterator {
using internal_iterator = std::map<SynchronizationTag, UInt>::const_iterator;
public:
tag_iterator(const internal_iterator & it) : it(it) {}
tag_iterator & operator++() {
++it;
return *this;
}
SynchronizationTag operator*() { return it->first; }
bool operator==(const tag_iterator & other) const { return it == other.it; }
bool operator!=(const tag_iterator & other) const { return it != other.it; }
private:
internal_iterator it;
};
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::CommunicationPerProcs &
Communications<Entity>::getCommunications(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) {
auto comm_it = this->communications[sr].find(tag);
if (comm_it == this->communications[sr].end())
AKANTU_CUSTOM_EXCEPTION_INFO(
debug::CommunicationException(),
"No known communications for the tag: " << tag);
return comm_it->second;
}
/* ---------------------------------------------------------------------- */
template <class Entity>
UInt Communications<Entity>::getPending(
const SynchronizationTag & tag, const CommunicationSendRecv & sr) const {
const std::map<SynchronizationTag, UInt> & pending =
pending_communications[sr];
auto it = pending.find(tag);
if (it == pending.end())
return 0;
return it->second;
}
/* -------------------------------------------------------------------------- */
template <class Entity>
bool Communications<Entity>::hasPending(
const SynchronizationTag & tag, const CommunicationSendRecv & sr) const {
return this->hasCommunication(tag) && (this->getPending(tag, sr) != 0);
}
/* ---------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::iterator
Communications<Entity>::begin(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) {
auto & comms = this->getCommunications(tag, sr);
return iterator(this->schemes[sr].begin(), comms.begin(), *this, tag);
}
template <class Entity>
typename Communications<Entity>::iterator
Communications<Entity>::end(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) {
auto & comms = this->getCommunications(tag, sr);
return iterator(this->schemes[sr].end(), comms.end(), *this, tag);
}
/* ---------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::iterator
Communications<Entity>::waitAny(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) {
auto & comms = this->getCommunications(tag, sr);
auto it = comms.begin();
auto end = comms.end();
std::vector<CommunicationRequest> requests;
for (; it != end; ++it) {
auto & request = it->second.request();
if (!request.isFreed())
requests.push_back(request);
}
UInt req_id = communicator.waitAny(requests);
if (req_id != UInt(-1)) {
auto & request = requests[req_id];
UInt proc = sr == _recv ? request.getSource() : request.getDestination();
return iterator(this->schemes[sr].find(proc), comms.find(proc), *this, tag);
} else {
return this->end(tag, sr);
}
}
/* ---------------------------------------------------------------------- */
template <class Entity>
void Communications<Entity>::waitAll(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) {
auto & comms = this->getCommunications(tag, sr);
auto it = comms.begin();
auto end = comms.end();
std::vector<CommunicationRequest> requests;
for (; it != end; ++it) {
requests.push_back(it->second.request());
}
communicator.waitAll(requests);
}
template <class Entity>
void Communications<Entity>::incrementPending(
const SynchronizationTag & tag, const CommunicationSendRecv & sr) {
++(pending_communications[sr][tag]);
}
template <class Entity>
void Communications<Entity>::decrementPending(
const SynchronizationTag & tag, const CommunicationSendRecv & sr) {
--(pending_communications[sr][tag]);
}
template <class Entity>
void Communications<Entity>::freeRequests(const SynchronizationTag & tag,
const CommunicationSendRecv & sr) {
iterator it = this->begin(tag, sr);
iterator end = this->end(tag, sr);
for (; it != end; ++it) {
(*it).freeRequest();
}
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::Scheme &
Communications<Entity>::createScheme(UInt proc,
const CommunicationSendRecv & sr) {
// scheme_iterator it = schemes[sr].find(proc);
// if (it != schemes[sr].end()) {
// AKANTU_CUSTOM_EXCEPTION_INFO(debug::CommunicationException(),
// "Communication scheme("
// << sr
// << ") already created for proc: " <<
// proc);
// }
return schemes[sr][proc];
}
template <class Entity>
void Communications<Entity>::resetSchemes(const CommunicationSendRecv & sr) {
auto it = this->schemes[sr].begin();
auto end = this->schemes[sr].end();
for (; it != end; ++it) {
it->second.resize(0);
}
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void Communications<Entity>::setCommunicationSize(
const SynchronizationTag & tag, UInt proc, UInt size,
const CommunicationSendRecv & sr) {
// accessor that fails if it does not exists
comm_size_computed[tag] = true; // TODO: need perhaps to be split based on sr
auto & comms = this->communications[sr];
auto & comms_per_tag = comms.at(tag);
comms_per_tag.at(proc).resize(size);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void Communications<Entity>::initializeCommunications(
const SynchronizationTag & tag) {
for (auto t = send_recv_t::begin(); t != send_recv_t::end(); ++t) {
pending_communications[*t].insert(std::make_pair(tag, 0));
auto & comms = this->communications[*t];
auto & comms_per_tag =
comms.insert(std::make_pair(tag, CommunicationPerProcs()))
.first->second;
for (auto pair : this->schemes[*t]) {
comms_per_tag.emplace(std::piecewise_construct,
std::forward_as_tuple(pair.first),
std::forward_as_tuple(*t));
}
}
comm_counter.insert(std::make_pair(tag, 0));
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::tag_iterator
Communications<Entity>::begin_tag() {
return tag_iterator(comm_counter.begin());
}
template <class Entity>
typename Communications<Entity>::tag_iterator
Communications<Entity>::end_tag() {
return tag_iterator(comm_counter.end());
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::scheme_iterator
Communications<Entity>::begin_scheme(const CommunicationSendRecv & sr) {
return this->schemes[sr].begin();
}
template <class Entity>
typename Communications<Entity>::scheme_iterator
Communications<Entity>::end_scheme(const CommunicationSendRecv & sr) {
return this->schemes[sr].end();
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::const_scheme_iterator
Communications<Entity>::begin_scheme(const CommunicationSendRecv & sr) const {
return this->schemes[sr].begin();
}
template <class Entity>
typename Communications<Entity>::const_scheme_iterator
Communications<Entity>::end_scheme(const CommunicationSendRecv & sr) const {
return this->schemes[sr].end();
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::scheme_iterator
Communications<Entity>::begin_send_scheme() {
return this->begin_scheme(_send);
}
template <class Entity>
typename Communications<Entity>::scheme_iterator
Communications<Entity>::end_send_scheme() {
return this->end_scheme(_send);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::const_scheme_iterator
Communications<Entity>::begin_send_scheme() const {
return this->begin_scheme(_send);
}
template <class Entity>
typename Communications<Entity>::const_scheme_iterator
Communications<Entity>::end_send_scheme() const {
return this->end_scheme(_send);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::scheme_iterator
Communications<Entity>::begin_recv_scheme() {
return this->begin_scheme(_recv);
}
template <class Entity>
typename Communications<Entity>::scheme_iterator
Communications<Entity>::end_recv_scheme() {
return this->end_scheme(_recv);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::const_scheme_iterator
Communications<Entity>::begin_recv_scheme() const {
return this->begin_scheme(_recv);
}
template <class Entity>
typename Communications<Entity>::const_scheme_iterator
Communications<Entity>::end_recv_scheme() const {
return this->end_scheme(_recv);
}
/* ------------------------------------------------------------------------ */
template <class Entity>
bool Communications<Entity>::hasCommunication(
const SynchronizationTag & tag) const {
return (communications[_send].find(tag) != communications[_send].end());
}
template <class Entity>
void Communications<Entity>::incrementCounter(const SynchronizationTag & tag) {
auto it = comm_counter.find(tag);
if (it == comm_counter.end()) {
AKANTU_CUSTOM_EXCEPTION_INFO(
debug::CommunicationException(),
"No counter initialized in communications for the tags: " << tag);
}
++(it->second);
}
template <class Entity>
UInt Communications<Entity>::getCounter(const SynchronizationTag & tag) const {
auto it = comm_counter.find(tag);
if (it == comm_counter.end()) {
AKANTU_CUSTOM_EXCEPTION_INFO(
debug::CommunicationException(),
"No counter initialized in communications for the tags: " << tag);
}
return it->second;
}
template <class Entity>
bool Communications<Entity>::hasCommunicationSize(
const SynchronizationTag & tag) const {
auto it = comm_size_computed.find(tag);
if (it == comm_size_computed.end()) {
return false;
}
return it->second;
}
template <class Entity> void Communications<Entity>::invalidateSizes() {
for (auto && pair : comm_size_computed) {
pair.second = true;
}
}
template <class Entity>
bool Communications<Entity>::hasPendingRecv(
const SynchronizationTag & tag) const {
return this->hasPending(tag, _recv);
}
template <class Entity>
bool Communications<Entity>::hasPendingSend(
const SynchronizationTag & tag) const {
return this->hasPending(tag, _send);
}
template <class Entity>
const auto & Communications<Entity>::getCommunicator() const {
return communicator;
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::iterator
Communications<Entity>::waitAnyRecv(const SynchronizationTag & tag) {
return this->waitAny(tag, _recv);
}
template <class Entity>
typename Communications<Entity>::iterator
Communications<Entity>::waitAnySend(const SynchronizationTag & tag) {
return this->waitAny(tag, _send);
}
template <class Entity>
void Communications<Entity>::waitAllRecv(const SynchronizationTag & tag) {
this->waitAll(tag, _recv);
}
template <class Entity>
void Communications<Entity>::waitAllSend(const SynchronizationTag & tag) {
this->waitAll(tag, _send);
}
template <class Entity>
void Communications<Entity>::freeSendRequests(const SynchronizationTag & tag) {
this->freeRequests(tag, _send);
}
template <class Entity>
void Communications<Entity>::freeRecvRequests(const SynchronizationTag & tag) {
this->freeRequests(tag, _recv);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::Scheme &
Communications<Entity>::createSendScheme(UInt proc) {
return createScheme(proc, _send);
}
template <class Entity>
typename Communications<Entity>::Scheme &
Communications<Entity>::createRecvScheme(UInt proc) {
return createScheme(proc, _recv);
}
/* -------------------------------------------------------------------------- */
template <class Entity> void Communications<Entity>::resetSchemes() {
resetSchemes(_send);
resetSchemes(_recv);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
typename Communications<Entity>::Scheme &
Communications<Entity>::getScheme(UInt proc, const CommunicationSendRecv & sr) {
return this->schemes[sr].find(proc)->second;
}
/* -------------------------------------------------------------------------- */
template <class Entity>
const typename Communications<Entity>::Scheme &
Communications<Entity>::getScheme(UInt proc,
const CommunicationSendRecv & sr) const {
return this->schemes[sr].find(proc)->second;
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void Communications<Entity>::setSendCommunicationSize(
const SynchronizationTag & tag, UInt proc, UInt size) {
this->setCommunicationSize(tag, proc, size, _send);
}
template <class Entity>
void Communications<Entity>::setRecvCommunicationSize(
const SynchronizationTag & tag, UInt proc, UInt size) {
this->setCommunicationSize(tag, proc, size, _recv);
}
} // namespace akantu
#endif /* __AKANTU_COMMUNICATIONS_TMPL_HH__ */
diff --git a/src/synchronizer/communicator.cc b/src/synchronizer/communicator.cc
index 83102da56..ff8ae1f9a 100644
--- a/src/synchronizer/communicator.cc
+++ b/src/synchronizer/communicator.cc
@@ -1,180 +1,182 @@
/**
* @file static_communicator.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Jan 19 2016
*
* @brief implementation of the common part of the static communicator
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communicator.hh"
#if defined(AKANTU_USE_MPI)
#include "mpi_communicator_data.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
#if defined(AKANTU_USE_MPI)
int MPICommunicatorData::is_externaly_initialized = 0;
#endif
UInt InternalCommunicationRequest::counter = 0;
/* -------------------------------------------------------------------------- */
InternalCommunicationRequest::InternalCommunicationRequest(UInt source,
UInt dest)
: source(source), destination(dest) {
this->id = counter++;
}
/* -------------------------------------------------------------------------- */
InternalCommunicationRequest::~InternalCommunicationRequest() = default;
/* -------------------------------------------------------------------------- */
void InternalCommunicationRequest::printself(std::ostream & stream,
int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "CommunicationRequest [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + source : " << source << std::endl;
stream << space << " + destination : " << destination << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
Communicator::~Communicator() {
auto * event = new FinalizeCommunicatorEvent(*this);
this->sendEvent(*event);
delete event;
}
/* -------------------------------------------------------------------------- */
Communicator & Communicator::getStaticCommunicator() {
AKANTU_DEBUG_IN();
if (!static_communicator) {
int nb_args = 0;
char ** null = nullptr;
- static_communicator = std::make_unique<Communicator>(nb_args, null, private_member{});
+ static_communicator =
+ std::make_unique<Communicator>(nb_args, null, private_member{});
}
AKANTU_DEBUG_OUT();
return *static_communicator;
}
/* -------------------------------------------------------------------------- */
Communicator & Communicator::getStaticCommunicator(int & argc, char **& argv) {
if (!static_communicator)
- static_communicator = std::make_unique<Communicator>(argc, argv, private_member{});
+ static_communicator =
+ std::make_unique<Communicator>(argc, argv, private_member{});
return getStaticCommunicator();
}
} // namespace akantu
#ifdef AKANTU_USE_MPI
-# include "communicator_mpi_inline_impl.cc"
+#include "communicator_mpi_inline_impl.cc"
#else
-# include "communicator_dummy_inline_impl.cc"
+#include "communicator_dummy_inline_impl.cc"
#endif
namespace akantu {
/* -------------------------------------------------------------------------- */
/* Template instantiation */
/* -------------------------------------------------------------------------- */
#define AKANTU_COMM_INSTANTIATE(T) \
template void Communicator::probe<T>(Int sender, Int tag, \
CommunicationStatus & status) const; \
template bool Communicator::asyncProbe<T>( \
Int sender, Int tag, CommunicationStatus & status) const; \
template void Communicator::sendImpl<T>( \
- const T * buffer, Int size, Int receiver, Int tag, \
+ const T * buffer, Int size, Int receiver, Int tag, \
const CommunicationMode & mode) const; \
template void Communicator::receiveImpl<T>(T * buffer, Int size, Int sender, \
Int tag) const; \
template CommunicationRequest Communicator::asyncSendImpl<T>( \
- const T * buffer, Int size, Int receiver, Int tag, \
+ const T * buffer, Int size, Int receiver, Int tag, \
const CommunicationMode & mode) const; \
template CommunicationRequest Communicator::asyncReceiveImpl<T>( \
T * buffer, Int size, Int sender, Int tag) const; \
template void Communicator::allGatherImpl<T>(T * values, int nb_values) \
const; \
template void Communicator::allGatherVImpl<T>(T * values, int * nb_values) \
const; \
template void Communicator::gatherImpl<T>(T * values, int nb_values, \
int root) const; \
template void Communicator::gatherImpl<T>( \
T * values, int nb_values, T * gathered, int nb_gathered) const; \
template void Communicator::gatherVImpl<T>(T * values, int * nb_values, \
int root) const; \
template void Communicator::broadcastImpl<T>(T * values, int nb_values, \
int root) const; \
template void Communicator::allReduceImpl<T>( \
T * values, int nb_values, const SynchronizerOperation & op) const
#define MIN_MAX_REAL SCMinMaxLoc<Real, int>
AKANTU_COMM_INSTANTIATE(bool);
AKANTU_COMM_INSTANTIATE(Real);
AKANTU_COMM_INSTANTIATE(UInt);
AKANTU_COMM_INSTANTIATE(Int);
AKANTU_COMM_INSTANTIATE(char);
AKANTU_COMM_INSTANTIATE(NodeType);
AKANTU_COMM_INSTANTIATE(MIN_MAX_REAL);
#if AKANTU_INTEGER_SIZE > 4
AKANTU_COMM_INSTANTIATE(int);
#endif
// template void Communicator::send<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
// template void Communicator::receive<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
// template CommunicationRequest
// Communicator::asyncSend<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
// template CommunicationRequest
// Communicator::asyncReceive<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
// template void Communicator::probe<SCMinMaxLoc<Real, int>>(
// Int sender, Int tag, CommunicationStatus & status);
// template void Communicator::allGather<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * values, int nb_values);
// template void Communicator::allGatherV<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * values, int * nb_values);
// template void Communicator::gather<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * values, int nb_values, int root);
// template void Communicator::gatherV<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * values, int * nb_values, int root);
// template void Communicator::broadcast<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * values, int nb_values, int root);
// template void Communicator::allReduce<SCMinMaxLoc<Real, int>>(
// SCMinMaxLoc<Real, int> * values, int nb_values,
// const SynchronizerOperation & op);
} // akantu
diff --git a/src/synchronizer/communicator_dummy_inline_impl.cc b/src/synchronizer/communicator_dummy_inline_impl.cc
index 0899a534f..9b92a14fd 100644
--- a/src/synchronizer/communicator_dummy_inline_impl.cc
+++ b/src/synchronizer/communicator_dummy_inline_impl.cc
@@ -1,111 +1,118 @@
/**
* @file static_communicator_dummy.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Wed Jan 13 2016
*
* @brief Dummy communicator to make everything work im sequential
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <cstring>
#include <type_traits>
#include <vector>
/* -------------------------------------------------------------------------- */
namespace akantu {
Communicator::Communicator(int & /*argc*/, char **& /*argv*/,
const private_member & /*unused*/) {}
template <typename T>
void Communicator::sendImpl(const T *, Int, Int, Int,
const CommunicationMode &) const {}
template <typename T>
void Communicator::receiveImpl(T *, Int, Int, Int) const {}
template <typename T>
CommunicationRequest
Communicator::asyncSendImpl(const T *, Int, Int, Int,
const CommunicationMode &) const {
return std::shared_ptr<InternalCommunicationRequest>(
new InternalCommunicationRequest(0, 0));
}
template <typename T>
CommunicationRequest Communicator::asyncReceiveImpl(T *, Int, Int, Int) const {
return std::shared_ptr<InternalCommunicationRequest>(
new InternalCommunicationRequest(0, 0));
}
template <typename T>
void Communicator::probe(Int, Int, CommunicationStatus &) const {}
template <typename T>
-bool Communicator::asyncProbe(Int, Int, CommunicationStatus &) const { return true; }
+bool Communicator::asyncProbe(Int, Int, CommunicationStatus &) const {
+ return true;
+}
bool Communicator::test(CommunicationRequest &) const { return true; }
-bool Communicator::testAll(std::vector<CommunicationRequest> &) const { return true; }
+bool Communicator::testAll(std::vector<CommunicationRequest> &) const {
+ return true;
+}
void Communicator::wait(CommunicationRequest &) const {}
void Communicator::waitAll(std::vector<CommunicationRequest> &) const {}
UInt Communicator::waitAny(std::vector<CommunicationRequest> &) const {
return UInt(-1);
}
void Communicator::barrier() const {}
- CommunicationRequest Communicator::asyncBarrier() const { return std::shared_ptr<InternalCommunicationRequest>(new InternalCommunicationRequest(0, 0)); }
+CommunicationRequest Communicator::asyncBarrier() const {
+ return std::shared_ptr<InternalCommunicationRequest>(
+ new InternalCommunicationRequest(0, 0));
+}
template <typename T>
void Communicator::reduceImpl(T *, int, const SynchronizerOperation &,
int) const {}
template <typename T>
void Communicator::allReduceImpl(T *, int,
const SynchronizerOperation &) const {}
template <typename T> inline void Communicator::allGatherImpl(T *, int) const {}
template <typename T>
inline void Communicator::allGatherVImpl(T *, int *) const {}
template <typename T>
inline void Communicator::gatherImpl(T *, int, int) const {}
template <typename T>
void Communicator::gatherImpl(T * values, int nb_values, T * gathered,
int) const {
static_assert(std::is_trivially_copyable<T>{},
"Cannot send this type of data");
std::memcpy(gathered, values, nb_values);
}
template <typename T>
inline void Communicator::gatherVImpl(T *, int *, int) const {}
template <typename T>
inline void Communicator::broadcastImpl(T *, int, int) const {}
int Communicator::getMaxTag() const { return std::numeric_limits<int>::max(); }
int Communicator::getMinTag() const { return 0; }
} // namespace akantu
diff --git a/src/synchronizer/communicator_event_handler.hh b/src/synchronizer/communicator_event_handler.hh
index 981cc7501..9265521c7 100644
--- a/src/synchronizer/communicator_event_handler.hh
+++ b/src/synchronizer/communicator_event_handler.hh
@@ -1,59 +1,58 @@
/**
* @file communicator_event_handler.hh
*
* @author Nicolas Richart
*
* @date creation Wed Nov 15 2017
*
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_COMMUNICATOR_EVENT_HANDLER_HH__
#define __AKANTU_COMMUNICATOR_EVENT_HANDLER_HH__
namespace akantu {
class Communicator;
struct FinalizeCommunicatorEvent {
explicit FinalizeCommunicatorEvent(const Communicator & comm)
: communicator(comm) {}
const Communicator & communicator;
};
class CommunicatorEventHandler {
public:
virtual ~CommunicatorEventHandler() = default;
virtual void onCommunicatorFinalize() = 0;
private:
inline void sendEvent(const FinalizeCommunicatorEvent &) {
this->onCommunicatorFinalize();
}
template <class EventHandler> friend class EventHandlerManager;
};
-
-} // akantu
+} // akantu
#endif /* __AKANTU_COMMUNICATOR_EVENT_HANDLER_HH__ */
diff --git a/src/synchronizer/communicator_inline_impl.hh b/src/synchronizer/communicator_inline_impl.hh
index c7d036b92..3d669332b 100644
--- a/src/synchronizer/communicator_inline_impl.hh
+++ b/src/synchronizer/communicator_inline_impl.hh
@@ -1,89 +1,88 @@
/**
* @file static_communicator_inline_impl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Sep 06 2010
* @date last modification: Thu Dec 10 2015
*
* @brief implementation of inline functions
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STATIC_COMMUNICATOR_INLINE_IMPL_HH__
#define __AKANTU_STATIC_COMMUNICATOR_INLINE_IMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline void
Communicator::freeCommunicationRequest(CommunicationRequest & request) const {
request.free();
}
/* -------------------------------------------------------------------------- */
inline void Communicator::freeCommunicationRequest(
std::vector<CommunicationRequest> & requests) const {
std::vector<CommunicationRequest>::iterator it;
for (it = requests.begin(); it != requests.end(); ++it) {
it->free();
}
}
/* -------------------------------------------------------------------------- */
template <typename T, typename MsgProcessor, typename TagGen>
inline void Communicator::receiveAnyNumber(
std::vector<CommunicationRequest> & send_requests, Array<T> receive_buffer,
MsgProcessor && processor, TagGen && tag_gen) const {
CommunicationRequest barrier_request;
bool got_all = false, are_send_finished = false;
while (not got_all) {
bool are_receives_ready = true;
while (are_receives_ready) {
auto && tag = std::forward<TagGen>(tag_gen)();
CommunicationStatus status;
- are_receives_ready =
- asyncProbe<UInt>(_any_source, tag, status);
+ are_receives_ready = asyncProbe<UInt>(_any_source, tag, status);
if (are_receives_ready) {
receive_buffer.resize(status.size());
receive(receive_buffer, status.getSource(), tag);
std::forward<MsgProcessor>(processor)(status.getSource(),
receive_buffer);
}
}
if (not are_send_finished) {
are_send_finished = testAll(send_requests);
if (are_send_finished)
barrier_request = asyncBarrier();
}
if (are_send_finished) {
got_all = test(barrier_request);
}
}
}
} // namespace akantu
#endif /* __AKANTU_STATIC_COMMUNICATOR_INLINE_IMPL_HH__ */
diff --git a/src/synchronizer/communicator_mpi_inline_impl.cc b/src/synchronizer/communicator_mpi_inline_impl.cc
index 721acb925..9bd9fcf51 100644
--- a/src/synchronizer/communicator_mpi_inline_impl.cc
+++ b/src/synchronizer/communicator_mpi_inline_impl.cc
@@ -1,461 +1,460 @@
/**
* @file static_communicator_mpi.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 26 2010
* @date last modification: Thu Jan 21 2016
*
* @brief StaticCommunicatorMPI implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_iterators.hh"
#include "communicator.hh"
#include "mpi_communicator_data.hh"
/* -------------------------------------------------------------------------- */
+#include <memory>
#include <type_traits>
#include <unordered_map>
#include <vector>
-#include <memory>
/* -------------------------------------------------------------------------- */
#include <mpi.h>
/* -------------------------------------------------------------------------- */
#if (defined(__GNUC__) || defined(__GNUG__))
#if AKA_GCC_VERSION < 60000
namespace std {
template <> struct hash<akantu::SynchronizerOperation> {
using argument_type = akantu::SynchronizerOperation;
size_t operator()(const argument_type & e) const noexcept {
auto ue = underlying_type_t<argument_type>(e);
- return uh(ue);
- }
+ return uh(ue);
+ }
- private:
- const hash<underlying_type_t<argument_type>> uh{};
- };
+private:
+ const hash<underlying_type_t<argument_type>> uh{};
+};
} // namespace std
#endif
#endif
-
namespace akantu {
class CommunicationRequestMPI : public InternalCommunicationRequest {
public:
CommunicationRequestMPI(UInt source, UInt dest)
: InternalCommunicationRequest(source, dest),
request(std::make_unique<MPI_Request>()) {}
MPI_Request & getMPIRequest() { return *request; };
private:
std::unique_ptr<MPI_Request> request;
};
namespace {
template <typename T> inline MPI_Datatype getMPIDatatype();
MPI_Op getMPISynchronizerOperation(const SynchronizerOperation & op) {
std::unordered_map<SynchronizerOperation, MPI_Op> _operations{
{SynchronizerOperation::_sum, MPI_SUM},
{SynchronizerOperation::_min, MPI_MIN},
{SynchronizerOperation::_max, MPI_MAX},
{SynchronizerOperation::_prod, MPI_PROD},
{SynchronizerOperation::_land, MPI_LAND},
{SynchronizerOperation::_band, MPI_BAND},
{SynchronizerOperation::_lor, MPI_LOR},
{SynchronizerOperation::_bor, MPI_BOR},
{SynchronizerOperation::_lxor, MPI_LXOR},
{SynchronizerOperation::_bxor, MPI_BXOR},
{SynchronizerOperation::_min_loc, MPI_MINLOC},
{SynchronizerOperation::_max_loc, MPI_MAXLOC},
{SynchronizerOperation::_null, MPI_OP_NULL}};
return _operations[op];
}
template <typename T> MPI_Datatype inline getMPIDatatype() {
return MPI_DATATYPE_NULL;
}
#define SPECIALIZE_MPI_DATATYPE(type, mpi_type) \
template <> MPI_Datatype inline getMPIDatatype<type>() { return mpi_type; }
#define COMMA ,
SPECIALIZE_MPI_DATATYPE(char, MPI_CHAR)
SPECIALIZE_MPI_DATATYPE(float, MPI_FLOAT)
SPECIALIZE_MPI_DATATYPE(double, MPI_DOUBLE)
SPECIALIZE_MPI_DATATYPE(long double, MPI_LONG_DOUBLE)
SPECIALIZE_MPI_DATATYPE(signed int, MPI_INT)
SPECIALIZE_MPI_DATATYPE(NodeType, getMPIDatatype<Int>())
SPECIALIZE_MPI_DATATYPE(unsigned int, MPI_UNSIGNED)
SPECIALIZE_MPI_DATATYPE(signed long int, MPI_LONG)
SPECIALIZE_MPI_DATATYPE(unsigned long int, MPI_UNSIGNED_LONG)
SPECIALIZE_MPI_DATATYPE(signed long long int, MPI_LONG_LONG)
SPECIALIZE_MPI_DATATYPE(unsigned long long int, MPI_UNSIGNED_LONG_LONG)
SPECIALIZE_MPI_DATATYPE(SCMinMaxLoc<double COMMA int>, MPI_DOUBLE_INT)
SPECIALIZE_MPI_DATATYPE(SCMinMaxLoc<float COMMA int>, MPI_FLOAT_INT)
SPECIALIZE_MPI_DATATYPE(bool, MPI_CXX_BOOL)
inline int getMPISource(int src) {
if (src == _any_source)
return MPI_ANY_SOURCE;
return src;
}
decltype(auto) convertRequests(std::vector<CommunicationRequest> & requests) {
std::vector<MPI_Request> mpi_requests(requests.size());
for (auto && request_pair : zip(requests, mpi_requests)) {
auto && req = std::get<0>(request_pair);
auto && mpi_req = std::get<1>(request_pair);
mpi_req = dynamic_cast<CommunicationRequestMPI &>(req.getInternal())
.getMPIRequest();
}
return mpi_requests;
}
} // namespace
// this is ugly but shorten the code a lot
#define MPIDATA \
(*reinterpret_cast<MPICommunicatorData *>(communicator_data.get()))
/* -------------------------------------------------------------------------- */
/* Implementation */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Communicator::Communicator(int & /*argc*/, char **& /*argv*/,
const private_member & /*unused*/)
: communicator_data(std::make_unique<MPICommunicatorData>()) {
prank = MPIDATA.rank();
psize = MPIDATA.size();
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::sendImpl(const T * buffer, Int size, Int receiver, Int tag,
const CommunicationMode & mode) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Datatype type = getMPIDatatype<T>();
switch (mode) {
case CommunicationMode::_auto:
MPI_Send(buffer, size, type, receiver, tag, communicator);
break;
case CommunicationMode::_synchronous:
MPI_Ssend(buffer, size, type, receiver, tag, communicator);
break;
case CommunicationMode::_ready:
MPI_Rsend(buffer, size, type, receiver, tag, communicator);
break;
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::receiveImpl(T * buffer, Int size, Int sender,
Int tag) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Status status;
MPI_Datatype type = getMPIDatatype<T>();
MPI_Recv(buffer, size, type, getMPISource(sender), tag, communicator,
&status);
}
/* -------------------------------------------------------------------------- */
template <typename T>
CommunicationRequest
Communicator::asyncSendImpl(const T * buffer, Int size, Int receiver, Int tag,
const CommunicationMode & mode) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
auto * request = new CommunicationRequestMPI(prank, receiver);
MPI_Request & req = request->getMPIRequest();
MPI_Datatype type = getMPIDatatype<T>();
switch (mode) {
case CommunicationMode::_auto:
MPI_Isend(buffer, size, type, receiver, tag, communicator, &req);
break;
case CommunicationMode::_synchronous:
MPI_Issend(buffer, size, type, receiver, tag, communicator, &req);
break;
case CommunicationMode::_ready:
MPI_Irsend(buffer, size, type, receiver, tag, communicator, &req);
break;
}
return std::shared_ptr<InternalCommunicationRequest>(request);
}
/* -------------------------------------------------------------------------- */
template <typename T>
CommunicationRequest Communicator::asyncReceiveImpl(T * buffer, Int size,
Int sender, Int tag) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
auto * request = new CommunicationRequestMPI(sender, prank);
MPI_Datatype type = getMPIDatatype<T>();
MPI_Request & req = request->getMPIRequest();
MPI_Irecv(buffer, size, type, getMPISource(sender), tag, communicator, &req);
return std::shared_ptr<InternalCommunicationRequest>(request);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::probe(Int sender, Int tag,
CommunicationStatus & status) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Status mpi_status;
MPI_Probe(getMPISource(sender), tag, communicator, &mpi_status);
MPI_Datatype type = getMPIDatatype<T>();
int count;
MPI_Get_count(&mpi_status, type, &count);
status.setSource(mpi_status.MPI_SOURCE);
status.setTag(mpi_status.MPI_TAG);
status.setSize(count);
}
/* -------------------------------------------------------------------------- */
template <typename T>
bool Communicator::asyncProbe(Int sender, Int tag,
CommunicationStatus & status) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Status mpi_status;
int test;
MPI_Iprobe(getMPISource(sender), tag, communicator, &test, &mpi_status);
if (not test)
return false;
MPI_Datatype type = getMPIDatatype<T>();
int count;
MPI_Get_count(&mpi_status, type, &count);
status.setSource(mpi_status.MPI_SOURCE);
status.setTag(mpi_status.MPI_TAG);
status.setSize(count);
return true;
}
/* -------------------------------------------------------------------------- */
bool Communicator::test(CommunicationRequest & request) const {
MPI_Status status;
int flag;
auto & req_mpi =
dynamic_cast<CommunicationRequestMPI &>(request.getInternal());
MPI_Request & req = req_mpi.getMPIRequest();
#if !defined(AKANTU_NDEBUG)
int ret =
#endif
MPI_Test(&req, &flag, &status);
AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Test.");
return (flag != 0);
}
/* -------------------------------------------------------------------------- */
bool Communicator::testAll(std::vector<CommunicationRequest> & requests) const {
int are_finished;
auto && mpi_requests = convertRequests(requests);
MPI_Testall(mpi_requests.size(), mpi_requests.data(), &are_finished,
MPI_STATUSES_IGNORE);
return are_finished != 0 ? true : false;
}
/* -------------------------------------------------------------------------- */
void Communicator::wait(CommunicationRequest & request) const {
MPI_Status status;
auto & req_mpi =
dynamic_cast<CommunicationRequestMPI &>(request.getInternal());
MPI_Request & req = req_mpi.getMPIRequest();
MPI_Wait(&req, &status);
}
/* -------------------------------------------------------------------------- */
void Communicator::waitAll(std::vector<CommunicationRequest> & requests) const {
auto && mpi_requests = convertRequests(requests);
MPI_Waitall(mpi_requests.size(), mpi_requests.data(), MPI_STATUSES_IGNORE);
}
/* -------------------------------------------------------------------------- */
UInt Communicator::waitAny(std::vector<CommunicationRequest> & requests) const {
auto && mpi_requests = convertRequests(requests);
int pos;
MPI_Waitany(mpi_requests.size(), mpi_requests.data(), &pos,
MPI_STATUSES_IGNORE);
if (pos != MPI_UNDEFINED) {
return pos;
} else {
return UInt(-1);
}
}
/* -------------------------------------------------------------------------- */
void Communicator::barrier() const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Barrier(communicator);
}
/* -------------------------------------------------------------------------- */
CommunicationRequest Communicator::asyncBarrier() const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
auto * request = new CommunicationRequestMPI(0, 0);
MPI_Request & req = request->getMPIRequest();
MPI_Ibarrier(communicator, &req);
return std::shared_ptr<InternalCommunicationRequest>(request);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::reduceImpl(T * values, int nb_values,
const SynchronizerOperation & op,
int root) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Datatype type = getMPIDatatype<T>();
MPI_Reduce(MPI_IN_PLACE, values, nb_values, type,
getMPISynchronizerOperation(op), root, communicator);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::allReduceImpl(T * values, int nb_values,
const SynchronizerOperation & op) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Datatype type = getMPIDatatype<T>();
MPI_Allreduce(MPI_IN_PLACE, values, nb_values, type,
getMPISynchronizerOperation(op), communicator);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::allGatherImpl(T * values, int nb_values) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Datatype type = getMPIDatatype<T>();
MPI_Allgather(MPI_IN_PLACE, nb_values, type, values, nb_values, type,
communicator);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::allGatherVImpl(T * values, int * nb_values) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
std::vector<int> displs(psize);
displs[0] = 0;
for (int i = 1; i < psize; ++i) {
displs[i] = displs[i - 1] + nb_values[i - 1];
}
MPI_Datatype type = getMPIDatatype<T>();
MPI_Allgatherv(MPI_IN_PLACE, *nb_values, type, values, nb_values,
displs.data(), type, communicator);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::gatherImpl(T * values, int nb_values, int root) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
T *send_buf = nullptr, *recv_buf = nullptr;
if (prank == root) {
send_buf = (T *)MPI_IN_PLACE;
recv_buf = values;
} else {
send_buf = values;
}
MPI_Datatype type = getMPIDatatype<T>();
MPI_Gather(send_buf, nb_values, type, recv_buf, nb_values, type, root,
communicator);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::gatherImpl(T * values, int nb_values, T * gathered,
int nb_gathered) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
T * send_buf = values;
T * recv_buf = gathered;
if (nb_gathered == 0)
nb_gathered = nb_values;
MPI_Datatype type = getMPIDatatype<T>();
MPI_Gather(send_buf, nb_values, type, recv_buf, nb_gathered, type,
this->prank, communicator);
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::gatherVImpl(T * values, int * nb_values, int root) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
int * displs = nullptr;
if (prank == root) {
displs = new int[psize];
displs[0] = 0;
for (int i = 1; i < psize; ++i) {
displs[i] = displs[i - 1] + nb_values[i - 1];
}
}
T *send_buf = nullptr, *recv_buf = nullptr;
if (prank == root) {
send_buf = (T *)MPI_IN_PLACE;
recv_buf = values;
} else
send_buf = values;
MPI_Datatype type = getMPIDatatype<T>();
MPI_Gatherv(send_buf, *nb_values, type, recv_buf, nb_values, displs, type,
root, communicator);
if (prank == root) {
delete[] displs;
}
}
/* -------------------------------------------------------------------------- */
template <typename T>
void Communicator::broadcastImpl(T * values, int nb_values, int root) const {
MPI_Comm communicator = MPIDATA.getMPICommunicator();
MPI_Datatype type = getMPIDatatype<T>();
MPI_Bcast(values, nb_values, type, root, communicator);
}
/* -------------------------------------------------------------------------- */
int Communicator::getMaxTag() const { return MPIDATA.getMaxTag(); }
int Communicator::getMinTag() const { return 0; }
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/synchronizer/dof_synchronizer.cc b/src/synchronizer/dof_synchronizer.cc
index bfaa087d2..944332113 100644
--- a/src/synchronizer/dof_synchronizer.cc
+++ b/src/synchronizer/dof_synchronizer.cc
@@ -1,280 +1,280 @@
/**
* @file dof_synchronizer.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
* @date last modification: Wed Oct 21 2015
*
* @brief DOF synchronizing object implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dof_synchronizer.hh"
#include "aka_iterators.hh"
#include "dof_manager_default.hh"
#include "mesh.hh"
#include "node_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
/**
* A DOFSynchronizer needs a mesh and the number of degrees of freedom
* per node to be created. In the constructor computes the local and global dof
* number for each dof. The member
* proc_informations (std vector) is resized with the number of mpi
* processes. Each entry in the vector is a PerProcInformations object
* that contains the interactions of the current mpi process (prank) with the
* mpi process corresponding to the position of that entry. Every
* ProcInformations object contains one array with the dofs that have
* to be sent to prank and a second one with dofs that willl be received form
* prank.
* This information is needed for the asychronous communications. The
* constructor sets up this information.
*/
DOFSynchronizer::DOFSynchronizer(DOFManagerDefault & dof_manager, const ID & id,
MemoryID memory_id)
- : SynchronizerImpl<UInt>(dof_manager.getCommunicator(), id, memory_id), root(0),
- dof_manager(dof_manager), root_dofs(0, 1, "dofs-to-receive-from-master"),
- dof_changed(true) {
+ : SynchronizerImpl<UInt>(dof_manager.getCommunicator(), id, memory_id),
+ root(0), dof_manager(dof_manager),
+ root_dofs(0, 1, "dofs-to-receive-from-master"), dof_changed(true) {
std::vector<ID> dof_ids = dof_manager.getDOFIDs();
// Transfers nodes to global equation numbers in new schemes
for (const ID & dof_id : dof_ids) {
registerDOFs(dof_id);
}
this->initScatterGatherCommunicationScheme();
}
/* -------------------------------------------------------------------------- */
DOFSynchronizer::~DOFSynchronizer() = default;
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::registerDOFs(const ID & dof_id) {
if (this->nb_proc == 1)
return;
if (dof_manager.getSupportType(dof_id) != _dst_nodal)
return;
using const_scheme_iterator = Communications<UInt>::const_scheme_iterator;
const auto equation_numbers = dof_manager.getLocalEquationNumbers(dof_id);
const auto & associated_nodes = dof_manager.getDOFsAssociatedNodes(dof_id);
const auto & node_synchronizer = dof_manager.getMesh().getNodeSynchronizer();
const auto & node_communications = node_synchronizer.getCommunications();
auto transcode_node_to_global_dof_scheme =
[this, &associated_nodes,
&equation_numbers](const_scheme_iterator it, const_scheme_iterator end,
const CommunicationSendRecv & sr) -> void {
for (; it != end; ++it) {
auto & scheme = communications.createScheme(it->first, sr);
const auto & node_scheme = it->second;
for (auto & node : node_scheme) {
auto an_begin = associated_nodes.begin();
auto an_it = an_begin;
auto an_end = associated_nodes.end();
std::vector<UInt> global_dofs_per_node;
while ((an_it = std::find(an_it, an_end, node)) != an_end) {
UInt pos = an_it - an_begin;
UInt local_eq_num = equation_numbers(pos);
UInt global_eq_num =
dof_manager.localToGlobalEquationNumber(local_eq_num);
global_dofs_per_node.push_back(global_eq_num);
++an_it;
}
std::sort(global_dofs_per_node.begin(), global_dofs_per_node.end());
std::transform(global_dofs_per_node.begin(), global_dofs_per_node.end(),
global_dofs_per_node.begin(), [this](UInt g) -> UInt {
UInt l = dof_manager.globalToLocalEquationNumber(g);
return l;
});
for (auto & leqnum : global_dofs_per_node) {
scheme.push_back(leqnum);
}
}
}
};
for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
++sr_it) {
auto ncs_it = node_communications.begin_scheme(*sr_it);
auto ncs_end = node_communications.end_scheme(*sr_it);
transcode_node_to_global_dof_scheme(ncs_it, ncs_end, *sr_it);
}
dof_changed = true;
}
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::initScatterGatherCommunicationScheme() {
AKANTU_DEBUG_IN();
if (this->nb_proc == 1) {
dof_changed = false;
AKANTU_DEBUG_OUT();
return;
}
UInt nb_dofs = dof_manager.getLocalSystemSize();
this->root_dofs.clear();
this->master_receive_dofs.clear();
Array<UInt> dofs_to_send;
for (UInt n = 0; n < nb_dofs; ++n) {
if (dof_manager.isLocalOrMasterDOF(n)) {
auto & receive_per_proc = master_receive_dofs[this->root];
UInt global_dof = dof_manager.localToGlobalEquationNumber(n);
root_dofs.push_back(n);
receive_per_proc.push_back(global_dof);
dofs_to_send.push_back(global_dof);
}
}
if (this->rank == UInt(this->root)) {
Array<UInt> nb_dof_per_proc(this->nb_proc);
communicator.gather(dofs_to_send.size(), nb_dof_per_proc);
std::vector<CommunicationRequest> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if (p == UInt(this->root))
continue;
auto & receive_per_proc = master_receive_dofs[p];
receive_per_proc.resize(nb_dof_per_proc(p));
if (nb_dof_per_proc(p) != 0)
requests.push_back(communicator.asyncReceive(
receive_per_proc, p,
Tag::genTag(p, 0, Tag::_GATHER_INITIALIZATION, this->hash_id)));
}
communicator.waitAll(requests);
communicator.freeCommunicationRequest(requests);
} else {
communicator.gather(dofs_to_send.size(), this->root);
- AKANTU_DEBUG(dblDebug, "I have " << nb_dofs << " dofs ("
- << dofs_to_send.size()
- << " to send to master proc");
+ AKANTU_DEBUG(dblDebug,
+ "I have " << nb_dofs << " dofs (" << dofs_to_send.size()
+ << " to send to master proc");
if (dofs_to_send.size() != 0)
communicator.send(dofs_to_send, this->root,
Tag::genTag(this->rank, 0, Tag::_GATHER_INITIALIZATION,
this->hash_id));
}
dof_changed = false;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
bool DOFSynchronizer::hasChanged() {
communicator.allReduce(dof_changed, SynchronizerOperation::_lor);
return dof_changed;
}
/* -------------------------------------------------------------------------- */
void DOFSynchronizer::onNodesAdded(const Array<UInt> & nodes_list) {
auto dof_ids = dof_manager.getDOFIDs();
const auto & node_synchronizer = dof_manager.getMesh().getNodeSynchronizer();
const auto & node_communications = node_synchronizer.getCommunications();
std::set<UInt> relevant_nodes;
std::map<UInt, std::vector<UInt>> nodes_per_proc[2];
for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
++sr_it) {
auto sit = node_communications.begin_scheme(*sr_it);
auto send = node_communications.end_scheme(*sr_it);
for (; sit != send; ++sit) {
auto proc = sit->first;
const auto & scheme = sit->second;
for (auto node : nodes_list) {
if (scheme.find(node) == UInt(-1))
continue;
relevant_nodes.insert(node);
nodes_per_proc[*sr_it][proc].push_back(node);
}
}
}
std::map<UInt, std::vector<UInt>> dofs_per_proc[2];
for (auto & dof_id : dof_ids) {
const auto & associated_nodes = dof_manager.getDOFsAssociatedNodes(dof_id);
const auto & local_equation_numbers =
dof_manager.getEquationsNumbers(dof_id);
for (auto tuple : zip(associated_nodes, local_equation_numbers)) {
UInt assoc_node;
UInt local_eq_num;
std::tie(assoc_node, local_eq_num) = tuple;
for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
++sr_it) {
for (auto & pair : nodes_per_proc[*sr_it]) {
if (std::find(pair.second.end(), pair.second.end(), assoc_node) !=
pair.second.end()) {
dofs_per_proc[*sr_it][pair.first].push_back(local_eq_num);
}
}
}
}
}
for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
- ++sr_it) {
+ ++sr_it) {
for (auto & pair : dofs_per_proc[*sr_it]) {
std::sort(pair.second.begin(), pair.second.end(),
- [this] (UInt la, UInt lb) -> bool {
+ [this](UInt la, UInt lb) -> bool {
UInt ga = dof_manager.localToGlobalEquationNumber(la);
UInt gb = dof_manager.localToGlobalEquationNumber(lb);
return ga < gb;
});
auto & scheme = communications.getScheme(pair.first, *sr_it);
- for(auto leq : pair.second) {
+ for (auto leq : pair.second) {
scheme.push_back(leq);
}
}
}
dof_changed = true;
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/synchronizer/dof_synchronizer.hh b/src/synchronizer/dof_synchronizer.hh
index 386d2cb7f..8fbd31a28 100644
--- a/src/synchronizer/dof_synchronizer.hh
+++ b/src/synchronizer/dof_synchronizer.hh
@@ -1,115 +1,112 @@
/**
* @file dof_synchronizer.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
* @date last modification: Tue Dec 08 2015
*
* @brief Synchronize Array of DOFs
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "aka_common.hh"
#include "synchronizer_impl.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class Mesh;
class DOFManagerDefault;
}
#ifndef __AKANTU_DOF_SYNCHRONIZER_HH__
#define __AKANTU_DOF_SYNCHRONIZER_HH__
namespace akantu {
class DOFSynchronizer : public SynchronizerImpl<UInt> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- DOFSynchronizer(
- DOFManagerDefault & dof_manager, const ID & id = "dof_synchronizer",
- MemoryID memory_id = 0);
+ DOFSynchronizer(DOFManagerDefault & dof_manager,
+ const ID & id = "dof_synchronizer", MemoryID memory_id = 0);
~DOFSynchronizer() override;
virtual void registerDOFs(const ID & dof_id);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template <typename T>
/// Gather the DOF value on the root proccessor
void gather(const Array<T> & to_gather, Array<T> & gathered);
/// Gather the DOF value on the root proccessor
template <typename T> void gather(const Array<T> & to_gather);
/// Scatter a DOF Array form root to all processors
template <typename T>
void scatter(Array<T> & scattered, const Array<T> & to_scatter);
/// Scatter a DOF Array form root to all processors
template <typename T> void scatter(Array<T> & scattered);
template <typename T> void synchronize(Array<T> & vector) const;
template <template <class> class Op, typename T>
void reduceSynchronize(Array<T> & vector) const;
void onNodesAdded(const Array<UInt> & nodes);
protected:
/// check if dof changed set on at least one processor
bool hasChanged();
/// init the scheme for scatter and gather operation, need extra memory
void initScatterGatherCommunicationScheme();
- Int getRank(const UInt & /*node*/) const final {
- AKANTU_TO_IMPLEMENT();
- }
+ Int getRank(const UInt & /*node*/) const final { AKANTU_TO_IMPLEMENT(); }
private:
/// Root processor for scatter/gather operations
Int root;
/// information on the dofs
DOFManagerDefault & dof_manager;
/// dofs from root
Array<UInt> root_dofs;
/// Dofs received from slaves proc (only on master)
std::map<UInt, Array<UInt>> master_receive_dofs;
bool dof_changed;
};
} // akantu
#include "dof_synchronizer_inline_impl.cc"
#endif /* __AKANTU_DOF_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/dof_synchronizer_inline_impl.cc b/src/synchronizer/dof_synchronizer_inline_impl.cc
index 182863dfc..9165512ca 100644
--- a/src/synchronizer/dof_synchronizer_inline_impl.cc
+++ b/src/synchronizer/dof_synchronizer_inline_impl.cc
@@ -1,300 +1,298 @@
/**
* @file dof_synchronizer_inline_impl.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
* @date last modification: Tue Dec 09 2014
*
* @brief DOFSynchronizer inline implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "communication_buffer.hh"
#include "data_accessor.hh"
#include "dof_manager_default.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DOF_SYNCHRONIZER_INLINE_IMPL_CC__
#define __AKANTU_DOF_SYNCHRONIZER_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename T>
void DOFSynchronizer::gather(const Array<T> & to_gather, Array<T> & gathered) {
if (this->hasChanged())
initScatterGatherCommunicationScheme();
AKANTU_DEBUG_ASSERT(this->rank == UInt(this->root),
"This function cannot be called on a slave processor");
AKANTU_DEBUG_ASSERT(to_gather.size() ==
this->dof_manager.getLocalSystemSize(),
"The array to gather does not have the correct size");
AKANTU_DEBUG_ASSERT(gathered.size() == this->dof_manager.getSystemSize(),
"The gathered array does not have the correct size");
if (this->nb_proc == 1) {
gathered.copy(to_gather, true);
AKANTU_DEBUG_OUT();
return;
}
std::map<UInt, CommunicationBuffer> buffers;
std::vector<CommunicationRequest> requests;
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p == UInt(this->root))
continue;
auto receive_it = this->master_receive_dofs.find(p);
AKANTU_DEBUG_ASSERT(receive_it != this->master_receive_dofs.end(),
"Could not find the receive list for dofs of proc "
<< p);
const Array<UInt> & receive_dofs = receive_it->second;
if (receive_dofs.size() == 0)
continue;
CommunicationBuffer & buffer = buffers[p];
- buffer.resize(receive_dofs.size() * to_gather.getNbComponent() *
- sizeof(T));
+ buffer.resize(receive_dofs.size() * to_gather.getNbComponent() * sizeof(T));
AKANTU_DEBUG_INFO(
"Preparing to receive data for "
<< receive_dofs.size() << " dofs from processor " << p << " "
<< Tag::genTag(p, this->root, Tag::_GATHER, this->hash_id));
requests.push_back(communicator.asyncReceive(
buffer, p, Tag::genTag(p, this->root, Tag::_GATHER, this->hash_id)));
}
auto data_gathered_it = gathered.begin(to_gather.getNbComponent());
{ // copy master data
auto data_to_gather_it = to_gather.begin(to_gather.getNbComponent());
for (auto local_dof : root_dofs) {
UInt global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
Vector<T> dof_data_gathered = data_gathered_it[global_dof];
Vector<T> dof_data_to_gather = data_to_gather_it[local_dof];
dof_data_gathered = dof_data_to_gather;
}
}
auto rr = UInt(-1);
while ((rr = communicator.waitAny(requests)) != UInt(-1)) {
CommunicationRequest & request = requests[rr];
UInt sender = request.getSource();
AKANTU_DEBUG_ASSERT(this->master_receive_dofs.find(sender) !=
this->master_receive_dofs.end() &&
buffers.find(sender) != buffers.end(),
"Missing infos concerning proc " << sender);
const Array<UInt> & receive_dofs =
this->master_receive_dofs.find(sender)->second;
CommunicationBuffer & buffer = buffers[sender];
for (auto global_dof : receive_dofs) {
Vector<T> dof_data = data_gathered_it[global_dof];
buffer >> dof_data;
}
requests.erase(requests.begin() + rr);
}
}
/* -------------------------------------------------------------------------- */
template <typename T> void DOFSynchronizer::gather(const Array<T> & to_gather) {
AKANTU_DEBUG_IN();
if (this->hasChanged())
initScatterGatherCommunicationScheme();
AKANTU_DEBUG_ASSERT(this->rank != UInt(this->root),
"This function cannot be called on the root processor");
AKANTU_DEBUG_ASSERT(to_gather.size() ==
this->dof_manager.getLocalSystemSize(),
"The array to gather does not have the correct size");
if (this->root_dofs.size() == 0) {
AKANTU_DEBUG_OUT();
return;
}
CommunicationBuffer buffer(this->root_dofs.size() *
to_gather.getNbComponent() * sizeof(T));
auto data_it = to_gather.begin(to_gather.getNbComponent());
for (auto dof : this->root_dofs) {
Vector<T> data = data_it[dof];
buffer << data;
}
AKANTU_DEBUG_INFO("Gathering data for "
- << to_gather.size() << " dofs on processor "
- << this->root << " "
+ << to_gather.size() << " dofs on processor " << this->root
+ << " "
<< Tag::genTag(this->rank, 0, Tag::_GATHER, this->hash_id));
communicator.send(buffer, this->root,
Tag::genTag(this->rank, 0, Tag::_GATHER, this->hash_id));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T>
void DOFSynchronizer::scatter(Array<T> & scattered,
const Array<T> & to_scatter) {
AKANTU_DEBUG_IN();
if (this->hasChanged())
initScatterGatherCommunicationScheme();
AKANTU_DEBUG_ASSERT(this->rank == UInt(this->root),
"This function cannot be called on a slave processor");
AKANTU_DEBUG_ASSERT(scattered.size() ==
this->dof_manager.getLocalSystemSize(),
"The scattered array does not have the correct size");
AKANTU_DEBUG_ASSERT(to_scatter.size() == this->dof_manager.getSystemSize(),
"The array to scatter does not have the correct size");
if (this->nb_proc == 1) {
scattered.copy(to_scatter, true);
AKANTU_DEBUG_OUT();
return;
}
std::map<UInt, CommunicationBuffer> buffers;
std::vector<CommunicationRequest> requests;
for (UInt p = 0; p < nb_proc; ++p) {
auto data_to_scatter_it = to_scatter.begin(to_scatter.getNbComponent());
if (p == this->rank) {
auto data_scattered_it = scattered.begin(to_scatter.getNbComponent());
// copy the data for the local processor
for (auto local_dof : root_dofs) {
auto global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
Vector<T> dof_data_to_scatter = data_to_scatter_it[global_dof];
Vector<T> dof_data_scattered = data_scattered_it[local_dof];
dof_data_scattered = dof_data_to_scatter;
}
continue;
}
const Array<UInt> & receive_dofs =
this->master_receive_dofs.find(p)->second;
// prepare the send buffer
CommunicationBuffer & buffer = buffers[p];
- buffer.resize(receive_dofs.size() * scattered.getNbComponent() *
- sizeof(T));
+ buffer.resize(receive_dofs.size() * scattered.getNbComponent() * sizeof(T));
// pack the data
for (auto global_dof : receive_dofs) {
Vector<T> dof_data_to_scatter = data_to_scatter_it[global_dof];
buffer << dof_data_to_scatter;
}
// send the data
requests.push_back(communicator.asyncSend(
buffer, p, Tag::genTag(p, 0, Tag::_SCATTER, this->hash_id)));
}
// wait a clean communications
communicator.waitAll(requests);
communicator.freeCommunicationRequest(requests);
// synchronize slave and ghost nodes
synchronize(scattered);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T> void DOFSynchronizer::scatter(Array<T> & scattered) {
AKANTU_DEBUG_IN();
if (this->hasChanged())
this->initScatterGatherCommunicationScheme();
AKANTU_DEBUG_ASSERT(this->rank != UInt(this->root),
"This function cannot be called on the root processor");
AKANTU_DEBUG_ASSERT(scattered.size() ==
this->dof_manager.getLocalSystemSize(),
"The scattered array does not have the correct size");
// prepare the data
auto data_scattered_it = scattered.begin(scattered.getNbComponent());
CommunicationBuffer buffer(this->root_dofs.size() *
scattered.getNbComponent() * sizeof(T));
// receive the data
communicator.receive(
buffer, this->root,
Tag::genTag(this->rank, 0, Tag::_SCATTER, this->hash_id));
// unpack the data
for (auto local_dof : root_dofs) {
Vector<T> dof_data_scattered = data_scattered_it[local_dof];
buffer >> dof_data_scattered;
}
// synchronize the ghosts
synchronize(scattered);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T>
void DOFSynchronizer::synchronize(Array<T> & dof_values_to_synchronize) const {
AKANTU_DEBUG_IN();
SimpleUIntDataAccessor<T> data_accessor(dof_values_to_synchronize,
_gst_whatever);
this->synchronizeOnce(data_accessor, _gst_whatever);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <template <class> class Op, typename T>
void DOFSynchronizer::reduceSynchronize(Array<T> & dof_vector) const {
AKANTU_DEBUG_IN();
ReduceUIntDataAccessor<Op, T> data_accessor(dof_vector, _gst_whatever);
this->synchronizeOnce(data_accessor, _gst_whatever);
AKANTU_DEBUG_OUT();
}
} // akantu
#endif /* __AKANTU_DOF_SYNCHRONIZER_INLINE_IMPL_CC__ */
diff --git a/src/synchronizer/element_info_per_processor.cc b/src/synchronizer/element_info_per_processor.cc
index 547888ff0..a1ae4e5a4 100644
--- a/src/synchronizer/element_info_per_processor.cc
+++ b/src/synchronizer/element_info_per_processor.cc
@@ -1,109 +1,109 @@
/**
* @file element_info_per_processor.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Mar 11 14:56:42 2016
*
* @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_info_per_processor.hh"
-#include "element_synchronizer.hh"
#include "communicator.hh"
+#include "element_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <iostream>
#include <map>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
ElementInfoPerProc::ElementInfoPerProc(ElementSynchronizer & synchronizer,
UInt message_cnt, UInt root,
ElementType type)
: MeshAccessor(synchronizer.getMesh()), synchronizer(synchronizer),
rank(synchronizer.getCommunicator().whoAmI()),
nb_proc(synchronizer.getCommunicator().getNbProc()), root(root),
type(type), message_count(message_cnt), mesh(synchronizer.getMesh()),
comm(synchronizer.getCommunicator()) {}
/* -------------------------------------------------------------------------- */
void ElementInfoPerProc::fillCommunicationScheme(
const Array<UInt> & partition) {
AKANTU_DEBUG_IN();
Element element;
element.type = this->type;
auto & communications = this->synchronizer.getCommunications();
auto part = partition.begin();
std::map<UInt, Array<Element>> send_array_per_proc;
for (UInt lel = 0; lel < nb_local_element; ++lel) {
UInt nb_send = *part;
++part;
element.element = lel;
element.ghost_type = _not_ghost;
for (UInt p = 0; p < nb_send; ++p, ++part) {
UInt proc = *part;
AKANTU_DEBUG(dblAccessory,
"Must send : " << element << " to proc " << proc);
send_array_per_proc[proc].push_back(element);
}
}
for (auto & send_schemes : send_array_per_proc) {
if (send_schemes.second.size() == 0)
continue;
auto & scheme = communications.createSendScheme(send_schemes.first);
scheme.append(send_schemes.second);
}
std::map<UInt, Array<Element>> recv_array_per_proc;
for (UInt gel = 0; gel < nb_ghost_element; ++gel, ++part) {
UInt proc = *part;
element.element = gel;
element.ghost_type = _ghost;
AKANTU_DEBUG(dblAccessory,
"Must recv : " << element << " from proc " << proc);
recv_array_per_proc[proc].push_back(element);
}
for (auto & recv_schemes : recv_array_per_proc) {
if (recv_schemes.second.size() == 0)
continue;
auto & scheme = communications.createRecvScheme(recv_schemes.first);
scheme.append(recv_schemes.second);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/synchronizer/element_info_per_processor_tmpl.hh b/src/synchronizer/element_info_per_processor_tmpl.hh
index 0ad6bf8f1..299a61f4a 100644
--- a/src/synchronizer/element_info_per_processor_tmpl.hh
+++ b/src/synchronizer/element_info_per_processor_tmpl.hh
@@ -1,146 +1,145 @@
/**
* @file element_info_per_processor_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Mar 11 15:03:12 2016
*
* @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_group.hh"
#include "element_info_per_processor.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_INFO_PER_PROCESSOR_TMPL_HH__
#define __AKANTU_ELEMENT_INFO_PER_PROCESSOR_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename T, typename BufferType>
void ElementInfoPerProc::fillMeshDataTemplated(BufferType & buffer,
const std::string & tag_name,
UInt nb_component) {
AKANTU_DEBUG_ASSERT(this->mesh.getNbElement(this->type) == nb_local_element,
"Did not got enought informations for the tag "
<< tag_name << " and the element type " << this->type
<< ":"
<< "_not_ghost."
<< " Got " << nb_local_element << " values, expected "
<< mesh.getNbElement(this->type));
MeshData & mesh_data = this->getMeshData();
mesh_data.registerElementalData<T>(tag_name);
Array<T> & data = mesh_data.getElementalDataArrayAlloc<T>(
tag_name, this->type, _not_ghost, nb_component);
data.resize(nb_local_element);
/// unpacking the data, element by element
for (UInt i(0); i < nb_local_element; ++i) {
for (UInt j(0); j < nb_component; ++j) {
buffer >> data(i, j);
}
}
AKANTU_DEBUG_ASSERT(mesh.getNbElement(this->type, _ghost) == nb_ghost_element,
"Did not got enought informations for the tag "
<< tag_name << " and the element type " << this->type
<< ":"
<< "_ghost."
<< " Got " << nb_ghost_element << " values, expected "
<< mesh.getNbElement(this->type, _ghost));
Array<T> & data_ghost = mesh_data.getElementalDataArrayAlloc<T>(
tag_name, this->type, _ghost, nb_component);
data_ghost.resize(nb_ghost_element);
/// unpacking the ghost data, element by element
for (UInt j(0); j < nb_ghost_element; ++j) {
for (UInt k(0); k < nb_component; ++k) {
buffer >> data_ghost(j, k);
}
}
}
/* -------------------------------------------------------------------------- */
template <typename BufferType>
void ElementInfoPerProc::fillMeshData(BufferType & buffer,
const std::string & tag_name,
const MeshDataTypeCode & type_code,
UInt nb_component) {
#define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem): { \
fillMeshDataTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(buffer, tag_name, \
nb_component); \
break; \
}
switch (type_code) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, ,
AKANTU_MESH_DATA_TYPES)
default:
- AKANTU_ERROR("Could not determine the type of tag" << tag_name
- << "!");
+ AKANTU_ERROR("Could not determine the type of tag" << tag_name << "!");
break;
}
#undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
}
/* -------------------------------------------------------------------------- */
template <class CommunicationBuffer>
void ElementInfoPerProc::fillElementGroupsFromBuffer(
CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
Element el;
el.type = type;
- for(auto ghost_type : ghost_types) {
+ for (auto ghost_type : ghost_types) {
UInt nb_element = mesh.getNbElement(type, ghost_type);
el.ghost_type = ghost_type;
for (UInt e = 0; e < nb_element; ++e) {
el.element = e;
std::vector<std::string> element_to_group;
buffer >> element_to_group;
AKANTU_DEBUG_ASSERT(e < mesh.getNbElement(type, ghost_type),
"The mesh does not have the element " << e);
for (auto && element : element_to_group) {
mesh.getElementGroup(element).add(el, false, false);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // akantu
#endif /* __AKANTU_ELEMENT_INFO_PER_PROCESSOR_TMPL_HH__ */
diff --git a/src/synchronizer/facet_synchronizer_inline_impl.cc b/src/synchronizer/facet_synchronizer_inline_impl.cc
index fadf9c105..35656bd14 100644
--- a/src/synchronizer/facet_synchronizer_inline_impl.cc
+++ b/src/synchronizer/facet_synchronizer_inline_impl.cc
@@ -1,117 +1,127 @@
/**
* @file facet_synchronizer_inline_impl.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief facet synchronizer inline implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
// template<GhostType ghost_facets>
-// inline void FacetSynchronizer::getFacetGlobalConnectivity(const DistributedSynchronizer & distributed_synchronizer,
-// const ElementTypeMapArray<UInt> & rank_to_facet,
-// const Array<Element> * elements,
-// Array<ElementTypeMapArray<UInt> *> & connectivity,
-// Array<ElementTypeMapArray<UInt> *> & facets) {
+// inline void FacetSynchronizer::getFacetGlobalConnectivity(const
+// DistributedSynchronizer & distributed_synchronizer,
+// const
+// ElementTypeMapArray<UInt>
+// & rank_to_facet,
+// const Array<Element> *
+// elements,
+// Array<ElementTypeMapArray<UInt>
+// *> & connectivity,
+// Array<ElementTypeMapArray<UInt>
+// *> & facets) {
// AKANTU_DEBUG_IN();
// UInt spatial_dimension = mesh.getSpatialDimension();
// /// init facet check tracking
// ElementTypeMapArray<bool> facet_checked("facet_checked", id);
// mesh.initElementTypeMapArray(facet_checked, 1, spatial_dimension - 1);
-// Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1, ghost_facets);
-// Mesh::type_iterator last = mesh.lastType(spatial_dimension - 1, ghost_facets);
+// Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1,
+// ghost_facets);
+// Mesh::type_iterator last = mesh.lastType(spatial_dimension - 1,
+// ghost_facets);
// for (; first != last; ++first) {
// ElementType type = *first;
// Array<bool> & f_checked = facet_checked(type, ghost_facets);
// UInt nb_facet = mesh.getNbElement(type, ghost_facets);
// f_checked.resize(nb_facet);
// }
// const Array<UInt> & nodes_global_ids =
// distributed_synchronizer.mesh.getGlobalNodesIds();
// /// loop on every processor
// for (UInt p = 0; p < nb_proc; ++p) {
// if (p == rank) continue;
// /// reset facet check
-// Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1, ghost_facets);
-// Mesh::type_iterator last = mesh.lastType(spatial_dimension - 1, ghost_facets);
+// Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1,
+// ghost_facets);
+// Mesh::type_iterator last = mesh.lastType(spatial_dimension - 1,
+// ghost_facets);
// for (; first != last; ++first) {
// ElementType type = *first;
// Array<bool> & f_checked = facet_checked(type, ghost_facets);
// f_checked.clear();
// }
// ElementTypeMapArray<UInt> & global_conn = (*connectivity(p));
// const Array<Element> & elem = elements[p];
// ElementTypeMapArray<UInt> & facet_list = (*facets(p));
// UInt nb_element = elem.getSize();
// /// loop on every send/recv element
// for (UInt el = 0; el < nb_element; ++el) {
// ElementType type = elem(el).type;
// GhostType gt = elem(el).ghost_type;
// UInt el_index = elem(el).element;
// const Array<Element> & facet_to_element =
// mesh.getSubelementToElement(type, gt);
// UInt nb_facets_per_element = Mesh::getNbFacetsPerElement(type);
// ElementType facet_type = Mesh::getFacetType(type);
// UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(facet_type);
// Vector<UInt> conn_tmp(nb_nodes_per_facet);
// /// loop on every facet of the element
// for (UInt f = 0; f < nb_facets_per_element; ++f) {
// const Element & facet = facet_to_element(el_index, f);
// if (facet == ElementNull) continue;
// UInt facet_index = facet.element;
// GhostType facet_gt = facet.ghost_type;
// const Array<UInt> & t_to_f = rank_to_facet(facet_type, facet_gt);
// /// exclude not ghost facets, facets assigned to other
// /// processors
// if (facet_gt != ghost_facets) continue;
// if ((facet_gt == _ghost) && (t_to_f(facet_index) != p)) continue;
// /// exclude facets that have already been added
// Array<bool> & f_checked = facet_checked(facet_type, facet_gt);
// if (f_checked(facet_index)) continue;
// else f_checked(facet_index) = true;
// /// add facet index
// Array<UInt> & f_list = facet_list(facet_type, facet_gt);
// f_list.push_back(facet_index);
// /// add sorted facet global connectivity
// const Array<UInt> & conn = mesh.getConnectivity(facet_type, facet_gt);
// Array<UInt> & g_conn = global_conn(facet_type, facet_gt);
// for (UInt n = 0; n < nb_nodes_per_facet; ++n)
// conn_tmp(n) = nodes_global_ids(conn(facet_index, n));
// std::sort(conn_tmp.storage(), conn_tmp.storage() + nb_nodes_per_facet);
// g_conn.push_back(conn_tmp);
// }
// }
// }
// AKANTU_DEBUG_OUT();
// }
diff --git a/src/synchronizer/grid_synchronizer.cc b/src/synchronizer/grid_synchronizer.cc
index 4ee171670..2a2896e8f 100644
--- a/src/synchronizer/grid_synchronizer.cc
+++ b/src/synchronizer/grid_synchronizer.cc
@@ -1,543 +1,543 @@
/**
* @file grid_synchronizer.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Oct 03 2011
* @date last modification: Fri Jan 22 2016
*
* @brief implementation of the grid synchronizer
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "grid_synchronizer.hh"
#include "aka_grid_dynamic.hh"
+#include "communicator.hh"
#include "fe_engine.hh"
#include "integration_point.hh"
#include "mesh.hh"
#include "mesh_io.hh"
-#include "communicator.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class E>
void GridSynchronizer::createGridSynchronizer(const SpatialGrid<E> & grid) {
AKANTU_DEBUG_IN();
const Communicator & comm = this->mesh.getCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
if (nb_proc == 1)
return;
UInt spatial_dimension = this->mesh.getSpatialDimension();
Tensor3<Real> bounding_boxes(spatial_dimension, 2, nb_proc);
Matrix<Real> my_bounding_box = bounding_boxes(my_rank);
const auto & lower = grid.getLowerBounds();
const auto & upper = grid.getUpperBounds();
const auto & spacing = grid.getSpacing();
Vector<Real>(my_bounding_box(0)) = lower - spacing;
Vector<Real>(my_bounding_box(1)) = upper + spacing;
AKANTU_DEBUG_INFO(
"Exchange of bounding box to detect the overlapping regions.");
comm.allGather(bounding_boxes);
std::vector<bool> intersects_proc(nb_proc);
std::fill(intersects_proc.begin(), intersects_proc.end(), true);
Matrix<Int> first_cells(spatial_dimension, nb_proc);
Matrix<Int> last_cells(spatial_dimension, nb_proc);
std::map<UInt, ElementTypeMapArray<UInt>> element_per_proc;
// check the overlapping between my box and the one from other processors
for (UInt p = 0; p < nb_proc; ++p) {
if (p == my_rank)
continue;
Matrix<Real> proc_bounding_box = bounding_boxes(p);
bool intersects = false;
Vector<Int> first_cell_p = first_cells(p);
Vector<Int> last_cell_p = last_cells(p);
for (UInt s = 0; s < spatial_dimension; ++s) {
// check overlapping of grid
intersects =
Math::intersects(my_bounding_box(s, 0), my_bounding_box(s, 1),
proc_bounding_box(s, 0), proc_bounding_box(s, 1));
intersects_proc[p] = intersects_proc[p] & intersects;
if (intersects) {
AKANTU_DEBUG_INFO("I intersects with processor "
<< p << " in direction " << s);
// is point 1 of proc p in the dimension s in the range ?
bool point1 =
Math::is_in_range(proc_bounding_box(s, 0), my_bounding_box(s, 0),
my_bounding_box(s, 1));
// is point 2 of proc p in the dimension s in the range ?
bool point2 =
Math::is_in_range(proc_bounding_box(s, 1), my_bounding_box(s, 0),
my_bounding_box(s, 1));
Real start = 0.;
Real end = 0.;
if (point1 && !point2) {
/* |-----------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = proc_bounding_box(s, 0);
end = my_bounding_box(s, 1);
AKANTU_DEBUG_INFO("Intersection scheme 1 in direction "
<< s << " with processor " << p << " [" << start
<< ", " << end << "]");
} else if (point1 && point2) {
/* |-----------------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = proc_bounding_box(s, 0);
end = proc_bounding_box(s, 1);
AKANTU_DEBUG_INFO("Intersection scheme 2 in direction "
<< s << " with processor " << p << " [" << start
<< ", " << end << "]");
} else if (!point1 && point2) {
/* |-----------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = my_bounding_box(s, 0);
end = proc_bounding_box(s, 1);
AKANTU_DEBUG_INFO("Intersection scheme 3 in direction "
<< s << " with processor " << p << " [" << start
<< ", " << end << "]");
} else {
/* |-----------| my_bounding_box(i)
* |-----------------| proc_bounding_box(i)
* 1 2
*/
start = my_bounding_box(s, 0);
end = my_bounding_box(s, 1);
AKANTU_DEBUG_INFO("Intersection scheme 4 in direction "
<< s << " with processor " << p << " [" << start
<< ", " << end << "]");
}
first_cell_p(s) = grid.getCellID(start, s);
last_cell_p(s) = grid.getCellID(end, s);
}
}
// create the list of cells in the overlapping
using CellID = typename SpatialGrid<E>::CellID;
std::vector<CellID> cell_ids;
if (intersects_proc[p]) {
AKANTU_DEBUG_INFO("I intersects with processor " << p);
CellID cell_id(spatial_dimension);
// for (UInt i = 0; i < spatial_dimension; ++i) {
// if(first_cell_p[i] != 0) --first_cell_p[i];
// if(last_cell_p[i] != 0) ++last_cell_p[i];
// }
for (Int fd = first_cell_p(0); fd <= last_cell_p(0); ++fd) {
cell_id.setID(0, fd);
if (spatial_dimension == 1) {
cell_ids.push_back(cell_id);
} else {
for (Int sd = first_cell_p(1); sd <= last_cell_p(1); ++sd) {
cell_id.setID(1, sd);
if (spatial_dimension == 2) {
cell_ids.push_back(cell_id);
} else {
for (Int ld = first_cell_p(2); ld <= last_cell_p(2); ++ld) {
cell_id.setID(2, ld);
cell_ids.push_back(cell_id);
}
}
}
}
}
// get the list of elements in the cells of the overlapping
std::set<Element> to_send;
for (auto & cur_cell_id : cell_ids) {
auto & cell = grid.getCell(cur_cell_id);
for (auto & element : cell) {
to_send.insert(element);
}
}
AKANTU_DEBUG_INFO("I have prepared " << to_send.size()
<< " elements to send to processor "
<< p);
auto & scheme = this->getCommunications().createSendScheme(p);
std::stringstream sstr;
sstr << "element_per_proc_" << p;
element_per_proc.emplace(
std::piecewise_construct, std::forward_as_tuple(p),
std::forward_as_tuple(sstr.str(), id, memory_id));
ElementTypeMapArray<UInt> & elempproc = element_per_proc[p];
for (auto elem : to_send) {
ElementType type = elem.type;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
// /!\ this part must be slow due to the access in the
// ElementTypeMapArray<UInt>
if (!elempproc.exists(type, _not_ghost))
elempproc.alloc(0, nb_nodes_per_element, type, _not_ghost);
Vector<UInt> global_connect(nb_nodes_per_element);
Vector<UInt> local_connect = mesh.getConnectivity(type).begin(
nb_nodes_per_element)[elem.element];
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
global_connect(i) = mesh.getNodeGlobalId(local_connect(i));
AKANTU_DEBUG_ASSERT(
global_connect(i) < mesh.getNbGlobalNodes(),
"This global node send in the connectivity does not seem correct "
<< global_connect(i) << " corresponding to "
<< local_connect(i) << " from element " << elem.element);
}
elempproc(type).push_back(global_connect);
scheme.push_back(elem);
}
}
}
AKANTU_DEBUG_INFO("I have finished to compute intersection,"
<< " no it's time to communicate with my neighbors");
/**
* Sending loop, sends the connectivity asynchronously to all concerned proc
*/
std::vector<CommunicationRequest> isend_requests;
Tensor3<UInt> space(2, _max_element_type, nb_proc);
for (UInt p = 0; p < nb_proc; ++p) {
if (p == my_rank)
continue;
if (not intersects_proc[p])
continue;
Matrix<UInt> info_proc = space(p);
auto & elempproc = element_per_proc[p];
UInt count = 0;
for (auto type : elempproc.elementTypes(_all_dimensions, _not_ghost)) {
Array<UInt> & conn = elempproc(type, _not_ghost);
Vector<UInt> info = info_proc((UInt)type);
info[0] = (UInt)type;
info[1] = conn.size() * conn.getNbComponent();
AKANTU_DEBUG_INFO(
"I have " << conn.size() << " elements of type " << type
<< " to send to processor " << p << " (communication tag : "
<< Tag::genTag(my_rank, count, DATA_TAG) << ")");
isend_requests.push_back(
comm.asyncSend(info, p, Tag::genTag(my_rank, count, SIZE_TAG)));
if (info[1] != 0)
isend_requests.push_back(comm.asyncSend<UInt>(
conn, p, Tag::genTag(my_rank, count, DATA_TAG)));
++count;
}
Vector<UInt> info = info_proc((UInt)_not_defined);
info[0] = (UInt)_not_defined;
info[1] = 0;
isend_requests.push_back(
comm.asyncSend(info, p, Tag::genTag(my_rank, count, SIZE_TAG)));
}
/**
* Receives the connectivity and store them in the ghosts elements
*/
MeshAccessor mesh_accessor(mesh);
auto & global_nodes_ids = mesh_accessor.getNodesGlobalIds();
auto & nodes_type = mesh_accessor.getNodesType();
std::vector<CommunicationRequest> isend_nodes_requests;
Vector<UInt> nb_nodes_to_recv(nb_proc);
UInt nb_total_nodes_to_recv = 0;
UInt nb_current_nodes = global_nodes_ids.size();
NewNodesEvent new_nodes;
NewElementsEvent new_elements;
std::map<UInt, std::vector<UInt>> ask_nodes_per_proc;
for (UInt p = 0; p < nb_proc; ++p) {
nb_nodes_to_recv(p) = 0;
if (p == my_rank)
continue;
if (!intersects_proc[p])
continue;
auto & scheme = this->getCommunications().createRecvScheme(p);
ask_nodes_per_proc.emplace(std::piecewise_construct,
std::forward_as_tuple(p),
std::forward_as_tuple(0));
auto & ask_nodes = ask_nodes_per_proc[p];
UInt count = 0;
ElementType type = _not_defined;
do {
Vector<UInt> info(2);
comm.receive(info, p, Tag::genTag(p, count, SIZE_TAG));
type = (ElementType)info[0];
if (type == _not_defined)
break;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
UInt nb_element = info[1] / nb_nodes_per_element;
Array<UInt> tmp_conn(nb_element, nb_nodes_per_element);
tmp_conn.clear();
if (info[1] != 0)
comm.receive<UInt>(tmp_conn, p, Tag::genTag(p, count, DATA_TAG));
AKANTU_DEBUG_INFO("I will receive "
<< nb_element << " elements of type "
<< ElementType(info[0]) << " from processor " << p
<< " (communication tag : "
<< Tag::genTag(p, count, DATA_TAG) << ")");
auto & ghost_connectivity = mesh_accessor.getConnectivity(type, _ghost);
auto & ghost_counter = mesh_accessor.getGhostsCounters(type, _ghost);
UInt nb_ghost_element = ghost_connectivity.size();
Element element{type, 0, _ghost};
Vector<UInt> conn(nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el) {
UInt nb_node_to_ask_for_elem = 0;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt gn = tmp_conn(el, n);
UInt ln = global_nodes_ids.find(gn);
AKANTU_DEBUG_ASSERT(gn < mesh.getNbGlobalNodes(),
"This global node seems not correct "
<< gn << " from element " << el << " node "
<< n);
if (ln == UInt(-1)) {
global_nodes_ids.push_back(gn);
nodes_type.push_back(_nt_pure_gost); // pure ghost node
ln = nb_current_nodes;
new_nodes.getList().push_back(ln);
++nb_current_nodes;
ask_nodes.push_back(gn);
++nb_node_to_ask_for_elem;
}
conn[n] = ln;
}
// all the nodes are already known locally, the element should
// already exists
auto c = UInt(-1);
if (nb_node_to_ask_for_elem == 0) {
c = ghost_connectivity.find(conn);
element.element = c;
}
if (c == UInt(-1)) {
element.element = nb_ghost_element;
++nb_ghost_element;
ghost_connectivity.push_back(conn);
ghost_counter.push_back(1);
new_elements.getList().push_back(element);
} else {
++ghost_counter(c);
}
scheme.push_back(element);
}
count++;
} while (type != _not_defined);
AKANTU_DEBUG_INFO("I have "
<< ask_nodes.size()
<< " missing nodes for elements coming from processor "
<< p << " (communication tag : "
<< Tag::genTag(my_rank, 0, ASK_NODES_TAG) << ")");
ask_nodes.push_back(UInt(-1));
isend_nodes_requests.push_back(
comm.asyncSend(ask_nodes, p, Tag::genTag(my_rank, 0, ASK_NODES_TAG)));
nb_nodes_to_recv(p) = ask_nodes.size() - 1;
nb_total_nodes_to_recv += nb_nodes_to_recv(p);
}
comm.waitAll(isend_requests);
comm.freeCommunicationRequest(isend_requests);
/**
* Sends requested nodes to proc
*/
auto & nodes = const_cast<Array<Real> &>(mesh.getNodes());
UInt nb_nodes = nodes.size();
std::vector<CommunicationRequest> isend_coordinates_requests;
std::map<UInt, Array<Real>> nodes_to_send_per_proc;
for (UInt p = 0; p < nb_proc; ++p) {
if (p == my_rank || !intersects_proc[p])
continue;
Array<UInt> asked_nodes;
CommunicationStatus status;
AKANTU_DEBUG_INFO("Waiting list of nodes to send to processor "
<< p << "(communication tag : "
<< Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
comm.probe<UInt>(p, Tag::genTag(p, 0, ASK_NODES_TAG), status);
UInt nb_nodes_to_send = status.size();
asked_nodes.resize(nb_nodes_to_send);
AKANTU_DEBUG_INFO("I have " << nb_nodes_to_send - 1
<< " nodes to send to processor " << p
<< " (communication tag : "
<< Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
AKANTU_DEBUG_INFO("Getting list of nodes to send to processor "
<< p << " (communication tag : "
<< Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
comm.receive(asked_nodes, p, Tag::genTag(p, 0, ASK_NODES_TAG));
nb_nodes_to_send--;
asked_nodes.resize(nb_nodes_to_send);
nodes_to_send_per_proc.emplace(std::piecewise_construct,
std::forward_as_tuple(p),
std::forward_as_tuple(0, spatial_dimension));
auto & nodes_to_send = nodes_to_send_per_proc[p];
auto node_it = nodes.begin(spatial_dimension);
for (UInt n = 0; n < nb_nodes_to_send; ++n) {
UInt ln = global_nodes_ids.find(asked_nodes(n));
- AKANTU_DEBUG_ASSERT(ln != UInt(-1), "The node ["
- << asked_nodes(n)
- << "] requested by proc " << p
- << " was not found locally!");
+ AKANTU_DEBUG_ASSERT(ln != UInt(-1),
+ "The node [" << asked_nodes(n)
+ << "] requested by proc " << p
+ << " was not found locally!");
nodes_to_send.push_back(node_it + ln);
}
if (nb_nodes_to_send != 0) {
AKANTU_DEBUG_INFO("Sending the "
<< nb_nodes_to_send << " nodes to processor " << p
<< " (communication tag : "
<< Tag::genTag(p, 0, SEND_NODES_TAG) << ")");
isend_coordinates_requests.push_back(comm.asyncSend(
nodes_to_send, p, Tag::genTag(my_rank, 0, SEND_NODES_TAG)));
}
#if not defined(AKANTU_NDEBUG)
else {
AKANTU_DEBUG_INFO("No nodes to send to processor " << p);
}
#endif
}
comm.waitAll(isend_nodes_requests);
comm.freeCommunicationRequest(isend_nodes_requests);
nodes.resize(nb_total_nodes_to_recv + nb_nodes);
for (UInt p = 0; p < nb_proc; ++p) {
if ((p != my_rank) && (nb_nodes_to_recv(p) > 0)) {
AKANTU_DEBUG_INFO("Receiving the "
<< nb_nodes_to_recv(p) << " nodes from processor " << p
<< " (communication tag : "
<< Tag::genTag(p, 0, SEND_NODES_TAG) << ")");
Vector<Real> nodes_to_recv(nodes.storage() + nb_nodes * spatial_dimension,
nb_nodes_to_recv(p) * spatial_dimension);
comm.receive(nodes_to_recv, p, Tag::genTag(p, 0, SEND_NODES_TAG));
nb_nodes += nb_nodes_to_recv(p);
}
#if not defined(AKANTU_NDEBUG)
else {
if (p != my_rank) {
AKANTU_DEBUG_INFO("No nodes to receive from processor " << p);
}
}
#endif
}
comm.waitAll(isend_coordinates_requests);
comm.freeCommunicationRequest(isend_coordinates_requests);
mesh.sendEvent(new_nodes);
mesh.sendEvent(new_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template void GridSynchronizer::createGridSynchronizer<IntegrationPoint>(
const SpatialGrid<IntegrationPoint> & grid);
template void GridSynchronizer::createGridSynchronizer<Element>(
const SpatialGrid<Element> & grid);
} // namespace akantu
diff --git a/src/synchronizer/grid_synchronizer_tmpl.hh b/src/synchronizer/grid_synchronizer_tmpl.hh
index f35940969..fc33da1fe 100644
--- a/src/synchronizer/grid_synchronizer_tmpl.hh
+++ b/src/synchronizer/grid_synchronizer_tmpl.hh
@@ -1,72 +1,73 @@
/**
* @file grid_synchronizer_tmpl.hh
*
* @author Nicolas Richart
*
* @date creation Tue Jun 20 2017
*
* @brief A Documented file.
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "grid_synchronizer.hh"
#ifndef __AKANTU_GRID_SYNCHRONIZER_TMPL_HH__
#define __AKANTU_GRID_SYNCHRONIZER_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <typename E>
GridSynchronizer::GridSynchronizer(Mesh & mesh, const SpatialGrid<E> & grid,
const ID & id, MemoryID memory_id,
const bool register_to_event_manager,
EventHandlerPriority event_priority)
- : ElementSynchronizer(mesh, id, memory_id, register_to_event_manager, event_priority) {
+ : ElementSynchronizer(mesh, id, memory_id, register_to_event_manager,
+ event_priority) {
AKANTU_DEBUG_IN();
this->createGridSynchronizer(grid);
AKANTU_DEBUG_OUT();
}
template <typename E>
GridSynchronizer::GridSynchronizer(
Mesh & mesh, const SpatialGrid<E> & grid,
SynchronizerRegistry & synchronizer_registry,
const std::set<SynchronizationTag> & tags_to_register, const ID & id,
MemoryID memory_id, const bool register_to_event_manager,
EventHandlerPriority event_priority)
: GridSynchronizer(mesh, grid, id, memory_id, register_to_event_manager,
event_priority) {
AKANTU_DEBUG_IN();
// Register the tags if any
for (auto & tag : tags_to_register) {
synchronizer_registry.registerSynchronizer(*this, tag);
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
#endif /* __AKANTU_GRID_SYNCHRONIZER_TMPL_HH__ */
diff --git a/src/synchronizer/master_element_info_per_processor.cc b/src/synchronizer/master_element_info_per_processor.cc
index f27f9ee51..b3b91967a 100644
--- a/src/synchronizer/master_element_info_per_processor.cc
+++ b/src/synchronizer/master_element_info_per_processor.cc
@@ -1,461 +1,461 @@
/**
* @file master_element_info_per_processor.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Mar 11 14:57:13 2016
*
* @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_iterators.hh"
#include "communicator.hh"
#include "element_group.hh"
#include "element_info_per_processor.hh"
#include "element_synchronizer.hh"
#include "mesh_iterators.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <iostream>
#include <map>
#include <tuple>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
MasterElementInfoPerProc::MasterElementInfoPerProc(
ElementSynchronizer & synchronizer, UInt message_cnt, UInt root,
ElementType type, const MeshPartition & partition)
: ElementInfoPerProc(synchronizer, message_cnt, root, type),
partition(partition), all_nb_local_element(nb_proc, 0),
all_nb_ghost_element(nb_proc, 0), all_nb_element_to_send(nb_proc, 0) {
Vector<UInt> size(5);
size(0) = (UInt)type;
if (type != _not_defined) {
nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
nb_element = mesh.getNbElement(type);
const auto & partition_num =
this->partition.getPartition(this->type, _not_ghost);
const auto & ghost_partition =
this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
for (UInt el = 0; el < nb_element; ++el) {
this->all_nb_local_element[partition_num(el)]++;
for (auto part = ghost_partition.begin(el);
part != ghost_partition.end(el); ++part) {
this->all_nb_ghost_element[*part]++;
}
this->all_nb_element_to_send[partition_num(el)] +=
ghost_partition.getNbCols(el) + 1;
}
/// tag info
std::vector<std::string> tag_names;
this->getMeshData().getTagNames(tag_names, type);
this->nb_tags = tag_names.size();
size(4) = nb_tags;
for (UInt p = 0; p < nb_proc; ++p) {
if (p != root) {
size(1) = this->all_nb_local_element[p];
size(2) = this->all_nb_ghost_element[p];
size(3) = this->all_nb_element_to_send[p];
AKANTU_DEBUG_INFO(
"Sending connectivities informations to proc "
<< p << " TAG("
<< Tag::genTag(this->rank, this->message_count, Tag::_SIZES)
<< ")");
comm.send(size, p,
Tag::genTag(this->rank, this->message_count, Tag::_SIZES));
} else {
this->nb_local_element = this->all_nb_local_element[p];
this->nb_ghost_element = this->all_nb_ghost_element[p];
}
}
} else {
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p != this->root) {
AKANTU_DEBUG_INFO(
"Sending empty connectivities informations to proc "
<< p << " TAG("
<< Tag::genTag(this->rank, this->message_count, Tag::_SIZES)
<< ")");
comm.send(size, p,
Tag::genTag(this->rank, this->message_count, Tag::_SIZES));
}
}
}
}
/* ------------------------------------------------------------------------ */
void MasterElementInfoPerProc::synchronizeConnectivities() {
const auto & partition_num =
this->partition.getPartition(this->type, _not_ghost);
const auto & ghost_partition =
this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
std::vector<Array<UInt>> buffers(this->nb_proc);
const auto & connectivities =
this->mesh.getConnectivity(this->type, _not_ghost);
/// copying the local connectivity
for (auto && part_conn :
zip(partition_num,
make_view(connectivities, this->nb_nodes_per_element))) {
auto && part = std::get<0>(part_conn);
auto && conn = std::get<1>(part_conn);
for (UInt i = 0; i < conn.size(); ++i) {
buffers[part].push_back(conn[i]);
}
}
/// copying the connectivity of ghost element
for (auto && tuple :
- enumerate(make_view(connectivities, this->nb_nodes_per_element))) {
+ enumerate(make_view(connectivities, this->nb_nodes_per_element))) {
auto && el = std::get<0>(tuple);
auto && conn = std::get<1>(tuple);
for (auto part = ghost_partition.begin(el); part != ghost_partition.end(el);
++part) {
UInt proc = *part;
for (UInt i = 0; i < conn.size(); ++i) {
buffers[proc].push_back(conn[i]);
}
}
}
#ifndef AKANTU_NDEBUG
for (auto p : arange(this->nb_proc)) {
UInt size = this->nb_nodes_per_element *
(this->all_nb_local_element[p] + this->all_nb_ghost_element[p]);
AKANTU_DEBUG_ASSERT(
buffers[p].size() == size,
"The connectivity data packed in the buffer are not correct");
}
#endif
/// send all connectivity and ghost information to all processors
std::vector<CommunicationRequest> requests;
for (auto p : arange(this->nb_proc)) {
if (p == this->root)
continue;
auto && tag =
Tag::genTag(this->rank, this->message_count, Tag::_CONNECTIVITY);
AKANTU_DEBUG_INFO("Sending connectivities to proc " << p << " TAG(" << tag
<< ")");
requests.push_back(comm.asyncSend(buffers[p], p, tag));
}
Array<UInt> & old_nodes = this->getNodesGlobalIds();
/// create the renumbered connectivity
AKANTU_DEBUG_INFO("Renumbering local connectivities");
MeshUtils::renumberMeshNodes(mesh, buffers[root], all_nb_local_element[root],
all_nb_ghost_element[root], type, old_nodes);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
}
/* ------------------------------------------------------------------------ */
void MasterElementInfoPerProc::synchronizePartitions() {
const auto & partition_num =
this->partition.getPartition(this->type, _not_ghost);
const auto & ghost_partition =
this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
std::vector<Array<UInt>> buffers(this->partition.getNbPartition());
/// splitting the partition information to send them to processors
Vector<UInt> count_by_proc(nb_proc, 0);
for (UInt el = 0; el < nb_element; ++el) {
UInt proc = partition_num(el);
buffers[proc].push_back(ghost_partition.getNbCols(el));
UInt i(0);
for (auto part = ghost_partition.begin(el); part != ghost_partition.end(el);
++part, ++i) {
buffers[proc].push_back(*part);
}
}
for (UInt el = 0; el < nb_element; ++el) {
UInt i(0);
for (auto part = ghost_partition.begin(el); part != ghost_partition.end(el);
++part, ++i) {
buffers[*part].push_back(partition_num(el));
}
}
#ifndef AKANTU_NDEBUG
for (UInt p = 0; p < this->nb_proc; ++p) {
AKANTU_DEBUG_ASSERT(buffers[p].size() == (this->all_nb_ghost_element[p] +
this->all_nb_element_to_send[p]),
"Data stored in the buffer are most probably wrong");
}
#endif
std::vector<CommunicationRequest> requests;
/// last data to compute the communication scheme
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p == this->root)
continue;
auto && tag =
Tag::genTag(this->rank, this->message_count, Tag::_PARTITIONS);
AKANTU_DEBUG_INFO("Sending partition informations to proc " << p << " TAG("
<< tag << ")");
requests.push_back(comm.asyncSend(buffers[p], p, tag));
}
if (Mesh::getSpatialDimension(this->type) ==
this->mesh.getSpatialDimension()) {
AKANTU_DEBUG_INFO("Creating communications scheme");
this->fillCommunicationScheme(buffers[this->rank]);
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
}
/* -------------------------------------------------------------------------- */
void MasterElementInfoPerProc::synchronizeTags() {
AKANTU_DEBUG_IN();
if (this->nb_tags == 0) {
AKANTU_DEBUG_OUT();
return;
}
UInt mesh_data_sizes_buffer_length;
auto & mesh_data = this->getMeshData();
/// tag info
std::vector<std::string> tag_names;
mesh_data.getTagNames(tag_names, type);
// Make sure the tags are sorted (or at least not in random order),
// because they come from a map !!
std::sort(tag_names.begin(), tag_names.end());
// Sending information about the tags in mesh_data: name, data type and
// number of components of the underlying array associated to the current
// type
DynamicCommunicationBuffer mesh_data_sizes_buffer;
for (auto && tag_name : tag_names) {
mesh_data_sizes_buffer << tag_name;
mesh_data_sizes_buffer << mesh_data.getTypeCode(tag_name);
mesh_data_sizes_buffer << mesh_data.getNbComponent(tag_name, type);
}
mesh_data_sizes_buffer_length = mesh_data_sizes_buffer.size();
AKANTU_DEBUG_INFO(
"Broadcasting the size of the information about the mesh data tags: ("
<< mesh_data_sizes_buffer_length << ").");
comm.broadcast(mesh_data_sizes_buffer_length, root);
AKANTU_DEBUG_INFO(
"Broadcasting the information about the mesh data tags, addr "
<< (void *)mesh_data_sizes_buffer.storage());
if (mesh_data_sizes_buffer_length != 0)
comm.broadcast(mesh_data_sizes_buffer, root);
if (mesh_data_sizes_buffer_length != 0) {
// Sending the actual data to each processor
std::vector<DynamicCommunicationBuffer> buffers(nb_proc);
// Loop over each tag for the current type
for (auto && tag_name : tag_names) {
// Type code of the current tag (i.e. the tag named *names_it)
this->fillTagBuffer(buffers, tag_name);
}
std::vector<CommunicationRequest> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if (p == root)
continue;
auto && tag =
Tag::genTag(this->rank, this->message_count, Tag::_MESH_DATA);
AKANTU_DEBUG_INFO("Sending " << buffers[p].size()
<< " bytes of mesh data to proc " << p
<< " TAG(" << tag << ")");
requests.push_back(comm.asyncSend(buffers[p], p, tag));
}
// Loop over each tag for the current type
for (auto && tag_name : tag_names) {
// Reinitializing the mesh data on the master
this->fillMeshData(buffers[root], tag_name,
mesh_data.getTypeCode(tag_name),
mesh_data.getNbComponent(tag_name, type));
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename T>
void MasterElementInfoPerProc::fillTagBufferTemplated(
std::vector<DynamicCommunicationBuffer> & buffers,
const std::string & tag_name) {
MeshData & mesh_data = this->getMeshData();
const auto & data = mesh_data.getElementalDataArray<T>(tag_name, type);
const auto & partition_num =
this->partition.getPartition(this->type, _not_ghost);
const auto & ghost_partition =
this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
// Not possible to use the iterator because it potentially triggers the
// creation of complex
// type templates (such as akantu::Vector< std::vector<Element> > which don't
// implement the right interface
// (e.g. operator<< in that case).
// typename Array<T>::template const_iterator< Vector<T> > data_it =
// data.begin(data.getNbComponent());
// typename Array<T>::template const_iterator< Vector<T> > data_end =
// data.end(data.getNbComponent());
const T * data_it = data.storage();
const T * data_end = data.storage() + data.size() * data.getNbComponent();
const UInt * part = partition_num.storage();
/// copying the data, element by element
for (; data_it != data_end; ++part) {
for (UInt j(0); j < data.getNbComponent(); ++j, ++data_it) {
buffers[*part] << *data_it;
}
}
data_it = data.storage();
/// copying the data for the ghost element
for (UInt el(0); data_it != data_end;
data_it += data.getNbComponent(), ++el) {
auto it = ghost_partition.begin(el);
auto end = ghost_partition.end(el);
for (; it != end; ++it) {
UInt proc = *it;
for (UInt j(0); j < data.getNbComponent(); ++j) {
buffers[proc] << data_it[j];
}
}
}
}
/* -------------------------------------------------------------------------- */
void MasterElementInfoPerProc::fillTagBuffer(
std::vector<DynamicCommunicationBuffer> & buffers,
const std::string & tag_name) {
MeshData & mesh_data = this->getMeshData();
#define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem): { \
this->fillTagBufferTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(buffers, \
tag_name); \
break; \
}
MeshDataTypeCode data_type_code = mesh_data.getTypeCode(tag_name);
switch (data_type_code) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, ,
AKANTU_MESH_DATA_TYPES)
default:
AKANTU_ERROR("Could not obtain the type of tag" << tag_name << "!");
break;
}
#undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
}
/* -------------------------------------------------------------------------- */
void MasterElementInfoPerProc::synchronizeGroups() {
AKANTU_DEBUG_IN();
std::vector<DynamicCommunicationBuffer> buffers(nb_proc);
using ElementToGroup = std::vector<std::vector<std::string>>;
ElementToGroup element_to_group(nb_element);
for (auto & eg : ElementGroupsIterable(mesh)) {
const auto & name = eg.getName();
for (const auto & element : eg.getElements(type, _not_ghost)) {
element_to_group[element].push_back(name);
}
auto eit = eg.begin(type, _not_ghost);
if (eit != eg.end(type, _not_ghost))
const_cast<Array<UInt> &>(eg.getElements(type)).empty();
}
const auto & partition_num =
this->partition.getPartition(this->type, _not_ghost);
const auto & ghost_partition =
this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
/// copying the data, element by element
for (auto && pair : zip(partition_num, element_to_group)) {
buffers[std::get<0>(pair)] << std::get<1>(pair);
}
/// copying the data for the ghost element
for (auto && pair : enumerate(element_to_group)) {
auto && el = std::get<0>(pair);
auto it = ghost_partition.begin(el);
auto end = ghost_partition.end(el);
for (; it != end; ++it) {
UInt proc = *it;
buffers[proc] << std::get<1>(pair);
}
}
std::vector<CommunicationRequest> requests;
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p == this->rank)
continue;
auto && tag = Tag::genTag(this->rank, p, Tag::_ELEMENT_GROUP);
AKANTU_DEBUG_INFO("Sending element groups to proc " << p << " TAG(" << tag
<< ")");
requests.push_back(comm.asyncSend(buffers[p], p, tag));
}
this->fillElementGroupsFromBuffer(buffers[this->rank]);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // namespace akantu
diff --git a/src/synchronizer/mpi_communicator_data.hh b/src/synchronizer/mpi_communicator_data.hh
index 526316228..be387e22b 100644
--- a/src/synchronizer/mpi_communicator_data.hh
+++ b/src/synchronizer/mpi_communicator_data.hh
@@ -1,134 +1,135 @@
/**
* @file mpi_type_wrapper.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Wed Oct 07 2015
*
* @brief Wrapper on MPI types to have a better separation between libraries
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined(__clang__) // test clang to be sure that when we test for gnu it
- // is only gnu
+// is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
#if __cplusplus > 199711L
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wliteral-suffix"
#endif
#endif
#include <mpi.h>
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined(__clang__) // test clang to be sure that when we test for gnu it
- // is only gnu
+// is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
#if __cplusplus > 199711L
#pragma GCC diagnostic pop
#endif
#endif
/* -------------------------------------------------------------------------- */
#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <unordered_map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MPI_TYPE_WRAPPER_HH__
#define __AKANTU_MPI_TYPE_WRAPPER_HH__
namespace akantu {
class MPICommunicatorData : public CommunicatorInternalData {
public:
MPICommunicatorData() {
MPI_Initialized(&is_externaly_initialized);
if (!is_externaly_initialized) {
MPI_Init(nullptr, nullptr); // valid according to the spec
}
- MPI_Comm_create_errhandler(MPICommunicatorData::errorHandler, &error_handler);
+ MPI_Comm_create_errhandler(MPICommunicatorData::errorHandler,
+ &error_handler);
MPI_Comm_set_errhandler(MPI_COMM_WORLD, error_handler);
setMPICommunicator(MPI_COMM_WORLD);
}
~MPICommunicatorData() override {
if (not is_externaly_initialized) {
MPI_Finalize();
}
}
inline void setMPICommunicator(MPI_Comm comm) {
MPI_Comm_set_errhandler(communicator, save_error_handler);
communicator = comm;
MPI_Comm_get_errhandler(comm, &save_error_handler);
MPI_Comm_set_errhandler(comm, error_handler);
}
inline int rank() const {
int prank;
MPI_Comm_rank(communicator, &prank);
return prank;
}
inline int size() const {
int psize;
MPI_Comm_size(communicator, &psize);
return psize;
}
inline MPI_Comm getMPICommunicator() const { return communicator; }
inline int getMaxTag() const {
int flag;
int * value;
MPI_Comm_get_attr(communicator, MPI_TAG_UB, &value, &flag);
AKANTU_DEBUG_ASSERT(flag, "No attribute MPI_TAG_UB.");
return *value;
}
private:
MPI_Comm communicator{MPI_COMM_WORLD};
MPI_Errhandler save_error_handler{MPI_ERRORS_ARE_FATAL};
static int is_externaly_initialized;
/* ------------------------------------------------------------------------ */
MPI_Errhandler error_handler;
static void errorHandler(MPI_Comm * /*comm*/, int * error_code, ...) {
char error_string[MPI_MAX_ERROR_STRING];
int str_len;
MPI_Error_string(*error_code, error_string, &str_len);
AKANTU_CUSTOM_EXCEPTION_INFO(debug::CommunicationException(),
"MPI failed with the error code "
<< *error_code << ": \"" << error_string
<< "\"");
}
};
} // namespace akantu
#endif /* __AKANTU_MPI_TYPE_WRAPPER_HH__ */
diff --git a/src/synchronizer/node_info_per_processor.cc b/src/synchronizer/node_info_per_processor.cc
index 2e97b07ff..3b4a73b32 100644
--- a/src/synchronizer/node_info_per_processor.cc
+++ b/src/synchronizer/node_info_per_processor.cc
@@ -1,500 +1,497 @@
/**
* @file node_info_per_processor.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Mar 11 15:49:43 2016
*
* @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "node_info_per_processor.hh"
+#include "communicator.hh"
#include "node_group.hh"
#include "node_synchronizer.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
NodeInfoPerProc::NodeInfoPerProc(NodeSynchronizer & synchronizer,
UInt message_cnt, UInt root)
: MeshAccessor(synchronizer.getMesh()), synchronizer(synchronizer),
comm(synchronizer.getCommunicator()), rank(comm.whoAmI()),
nb_proc(comm.getNbProc()), root(root), mesh(synchronizer.getMesh()),
spatial_dimension(synchronizer.getMesh().getSpatialDimension()),
message_count(message_cnt) {}
/* -------------------------------------------------------------------------- */
template <class CommunicationBuffer>
void NodeInfoPerProc::fillNodeGroupsFromBuffer(CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
std::vector<std::vector<std::string>> node_to_group;
buffer >> node_to_group;
AKANTU_DEBUG_ASSERT(node_to_group.size() == mesh.getNbGlobalNodes(),
"Not the good amount of nodes where transmitted");
const auto & global_nodes = mesh.getGlobalNodesIds();
auto nbegin = global_nodes.begin();
auto nit = global_nodes.begin();
auto nend = global_nodes.end();
for (; nit != nend; ++nit) {
auto it = node_to_group[*nit].begin();
auto end = node_to_group[*nit].end();
for (; it != end; ++it) {
mesh.getNodeGroup(*it).add(nit - nbegin, false);
}
}
GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
GroupManager::const_node_group_iterator nge = mesh.node_group_end();
for (; ngi != nge; ++ngi) {
NodeGroup & ng = *(ngi->second);
ng.optimize();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NodeInfoPerProc::fillNodesType() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
Array<NodeType> & nodes_type = this->getNodesType();
Array<UInt> nodes_set(nb_nodes);
nodes_set.set(0);
enum NodeSet {
NORMAL_SET = 1,
GHOST_SET = 2,
};
Array<bool> already_seen(nb_nodes, 1, false);
for (UInt g = _not_ghost; g <= _ghost; ++g) {
auto gt = (GhostType)g;
UInt set = NORMAL_SET;
if (gt == _ghost)
set = GHOST_SET;
already_seen.set(false);
Mesh::type_iterator it =
mesh.firstType(_all_dimensions, gt, _ek_not_defined);
Mesh::type_iterator end =
mesh.lastType(_all_dimensions, gt, _ek_not_defined);
for (; it != end; ++it) {
ElementType type = *it;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(type, gt);
Array<UInt>::const_vector_iterator conn_it =
mesh.getConnectivity(type, gt).begin(nb_nodes_per_element);
for (UInt e = 0; e < nb_element; ++e, ++conn_it) {
const Vector<UInt> & conn = *conn_it;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
AKANTU_DEBUG_ASSERT(conn(n) < nb_nodes,
"Node " << conn(n)
<< " bigger than number of nodes "
<< nb_nodes);
if (!already_seen(conn(n))) {
nodes_set(conn(n)) += set;
already_seen(conn(n)) = true;
}
}
}
}
}
for (UInt i = 0; i < nb_nodes; ++i) {
if (nodes_set(i) == NORMAL_SET)
nodes_type(i) = _nt_normal;
else if (nodes_set(i) == GHOST_SET)
nodes_type(i) = _nt_pure_gost;
else if (nodes_set(i) == (GHOST_SET + NORMAL_SET))
nodes_type(i) = _nt_master;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void NodeInfoPerProc::fillCommunicationScheme(const Array<UInt> & master_info) {
AKANTU_DEBUG_IN();
Communications<UInt> & communications =
this->synchronizer.getCommunications();
{ // send schemes
auto it = master_info.begin_reinterpret(2, master_info.size() / 2);
auto end = master_info.end_reinterpret(2, master_info.size() / 2);
std::map<UInt, Array<UInt>> send_array_per_proc;
for (; it != end; ++it) {
const Vector<UInt> & send_info = *it;
send_array_per_proc[send_info(0)].push_back(send_info(1));
}
for (auto & send_schemes : send_array_per_proc) {
auto & scheme = communications.createSendScheme(send_schemes.first);
auto & sends = send_schemes.second;
std::sort(sends.begin(), sends.end());
std::transform(sends.begin(), sends.end(), sends.begin(),
[this](UInt g) -> UInt { return mesh.getNodeLocalId(g); });
scheme.copy(sends);
}
}
{ // receive schemes
const Array<NodeType> & nodes_type = this->getNodesType();
std::map<UInt, Array<UInt>> recv_array_per_proc;
UInt node = 0;
for (auto & node_type : nodes_type) {
if (Int(node_type) >= 0) {
recv_array_per_proc[node_type].push_back(mesh.getNodeGlobalId(node));
}
++node;
}
for (auto & recv_schemes : recv_array_per_proc) {
auto & scheme = communications.createRecvScheme(recv_schemes.first);
auto & recvs = recv_schemes.second;
std::sort(recvs.begin(), recvs.end());
std::transform(recvs.begin(), recvs.end(), recvs.begin(),
[this](UInt g) -> UInt { return mesh.getNodeLocalId(g); });
scheme.copy(recvs);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
MasterNodeInfoPerProc::MasterNodeInfoPerProc(NodeSynchronizer & synchronizer,
UInt message_cnt, UInt root)
: NodeInfoPerProc(synchronizer, message_cnt, root) {
UInt nb_global_nodes = this->mesh.getNbGlobalNodes();
this->comm.broadcast(nb_global_nodes, this->root);
}
/* -------------------------------------------------------------------------- */
void MasterNodeInfoPerProc::synchronizeNodes() {
this->nodes_per_proc.resize(nb_proc);
this->nb_nodes_per_proc.resize(nb_proc);
Array<Real> local_nodes(0, spatial_dimension);
Array<Real> & nodes = this->getNodes();
for (UInt p = 0; p < nb_proc; ++p) {
UInt nb_nodes = 0;
// UInt * buffer;
Array<Real> * nodes_to_send;
Array<UInt> & nodespp = nodes_per_proc[p];
if (p != root) {
nodes_to_send = new Array<Real>(0, spatial_dimension);
AKANTU_DEBUG_INFO("Receiving number of nodes from proc "
<< p << " " << Tag::genTag(p, 0, Tag::_NB_NODES));
comm.receive(nb_nodes, p, Tag::genTag(p, 0, Tag::_NB_NODES));
nodespp.resize(nb_nodes);
this->nb_nodes_per_proc(p) = nb_nodes;
AKANTU_DEBUG_INFO("Receiving list of nodes from proc "
<< p << " " << Tag::genTag(p, 0, Tag::_NODES));
comm.receive(nodespp, p, Tag::genTag(p, 0, Tag::_NODES));
} else {
Array<UInt> & local_ids = this->getNodesGlobalIds();
this->nb_nodes_per_proc(p) = local_ids.size();
nodespp.copy(local_ids);
nodes_to_send = &local_nodes;
}
Array<UInt>::const_scalar_iterator it = nodespp.begin();
Array<UInt>::const_scalar_iterator end = nodespp.end();
/// get the coordinates for the selected nodes
for (; it != end; ++it) {
Vector<Real> coord(nodes.storage() + spatial_dimension * *it,
spatial_dimension);
nodes_to_send->push_back(coord);
}
if (p != root) { /// send them for distant processors
AKANTU_DEBUG_INFO("Sending coordinates to proc "
<< p << " "
<< Tag::genTag(this->rank, 0, Tag::_COORDINATES));
comm.send(*nodes_to_send, p,
Tag::genTag(this->rank, 0, Tag::_COORDINATES));
delete nodes_to_send;
}
}
/// construct the local nodes coordinates
nodes.copy(local_nodes);
}
/* -------------------------------------------------------------------------- */
void MasterNodeInfoPerProc::synchronizeTypes() {
// <global_id, <proc, local_id> >
std::multimap<UInt, std::pair<UInt, UInt>> nodes_to_proc;
std::vector<Array<NodeType>> nodes_type_per_proc(nb_proc);
// arrays containing pairs of (proc, node)
std::vector<Array<UInt>> nodes_to_send_per_proc(nb_proc);
for (UInt p = 0; p < nb_proc; ++p) {
nodes_type_per_proc[p].resize(nb_nodes_per_proc(p));
}
this->fillNodesType();
for (UInt p = 0; p < nb_proc; ++p) {
auto & nodes_types = nodes_type_per_proc[p];
if (p != root) {
AKANTU_DEBUG_INFO(
"Receiving first nodes types from proc "
<< p << " "
<< Tag::genTag(this->rank, this->message_count, Tag::_NODES_TYPE));
comm.receive(nodes_types, p, Tag::genTag(p, 0, Tag::_NODES_TYPE));
} else {
nodes_types.copy(this->getNodesType());
}
// stack all processors claiming to be master for a node
for (UInt local_node = 0; local_node < nb_nodes_per_proc(p); ++local_node) {
if (nodes_types(local_node) == _nt_master) {
UInt global_node = nodes_per_proc[p](local_node);
- nodes_to_proc.insert(std::make_pair(global_node, std::make_pair(p, local_node)));
+ nodes_to_proc.insert(
+ std::make_pair(global_node, std::make_pair(p, local_node)));
}
}
}
for (UInt i = 0; i < mesh.getNbGlobalNodes(); ++i) {
auto it_range = nodes_to_proc.equal_range(i);
if (it_range.first == nodes_to_proc.end() || it_range.first->first != i)
continue;
// pick the first processor out of the multi-map as the actual master
UInt master_proc = (it_range.first)->second.first;
for (auto it_node = it_range.first; it_node != it_range.second; ++it_node) {
UInt proc = it_node->second.first;
UInt node = it_node->second.second;
if (proc != master_proc) {
// store the info on all the slaves for a given master
nodes_type_per_proc[proc](node) = NodeType(master_proc);
nodes_to_send_per_proc[master_proc].push_back(proc);
nodes_to_send_per_proc[master_proc].push_back(i);
}
}
}
-
std::vector<CommunicationRequest> requests_send_type;
std::vector<CommunicationRequest> requests_send_master_info;
for (UInt p = 0; p < nb_proc; ++p) {
if (p != root) {
AKANTU_DEBUG_INFO("Sending nodes types to proc "
<< p << " "
<< Tag::genTag(this->rank, 0, Tag::_NODES_TYPE));
requests_send_type.push_back(
comm.asyncSend(nodes_type_per_proc[p], p,
Tag::genTag(this->rank, 0, Tag::_NODES_TYPE)));
auto & nodes_to_send = nodes_to_send_per_proc[p];
/// push back an element to avoid a send of size 0
nodes_to_send.push_back(-1);
AKANTU_DEBUG_INFO("Sending nodes master info to proc "
<< p << " "
<< Tag::genTag(this->rank, 1, Tag::_NODES_TYPE));
- requests_send_master_info.push_back(
- comm.asyncSend(nodes_to_send, p,
- Tag::genTag(this->rank, 1, Tag::_NODES_TYPE)));
+ requests_send_master_info.push_back(comm.asyncSend(
+ nodes_to_send, p, Tag::genTag(this->rank, 1, Tag::_NODES_TYPE)));
} else {
this->getNodesType().copy(nodes_type_per_proc[p]);
this->fillCommunicationScheme(nodes_to_send_per_proc[root]);
}
}
comm.waitAll(requests_send_type);
comm.freeCommunicationRequest(requests_send_type);
requests_send_type.clear();
comm.waitAll(requests_send_master_info);
comm.freeCommunicationRequest(requests_send_master_info);
}
/* -------------------------------------------------------------------------- */
void MasterNodeInfoPerProc::synchronizeGroups() {
AKANTU_DEBUG_IN();
UInt nb_total_nodes = mesh.getNbGlobalNodes();
DynamicCommunicationBuffer buffer;
using NodeToGroup = std::vector<std::vector<std::string>>;
NodeToGroup node_to_group;
node_to_group.resize(nb_total_nodes);
GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
GroupManager::const_node_group_iterator nge = mesh.node_group_end();
for (; ngi != nge; ++ngi) {
NodeGroup & ng = *(ngi->second);
std::string name = ngi->first;
NodeGroup::const_node_iterator nit = ng.begin();
NodeGroup::const_node_iterator nend = ng.end();
for (; nit != nend; ++nit) {
node_to_group[*nit].push_back(name);
}
nit = ng.begin();
if (nit != nend)
ng.empty();
}
buffer << node_to_group;
std::vector<CommunicationRequest> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if (p == this->rank)
continue;
AKANTU_DEBUG_INFO("Sending node groups to proc "
<< p << " "
<< Tag::genTag(this->rank, p, Tag::_NODE_GROUP));
requests.push_back(comm.asyncSend(
buffer, p, Tag::genTag(this->rank, p, Tag::_NODE_GROUP)));
}
this->fillNodeGroupsFromBuffer(buffer);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
SlaveNodeInfoPerProc::SlaveNodeInfoPerProc(NodeSynchronizer & synchronizer,
UInt message_cnt, UInt root)
: NodeInfoPerProc(synchronizer, message_cnt, root) {
UInt nb_global_nodes = 0;
comm.broadcast(nb_global_nodes, root);
this->setNbGlobalNodes(nb_global_nodes);
}
/* -------------------------------------------------------------------------- */
void SlaveNodeInfoPerProc::synchronizeNodes() {
AKANTU_DEBUG_INFO("Sending list of nodes to proc "
<< root << " " << Tag::genTag(this->rank, 0, Tag::_NB_NODES)
<< " " << Tag::genTag(this->rank, 0, Tag::_NODES));
Array<UInt> & local_ids = this->getNodesGlobalIds();
Array<Real> & nodes = this->getNodes();
UInt nb_nodes = local_ids.size();
comm.send(nb_nodes, root, Tag::genTag(this->rank, 0, Tag::_NB_NODES));
comm.send(local_ids, root, Tag::genTag(this->rank, 0, Tag::_NODES));
/* --------<<<<-COORDINATES---------------------------------------------- */
nodes.resize(nb_nodes);
AKANTU_DEBUG_INFO("Receiving coordinates from proc "
<< root << " " << Tag::genTag(root, 0, Tag::_COORDINATES));
comm.receive(nodes, root, Tag::genTag(root, 0, Tag::_COORDINATES));
}
/* -------------------------------------------------------------------------- */
void SlaveNodeInfoPerProc::synchronizeTypes() {
this->fillNodesType();
Array<NodeType> & nodes_types = this->getNodesType();
AKANTU_DEBUG_INFO("Sending first nodes types to proc "
<< root << ""
<< Tag::genTag(this->rank, 0, Tag::_NODES_TYPE));
comm.send(nodes_types, root, Tag::genTag(this->rank, 0, Tag::_NODES_TYPE));
AKANTU_DEBUG_INFO("Receiving nodes types from proc "
<< root << " " << Tag::genTag(root, 0, Tag::_NODES_TYPE));
comm.receive(nodes_types, root, Tag::genTag(root, 0, Tag::_NODES_TYPE));
-
AKANTU_DEBUG_INFO("Receiving nodes master info from proc "
<< root << " " << Tag::genTag(root, 1, Tag::_NODES_TYPE));
CommunicationStatus status;
comm.probe<UInt>(root, Tag::genTag(root, 1, Tag::_NODES_TYPE), status);
Array<UInt> nodes_master_info(status.size());
- comm.receive(nodes_master_info, root,
- Tag::genTag(root, 1, Tag::_NODES_TYPE));
+ comm.receive(nodes_master_info, root, Tag::genTag(root, 1, Tag::_NODES_TYPE));
nodes_master_info.resize(nodes_master_info.size() - 1);
this->fillCommunicationScheme(nodes_master_info);
}
/* -------------------------------------------------------------------------- */
void SlaveNodeInfoPerProc::synchronizeGroups() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Receiving node groups from proc "
<< root << " "
<< Tag::genTag(root, this->rank, Tag::_NODE_GROUP));
CommunicationStatus status;
comm.probe<char>(root, Tag::genTag(root, this->rank, Tag::_NODE_GROUP),
status);
CommunicationBuffer buffer(status.size());
comm.receive(buffer, root, Tag::genTag(root, this->rank, Tag::_NODE_GROUP));
this->fillNodeGroupsFromBuffer(buffer);
AKANTU_DEBUG_OUT();
}
} // akantu
diff --git a/src/synchronizer/node_info_per_processor.hh b/src/synchronizer/node_info_per_processor.hh
index e75fcafd7..da67e5479 100644
--- a/src/synchronizer/node_info_per_processor.hh
+++ b/src/synchronizer/node_info_per_processor.hh
@@ -1,110 +1,107 @@
/**
* @file node_info_per_processor.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Mar 11 14:45:15 2016
*
* @brief Helper classes to create the distributed synchronizer and distribute
* a mesh
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_accessor.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NODE_INFO_PER_PROCESSOR_HH__
#define __AKANTU_NODE_INFO_PER_PROCESSOR_HH__
namespace akantu {
class NodeSynchronizer;
class Communicator;
}
/* -------------------------------------------------------------------------- */
namespace akantu {
class NodeInfoPerProc : protected MeshAccessor {
public:
- NodeInfoPerProc(NodeSynchronizer & synchronizer,
- UInt message_cnt,
- UInt root);
+ NodeInfoPerProc(NodeSynchronizer & synchronizer, UInt message_cnt, UInt root);
virtual void synchronizeNodes() = 0;
virtual void synchronizeTypes() = 0;
virtual void synchronizeGroups() = 0;
protected:
template <class CommunicationBuffer>
void fillNodeGroupsFromBuffer(CommunicationBuffer & buffer);
void fillNodesType();
void fillCommunicationScheme(const Array<UInt> &);
+
protected:
NodeSynchronizer & synchronizer;
const Communicator & comm;
UInt rank;
UInt nb_proc;
UInt root;
Mesh & mesh;
UInt spatial_dimension;
UInt message_count;
};
/* -------------------------------------------------------------------------- */
class MasterNodeInfoPerProc : protected NodeInfoPerProc {
public:
- MasterNodeInfoPerProc(NodeSynchronizer & synchronizer,
- UInt message_cnt,
+ MasterNodeInfoPerProc(NodeSynchronizer & synchronizer, UInt message_cnt,
UInt root);
void synchronizeNodes() override;
void synchronizeTypes() override;
void synchronizeGroups() override;
private:
/// get the list of nodes to send and send them
- std::vector<Array<UInt> > nodes_per_proc;
+ std::vector<Array<UInt>> nodes_per_proc;
Array<UInt> nb_nodes_per_proc;
};
/* -------------------------------------------------------------------------- */
class SlaveNodeInfoPerProc : protected NodeInfoPerProc {
public:
- SlaveNodeInfoPerProc(NodeSynchronizer & synchronizer,
- UInt message_cnt,
+ SlaveNodeInfoPerProc(NodeSynchronizer & synchronizer, UInt message_cnt,
UInt root);
void synchronizeNodes() override;
void synchronizeTypes() override;
void synchronizeGroups() override;
private:
};
} // akantu
#endif /* __AKANTU_NODE_INFO_PER_PROCESSOR_HH__ */
diff --git a/src/synchronizer/node_synchronizer.hh b/src/synchronizer/node_synchronizer.hh
index 08b8b48d0..cc600ca2b 100644
--- a/src/synchronizer/node_synchronizer.hh
+++ b/src/synchronizer/node_synchronizer.hh
@@ -1,88 +1,86 @@
/**
* @file node_synchronizer.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Sep 23 11:45:24 2016
*
* @brief Synchronizer for nodal information
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_events.hh"
#include "synchronizer_impl.hh"
/* -------------------------------------------------------------------------- */
#include <unordered_map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NODE_SYNCHRONIZER_HH__
#define __AKANTU_NODE_SYNCHRONIZER_HH__
namespace akantu {
class NodeSynchronizer : public MeshEventHandler,
public SynchronizerImpl<UInt> {
public:
NodeSynchronizer(Mesh & mesh, const ID & id = "element_synchronizer",
MemoryID memory_id = 0,
const bool register_to_event_manager = true,
EventHandlerPriority event_priority = _ehp_synchronizer);
~NodeSynchronizer() override;
friend class NodeInfoPerProc;
/// function to implement to react on akantu::NewNodesEvent
void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override;
/// function to implement to react on akantu::RemovedNodesEvent
void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
const RemovedNodesEvent &) override {}
/// function to implement to react on akantu::NewElementsEvent
void onElementsAdded(const Array<Element> &,
const NewElementsEvent &) override {}
/// function to implement to react on akantu::RemovedElementsEvent
void onElementsRemoved(const Array<Element> &,
const ElementTypeMapArray<UInt> &,
const RemovedElementsEvent &) override {}
/// function to implement to react on akantu::ChangedElementsEvent
void onElementsChanged(const Array<Element> &, const Array<Element> &,
const ElementTypeMapArray<UInt> &,
const ChangedElementsEvent &) override {}
public:
AKANTU_GET_MACRO(Mesh, mesh, Mesh &);
protected:
- Int getRank(const UInt & /*node*/) const final {
- AKANTU_TO_IMPLEMENT();
- }
+ Int getRank(const UInt & /*node*/) const final { AKANTU_TO_IMPLEMENT(); }
protected:
Mesh & mesh;
- //std::unordered_map<UInt, Int> node_to_prank;
+ // std::unordered_map<UInt, Int> node_to_prank;
};
} // namespace akantu
#endif /* __AKANTU_NODE_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/slave_element_info_per_processor.cc b/src/synchronizer/slave_element_info_per_processor.cc
index ed2e9c514..0d9415e1a 100644
--- a/src/synchronizer/slave_element_info_per_processor.cc
+++ b/src/synchronizer/slave_element_info_per_processor.cc
@@ -1,197 +1,197 @@
/**
* @file slave_element_info_per_processor.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Mar 11 14:59:21 2016
*
* @brief
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include "communicator.hh"
#include "element_info_per_processor.hh"
#include "element_synchronizer.hh"
#include "mesh_utils.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <algorithm>
#include <iostream>
#include <map>
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
SlaveElementInfoPerProc::SlaveElementInfoPerProc(
ElementSynchronizer & synchronizer, UInt message_cnt, UInt root)
: ElementInfoPerProc(synchronizer, message_cnt, root, _not_defined) {
Vector<UInt> size(5);
comm.receive(size, this->root,
Tag::genTag(this->root, this->message_count, Tag::_SIZES));
this->type = (ElementType)size[0];
this->nb_local_element = size[1];
this->nb_ghost_element = size[2];
this->nb_element_to_receive = size[3];
this->nb_tags = size[4];
if (this->type != _not_defined)
this->nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
}
/* -------------------------------------------------------------------------- */
bool SlaveElementInfoPerProc::needSynchronize() {
return this->type != _not_defined;
}
/* -------------------------------------------------------------------------- */
void SlaveElementInfoPerProc::synchronizeConnectivities() {
Array<UInt> local_connectivity(
(this->nb_local_element + this->nb_ghost_element) *
this->nb_nodes_per_element);
AKANTU_DEBUG_INFO("Receiving connectivities from proc " << root);
comm.receive(
local_connectivity, this->root,
Tag::genTag(this->root, this->message_count, Tag::_CONNECTIVITY));
auto & old_nodes = this->getNodesGlobalIds();
AKANTU_DEBUG_INFO("Renumbering local connectivities");
MeshUtils::renumberMeshNodes(this->mesh, local_connectivity,
this->nb_local_element, this->nb_ghost_element,
this->type, old_nodes);
}
/* -------------------------------------------------------------------------- */
void SlaveElementInfoPerProc::synchronizePartitions() {
Array<UInt> local_partitions(this->nb_element_to_receive +
this->nb_ghost_element * 2);
AKANTU_DEBUG_INFO("Receiving partition informations from proc " << root);
this->comm.receive(local_partitions, this->root,
Tag::genTag(root, this->message_count, Tag::_PARTITIONS));
if (Mesh::getSpatialDimension(this->type) ==
this->mesh.getSpatialDimension()) {
AKANTU_DEBUG_INFO("Creating communications scheme");
this->fillCommunicationScheme(local_partitions);
}
}
/* -------------------------------------------------------------------------- */
void SlaveElementInfoPerProc::synchronizeTags() {
AKANTU_DEBUG_IN();
if (this->nb_tags == 0) {
AKANTU_DEBUG_OUT();
return;
}
/* --------<<<<-TAGS------------------------------------------------- */
UInt mesh_data_sizes_buffer_length = 0;
CommunicationBuffer mesh_data_sizes_buffer;
AKANTU_DEBUG_INFO(
"Receiving the size of the information about the mesh data tags.");
comm.broadcast(mesh_data_sizes_buffer_length, root);
if (mesh_data_sizes_buffer_length != 0) {
mesh_data_sizes_buffer.resize(mesh_data_sizes_buffer_length);
AKANTU_DEBUG_INFO(
"Receiving the information about the mesh data tags, addr "
<< (void *)mesh_data_sizes_buffer.storage());
comm.broadcast(mesh_data_sizes_buffer, root);
AKANTU_DEBUG_INFO("Size of the information about the mesh data: "
<< mesh_data_sizes_buffer_length);
std::vector<std::string> tag_names;
std::vector<MeshDataTypeCode> tag_type_codes;
std::vector<UInt> tag_nb_component;
tag_names.resize(nb_tags);
tag_type_codes.resize(nb_tags);
tag_nb_component.resize(nb_tags);
CommunicationBuffer mesh_data_buffer;
UInt type_code_int;
for (UInt i(0); i < nb_tags; ++i) {
mesh_data_sizes_buffer >> tag_names[i];
mesh_data_sizes_buffer >> type_code_int;
tag_type_codes[i] = static_cast<MeshDataTypeCode>(type_code_int);
mesh_data_sizes_buffer >> tag_nb_component[i];
}
std::vector<std::string>::const_iterator names_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
CommunicationStatus mesh_data_comm_status;
AKANTU_DEBUG_INFO("Checking size of data to receive for mesh data TAG("
<< Tag::genTag(root, this->message_count, Tag::_MESH_DATA)
<< ")");
comm.probe<char>(root,
Tag::genTag(root, this->message_count, Tag::_MESH_DATA),
mesh_data_comm_status);
UInt mesh_data_buffer_size(mesh_data_comm_status.size());
AKANTU_DEBUG_INFO("Receiving "
<< mesh_data_buffer_size << " bytes of mesh data TAG("
<< Tag::genTag(root, this->message_count, Tag::_MESH_DATA)
<< ")");
mesh_data_buffer.resize(mesh_data_buffer_size);
comm.receive(mesh_data_buffer, root,
Tag::genTag(root, this->message_count, Tag::_MESH_DATA));
// Loop over each tag for the current type
UInt k(0);
for (; names_it != names_end; ++names_it, ++k) {
this->fillMeshData(mesh_data_buffer, *names_it, tag_type_codes[k],
tag_nb_component[k]);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SlaveElementInfoPerProc::synchronizeGroups() {
AKANTU_DEBUG_IN();
const Communicator & comm = mesh.getCommunicator();
UInt my_rank = comm.whoAmI();
AKANTU_DEBUG_INFO("Receiving element groups from proc "
<< root << " TAG("
<< Tag::genTag(root, my_rank, Tag::_ELEMENT_GROUP) << ")");
CommunicationStatus status;
comm.probe<char>(root, Tag::genTag(root, my_rank, Tag::_ELEMENT_GROUP),
status);
CommunicationBuffer buffer(status.size());
comm.receive(buffer, root, Tag::genTag(root, my_rank, Tag::_ELEMENT_GROUP));
this->fillElementGroupsFromBuffer(buffer);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
} // akantu
diff --git a/src/synchronizer/synchronizer_impl_tmpl.hh b/src/synchronizer/synchronizer_impl_tmpl.hh
index b8129ce99..7831fbc79 100644
--- a/src/synchronizer/synchronizer_impl_tmpl.hh
+++ b/src/synchronizer/synchronizer_impl_tmpl.hh
@@ -1,314 +1,314 @@
/**
* @file synchronizer_impl_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Aug 24 13:29:47 2016
*
* @brief Implementation of the SynchronizerImpl
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "synchronizer_impl.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SYNCHRONIZER_IMPL_TMPL_HH__
#define __AKANTU_SYNCHRONIZER_IMPL_TMPL_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template <class Entity>
SynchronizerImpl<Entity>::SynchronizerImpl(const Communicator & comm,
const ID & id, MemoryID memory_id)
: Synchronizer(comm, id, memory_id), communications(comm) {}
/* -------------------------------------------------------------------------- */
template <class Entity>
SynchronizerImpl<Entity>::SynchronizerImpl(const SynchronizerImpl & other,
- const ID & id)
+ const ID & id)
: Synchronizer(other), communications(other.communications) {
this->id = id;
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void SynchronizerImpl<Entity>::synchronizeOnceImpl(
DataAccessor<Entity> & data_accessor,
const SynchronizationTag & tag) const {
// no need to synchronize
if (this->nb_proc == 1)
return;
using CommunicationRequests = std::vector<CommunicationRequest>;
using CommunicationBuffers = std::map<UInt, CommunicationBuffer>;
CommunicationRequests send_requests, recv_requests;
CommunicationBuffers send_buffers, recv_buffers;
auto postComm = [&](const CommunicationSendRecv & sr,
CommunicationBuffers & buffers,
CommunicationRequests & requests) -> void {
for (auto && pair : communications.iterateSchemes(sr)) {
auto & proc = pair.first;
const auto & scheme = pair.second;
auto & buffer = buffers[proc];
UInt buffer_size = data_accessor.getNbData(scheme, tag);
buffer.resize(buffer_size);
if (sr == _recv) {
requests.push_back(communicator.asyncReceive(
buffer, proc,
Tag::genTag(this->rank, 0, Tag::_SYNCHRONIZE, this->hash_id)));
} else {
data_accessor.packData(buffer, scheme, tag);
send_requests.push_back(communicator.asyncSend(
buffer, proc,
Tag::genTag(proc, 0, Tag::_SYNCHRONIZE, this->hash_id)));
}
}
};
// post the receive requests
postComm(_recv, recv_buffers, recv_requests);
// post the send data requests
postComm(_send, send_buffers, send_requests);
// treat the receive requests
UInt request_ready;
while ((request_ready = communicator.waitAny(recv_requests)) != UInt(-1)) {
CommunicationRequest & req = recv_requests[request_ready];
UInt proc = req.getSource();
CommunicationBuffer & buffer = recv_buffers[proc];
const auto & scheme = this->communications.getScheme(proc, _recv);
data_accessor.unpackData(buffer, scheme, tag);
req.free();
recv_requests.erase(recv_requests.begin() + request_ready);
}
communicator.waitAll(send_requests);
communicator.freeCommunicationRequest(send_requests);
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void SynchronizerImpl<Entity>::asynchronousSynchronizeImpl(
const DataAccessor<Entity> & data_accessor,
const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
if (not this->communications.hasCommunicationSize(tag))
this->computeBufferSize(data_accessor, tag);
this->communications.incrementCounter(tag);
// Posting the receive -------------------------------------------------------
if (this->communications.hasPendingRecv(tag)) {
AKANTU_CUSTOM_EXCEPTION_INFO(
debug::CommunicationException(),
"There must still be some pending receive communications."
<< " Tag is " << tag << " Cannot start new ones");
}
for (auto && comm_desc : this->communications.iterateRecv(tag)) {
comm_desc.postRecv(this->hash_id);
}
// Posting the sends -------------------------------------------------------
if (communications.hasPendingSend(tag)) {
AKANTU_CUSTOM_EXCEPTION_INFO(
debug::CommunicationException(),
"There must be some pending sending communications."
<< " Tag is " << tag);
}
for (auto && comm_desc : this->communications.iterateSend(tag)) {
comm_desc.resetBuffer();
#ifndef AKANTU_NDEBUG
this->packSanityCheckData(comm_desc);
#endif
comm_desc.packData(data_accessor);
comm_desc.postSend(this->hash_id);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void SynchronizerImpl<Entity>::waitEndSynchronizeImpl(
DataAccessor<Entity> & data_accessor, const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
#ifndef AKANTU_NDEBUG
if (this->communications.begin(tag, _recv) !=
this->communications.end(tag, _recv) &&
!this->communications.hasPendingRecv(tag))
AKANTU_CUSTOM_EXCEPTION_INFO(debug::CommunicationException(),
"No pending communication with the tag \""
<< tag);
#endif
auto recv_end = this->communications.end(tag, _recv);
decltype(recv_end) recv_it;
while ((recv_it = this->communications.waitAnyRecv(tag)) != recv_end) {
auto && comm_desc = *recv_it;
#ifndef AKANTU_NDEBUG
this->unpackSanityCheckData(comm_desc);
#endif
comm_desc.unpackData(data_accessor);
comm_desc.resetBuffer();
comm_desc.freeRequest();
}
this->communications.waitAllSend(tag);
this->communications.freeSendRequests(tag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void SynchronizerImpl<Entity>::computeAllBufferSizes(
const DataAccessor<Entity> & data_accessor) {
for (auto && tag : this->communications.iterateTags()) {
this->computeBufferSize(data_accessor, tag);
}
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void SynchronizerImpl<Entity>::computeBufferSizeImpl(
const DataAccessor<Entity> & data_accessor,
const SynchronizationTag & tag) {
AKANTU_DEBUG_IN();
if (not this->communications.hasCommunication(tag)) {
this->communications.initializeCommunications(tag);
AKANTU_DEBUG_ASSERT(communications.hasCommunication(tag) == true,
"Communications where not properly initialized");
}
for (auto sr : iterate_send_recv) {
for (auto && pair : this->communications.iterateSchemes(sr)) {
auto proc = pair.first;
const auto & scheme = pair.second;
UInt size = 0;
#ifndef AKANTU_NDEBUG
size += this->sanityCheckDataSize(scheme, tag);
#endif
size += data_accessor.getNbData(scheme, tag);
AKANTU_DEBUG_INFO("I have "
<< size << "(" << printMemorySize<char>(size) << " - "
<< scheme.size() << " element(s)) data to "
<< std::string(sr == _recv ? "receive from" : "send to")
<< proc << " for tag " << tag);
this->communications.setCommunicationSize(tag, proc, size, sr);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename Entity>
template <typename Pred>
void SynchronizerImpl<Entity>::split(SynchronizerImpl<Entity> & in_synchronizer,
Pred && pred) {
AKANTU_DEBUG_IN();
auto filter_list = [&](auto & list, auto & new_list) {
auto copy = list;
list.resize(0);
new_list.resize(0);
for (auto && entity : copy) {
if (std::forward<Pred>(pred)(entity)) {
new_list.push_back(entity);
} else {
list.push_back(entity);
}
}
};
for (auto sr : iterate_send_recv) {
for (auto & scheme_pair :
in_synchronizer.communications.iterateSchemes(sr)) {
auto proc = scheme_pair.first;
auto & scheme = scheme_pair.second;
auto & new_scheme = communications.createScheme(proc, sr);
filter_list(scheme, new_scheme);
}
}
in_synchronizer.communications.invalidateSizes();
communications.invalidateSizes();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <typename Entity>
template <typename Updater>
void SynchronizerImpl<Entity>::updateSchemes(Updater && scheme_updater) {
for (auto sr : iterate_send_recv) {
for (auto & scheme_pair : communications.iterateSchemes(sr)) {
auto proc = scheme_pair.first;
auto & scheme = scheme_pair.second;
std::forward<Updater>(scheme_updater)(scheme, proc, sr);
}
}
communications.invalidateSizes();
}
/* -------------------------------------------------------------------------- */
template <class Entity>
UInt SynchronizerImpl<Entity>::sanityCheckDataSize(
const Array<Entity> &, const SynchronizationTag &) const {
return 0;
}
/* -------------------------------------------------------------------------- */
template <class Entity>
void SynchronizerImpl<Entity>::packSanityCheckData(
CommunicationDescriptor<Entity> &) const {}
/* -------------------------------------------------------------------------- */
template <class Entity>
void SynchronizerImpl<Entity>::unpackSanityCheckData(
CommunicationDescriptor<Entity> &) const {}
/* -------------------------------------------------------------------------- */
} // namespace akantu
#endif /* __AKANTU_SYNCHRONIZER_IMPL_TMPL_HH__ */
diff --git a/src/synchronizer/synchronizer_registry.hh b/src/synchronizer/synchronizer_registry.hh
index 3d53e91a3..1edf20b9a 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/src/synchronizer/synchronizer_registry.hh
@@ -1,92 +1,91 @@
/**
* @file synchronizer_registry.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Tue Dec 09 2014
*
* @brief Registry of synchronizers
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SYNCHRONIZER_REGISTRY_HH__
#define __AKANTU_SYNCHRONIZER_REGISTRY_HH__
namespace akantu {
class DataAccessorBase;
class Synchronizer;
}
namespace akantu {
class SynchronizerRegistry {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SynchronizerRegistry();
virtual ~SynchronizerRegistry();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// synchronize operation
void synchronize(SynchronizationTag tag);
/// asynchronous synchronization
void asynchronousSynchronize(SynchronizationTag tag);
/// wait end of asynchronous synchronization
void waitEndSynchronize(SynchronizationTag tag);
/// register a new synchronization
void registerSynchronizer(Synchronizer & synchronizer,
SynchronizationTag tag);
/// Register a different data accessor.
void registerDataAccessor(DataAccessorBase & data_accessor);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
using Tag2Sync = std::multimap<SynchronizationTag, Synchronizer *>;
/// list of registered synchronization
Tag2Sync synchronizers;
/// data accessor that will permit to do the pack/unpack things
DataAccessorBase * data_accessor{nullptr};
};
-
} // akantu
#endif /* __AKANTU_SYNCHRONIZER_REGISTRY_HH__ */
diff --git a/test/test_common/test_csr.cc b/test/test_common/test_csr.cc
index a04264867..cf032e5fe 100644
--- a/test/test_common/test_csr.cc
+++ b/test/test_common/test_csr.cc
@@ -1,105 +1,103 @@
/**
* @file test_csr.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 30 2012
* @date last modification: Sun Oct 19 2014
*
* @brief Test the CSR (compressed sparse row) data structure
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_csr.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
class TestCsrFixture : public ::testing::Test {
protected:
void SetUp() override {
csr.resizeRows(N);
csr.clearRows();
for (UInt i = 0; i < N; ++i) {
UInt nb_cols(UInt(rand() * double(N) / (RAND_MAX + 1.)));
nb_cols_per_row.push_back(nb_cols);
for (UInt j = 0; j < nb_cols; ++j) {
++csr.rowOffset(i);
}
}
csr.countToCSR();
csr.resizeCols();
csr.beginInsertions();
for (UInt i = 0; i < N; ++i) {
UInt nb_cols = nb_cols_per_row[i];
for (UInt j = 0; j < nb_cols; ++j) {
csr.insertInRow(i, nb_cols - j);
}
}
csr.endInsertions();
}
std::vector<UInt> nb_cols_per_row;
CSR<UInt> csr;
size_t N = 1000;
};
-TEST_F(TestCsrFixture, CheckInsertion) {
- EXPECT_EQ(N, this->csr.getNbRows());
-}
+TEST_F(TestCsrFixture, CheckInsertion) { EXPECT_EQ(N, this->csr.getNbRows()); }
TEST_F(TestCsrFixture, Iteration) {
for (UInt i = 0; i < this->csr.getNbRows(); ++i) {
auto it = this->csr.begin(i);
auto end = this->csr.end(i);
UInt nb_cols = this->nb_cols_per_row[i];
for (; it != end; ++it) {
EXPECT_EQ(nb_cols, *it);
nb_cols--;
}
EXPECT_EQ(0, nb_cols);
}
}
TEST_F(TestCsrFixture, ReverseIteration) {
for (UInt i = 0; i < csr.getNbRows(); ++i) {
auto it = csr.rbegin(i);
auto end = csr.rend(i);
UInt nb_cols = nb_cols_per_row[i];
UInt j = nb_cols;
for (; it != end; --it) {
EXPECT_EQ((nb_cols - j + 1), *it);
j--;
}
EXPECT_EQ(0, j);
}
}
diff --git a/test/test_common/test_grid.cc b/test/test_common/test_grid.cc
index 4638b4c5f..d9093ca7f 100644
--- a/test/test_common/test_grid.cc
+++ b/test/test_common/test_grid.cc
@@ -1,107 +1,108 @@
/**
* @file test_grid.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Thu Aug 06 2015
*
* @brief Test the grid object
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_grid_dynamic.hh"
#include "mesh.hh"
#include "mesh_io.hh"
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
const UInt spatial_dimension = 2;
akantu::initialize(argc, argv);
Mesh circle(spatial_dimension);
circle.read("circle.msh");
const auto & l = circle.getLocalLowerBounds();
const auto & u = circle.getLocalUpperBounds();
Real spacing[spatial_dimension] = {0.2, 0.2};
Vector<Real> s(spacing, spatial_dimension);
Vector<Real> c = u;
c += l;
c /= 2.;
SpatialGrid<Element> grid(spatial_dimension, s, c);
Vector<Real> bary(spatial_dimension);
Element el;
el.ghost_type = _not_ghost;
- auto it = circle.firstType(spatial_dimension);
- auto last_type = circle.lastType (spatial_dimension);
- for(; it != last_type; ++it) {
+ auto it = circle.firstType(spatial_dimension);
+ auto last_type = circle.lastType(spatial_dimension);
+ for (; it != last_type; ++it) {
UInt nb_element = circle.getNbElement(*it);
el.type = *it;
for (UInt e = 0; e < nb_element; ++e) {
el.element = e;
circle.getBarycenter(el, bary);
grid.insert(el, bary);
}
}
std::cout << grid << std::endl;
Mesh mesh(spatial_dimension, "save");
grid.saveAsMesh(mesh);
mesh.write("grid.msh");
Vector<Real> pos(spatial_dimension);
// const SpatialGrid<Element>::CellID & id = grid.getCellID(pos);
-// #if !defined AKANTU_NDEBUG
-// SpatialGrid<Element>::neighbor_cells_iterator nit = grid.beginNeighborCells(id);
-// SpatialGrid<Element>::neighbor_cells_iterator nend = grid.endNeighborCells(id);
-// for(;nit != nend; ++nit) {
-// std::cout << std::endl;
-// const SpatialGrid<Element>::Cell & cell = grid.getCell(*nit);
-// SpatialGrid<Element>::Cell::const_iterator cit = cell.begin();
-// SpatialGrid<Element>::Cell::position_iterator pit = cell.begin_pos();
-// SpatialGrid<Element>::Cell::const_iterator cend = cell.end();
-// for (; cit != cend; ++cit, ++pit) {
-// std::cout << *cit << " " << *pit << std::endl;
-// }
-// }
-// #endif
-
+ // #if !defined AKANTU_NDEBUG
+ // SpatialGrid<Element>::neighbor_cells_iterator nit =
+ // grid.beginNeighborCells(id);
+ // SpatialGrid<Element>::neighbor_cells_iterator nend =
+ // grid.endNeighborCells(id);
+ // for(;nit != nend; ++nit) {
+ // std::cout << std::endl;
+ // const SpatialGrid<Element>::Cell & cell = grid.getCell(*nit);
+ // SpatialGrid<Element>::Cell::const_iterator cit = cell.begin();
+ // SpatialGrid<Element>::Cell::position_iterator pit = cell.begin_pos();
+ // SpatialGrid<Element>::Cell::const_iterator cend = cell.end();
+ // for (; cit != cend; ++cit, ++pit) {
+ // std::cout << *cit << " " << *pit << std::endl;
+ // }
+ // }
+ // #endif
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_common/test_tensors.cc b/test/test_common/test_tensors.cc
index d52b9d302..ec1797a10 100644
--- a/test/test_common/test_tensors.cc
+++ b/test/test_common/test_tensors.cc
@@ -1,533 +1,533 @@
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "aka_types.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <gtest/gtest.h>
#include <memory>
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
/* -------------------------------------------------------------------------- */
class TensorConstructorFixture : public ::testing::Test {
public:
void SetUp() override {
for (auto & r : reference) {
r = rand(); // google-test seeds srand()
}
}
void TearDown() override {}
template <typename V> void compareToRef(const V & v) {
for (int i = 0; i < size_; ++i) {
EXPECT_DOUBLE_EQ(reference[i], v.storage()[i]);
}
}
protected:
const int size_{24};
const std::array<int, 2> mat_size{{4, 6}};
// const std::array<int, 3> tens3_size{{4, 2, 3}};
std::array<double, 24> reference;
};
/* -------------------------------------------------------------------------- */
class TensorFixture : public TensorConstructorFixture {
public:
TensorFixture()
: vref(reference.data(), size_),
mref(reference.data(), mat_size[0], mat_size[1]) {}
protected:
Vector<double> vref;
Matrix<double> mref;
};
/* -------------------------------------------------------------------------- */
// Vector ----------------------------------------------------------------------
TEST_F(TensorConstructorFixture, VectorDefaultConstruct) {
Vector<double> v;
EXPECT_EQ(0, v.size());
EXPECT_EQ(nullptr, v.storage());
EXPECT_EQ(false, v.isWrapped());
}
TEST_F(TensorConstructorFixture, VectorConstruct1) {
double r = rand();
Vector<double> v(size_, r);
EXPECT_EQ(size_, v.size());
EXPECT_EQ(false, v.isWrapped());
for (int i = 0; i < size_; ++i) {
EXPECT_DOUBLE_EQ(r, v(i));
EXPECT_DOUBLE_EQ(r, v[i]);
}
}
TEST_F(TensorConstructorFixture, VectorConstructWrapped) {
Vector<double> v(reference.data(), size_);
EXPECT_EQ(size_, v.size());
EXPECT_EQ(true, v.isWrapped());
for (int i = 0; i < size_; ++i) {
EXPECT_DOUBLE_EQ(reference[i], v(i));
EXPECT_DOUBLE_EQ(reference[i], v[i]);
}
}
TEST_F(TensorConstructorFixture, VectorConstructInitializer) {
Vector<double> v{0., 1., 2., 3., 4., 5.};
EXPECT_EQ(6, v.size());
EXPECT_EQ(false, v.isWrapped());
for (int i = 0; i < 6; ++i) {
EXPECT_DOUBLE_EQ(i, v(i));
}
}
TEST_F(TensorConstructorFixture, VectorConstructCopy1) {
Vector<double> vref(reference.data(), reference.size());
Vector<double> v(vref);
EXPECT_EQ(size_, v.size());
EXPECT_EQ(false, v.isWrapped());
compareToRef(v);
}
TEST_F(TensorConstructorFixture, VectorConstructCopy2) {
Vector<double> vref(reference.data(), reference.size());
Vector<double> v(vref, false);
EXPECT_EQ(size_, v.size());
EXPECT_EQ(true, v.isWrapped());
compareToRef(v);
}
TEST_F(TensorConstructorFixture, VectorConstructProxy1) {
VectorProxy<double> vref(reference.data(), reference.size());
EXPECT_EQ(size_, vref.size());
compareToRef(vref);
Vector<double> v(vref);
EXPECT_EQ(size_, v.size());
EXPECT_EQ(true, v.isWrapped());
compareToRef(v);
}
TEST_F(TensorConstructorFixture, VectorConstructProxy2) {
Vector<double> vref(reference.data(), reference.size());
VectorProxy<double> v(vref);
EXPECT_EQ(size_, v.size());
compareToRef(v);
}
/* -------------------------------------------------------------------------- */
TEST_F(TensorFixture, VectorEqual) {
Vector<double> v;
v = vref;
compareToRef(v);
EXPECT_EQ(size_, v.size());
EXPECT_EQ(false, v.isWrapped());
}
TEST_F(TensorFixture, VectorEqualProxy) {
VectorProxy<double> vref_proxy(vref);
Vector<double> v;
v = vref;
compareToRef(v);
EXPECT_EQ(size_, v.size());
EXPECT_EQ(false, v.isWrapped());
}
TEST_F(TensorFixture, VectorEqualProxy2) {
Vector<double> v_store(size_, 0.);
VectorProxy<double> v(v_store);
v = vref;
compareToRef(v);
compareToRef(v_store);
}
/* -------------------------------------------------------------------------- */
TEST_F(TensorFixture, VectorSet) {
Vector<double> v(vref);
compareToRef(v);
double r = rand();
v.set(r);
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(r, v[i]);
}
TEST_F(TensorFixture, VectorClear) {
Vector<double> v(vref);
compareToRef(v);
v.clear();
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(0, v[i]);
}
/* -------------------------------------------------------------------------- */
TEST_F(TensorFixture, VectorDivide) {
Vector<double> v;
double r = rand();
v = vref / r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] / r, v[i]);
}
TEST_F(TensorFixture, VectorMultiply1) {
Vector<double> v;
double r = rand();
v = vref * r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * r, v[i]);
}
TEST_F(TensorFixture, VectorMultiply2) {
Vector<double> v;
double r = rand();
v = r * vref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * r, v[i]);
}
TEST_F(TensorFixture, VectorAddition) {
Vector<double> v;
v = vref + vref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * 2., v[i]);
}
TEST_F(TensorFixture, VectorSubstract) {
Vector<double> v;
v = vref - vref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(0., v[i]);
}
TEST_F(TensorFixture, VectorDivideEqual) {
Vector<double> v(vref);
double r = rand();
v /= r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] / r, v[i]);
}
TEST_F(TensorFixture, VectorMultiplyEqual1) {
Vector<double> v(vref);
double r = rand();
v *= r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * r, v[i]);
}
TEST_F(TensorFixture, VectorMultiplyEqual2) {
Vector<double> v(vref);
v *= v;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * reference[i], v[i]);
}
TEST_F(TensorFixture, VectorAdditionEqual) {
Vector<double> v(vref);
v += vref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * 2., v[i]);
}
TEST_F(TensorFixture, VectorSubstractEqual) {
Vector<double> v(vref);
v -= vref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(0., v[i]);
}
/* -------------------------------------------------------------------------- */
// Matrix ----------------------------------------------------------------------
TEST_F(TensorConstructorFixture, MatrixDefaultConstruct) {
Matrix<double> m;
EXPECT_EQ(0, m.size());
EXPECT_EQ(0, m.rows());
EXPECT_EQ(0, m.cols());
EXPECT_EQ(nullptr, m.storage());
EXPECT_EQ(false, m.isWrapped());
}
TEST_F(TensorConstructorFixture, MatrixConstruct1) {
double r = rand();
Matrix<double> m(mat_size[0], mat_size[1], r);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.rows());
EXPECT_EQ(mat_size[1], m.cols());
EXPECT_EQ(false, m.isWrapped());
for (int i = 0; i < mat_size[0]; ++i) {
for (int j = 0; j < mat_size[1]; ++j) {
EXPECT_EQ(r, m(i, j));
EXPECT_EQ(r, m[i + j * mat_size[0]]);
}
}
}
TEST_F(TensorConstructorFixture, MatrixConstructWrapped) {
Matrix<double> m(reference.data(), mat_size[0], mat_size[1]);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.rows());
EXPECT_EQ(mat_size[1], m.cols());
EXPECT_EQ(true, m.isWrapped());
for (int i = 0; i < mat_size[0]; ++i) {
for (int j = 0; j < mat_size[1]; ++j) {
EXPECT_DOUBLE_EQ(reference[i + j * mat_size[0]], m(i, j));
}
}
compareToRef(m);
}
TEST_F(TensorConstructorFixture, MatrixConstructInitializer) {
Matrix<double> m{{0., 1., 2.}, {3., 4., 5.}};
EXPECT_EQ(6, m.size());
EXPECT_EQ(2, m.rows());
EXPECT_EQ(3, m.cols());
EXPECT_EQ(false, m.isWrapped());
int c = 0;
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j, ++c) {
EXPECT_DOUBLE_EQ(c, m(i, j));
}
}
}
TEST_F(TensorConstructorFixture, MatrixConstructCopy1) {
Matrix<double> mref(reference.data(), mat_size[0], mat_size[1]);
Matrix<double> m(mref);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.rows());
EXPECT_EQ(mat_size[1], m.cols());
EXPECT_EQ(false, m.isWrapped());
compareToRef(m);
}
TEST_F(TensorConstructorFixture, MatrixConstructCopy2) {
Matrix<double> mref(reference.data(), mat_size[0], mat_size[1]);
Matrix<double> m(mref);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.rows());
EXPECT_EQ(mat_size[1], m.cols());
EXPECT_EQ(false, m.isWrapped());
compareToRef(m);
}
TEST_F(TensorConstructorFixture, MatrixConstructProxy1) {
MatrixProxy<double> mref(reference.data(), mat_size[0], mat_size[1]);
EXPECT_EQ(size_, mref.size());
EXPECT_EQ(mat_size[0], mref.size(0));
EXPECT_EQ(mat_size[1], mref.size(1));
compareToRef(mref);
Matrix<double> m(mref);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.rows());
EXPECT_EQ(mat_size[1], m.cols());
EXPECT_EQ(true, m.isWrapped());
compareToRef(m);
}
TEST_F(TensorConstructorFixture, MatrixConstructProxy2) {
Matrix<double> mref(reference.data(), mat_size[0], mat_size[1]);
MatrixProxy<double> m(mref);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.size(0));
EXPECT_EQ(mat_size[1], m.size(1));
compareToRef(m);
}
/* -------------------------------------------------------------------------- */
TEST_F(TensorFixture, MatrixEqual) {
Matrix<double> m;
m = mref;
compareToRef(m);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.rows());
EXPECT_EQ(mat_size[1], m.cols());
EXPECT_EQ(false, m.isWrapped());
}
TEST_F(TensorFixture, MatrixEqualProxy1) {
MatrixProxy<double> mref_proxy(mref);
Matrix<double> m;
m = mref;
compareToRef(m);
EXPECT_EQ(size_, m.size());
EXPECT_EQ(mat_size[0], m.rows());
EXPECT_EQ(mat_size[1], m.cols());
EXPECT_EQ(false, m.isWrapped());
}
TEST_F(TensorFixture, MatrixEqualProxy2) {
Matrix<double> m_store(mat_size[0], mat_size[1], 0.);
MatrixProxy<double> m(m_store);
m = mref;
compareToRef(m);
compareToRef(m_store);
}
TEST_F(TensorFixture, MatrixEqualSlice) {
Matrix<double> m(mat_size[0], mat_size[1], 0.);
for (unsigned int i = 0; i < m.cols(); ++i)
m(i) = Vector<Real>(mref(i));
compareToRef(m);
}
/* -------------------------------------------------------------------------- */
TEST_F(TensorFixture, MatrixSet) {
Matrix<double> m(mref);
compareToRef(m);
double r = rand();
m.set(r);
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(r, m[i]);
}
TEST_F(TensorFixture, MatrixClear) {
Matrix<double> m(mref);
compareToRef(m);
m.clear();
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(0, m[i]);
}
/* -------------------------------------------------------------------------- */
TEST_F(TensorFixture, MatrixDivide) {
Matrix<double> m;
double r = rand();
m = mref / r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] / r, m[i]);
}
TEST_F(TensorFixture, MatrixMultiply1) {
Matrix<double> m;
double r = rand();
m = mref * r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * r, m[i]);
}
TEST_F(TensorFixture, MatrixMultiply2) {
Matrix<double> m;
double r = rand();
m = r * mref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * r, m[i]);
}
TEST_F(TensorFixture, MatrixAddition) {
Matrix<double> m;
m = mref + mref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * 2., m[i]);
}
TEST_F(TensorFixture, MatrixSubstract) {
Matrix<double> m;
m = mref - mref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(0., m[i]);
}
TEST_F(TensorFixture, MatrixDivideEqual) {
Matrix<double> m(mref);
double r = rand();
m /= r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] / r, m[i]);
}
TEST_F(TensorFixture, MatrixMultiplyEqual1) {
Matrix<double> m(mref);
double r = rand();
m *= r;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * r, m[i]);
}
TEST_F(TensorFixture, MatrixAdditionEqual) {
Matrix<double> m(mref);
m += mref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(reference[i] * 2., m[i]);
}
TEST_F(TensorFixture, MatrixSubstractEqual) {
Matrix<double> m(mref);
m -= mref;
for (int i = 0; i < size_; ++i)
EXPECT_DOUBLE_EQ(0., m[i]);
}
-#if defined (AKANTU_USE_LAPACK)
+#if defined(AKANTU_USE_LAPACK)
TEST_F(TensorFixture, MatrixEigs) {
Matrix<double> m{{0, 1, 0, 0}, {1., 0, 0, 0}, {0, 1, 0, 1}, {0, 0, 4, 0}};
Matrix<double> eig_vects(4, 4);
Vector<double> eigs(4);
m.eig(eigs, eig_vects);
Vector<double> eigs_ref{2, 1., -1., -2};
auto lambda_v = m * eig_vects;
for (int i = 0; i < 4; ++i) {
EXPECT_NEAR(eigs_ref(i), eigs(i), 1e-14);
for (int j = 0; j < 4; ++j) {
EXPECT_NEAR(lambda_v(i)(j), eigs(i) * eig_vects(i)(j), 1e-14);
}
}
}
#endif
/* -------------------------------------------------------------------------- */
} // namespace
diff --git a/test/test_common/test_types.cc b/test/test_common/test_types.cc
index afbaf36e7..375768c12 100644
--- a/test/test_common/test_types.cc
+++ b/test/test_common/test_types.cc
@@ -1,355 +1,355 @@
/**
* @file test_types.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 15 2015
* @date last modification: Sat Jul 11 2015
*
* @brief Test the types declared in aka_types.hh
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_types.hh"
#include <iostream>
#include <sstream>
#include <stdexcept>
using namespace akantu;
const Real tolerance = 1e-15;
std::string itoa(UInt a) {
std::stringstream sstr;
sstr << a;
return sstr.str();
}
UInt testcounter = 0;
struct wrap_error : std::runtime_error {
wrap_error(const std::string & msg) : std::runtime_error(msg) {}
};
struct size_error : std::runtime_error {
size_error(const std::string & msg) : std::runtime_error(msg) {}
};
struct data_error : std::runtime_error {
data_error(const std::string & msg, UInt i)
: std::runtime_error(msg), index(i) {}
UInt index;
};
template <class type>
void compare_storages_with_ref(const type & a, Real * ref, UInt size, UInt line,
const std::string & txt) {
std::cout << std::setw(3) << (testcounter++) << ": " << std::setw(10) << txt
<< " - " << a << " - wrapped: " << std::boolalpha << a.isWrapped()
<< std::endl;
if (a.size() != size)
throw size_error("the size is not correct " + itoa(a.size()) +
- " instead of " + itoa(size) + " [Test at line: " +
- itoa(line) + "]");
+ " instead of " + itoa(size) +
+ " [Test at line: " + itoa(line) + "]");
Real * a_ptr = a.storage();
for (UInt i = 0; i < a.size(); ++i) {
if (!((std::abs(a_ptr[i]) < tolerance && std::abs(ref[i]) < tolerance) ||
std::abs((a_ptr[i] - ref[i]) / a_ptr[i]) < tolerance)) {
std::stringstream txt;
txt << " std::abs(" << a_ptr[i] << " - " << ref[i]
<< " [= " << std::abs(a_ptr[i] - ref[i]) << "] ) > " << tolerance;
throw data_error("storage differs at index " + itoa(i) +
" [Test at line: " + itoa(line) + "]" + txt.str(),
i);
}
}
if (a_ptr == ref && !a.isWrapped())
throw wrap_error(
"the storage should be wrapped but it is not [Test at line: " +
itoa(line) + "]");
if (a_ptr != ref && a.isWrapped())
throw wrap_error(
"the storage should not be wrapped but it is [Test at line: " +
itoa(line) + "]");
}
#define COMPARE(a, aref, txt) \
compare_storages_with_ref(a, aref, sizeof(aref) / sizeof(aref[0]), __LINE__, \
txt)
#define COMPARE_STORAGE(a, aref, txt) \
compare_storages_with_ref(a, aref.storage(), aref.size(), __LINE__, txt)
const UInt ref_size = 10;
// clang-format off
/* -------------------------------------------------------------------------- */
void test_constructor() {
std::cout << "=== Test constructors ===" << std::endl;
Real ref1[ref_size] = { 0. };
Real ref2[ref_size] = { 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58 };
Real ref3[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
std::cout << "-- Vectors: " << std::endl;
Vector<Real> v0 = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
; COMPARE ( v0, ref3, "init_list" );
Vector<Real> v1(ref_size); COMPARE ( v1, ref1, "normal" );
Vector<Real> v2(ref_size, 1563.58); COMPARE ( v2, ref2, "defval" );
Vector<Real> v3(ref3, ref_size); COMPARE ( v3, ref3, "wrapped" );
Vector<Real> v3dcw(v3); COMPARE ( v3dcw, ref3, "wdeepcopy" );
Vector<Real> v3scw(v3, false); COMPARE ( v3scw, ref3, "wshallow" );
Vector<Real> v3dc(v3dcw); COMPARE_STORAGE( v3dc, v3dcw, "deepcopy" );
Vector<Real> v3sc(v3dcw, false); COMPARE_STORAGE( v3sc, v3dcw, "shallow" );
VectorProxy<Real> vp1(ref3, ref_size);
Vector<Real> v4(vp1); COMPARE ( v4, ref3, "proxyptr" );
VectorProxy<Real> vp2(v3dcw);
Vector<Real> v5(vp2); COMPARE_STORAGE( v5, v3dcw, "proxyvdc" );
VectorProxy<Real> vp3(v3scw);
Vector<Real> v6(vp3); COMPARE ( v6, ref3, "proxyvsc" );
/* ------------------------------------------------------------------------ */
std::cout << "-- Matrices: " << std::endl;
Matrix<Real> m0 = {{23.1594, 37.1445},
{79.6184, 64.8991},
{77.9052, 80.3364},
{47.9922, 98.4064},
{12.8674, 73.7858}};
COMPARE ( m0, ref3 , "init_list" );
Matrix<Real> m1(5, 2); COMPARE ( m1, ref1 , "normal" );
Matrix<Real> m1t(2, 5); COMPARE ( m1t, ref1 , "tnormal" );
Matrix<Real> m2(5, 2, 1563.58); COMPARE ( m2, ref2 , "defval" );
Matrix<Real> m2t(2, 5, 1563.58); COMPARE ( m2t, ref2 , "tdefval" );
Matrix<Real> m3(ref3, 5, 2); COMPARE ( m3, ref3 , "wrapped" );
Matrix<Real> m3t(ref3, 2, 5); COMPARE ( m3t, ref3 , "twrapped" );
Matrix<Real> m3dcw(m3); COMPARE ( m3dcw, ref3 , "wdeepcopy" );
Matrix<Real> m3scw(m3, false); COMPARE ( m3scw, ref3 , "wshallow" );
Matrix<Real> m3dc(m3dcw); COMPARE_STORAGE( m3dc, m3dcw , "deepcopy" );
Matrix<Real> m3sc(m3dcw, false); COMPARE_STORAGE( m3sc, m3dcw , "shallow" );
Matrix<Real> m3tdcw(m3t); COMPARE (m3tdcw, ref3 , "twdeepcopy");
Matrix<Real> m3tscw(m3t, false); COMPARE (m3tscw, ref3 , "twshallow" );
Matrix<Real> m3tdc(m3tdcw); COMPARE_STORAGE( m3tdc, m3tdcw, "tdeepcopy" );
Matrix<Real> m3tsc(m3tdcw, false); COMPARE_STORAGE( m3tsc, m3tdcw, "tshallow" );
MatrixProxy<Real> mp1(ref3, 5, 2);
Matrix<Real> m4(mp1); COMPARE ( m4, ref3, "proxyptr" );
MatrixProxy<Real> mp2(m3dcw);
Matrix<Real> m5(mp2); COMPARE_STORAGE( m5, m3dcw, "proxyvdc" );
MatrixProxy<Real> mp3(m3scw);
Matrix<Real> m6(mp3); COMPARE ( m6, ref3, "proxyvsc" );
MatrixProxy<Real> mp1t(ref3, 2, 5);
Matrix<Real> m4t(mp1t); COMPARE ( m4t, ref3, "tproxyptr" );
MatrixProxy<Real> mp2t(m3tdcw);
Matrix<Real> m5t(mp2t); COMPARE_STORAGE( m5t, m3tdcw, "tproxyvdc" );
MatrixProxy<Real> mp3t(m3tscw);
Matrix<Real> m6t(mp3t); COMPARE ( m6t, ref3, "tproxyvsc" );
}
/* -------------------------------------------------------------------------- */
void test_equal_and_accessors() {
std::cout << "=== Test operator=() ===" << std::endl;
Real ref[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
Real mod[ref_size] = { 98.7982, 72.1227, 19.7815, 57.6722, 47.1088, 14.9865, 13.3171, 62.7973, 33.9493, 98.3052 };
std::cout << "-- Vectors: " << std::endl;
Vector<Real> v (ref, ref_size);
Vector<Real> vm(mod, ref_size);
Vector<Real> vref1(v);
Vector<Real> v1;
v1 = vref1; COMPARE_STORAGE(v1, vref1, "simple=" );
for (UInt i = 0; i < ref_size; ++i) v1 (i) = mod[i]; COMPARE (v1, mod, "s_acces" );
COMPARE_STORAGE(vref1, v, "refcheck1");
Vector<Real> v2 = vref1; COMPARE_STORAGE(v2, vref1, "construc=");
for (UInt i = 0; i < ref_size; ++i) v2 (i) = mod[i]; COMPARE (v2, mod, "c_acces" );
COMPARE_STORAGE(vref1, v, "refcheck2");
Vector<Real> vref2(vref1, false);
Vector<Real> v1w;
v1w = vref2; COMPARE_STORAGE(v1w, vref1, "w_simple=" );
for (UInt i = 0; i < ref_size; ++i) v1w(i) = mod[i]; COMPARE (v1w, mod, "ws_acces" );
try { COMPARE(vref2, ref, "refcheck3"); } catch(wrap_error &) {}
Vector<Real> v2w = vref2; COMPARE_STORAGE(v2w, vref1, "w_constru=");
for (UInt i = 0; i < ref_size; ++i) v2w(i) = mod[i]; COMPARE (v2w, mod, "wc_acces" );
try { COMPARE(vref2, ref, "refcheck4"); } catch(wrap_error &) {}
VectorProxy<Real> vp1(vref1);
Vector<Real> v3;
v3 = vp1; COMPARE_STORAGE(v3, vref1, "p_simple=" );
for (UInt i = 0; i < ref_size; ++i) v3(i) = mod[i]; COMPARE (v3, mod, "ps_acces" );
COMPARE_STORAGE(vref1, v, "refcheck5");
Vector<Real> v4 = vp1; COMPARE_STORAGE(v4, vref1, "p_constru=");
for (UInt i = 0; i < ref_size; ++i) v4(i) = mod[i];
try { COMPARE(v4, mod, "pc_acces" ); } catch (wrap_error &) {}
COMPARE(vref1, mod, "refcheck6");
try { COMPARE(vref2, mod, "refcheck7"); } catch(wrap_error &) {}
vref2 = v;
VectorProxy<Real> vp2(vref2);
Vector<Real> v3w;
v3w = vp2; COMPARE_STORAGE(v3w, vref1, "pw_simpl=");
for (UInt i = 0; i < ref_size; ++i) v3w(i) = mod[i]; COMPARE (v3w, mod, "pws_acces");
try { COMPARE(vref2, ref, "refcheck8"); } catch(wrap_error &) {}
Vector<Real> v4w = vp2; COMPARE_STORAGE( v4w, vref1, "pw_constr=");
for (UInt i = 0; i < ref_size; ++i) v4w(i) = mod[i];
try { COMPARE(v4w, mod, "pwc_acces"); } catch (wrap_error &) {}
COMPARE_STORAGE(v4w, vref2, "refcheck9");
try { COMPARE(vref2, mod, "refcheck10"); } catch(wrap_error &) {}
vref1 = v;
Real store[ref_size] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
Vector<Real> vs(store, 10);
VectorProxy<Real> vp3(vs);
vp3 = vref1;
try { COMPARE(vref1, store, "vp_equal_v"); } catch(wrap_error &) {}
// Vector<Real> vref3(vm);
// VectorProxy<Real> vp4 = vref3;
// vp3 = vp4;
// try { COMPARE(vs, mod, "vp_equal_vp"); } catch(wrap_error &) {}
/* ------------------------------------------------------------------------ */
std::cout << "-- Matrices: " << std::endl;
Matrix<Real> m (ref, 5, 2);
Matrix<Real> mt(ref, 2, 5);
Matrix<Real> m1 (5, 2);
Matrix<Real> m1t(2, 5);
for (UInt i = 0; i < 5; ++i) {
for (UInt j = 0; j < 2; ++j) {
m1(i, j) = ref[i + j*5];
m1t(j, i) = ref[j + i*2];
}
}
COMPARE_STORAGE( m1, m, "access" );
COMPARE_STORAGE(m1t, m, "t_access");
Matrix<Real> mm (mod, 5, 2);
Matrix<Real> mmt(mod, 2, 5);
Matrix<Real> m2(m);
Matrix<Real> m3(m);
for (UInt j = 0; j < 2; ++j) {
Vector<Real> v = m2(j);
for (UInt i = 0; i < 5; ++i)
v(i) = mm(i, j);
}
COMPARE_STORAGE(m2, mm, "slicing");
for (UInt j = 0; j < 2; ++j)
m3(j) = mm(j);
COMPARE_STORAGE(m3, mm, "slic_slic");
COMPARE(mm, mod, "refcheck");
Real mod_1[ref_size] = { 98.7982, 72.1227, 197.815, 57.6722, 47.1088, 14.9865, 13.3171, 627.973, 33.9493, 98.3052 };
Matrix<Real> m4 (mm);
m4 (2,0) = 197.815;
m4 (2,1) = 627.973;
COMPARE(m4, mod_1, "partial");
Matrix<Real> m4t(mmt);
m4t(0,1) = 197.815;
m4t(1,3) = 627.973;
COMPARE(m4t, mod_1, "t_partial");
}
/* -------------------------------------------------------------------------- */
void test_simple_operators() {
std::cout << "=== Test simple operation ===" << std::endl;
Real ref[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
Real mod[ref_size] = { 98.7982, 72.1227, 19.7815, 57.6722, 47.1088, 14.9865, 13.3171, 62.7973, 33.9493, 98.3052 };
Real ref_div[ref_size] = { 1.163905920192984e+00, 4.001326766509196e+00,
3.915227661071464e+00, 2.411910744798472e+00,
6.466680068348578e-01, 1.866745401547894e+00,
3.261589104432606e+00, 4.037410795054780e+00,
4.945542265554328e+00, 3.708201829329581e+00 };
Real ref_tim[ref_size] = { 4.608257412000000e+02, 1.584246923200000e+03,
1.550157669600000e+03, 9.549487955999999e+02,
2.560355252000000e+02, 7.391012610000000e+02,
1.291362291800000e+03, 1.598533687200000e+03,
1.958090547200000e+03, 1.468189848400000e+03 };
Real ref_p_mod[ref_size] = { 1.219576000000000e+02, 1.517411000000000e+02,
9.768670000000000e+01, 1.056644000000000e+02,
5.997620000000001e+01, 5.213100000000000e+01,
7.821620000000000e+01, 1.431337000000000e+02,
1.323557000000000e+02, 1.720910000000000e+02 };
Real ref_m_mod[ref_size] = { -7.563879999999999e+01, 7.495699999999999e+00,
5.812369999999999e+01, -9.680000000000000e+00,
-3.424140000000000e+01, 2.215800000000000e+01,
5.158200000000001e+01, 1.753910000000000e+01,
6.445710000000000e+01, -2.451940000000000e+01 };
std::cout << "-- Vectors: " << std::endl;
Vector<Real> v (ref, ref_size);
Vector<Real> vm(mod, ref_size);
Vector<Real> vref(v);
Vector<Real> vmod(vm);
Vector<Real> v1 = vref / 19.898; COMPARE(v1, ref_div, "v / s" );
Vector<Real> v2 = vref * 19.898; COMPARE(v2, ref_tim, "v * s" );
Vector<Real> v3 = 19.898 * vref; COMPARE(v3, ref_tim, "s * v" );
Vector<Real> v4 = vref + vmod; COMPARE(v4, ref_p_mod, "v1 + v2" );
Vector<Real> v5 = vref - vmod; COMPARE(v5, ref_m_mod, "v1 - v2" );
Vector<Real> v6 = vref; v6 *= 19.898; COMPARE(v6, ref_tim, "v *= s" );
Vector<Real> v7 = vref; v7 /= 19.898; COMPARE(v7, ref_div, "v /= s" );
Vector<Real> v8 = vref; v8 += vmod; COMPARE(v8, ref_p_mod, "v1 += v2");
Vector<Real> v9 = vref; v9 -= vmod; COMPARE(v9, ref_m_mod, "v1 -= v2");
std::cout << "-- Matrices: " << std::endl;
Matrix<Real> m (ref, 5, 2);
Matrix<Real> mm(mod, 5, 2);
Matrix<Real> mref(m);
Matrix<Real> mmod(mm);
Matrix<Real> m1 = mref / 19.898; COMPARE(m1, ref_div, "m / s" );
Matrix<Real> m2 = mref * 19.898; COMPARE(m2, ref_tim, "m * s" );
Matrix<Real> m3 = 19.898 * mref; COMPARE(m3, ref_tim, "s * m" );
Matrix<Real> m4 = mref + mmod; COMPARE(m4, ref_p_mod, "m1 + m2" );
Matrix<Real> m5 = mref - mmod; COMPARE(m5, ref_m_mod, "m1 - m2" );
Matrix<Real> m6 = mref; m6 *= 19.898; COMPARE(m6, ref_tim, "m *= s" );
Matrix<Real> m7 = mref; m7 /= 19.898; COMPARE(m7, ref_div, "m /= s" );
Matrix<Real> m8 = mref; m8 += mmod; COMPARE(m8, ref_p_mod, "m1 += m2");
Matrix<Real> m9 = mref; m9 -= mmod; COMPARE(m9, ref_m_mod, "m1 -= m2");
}
// clang-format on
/* -------------------------------------------------------------------------- */
int main() {
test_constructor();
test_equal_and_accessors();
test_simple_operators();
return 0;
}
diff --git a/test/test_fe_engine/pybind11_akantu.cc b/test/test_fe_engine/pybind11_akantu.cc
index 594469b10..fd8e247a8 100644
--- a/test/test_fe_engine/pybind11_akantu.cc
+++ b/test/test_fe_engine/pybind11_akantu.cc
@@ -1,72 +1,73 @@
/* -------------------------------------------------------------------------- */
#include "pybind11_akantu.hh"
/* -------------------------------------------------------------------------- */
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
namespace akantu {
PYBIND11_MODULE(aka_test, m) {
m.doc() = "Module for the tests of akantu";
py::class_<ArrayProxy<Real>>(m, "ArrayProxy", py::buffer_protocol())
.def_buffer([](ArrayProxy<Real> & a) {
return py::buffer_info(
a.storage(), /* Pointer to buffer */
sizeof(Real), /* Size of one scalar */
py::format_descriptor<Real>::format(), /* Python struct-style
format descriptor */
2, /* Number of dimensions */
{a.size(), a.getNbComponent()}, /* Buffer dimensions */
{sizeof(Real) *
a.getNbComponent(), /* Strides (in bytes) for each index */
sizeof(Real)});
})
.def(py::init([](py::array & n) {
/* Request a buffer descriptor from Python */
py::buffer_info info = n.request();
/* Some sanity checks ... */
if (info.format != py::format_descriptor<Real>::format())
throw std::runtime_error(
"Incompatible format: expected a double array!");
if (info.ndim != 2)
throw std::runtime_error("Incompatible buffer dimension!");
return std::make_unique<ArrayProxy<Real>>(static_cast<Real *>(info.ptr),
info.shape[0], info.shape[1]);
}));
py::class_<MatrixProxy<Real>>(m, "Matrix", py::buffer_protocol())
.def_buffer([](MatrixProxy<Real> & a) {
return py::buffer_info(
a.storage(), /* Pointer to buffer */
sizeof(Real), /* Size of one scalar */
py::format_descriptor<Real>::format(), /* Python struct-style
format descriptor */
2, /* Number of dimensions */
- {a.size(0), a.size(1)}, /* Buffer dimensions */
- {sizeof(Real), a.size(0)*sizeof(Real)} /* Strides (in bytes) for each index */
- );
+ {a.size(0), a.size(1)}, /* Buffer dimensions */
+ {sizeof(Real), a.size(0) * sizeof(Real)}
+ /* Strides (in bytes) for each index */
+ );
})
.def(py::init([](py::array & n) {
/* Request a buffer descriptor from Python */
py::buffer_info info = n.request();
/* Some sanity checks ... */
if (info.format != py::format_descriptor<Real>::format())
throw std::runtime_error(
"Incompatible format: expected a double array!");
if (info.ndim != 2)
throw std::runtime_error("Incompatible buffer dimension!");
- return std::make_unique<MatrixProxy<Real>>(static_cast<Real *>(info.ptr),
- info.shape[0], info.shape[1]);
+ return std::make_unique<MatrixProxy<Real>>(
+ static_cast<Real *>(info.ptr), info.shape[0], info.shape[1]);
}));
} // Module aka test
} // namespace akantu
diff --git a/test/test_fe_engine/pybind11_akantu.hh b/test/test_fe_engine/pybind11_akantu.hh
index 98bacea8a..3602c1bfe 100644
--- a/test/test_fe_engine/pybind11_akantu.hh
+++ b/test/test_fe_engine/pybind11_akantu.hh
@@ -1,111 +1,110 @@
#include "aka_array.hh"
#include "aka_types.hh"
/* -------------------------------------------------------------------------- */
#include <pybind11/cast.h>
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PYBIND11_AKANTU_HH__
#define __AKANTU_PYBIND11_AKANTU_HH__
namespace akantu {
template <typename T> class ArrayProxy : public Array<T> {
public:
ArrayProxy(T * wrapped_memory, UInt size = 0, UInt nb_component = 1,
const ID & id = "")
: Array<T>(0, nb_component, id) {
this->values = wrapped_memory;
this->size_ = size;
}
ArrayProxy(const ArrayProxy<T> & array)
: Array<T>(0, array.nb_component, array.id) {
this->values = array.values;
this->size_ = array.size_;
}
ArrayProxy(ArrayProxy<T> && array) {
this->nb_component = std::move(array.nb_component);
this->values = std::move(array.values);
this->size_ = std::move(array.size_);
this->id = std::move(array.id);
}
ArrayProxy(Array<T> & array)
: Array<T>(0, array.getNbComponent(), array.getID()) {
this->values = array.storage();
this->size_ = array.size();
}
~ArrayProxy() {
this->values = nullptr;
this->size_ = 0;
}
void setNbComponent(UInt nb_component) {
UInt new_size = this->size_ / nb_component;
AKANTU_DEBUG_ASSERT(
nb_component * new_size == this->nb_component * this->size_,
nb_component
<< " is not valid as a new number of component for this array");
this->nb_component = nb_component;
this->size_ = new_size;
}
void resize(UInt new_size) {
AKANTU_DEBUG_ASSERT(this->size_ == new_size,
"cannot resize a temporary vector");
}
};
template <typename T> decltype(auto) make_proxy(Array<T> & array) {
return ArrayProxy<T>(array);
}
-template <typename T>
-decltype(auto) make_proxy(const Matrix<T> & array) {
+template <typename T> decltype(auto) make_proxy(const Matrix<T> & array) {
return MatrixProxy<T>(array);
}
} // namespace akantu
// namespace pybind11 {
// namespace detail {
// template <> struct type_caster<akantu::ArrayProxy<akantu::Real>> {
// public:
// PYBIND11_TYPE_CASTER(akantu::ArrayProxy<akantu::Real>, _("ArrayProxy"));
// bool load(handle, bool) {
// // /* Extract PyObject from handle */
// // PyObject *source = src.ptr();
// // /* Try converting into a Python integer value */
// // PyObject *tmp = PyNumber_Long(source);
// // if (!tmp)
// // return false;
// // /* Now try to convert into a C++ int */
// // value.long_value = PyLong_AsLong(tmp);
// // Py_DECREF(tmp);
// // /* Ensure return code was OK (to avoid out-of-range errors etc) */
// // return !(value.long_value == -1 && !PyErr_Occurred());
// return false;
// }
// static handle cast(akantu::ArrayProxy<akantu::Real> & src,
// return_value_policy /* policy */, handle parent) {
// constexpr ssize_t elem_size = sizeof(akantu::Real);
// ssize_t nb_comp = src.getNbComponent();
// ssize_t size = src.size();
// std::cout << "<memory at " << reinterpret_cast<void *>(src.storage())
// << ">\n";
// auto a = array({size, nb_comp}, {elem_size * nb_comp, elem_size},
// src.storage(), handle());
// return a.release();
// }
// };
// } // namespace detail
// } // namespace pybind11
#endif /* __AKANTU_PYBIND11_AKANTU_HH__ */
diff --git a/test/test_fe_engine/test_facet_element_mapping.cc b/test/test_fe_engine/test_facet_element_mapping.cc
index 39a7c259f..4a0e06fc8 100644
--- a/test/test_fe_engine/test_facet_element_mapping.cc
+++ b/test/test_fe_engine/test_facet_element_mapping.cc
@@ -1,120 +1,135 @@
/**
* @file test_facet_element_mapping.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri May 03 2013
* @date last modification: Mon Jul 13 2015
*
* @brief Test of the MeshData class
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "mesh.hh"
-#include "mesh_utils.hh"
#include "aka_common.hh"
#include "aka_error.hh"
+#include "mesh.hh"
+#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <string>
/* -------------------------------------------------------------------------- */
using namespace akantu;
using namespace std;
-int main(int argc, char *argv[]) {
-// Testing the subelement-to-element mappings
+int main(int argc, char * argv[]) {
+ // Testing the subelement-to-element mappings
UInt spatial_dimension(3);
akantu::initialize(argc, argv);
Mesh mesh(spatial_dimension, "my_mesh");
mesh.read("./cube_physical_names.msh");
- typedef Array< std::vector<Element> > ElemToSubelemMapping;
- typedef Array<Element> SubelemToElemMapping;
+ typedef Array<std::vector<Element>> ElemToSubelemMapping;
+ typedef Array<Element> SubelemToElemMapping;
std::cout << "ELEMENT-SUBELEMENT MAPPING:" << std::endl;
- for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
- Mesh::type_iterator tit = mesh.firstType(spatial_dimension, *git);
+ for (ghost_type_t::iterator git = ghost_type_t::begin();
+ git != ghost_type_t::end(); ++git) {
+ Mesh::type_iterator tit = mesh.firstType(spatial_dimension, *git);
Mesh::type_iterator tend = mesh.lastType(spatial_dimension, *git);
- std::cout << " " << "Ghost type: " << *git << std::endl;
- for (;tit != tend; ++tit) {
+ std::cout << " "
+ << "Ghost type: " << *git << std::endl;
+ for (; tit != tend; ++tit) {
- const SubelemToElemMapping & subelement_to_element = mesh.getSubelementToElement(*tit, *git);
- std::cout << " " << " " << "Element type: " << *tit << std::endl;
+ const SubelemToElemMapping & subelement_to_element =
+ mesh.getSubelementToElement(*tit, *git);
+ std::cout << " "
+ << " "
+ << "Element type: " << *tit << std::endl;
- std::cout << " " << " " << " " << "subelement_to_element:" << std::endl;
+ std::cout << " "
+ << " "
+ << " "
+ << "subelement_to_element:" << std::endl;
subelement_to_element.printself(std::cout, 8);
- for(UInt i(0); i < subelement_to_element.size(); ++i) {
+ for (UInt i(0); i < subelement_to_element.size(); ++i) {
std::cout << " ";
- for(UInt j(0); j < mesh.getNbFacetsPerElement(*tit); ++j) {
- if(subelement_to_element(i, j) != ElementNull) {
+ for (UInt j(0); j < mesh.getNbFacetsPerElement(*tit); ++j) {
+ if (subelement_to_element(i, j) != ElementNull) {
std::cout << subelement_to_element(i, j);
std::cout << ", ";
} else {
- std::cout << "ElementNull" << ", ";
+ std::cout << "ElementNull"
+ << ", ";
}
}
std::cout << "for element " << i << std::endl;
}
}
- tit = mesh.firstType(spatial_dimension -1, *git);
- tend = mesh.lastType(spatial_dimension -1 , *git);
+ tit = mesh.firstType(spatial_dimension - 1, *git);
+ tend = mesh.lastType(spatial_dimension - 1, *git);
- for (;tit != tend; ++tit) {
+ for (; tit != tend; ++tit) {
- const ElemToSubelemMapping & element_to_subelement = mesh.getElementToSubelement(*tit, *git);
- std::cout << " " << " " << "Element type: " << *tit << std::endl;
+ const ElemToSubelemMapping & element_to_subelement =
+ mesh.getElementToSubelement(*tit, *git);
+ std::cout << " "
+ << " "
+ << "Element type: " << *tit << std::endl;
- std::cout << " " << " " << " " << "element_to_subelement:" << std::endl;
+ std::cout << " "
+ << " "
+ << " "
+ << "element_to_subelement:" << std::endl;
element_to_subelement.printself(std::cout, 8);
- for(UInt i(0); i < element_to_subelement.size(); ++i) {
+ for (UInt i(0); i < element_to_subelement.size(); ++i) {
const std::vector<Element> & vec = element_to_subelement(i);
- std::cout << " " ;
+ std::cout << " ";
std::cout << "item " << i << ": [ ";
- if(vec.size() > 0) {
- for(UInt j(0); j < vec.size(); ++j) {
- if(vec[j] != ElementNull) {
+ if (vec.size() > 0) {
+ for (UInt j(0); j < vec.size(); ++j) {
+ if (vec[j] != ElementNull) {
std::cout << vec[j] << ", ";
} else {
- std::cout << "ElementNull" << ", ";
+ std::cout << "ElementNull"
+ << ", ";
}
}
} else {
- std::cout << "empty, " ;
+ std::cout << "empty, ";
}
- std::cout << "]" << ", " << std::endl;
+ std::cout << "]"
+ << ", " << std::endl;
}
std::cout << std::endl;
}
-
}
return 0;
}
-
diff --git a/test/test_fe_engine/test_fe_engine_gauss_integration.cc b/test/test_fe_engine/test_fe_engine_gauss_integration.cc
index 48fee7c9f..068899371 100644
--- a/test/test_fe_engine/test_fe_engine_gauss_integration.cc
+++ b/test/test_fe_engine/test_fe_engine_gauss_integration.cc
@@ -1,155 +1,155 @@
/**
* @file test_fe_engine_precomputation.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Mon Jul 13 2015
*
* @brief test integration on elements, this test consider that mesh is a cube
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_fe_engine_fixture.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
/* -------------------------------------------------------------------------- */
template <size_t t> using degree_t = std::integral_constant<size_t, t>;
/* -------------------------------------------------------------------------- */
-using TestDegreeTypes = std::tuple<degree_t<0>, degree_t<1>, degree_t<2>, degree_t<3>, degree_t<4>, degree_t<5>>;
+using TestDegreeTypes = std::tuple<degree_t<0>, degree_t<1>, degree_t<2>,
+ degree_t<3>, degree_t<4>, degree_t<5>>;
std::array<Polynomial<5>, 3> global_polys{
{{0.40062394, 0.13703225, 0.51731446, 0.87830084, 0.5410543, 0.71842292},
{0.41861835, 0.11080576, 0.49874043, 0.49077504, 0.85073835, 0.66259755},
{0.92620845, 0.7503478, 0.62962232, 0.31662719, 0.64069644, 0.30878135}}};
template <typename T>
class TestGaussIntegrationFixture
: public TestFEMFixture<std::tuple_element_t<0, T>> {
protected:
using parent = TestFEMFixture<std::tuple_element_t<0, T>>;
static constexpr size_t degree{std::tuple_element_t<1, T>::value};
public:
TestGaussIntegrationFixture() : integration_points_pos(0, parent::dim) {}
void SetUp() override {
parent::SetUp();
this->fem->initShapeFunctions();
auto integration_points =
this->fem->getIntegrator().template getIntegrationPoints <
parent::type,
degree == 0 ? 1 : degree > ();
nb_integration_points = integration_points.cols();
auto shapes_size = ElementClass<parent::type>::getShapeSize();
Array<Real> shapes(0, shapes_size);
this->fem->getShapeFunctions()
.template computeShapesOnIntegrationPoints<parent::type>(
this->mesh->getNodes(), integration_points, shapes, _not_ghost);
auto vect_size = this->nb_integration_points * this->nb_element;
integration_points_pos.resize(vect_size);
this->fem->getShapeFunctions()
.template interpolateOnIntegrationPoints<parent::type>(
this->mesh->getNodes(), integration_points_pos, this->dim, shapes);
for (size_t d = 0; d < this->dim; ++d) {
polys[d] = global_polys[d].extract(degree);
}
}
void testIntegrate() {
std::stringstream sstr;
sstr << this->type << ":" << this->degree;
SCOPED_TRACE(sstr.str().c_str());
auto vect_size = this->nb_integration_points * this->nb_element;
Array<Real> polynomial(vect_size);
size_t dim = parent::dim;
for (size_t d = 0; d < dim; ++d) {
auto poly = this->polys[d];
for (auto && pair :
zip(polynomial, make_view(this->integration_points_pos, dim))) {
auto && p = std::get<0>(pair);
auto & x = std::get<1>(pair);
p = poly(x(d));
}
auto res =
this->fem->getIntegrator()
- .template integrate<parent::type, (degree == 0 ? 1 : degree)>(polynomial);
+ .template integrate<parent::type, (degree == 0 ? 1 : degree)>(
+ polynomial);
auto expect = poly.integrate(this->lower(d), this->upper(d));
for (size_t o = 0; o < dim; ++o) {
if (o == d)
continue;
expect *= this->upper(d) - this->lower(d);
}
EXPECT_NEAR(expect, res, 5e-14);
}
}
protected:
UInt nb_integration_points;
std::array<Array<Real>, parent::dim> polynomial;
Array<Real> integration_points_pos;
std::array<Polynomial<5>, 3> polys;
};
-template <typename T>
-constexpr size_t TestGaussIntegrationFixture<T>::degree;
+template <typename T> constexpr size_t TestGaussIntegrationFixture<T>::degree;
/* -------------------------------------------------------------------------- */
/* Tests */
/* -------------------------------------------------------------------------- */
TYPED_TEST_CASE_P(TestGaussIntegrationFixture);
TYPED_TEST_P(TestGaussIntegrationFixture, ArbitraryOrder) {
this->testIntegrate();
}
REGISTER_TYPED_TEST_CASE_P(TestGaussIntegrationFixture, ArbitraryOrder);
-
-using TestTypes =
- gtest_list_t<tuple_split_t<50, cross_product_t<TestElementTypes, TestDegreeTypes>>>;
+using TestTypes = gtest_list_t<
+ tuple_split_t<50, cross_product_t<TestElementTypes, TestDegreeTypes>>>;
INSTANTIATE_TYPED_TEST_CASE_P(Split1, TestGaussIntegrationFixture, TestTypes);
-using TestTypesTail =
- gtest_list_t<tuple_split_tail_t<50, cross_product_t<TestElementTypes, TestDegreeTypes>>>;
-
-INSTANTIATE_TYPED_TEST_CASE_P(Split2, TestGaussIntegrationFixture, TestTypesTail);
+using TestTypesTail = gtest_list_t<
+ tuple_split_tail_t<50, cross_product_t<TestElementTypes, TestDegreeTypes>>>;
+INSTANTIATE_TYPED_TEST_CASE_P(Split2, TestGaussIntegrationFixture,
+ TestTypesTail);
}
diff --git a/test/test_fe_engine/test_fe_engine_precomputation.cc b/test/test_fe_engine/test_fe_engine_precomputation.cc
index 149785f5b..46d178384 100644
--- a/test/test_fe_engine/test_fe_engine_precomputation.cc
+++ b/test/test_fe_engine/test_fe_engine_precomputation.cc
@@ -1,113 +1,112 @@
/**
* @file test_fe_engine_precomputation.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Mon Jul 13 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "pybind11_akantu.hh"
#include "test_fe_engine_fixture.hh"
/* -------------------------------------------------------------------------- */
#include <pybind11/embed.h>
#include <pybind11/numpy.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace py = pybind11;
using namespace py::literals;
template <typename type_>
class TestFEMPyFixture : public TestFEMFixture<type_> {
using parent = TestFEMFixture<type_>;
public:
void SetUp() override {
parent::SetUp();
const auto & connectivities = this->mesh->getConnectivity(this->type);
const auto & nodes = this->mesh->getNodes().begin(this->dim);
coordinates = std::make_unique<Array<Real>>(
connectivities.size(), connectivities.getNbComponent() * this->dim);
for (auto && tuple :
zip(make_view(connectivities, connectivities.getNbComponent()),
make_view(*coordinates, this->dim,
connectivities.getNbComponent()))) {
const auto & conn = std::get<0>(tuple);
const auto & X = std::get<1>(tuple);
for (auto s : arange(conn.size())) {
Vector<Real>(X(s)) = Vector<Real>(nodes[conn(s)]);
}
}
}
void TearDown() override {
parent::TearDown();
coordinates.reset(nullptr);
}
protected:
std::unique_ptr<Array<Real>> coordinates;
};
TYPED_TEST_CASE(TestFEMPyFixture, types);
TYPED_TEST(TestFEMPyFixture, Precompute) {
SCOPED_TRACE(aka::to_string(this->type));
this->fem->initShapeFunctions();
const auto & N = this->fem->getShapeFunctions().getShapes(this->type);
const auto & B =
this->fem->getShapeFunctions().getShapesDerivatives(this->type);
const auto & j = this->fem->getIntegrator().getJacobians(this->type);
// Array<Real> ref_N(this->nb_quadrature_points_total, N.getNbComponent());
// Array<Real> ref_B(this->nb_quadrature_points_total, B.getNbComponent());
Array<Real> ref_j(this->nb_quadrature_points_total, j.getNbComponent());
auto ref_N(N);
auto ref_B(B);
py::module py_engine = py::module::import("py_engine");
auto py_shape = py_engine.attr("Shapes")(py::str(aka::to_string(this->type)));
auto kwargs = py::dict(
"N"_a = make_proxy(ref_N), "B"_a = make_proxy(ref_B),
"j"_a = make_proxy(ref_j), "X"_a = make_proxy(*this->coordinates),
- "Q"_a = make_proxy(
- this->fem->getIntegrationPoints(this->type)));
+ "Q"_a = make_proxy(this->fem->getIntegrationPoints(this->type)));
auto ret = py_shape.attr("precompute")(**kwargs);
auto check = [&](auto & ref_A, auto & A, const auto & id) {
SCOPED_TRACE(aka::to_string(this->type) + " " + id);
for (auto && n : zip(make_view(ref_A, ref_A.getNbComponent()),
make_view(A, A.getNbComponent()))) {
auto diff = (std::get<0>(n) - std::get<1>(n)).template norm<L_inf>();
EXPECT_NEAR(0., diff, 1e-10);
}
};
check(ref_N, N, "N");
check(ref_B, B, "B");
check(ref_j, j, "j");
}
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_bernoulli_2.cc b/test/test_fe_engine/test_fe_engine_precomputation_bernoulli_2.cc
index 68b04791e..54804fda6 100644
--- a/test/test_fe_engine/test_fe_engine_precomputation_bernoulli_2.cc
+++ b/test/test_fe_engine/test_fe_engine_precomputation_bernoulli_2.cc
@@ -1,153 +1,153 @@
/**
* @file test_fe_engine_precomputation.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Mon Jul 13 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "integrator_gauss.hh"
#include "shape_structural.hh"
/* -------------------------------------------------------------------------- */
#include <cmath>
-#include <iostream>
#include <functional>
+#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
Matrix<Real> globalToLocalRotation(Real theta) {
// clang-format off
return {{ std::cos(theta), std::sin(theta), 0},
{-std::sin(theta), std::cos(theta), 0},
{ 0, 0, 1}};
// clang-format on
}
Vector<Real> axialReference(Real xq) {
return {(1. - xq) / 2, 0, 0, (1. + xq) / 2, 0, 0};
}
Vector<Real> bendingReference(Real xq) {
return {0,
1. / 4. * Math::pow<2>(xq - 1) * (xq + 2),
1. / 4. * Math::pow<2>(xq - 1) * (xq + 1),
0,
1. / 4. * Math::pow<2>(xq + 1) * (2 - xq),
1. / 4. * Math::pow<2>(xq + 1) * (xq - 1)};
}
Vector<Real> bendingRotationReference(Real xq) {
return {0, 3. / 4. * (xq * xq - 1), 1. / 4. * (3 * xq * xq - 2 * xq - 1),
0, 3. / 4. * (1 - xq * xq), 1. / 4. * (3 * xq * xq + 2 * xq - 1)};
}
bool testBending(const Array<Real> & shape_functions, UInt shape_line_index,
std::function<Vector<Real>(Real)> reference) {
Real xq = -1. / std::sqrt(3.);
// Testing values for bending rotations shapes on quadrature points
for (auto && N : make_view(shape_functions, 3, 6)) {
auto Nt = N.transpose();
Vector<Real> N_bending = Nt(shape_line_index);
auto bending_reference = reference(xq);
if (!Math::are_vector_equal(6, N_bending.storage(),
bending_reference.storage()))
return false;
xq *= -1;
}
std::cout.flush();
return true;
}
int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
- //debug::setDebugLevel(dblTest);
+ // debug::setDebugLevel(dblTest);
constexpr ElementType type = _bernoulli_beam_2;
UInt dim = ElementClass<type>::getSpatialDimension();
Mesh mesh(dim);
// creating nodes
Vector<Real> node = {0, 0};
mesh.getNodes().push_back(node);
node = {3. / 5., 4. / 5.};
mesh.getNodes().push_back(node);
node = {2 * 3. / 5., 0};
mesh.getNodes().push_back(node);
mesh.addConnectivityType(type);
auto & connectivity = mesh.getConnectivity(type);
// creating elements
Vector<UInt> elem = {0, 1};
connectivity.push_back(elem);
elem = {1, 2};
connectivity.push_back(elem);
elem = {0, 2};
connectivity.push_back(elem);
using FE = FEEngineTemplate<IntegratorGauss, ShapeStructural, _ek_structural>;
using ShapeStruct = ShapeStructural<_ek_structural>;
auto fem = std::make_unique<FE>(mesh, dim, "test_fem");
fem->initShapeFunctions();
auto & shape = dynamic_cast<const ShapeStruct &>(fem->getShapeFunctions());
Array<Real> angles;
angles.push_back(std::atan(4. / 3.));
angles.push_back(-std::atan(4. / 3.));
angles.push_back(0);
/// Testing the rotation matrices
for (auto && tuple : zip(make_view(shape.getRotations(type), 3, 3), angles)) {
auto && rotation = std::get<0>(tuple);
auto theta = std::get<1>(tuple);
auto reference = globalToLocalRotation(theta);
if (!Math::are_vector_equal(9, reference.storage(), rotation.storage()))
return 1;
}
auto & shape_functions = shape.getShapes(type);
if (!testBending(shape_functions, 0, axialReference))
return 1;
// if (!testBending(shape_functions, 1, bendingReference))
// return 1;
// if (!testBending(shape_functions, 2, bendingRotationReference))
// return 1;
std::cout.flush();
finalize();
return 0;
}
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_structural.cc b/test/test_fe_engine/test_fe_engine_precomputation_structural.cc
index fc7e3b8e5..674f312e2 100644
--- a/test/test_fe_engine/test_fe_engine_precomputation_structural.cc
+++ b/test/test_fe_engine/test_fe_engine_precomputation_structural.cc
@@ -1,126 +1,126 @@
/**
* @file test_fe_engine_precomputation_structural.cc
*
* @author Lucas Frérot
*
* @date creation: Fri Feb 26 2018
*
* @brief test of the structural precomputations
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "integrator_gauss.hh"
#include "shape_structural.hh"
#include "test_fe_engine_structural_fixture.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
// Need a special fixture for the extra normal
class TestBernoulliB3
: public TestFEMStructuralFixture<element_type_t<_bernoulli_beam_3>> {
using parent = TestFEMStructuralFixture<element_type_t<_bernoulli_beam_3>>;
-public:
+public:
/// Load the mesh and provide extra normal direction
void readMesh(std::string filename) override {
parent::readMesh(filename);
auto & normals = this->mesh->registerData<Real>("extra_normal")
.alloc(0, dim, type, _not_ghost);
Vector<Real> normal = {-36. / 65, -48. / 65, 5. / 13};
normals.push_back(normal);
}
};
/* -------------------------------------------------------------------------- */
/// Type alias
using TestBernoulliB2 =
TestFEMStructuralFixture<element_type_t<_bernoulli_beam_2>>;
- using TestDKT18 =
- TestFEMStructuralFixture<element_type_t<_discrete_kirchhoff_triangle_18>>;
+using TestDKT18 =
+ TestFEMStructuralFixture<element_type_t<_discrete_kirchhoff_triangle_18>>;
/* -------------------------------------------------------------------------- */
/// Solution for 2D rotation matrices
Matrix<Real> globalToLocalRotation(Real theta) {
auto c = std::cos(theta);
auto s = std::sin(theta);
return {{c, s, 0}, {-s, c, 0}, {0, 0, 1}};
}
/* -------------------------------------------------------------------------- */
TEST_F(TestBernoulliB2, PrecomputeRotations) {
this->fem->initShapeFunctions();
using ShapeStruct = ShapeStructural<_ek_structural>;
auto & shape = dynamic_cast<const ShapeStruct &>(fem->getShapeFunctions());
auto & rot = shape.getRotations(type);
Real a = std::atan(4. / 3);
std::vector<Real> angles = {a, -a, 0};
Math::setTolerance(1e-15);
for (auto && tuple : zip(make_view(rot, ndof, ndof), angles)) {
auto rotation = std::get<0>(tuple);
auto angle = std::get<1>(tuple);
auto rotation_error = (rotation - globalToLocalRotation(angle)).norm<L_2>();
EXPECT_NEAR(rotation_error, 0., Math::getTolerance());
}
}
/* -------------------------------------------------------------------------- */
TEST_F(TestBernoulliB3, PrecomputeRotations) {
this->fem->initShapeFunctions();
using ShapeStruct = ShapeStructural<_ek_structural>;
auto & shape = dynamic_cast<const ShapeStruct &>(fem->getShapeFunctions());
auto & rot = shape.getRotations(type);
Matrix<Real> ref = {{3. / 13, 4. / 13, 12. / 13},
{-4. / 5, 3. / 5, 0},
{-36. / 65, -48. / 65, 5. / 13}};
Matrix<Real> solution{ndof, ndof};
solution.block(ref, 0, 0);
solution.block(ref, dim, dim);
// The default tolerance is too much, really
Math::setTolerance(1e-15);
for (auto & rotation : make_view(rot, ndof, ndof)) {
auto rotation_error = (rotation - solution).norm<L_2>();
EXPECT_NEAR(rotation_error, 0., Math::getTolerance());
}
}
/* -------------------------------------------------------------------------- */
TEST_F(TestDKT18, PrecomputeRotations) {
this->fem->initShapeFunctions();
using ShapeStruct = ShapeStructural<_ek_structural>;
auto & shape = dynamic_cast<const ShapeStruct &>(fem->getShapeFunctions());
auto & rot = shape.getRotations(type);
for (auto & rotation : make_view(rot, ndof, ndof)) {
std::cout << rotation << "\n";
}
std::cout.flush();
}
diff --git a/test/test_fe_engine/test_fe_engine_structural_fixture.hh b/test/test_fe_engine/test_fe_engine_structural_fixture.hh
index 06a3cf7ea..65c62c874 100644
--- a/test/test_fe_engine/test_fe_engine_structural_fixture.hh
+++ b/test/test_fe_engine/test_fe_engine_structural_fixture.hh
@@ -1,64 +1,64 @@
/**
* @file test_fe_engine_structural_fixture.hh
*
* @author Lucas Frérot
*
* @date creation: Fri Feb 26 2018
*
* @brief test of the fem class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "test_fe_engine_fixture.hh"
#include "mesh_io_msh_struct.hh"
+#include "test_fe_engine_fixture.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TEST_FE_ENGINE_STRUCTURAL_FIXTURE_HH__
#define __AKANTU_TEST_FE_ENGINE_STRUCTURAL_FIXTURE_HH__
using namespace akantu;
/// Base class for structural FEEngine tests with structural elements
template <typename type_>
class TestFEMStructuralFixture
: public TestFEMBaseFixture<type_, ShapeStructural, _ek_structural> {
using parent = TestFEMBaseFixture<type_, ShapeStructural, _ek_structural>;
+
public:
static const UInt ndof = ElementClass<parent::type>::getNbDegreeOfFreedom();
/// Need to tell the mesh to load structural elements
void readMesh(std::string file_name) override {
this->mesh->read(file_name, _miot_gmsh_struct);
}
};
-template <typename type_>
-const UInt TestFEMStructuralFixture<type_>::ndof;
+template <typename type_> const UInt TestFEMStructuralFixture<type_>::ndof;
// using types = gtest_list_t<TestElementTypes>;
// TYPED_TEST_CASE(TestFEMFixture, types);
#endif /* __AKANTU_TEST_FE_ENGINE_STRUCTURAL_FIXTURE_HH__ */
diff --git a/test/test_fe_engine/test_gradient.cc b/test/test_fe_engine/test_gradient.cc
index 4afb40172..521d548e1 100644
--- a/test/test_fe_engine/test_gradient.cc
+++ b/test/test_fe_engine/test_gradient.cc
@@ -1,105 +1,106 @@
/**
* @file test_gradient.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Peter Spijker <peter.spijker@epfl.ch>
*
* @date creation: Fri Sep 03 2010
* @date last modification: Thu Oct 15 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* This code is computing the gradient of a linear field and check that it gives
* a constant result. It also compute the gradient the coordinates of the mesh
* and check that it gives the identity
*
*/
/* -------------------------------------------------------------------------- */
#include "test_fe_engine_fixture.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
TYPED_TEST(TestFEMFixture, GradientPoly) {
this->fem->initShapeFunctions();
Real alpha[2][3] = {{13, 23, 31}, {11, 7, 5}};
const auto dim = this->dim;
const auto type = this->type;
const auto & position = this->fem->getMesh().getNodes();
Array<Real> const_val(this->fem->getMesh().getNbNodes(), 2, "const_val");
- for(auto && pair : zip(make_view(position, dim), make_view(const_val, 2))) {
+ for (auto && pair : zip(make_view(position, dim), make_view(const_val, 2))) {
auto & pos = std::get<0>(pair);
auto & const_ = std::get<1>(pair);
const_.set(0.);
for (UInt d = 0; d < dim; ++d) {
const_(0) += alpha[0][d] * pos(d);
const_(1) += alpha[1][d] * pos(d);
}
}
/// compute the gradient
- Array<Real> grad_on_quad(this->nb_quadrature_points_total, 2 * dim, "grad_on_quad");
+ Array<Real> grad_on_quad(this->nb_quadrature_points_total, 2 * dim,
+ "grad_on_quad");
this->fem->gradientOnIntegrationPoints(const_val, grad_on_quad, 2, type);
/// check the results
- for(auto && grad : make_view(grad_on_quad, 2, dim)) {
+ for (auto && grad : make_view(grad_on_quad, 2, dim)) {
for (UInt d = 0; d < dim; ++d) {
EXPECT_NEAR(grad(0, d), alpha[0][d], 5e-13);
EXPECT_NEAR(grad(1, d), alpha[1][d], 5e-13);
}
}
}
TYPED_TEST(TestFEMFixture, GradientPositions) {
this->fem->initShapeFunctions();
const auto dim = this->dim;
const auto type = this->type;
- UInt nb_quadrature_points = this->fem->getNbIntegrationPoints(type) * this->nb_element;
+ UInt nb_quadrature_points =
+ this->fem->getNbIntegrationPoints(type) * this->nb_element;
Array<Real> grad_coord_on_quad(nb_quadrature_points, dim * dim,
"grad_coord_on_quad");
const auto & position = this->mesh->getNodes();
- this->fem->gradientOnIntegrationPoints(position, grad_coord_on_quad,
- dim, type);
+ this->fem->gradientOnIntegrationPoints(position, grad_coord_on_quad, dim,
+ type);
- auto I = Matrix<Real>::eye(UInt(dim));
+ auto I = Matrix<Real>::eye(UInt(dim));
- for(auto && grad : make_view(grad_coord_on_quad, dim, dim)) {
- auto diff = (I - grad).template norm<L_inf>();
+ for (auto && grad : make_view(grad_coord_on_quad, dim, dim)) {
+ auto diff = (I - grad).template norm<L_inf>();
- EXPECT_NEAR(0., diff, 2e-14);
- }
+ EXPECT_NEAR(0., diff, 2e-14);
+ }
}
-
}
diff --git a/test/test_fe_engine/test_interpolate.cc b/test/test_fe_engine/test_interpolate.cc
index e01b59ec9..77e2b2d1a 100644
--- a/test/test_fe_engine/test_interpolate.cc
+++ b/test/test_fe_engine/test_interpolate.cc
@@ -1,72 +1,73 @@
/**
* @file test_interpolate.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Sep 03 2010
* @date last modification: Thu Oct 15 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_fe_engine_fixture.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
TYPED_TEST(TestFEMFixture, InterpolateConstant) {
const auto type = this->type;
const auto & position = this->fem->getMesh().getNodes();
Array<Real> const_val(position.size(), 2, "const_val");
Array<Real> val_on_quad(this->nb_quadrature_points_total, 2, "val_on_quad");
Vector<Real> value{1, 2};
for (auto && const_ : make_view(const_val, 2)) {
const_ = value;
}
// interpolate function on quadrature points
this->fem->interpolateOnIntegrationPoints(const_val, val_on_quad, 2, type);
for (auto && int_ : make_view(val_on_quad, 2)) {
auto diff = (value - int_).template norm<L_inf>();
EXPECT_NEAR(0, diff, 1e-14);
}
}
// TYPED_TEST(TestFEMFixture, InterpolatePosition) {
// const auto dim = this->dim;
// const auto type = this->type;
// const auto & position = this->fem->getMesh().getNodes();
// Array<Real> coord_on_quad(this->nb_quadrature_points_total, dim,
// "coord_on_quad");
-// this->fem->interpolateOnIntegrationPoints(position, coord_on_quad, dim, type);
+// this->fem->interpolateOnIntegrationPoints(position, coord_on_quad, dim,
+// type);
// }
} // namespace
diff --git a/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc b/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
index f976e48ba..8772d060f 100644
--- a/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
+++ b/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
@@ -1,134 +1,119 @@
/**
* @file test_interpolate_bernoulli_beam_2.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Mon Jul 13 2015
*
* @brief Test of the interpolation on the type _bernoulli_beam_2
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "fe_engine.hh"
+#include "fe_engine_template.hh"
#include "integrator_gauss.hh"
-#include "shape_linked.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
-#include "fe_engine_template.hh"
+#include "shape_linked.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(){
-
+int main() {
Mesh beams(2);
-
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
// Defining the mesh
- Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
- nodes.resize(4);
+ Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
+ nodes.resize(4);
- beams.addConnectivityType(_bernoulli_beam_2);
- Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_2));
- connectivity.resize(3);
+ beams.addConnectivityType(_bernoulli_beam_2);
+ Array<UInt> & connectivity =
+ const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_2));
+ connectivity.resize(3);
- for(UInt i=0; i<4; ++i) {
+ for (UInt i = 0; i < 4; ++i) {
- nodes(i,0)=(i+1)*2;
- nodes(i,1)=1;
- }
- for(UInt i=0; i<3; ++i) {
+ nodes(i, 0) = (i + 1) * 2;
+ nodes(i, 1) = 1;
+ }
+ for (UInt i = 0; i < 3; ++i) {
- connectivity(i,0)=i;
- connectivity(i,1)=i+1;
- }
- akantu::MeshIOMSH mesh_io;
- mesh_io.write("b_beam_2.msh", beams);
+ connectivity(i, 0) = i;
+ connectivity(i, 1) = i + 1;
+ }
+ akantu::MeshIOMSH mesh_io;
+ mesh_io.write("b_beam_2.msh", beams);
-/* -------------------------------------------------------------------------- */
- // Interpolation
+ /* --------------------------------------------------------------------------
+ */
+ // Interpolation
+ FEEngineTemplate<IntegratorGauss, ShapeLinked> * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLinked>(beams, 2);
- FEEngineTemplate<IntegratorGauss,ShapeLinked> *fem = new FEEngineTemplate<IntegratorGauss,ShapeLinked>(beams,2);
+ fem->initShapeFunctions();
- fem->initShapeFunctions();
+ Array<Real> displ_on_nodes(4, 3);
+ Array<Real> displ_on_quad(0, 3);
- Array<Real> displ_on_nodes(4,3);
- Array<Real> displ_on_quad(0,3);
+ for (UInt i = 0; i < 4; ++i) {
- for(UInt i=0; i<4; ++i) {
+ displ_on_nodes(i, 0) = (i + 1) * 2; // Definition of the displacement
+ displ_on_nodes(i, 1) = 0;
+ displ_on_nodes(i, 2) = 0;
+ }
- displ_on_nodes(i,0)=(i+1)*2; // Definition of the displacement
- displ_on_nodes(i,1)=0;
- displ_on_nodes(i,2)=0;
- }
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(
+ displ_on_nodes, displ_on_quad, 3, _not_ghost, NULL, false, 0, 0, 0);
- fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
- displ_on_quad,
- 3,_not_ghost,
- NULL, false,
- 0, 0, 0);
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(
+ displ_on_nodes, displ_on_quad, 3, _not_ghost, NULL, false, 1, 1, 1);
- fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
- displ_on_quad,
- 3, _not_ghost,
- NULL, false,
- 1, 1, 1);
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(
+ displ_on_nodes, displ_on_quad, 3, _not_ghost, NULL, true, 2, 2, 1);
- fem->getShapeFunctions(). interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
- displ_on_quad,
- 3, _not_ghost,
- NULL, true,
- 2, 2, 1);
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(
+ displ_on_nodes, displ_on_quad, 3, _not_ghost, NULL, false, 3, 2, 3);
- fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
- displ_on_quad,
- 3, _not_ghost,
- NULL, false,
- 3, 2, 3);
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(
+ displ_on_nodes, displ_on_quad, 3, _not_ghost, NULL, true, 4, 3, 3);
- fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
- displ_on_quad,
- 3, _not_ghost,
- NULL, true,
- 4, 3, 3);
+ Real * don = displ_on_nodes.storage();
+ Real * doq = displ_on_quad.storage();
- Real * don= displ_on_nodes.storage();
- Real * doq= displ_on_quad.storage();
-
- std::ofstream my_file("out.txt");
+ std::ofstream my_file("out.txt");
my_file << don << std::endl;
my_file << doq << std::endl;
return EXIT_SUCCESS;
-
}
diff --git a/test/test_fe_engine/test_inverse_map.cc b/test/test_fe_engine/test_inverse_map.cc
index 6da60b1df..32d62e4c9 100644
--- a/test/test_fe_engine/test_inverse_map.cc
+++ b/test/test_fe_engine/test_inverse_map.cc
@@ -1,71 +1,74 @@
/**
* @file test_inverse_map.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Fri Sep 03 2010
* @date last modification: Thu Oct 15 2015
*
* @brief test of the fem class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_fe_engine_fixture.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
TYPED_TEST(TestFEMFixture, InverseMap) {
this->fem->initShapeFunctions();
- Matrix<Real> quad = GaussIntegrationElement<TestFixture::type>::getQuadraturePoints();
+ Matrix<Real> quad =
+ GaussIntegrationElement<TestFixture::type>::getQuadraturePoints();
const auto & position = this->fem->getMesh().getNodes();
-/// get the quadrature points coordinates
+ /// get the quadrature points coordinates
Array<Real> coord_on_quad(quad.cols() * this->nb_element, this->dim,
"coord_on_quad");
- this->fem->interpolateOnIntegrationPoints(position, coord_on_quad, this->dim, this->type);
+ this->fem->interpolateOnIntegrationPoints(position, coord_on_quad, this->dim,
+ this->type);
Vector<Real> natural_coords(this->dim);
auto length = (this->upper - this->lower).template norm<L_inf>();
- for(auto && enum_ : enumerate(make_view(coord_on_quad, this->dim, quad.cols()))) {
+ for (auto && enum_ :
+ enumerate(make_view(coord_on_quad, this->dim, quad.cols()))) {
auto el = std::get<0>(enum_);
const auto & quads_coords = std::get<1>(enum_);
for (auto q : arange(quad.cols())) {
Vector<Real> quad_coord = quads_coords(q);
Vector<Real> ref_quad_coord = quad(q);
this->fem->inverseMap(quad_coord, el, this->type, natural_coords);
auto dis_normalized = ref_quad_coord.distance(natural_coords) / length;
EXPECT_NEAR(0., dis_normalized, 5e-12);
}
}
}
} // namespace
diff --git a/test/test_fe_engine/test_mesh_data.cc b/test/test_fe_engine/test_mesh_data.cc
index 409d17533..561c98aec 100644
--- a/test/test_fe_engine/test_mesh_data.cc
+++ b/test/test_fe_engine/test_mesh_data.cc
@@ -1,84 +1,86 @@
/**
* @file test_mesh_data.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri May 03 2013
* @date last modification: Mon Jul 13 2015
*
* @brief Test of the MeshData class
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <string>
#define QUOTES(x) #x
#define ADD_QUOTES(x) QUOTES(x)
-#define CAT(x,y) x ## _ ## y
-#define CONCAT(x,y) CAT(x,y)
+#define CAT(x, y) x##_##y
+#define CONCAT(x, y) CAT(x, y)
//#define TYPE std::string
//#define VALUE1 "abc"
//#define VALUE2 "qwe"
#define ELEMENT _triangle_6
-#define NAME CONCAT(TYPE,data)
+#define NAME CONCAT(TYPE, data)
/* -------------------------------------------------------------------------- */
using namespace akantu;
using namespace std;
int main() {
- std::cout << "Testing with type " << ADD_QUOTES(TYPE)
- << " and values " << ADD_QUOTES(VALUE1) << "," << ADD_QUOTES(VALUE2) << "..." << std::endl;
+ std::cout << "Testing with type " << ADD_QUOTES(TYPE) << " and values "
+ << ADD_QUOTES(VALUE1) << "," << ADD_QUOTES(VALUE2) << "..."
+ << std::endl;
MeshData mesh_data;
ElementType elem_type = ELEMENT;
const std::string name = ADD_QUOTES(NAME);
- Array<TYPE> & vec = mesh_data.getElementalDataArrayAlloc<TYPE>(name, elem_type);
+ Array<TYPE> & vec =
+ mesh_data.getElementalDataArrayAlloc<TYPE>(name, elem_type);
// XXX TO DELETE
// vec.copy(mesh_data.getElementalDataArrayAlloc<TYPE>(name, elem_type));
- TYPE value[2] = {VALUE1, VALUE2 };
+ TYPE value[2] = {VALUE1, VALUE2};
vec.push_back(value[0]);
vec.push_back(value[1]);
- for(UInt i(0); i < 2; i++) {
- AKANTU_DEBUG_ASSERT( vec(i) == value[i],
- "The Array accessed through the getElementDataArray method does not contain the right value." );
+ for (UInt i(0); i < 2; i++) {
+ AKANTU_DEBUG_ASSERT(vec(i) == value[i], "The Array accessed through the "
+ "getElementDataArray method does "
+ "not contain the right value.");
}
std::cout << vec << std::endl;
std::cout << mesh_data.getTypeCode(name) << std::endl;
return EXIT_SUCCESS;
}
-
diff --git a/test/test_geometry/test_geometry_intersection.cc b/test/test_geometry/test_geometry_intersection.cc
index 7b29e4962..96b76a626 100644
--- a/test/test_geometry/test_geometry_intersection.cc
+++ b/test/test_geometry/test_geometry_intersection.cc
@@ -1,127 +1,131 @@
/**
* @file test_geometry_intersection.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Fri Feb 27 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Tests the intersection module
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "geom_helper_functions.hh"
#include "mesh_geom_factory.hh"
#include "tree_type_helper.hh"
-#include "geom_helper_functions.hh"
#include "mesh_geom_common.hh"
#include <iostream>
#include <iterator>
#include <CGAL/Exact_spherical_kernel_3.h>
-#include <CGAL/intersections.h>
#include <CGAL/Spherical_kernel_intersections.h>
+#include <CGAL/intersections.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef cgal::Cartesian K;
-typedef IntersectionTypeHelper<TreeTypeHelper<Triangle<K>, K>, K::Segment_3>::intersection_type result_type;
+typedef IntersectionTypeHelper<TreeTypeHelper<Triangle<K>, K>,
+ K::Segment_3>::intersection_type result_type;
typedef cgal::Spherical SK;
-typedef boost::variant<std::pair<SK::Circular_arc_point_3, UInt> > sk_inter_res;
+typedef boost::variant<std::pair<SK::Circular_arc_point_3, UInt>> sk_inter_res;
/*typedef CGAL::cpp11::result_of<SK::Intersect_3(SK::Line_arc_3,
- SK::Sphere_3,
- std::back_insert_iterator<
- std::list<sk_inter_res> >)>::type sk_res;*/
+ SK::Sphere_3,
+ std::back_insert_iterator<
+ std::list<sk_inter_res> >)>::type sk_res;*/
typedef std::pair<SK::Circular_arc_point_3, UInt> pair_type;
-
/* -------------------------------------------------------------------------- */
-int main (int argc, char * argv[]) {
+int main(int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblWarning);
Mesh mesh(2);
mesh.read("test_geometry_triangle.msh");
MeshGeomFactory<2, _triangle_3, Triangle<K>, K> factory(mesh);
factory.constructData();
const TreeTypeHelper<Triangle<K>, K>::tree & tree = factory.getTree();
K::Point_3 a(0., 0.25, 0.), b(1., 0.25, 0.);
K::Segment_3 line(a, b);
K::Point_3 begin(a), intermediate(0.25, 0.25, 0.), end(0.75, 0.25, 0.);
K::Segment_3 result_0(begin, intermediate), result_1(intermediate, end);
std::list<result_type> list_of_intersections;
tree.all_intersections(line, std::back_inserter(list_of_intersections));
const result_type & intersection_0 = list_of_intersections.back();
const result_type & intersection_1 = list_of_intersections.front();
if (!intersection_0 || !intersection_1)
return EXIT_FAILURE;
/// *-> first is the intersection ; *->second is the primitive id
- if (const K::Segment_3 * segment = boost::get<K::Segment_3>(&(intersection_0->first))) {
+ if (const K::Segment_3 * segment =
+ boost::get<K::Segment_3>(&(intersection_0->first))) {
if (!compareSegments(*segment, result_0)) {
return EXIT_FAILURE;
}
- } else return EXIT_FAILURE;
+ } else
+ return EXIT_FAILURE;
- if (const K::Segment_3 * segment = boost::get<K::Segment_3>(&(intersection_1->first))) {
+ if (const K::Segment_3 * segment =
+ boost::get<K::Segment_3>(&(intersection_1->first))) {
if (!compareSegments(*segment, result_1)) {
return EXIT_FAILURE;
}
- } else return EXIT_FAILURE;
+ } else
+ return EXIT_FAILURE;
SK::Sphere_3 sphere(SK::Point_3(0, 0, 0), 3.);
SK::Segment_3 seg(SK::Point_3(0, 0, 0), SK::Point_3(2., 2., 2.));
SK::Line_arc_3 arc(seg);
std::list<sk_inter_res> s_results;
CGAL::intersection(arc, sphere, std::back_inserter(s_results));
if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
- std::cout << "xi = " << to_double(pair->first.x())
- << ", yi = " << to_double(pair->first.y()) << std::endl;
+ std::cout << "xi = " << to_double(pair->first.x())
+ << ", yi = " << to_double(pair->first.y()) << std::endl;
if (!comparePoints(pair->first, SK::Circular_arc_point_3(1.0, 1.0, 1.0)))
- return EXIT_FAILURE;
- } else return EXIT_FAILURE;
+ return EXIT_FAILURE;
+ } else
+ return EXIT_FAILURE;
MeshGeomFactory<2, _triangle_3, Line_arc<SK>, SK> Sfactory(mesh);
Sfactory.constructData();
finalize();
return EXIT_SUCCESS;
}
-
diff --git a/test/test_geometry/test_geometry_predicates.cc b/test/test_geometry/test_geometry_predicates.cc
index 2cee26181..0a79bcb22 100644
--- a/test/test_geometry/test_geometry_predicates.cc
+++ b/test/test_geometry/test_geometry_predicates.cc
@@ -1,88 +1,88 @@
/**
* @file test_geometry_predicates.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Thu Jan 14 2016
*
* @brief Tests the geometry predicates
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "geom_helper_functions.hh"
#include "mesh_geom_common.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef cgal::Cartesian K;
typedef K::Point_3 Point;
typedef K::Segment_3 Segment;
int main(int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblWarning);
Point a(0, 1, 0);
Point b(0, 1, 1);
Segment seg1(a, b);
Segment seg2(b, a);
if (!compareSegments(seg1, seg2))
return EXIT_FAILURE;
// Testing sort + unique on list of segments
- std::vector<std::pair<K::Segment_3, UInt> > pair_list;
+ std::vector<std::pair<K::Segment_3, UInt>> pair_list;
pair_list.push_back(std::make_pair(seg1, 1));
pair_list.push_back(std::make_pair(seg2, 2));
segmentPairsLess sorter;
std::sort(pair_list.begin(), pair_list.end(), sorter);
- std::vector<std::pair<K::Segment_3, UInt> >::iterator
- it = std::unique(pair_list.begin(), pair_list.end(), compareSegmentPairs);
+ std::vector<std::pair<K::Segment_3, UInt>>::iterator it =
+ std::unique(pair_list.begin(), pair_list.end(), compareSegmentPairs);
if (it - pair_list.begin() != 1) {
std::cout << pair_list.size() << std::endl;
return EXIT_FAILURE;
}
// Testing insertion in set
std::set<std::pair<K::Segment_3, UInt>, segmentPairsLess> pair_set;
pair_set.insert(pair_set.begin(), std::make_pair(seg1, 1));
pair_set.insert(pair_set.begin(), std::make_pair(seg2, 2));
if (pair_set.size() != 1) {
std::cout << pair_set.size() << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_geometry/test_segment_intersection_tetrahedron_4.cc b/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
index 62ce9b434..36a3d54b2 100644
--- a/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
+++ b/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
@@ -1,148 +1,145 @@
/**
* @file test_segment_intersection_tetrahedron_4.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Feb 27 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Tests the intersection module with _tetrahedron_4 elements
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh_segment_intersector.hh"
#include "mesh_geom_common.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef cgal::Cartesian K;
typedef K::Point_3 Point;
typedef K::Segment_3 Segment;
/* -------------------------------------------------------------------------- */
-int main (int argc, char * argv[]) {
+int main(int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblError);
Mesh mesh(3), interface_mesh(3, "interface_mesh");
mesh.read("test_geometry_tetrahedron.msh");
MeshSegmentIntersector<3, _tetrahedron_4> intersector(mesh, interface_mesh);
intersector.constructData();
// Testing a segment going through the cube
Point point(1., 1., 1.);
Segment segment(CGAL::ORIGIN, point);
intersector.computeIntersectionQuery(segment);
- std::cout << "number of seg_2 : " << interface_mesh.getNbElement(_segment_2) << std::endl;
+ std::cout << "number of seg_2 : " << interface_mesh.getNbElement(_segment_2)
+ << std::endl;
if (interface_mesh.getNbElement(_segment_2) != 2)
return EXIT_FAILURE;
Vector<Real> bary(2), bary1(2), bary2(2);
Element test;
test.type = _segment_2;
test.element = 0;
interface_mesh.getBarycenter(test, bary1);
test.element = 1;
interface_mesh.getBarycenter(test, bary2);
- Real first_bary[] = {1./6., 1./6., 1./6.};
- Real second_bary[] = {2./3., 2./3., 2./3.};
+ Real first_bary[] = {1. / 6., 1. / 6., 1. / 6.};
+ Real second_bary[] = {2. / 3., 2. / 3., 2. / 3.};
// We don't know the order of the elements, so here we test permutations
- if (!( (Math::are_vector_equal(3, bary1.storage(), first_bary) &&
- Math::are_vector_equal(3, bary2.storage(), second_bary) ) ||
- (Math::are_vector_equal(3, bary1.storage(), second_bary) &&
- Math::are_vector_equal(3, bary2.storage(), first_bary) ) ))
+ if (!((Math::are_vector_equal(3, bary1.storage(), first_bary) &&
+ Math::are_vector_equal(3, bary2.storage(), second_bary)) ||
+ (Math::are_vector_equal(3, bary1.storage(), second_bary) &&
+ Math::are_vector_equal(3, bary2.storage(), first_bary))))
return EXIT_FAILURE;
-
// Testing a segment completely inside one element
- Point a(0.05, 0.05, 0.05),
- b(0.06, 0.06, 0.06);
+ Point a(0.05, 0.05, 0.05), b(0.06, 0.06, 0.06);
Segment inside_segment(a, b);
intersector.computeIntersectionQuery(inside_segment);
test.element = interface_mesh.getNbElement(_segment_2) - 1;
interface_mesh.getBarycenter(test, bary);
Real third_bary[] = {0.055, 0.055, 0.055};
if (!Math::are_vector_equal(3, bary.storage(), third_bary))
return EXIT_FAILURE;
// Testing a segment whose end points are inside elements
- Point c(0.1, 0.1, 0.1),
- d(0.9, 0.9, 0.9);
+ Point c(0.1, 0.1, 0.1), d(0.9, 0.9, 0.9);
Segment crossing_segment(c, d);
intersector.computeIntersectionQuery(crossing_segment);
UInt el1 = interface_mesh.getNbElement(_segment_2) - 2;
UInt el2 = el1 + 1;
test.element = el1;
interface_mesh.getBarycenter(test, bary1);
test.element = el2;
interface_mesh.getBarycenter(test, bary2);
- Real fourth_bary[] = {13./60., 13./60., 13./60.};
- Real fifth_bary[] = {37./60., 37./60., 37./60.};
+ Real fourth_bary[] = {13. / 60., 13. / 60., 13. / 60.};
+ Real fifth_bary[] = {37. / 60., 37. / 60., 37. / 60.};
// We don't know the order of the elements, so here we test permutations
- if (!( (Math::are_vector_equal(3, bary1.storage(), fourth_bary) &&
- Math::are_vector_equal(3, bary2.storage(), fifth_bary) ) ||
- (Math::are_vector_equal(3, bary1.storage(), fifth_bary) &&
- Math::are_vector_equal(3, bary2.storage(), fourth_bary) ) ))
+ if (!((Math::are_vector_equal(3, bary1.storage(), fourth_bary) &&
+ Math::are_vector_equal(3, bary2.storage(), fifth_bary)) ||
+ (Math::are_vector_equal(3, bary1.storage(), fifth_bary) &&
+ Math::are_vector_equal(3, bary2.storage(), fourth_bary))))
return EXIT_FAILURE;
// Testing a segment along the edge of elements
- Point e(1, 0, 0),
- f(0, 1, 0);
+ Point e(1, 0, 0), f(0, 1, 0);
Segment edge_segment(e, f);
UInt current_nb_elements = interface_mesh.getNbElement(_segment_2);
intersector.computeIntersectionQuery(edge_segment);
if (interface_mesh.getNbElement(_segment_2) != current_nb_elements + 1)
return EXIT_FAILURE;
test.element = interface_mesh.getNbElement(_segment_2) - 1;
interface_mesh.getBarycenter(test, bary);
Real sixth_bary[] = {0.5, 0.5, 0};
if (!Math::are_vector_equal(3, bary.storage(), sixth_bary))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
diff --git a/test/test_geometry/test_segment_intersection_triangle_3.cc b/test/test_geometry/test_segment_intersection_triangle_3.cc
index 787a18f70..c837c417e 100644
--- a/test/test_geometry/test_segment_intersection_triangle_3.cc
+++ b/test/test_geometry/test_segment_intersection_triangle_3.cc
@@ -1,145 +1,138 @@
/**
* @file test_segment_intersection_triangle_3.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Fri Feb 27 2015
* @date last modification: Thu Jan 14 2016
*
* @brief Tests the interface mesh generation
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "mesh_segment_intersector.hh"
-#include "mesh_sphere_intersector.hh"
#include "geom_helper_functions.hh"
#include "mesh_geom_common.hh"
+#include "mesh_segment_intersector.hh"
+#include "mesh_sphere_intersector.hh"
#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef cgal::Cartesian K;
typedef cgal::Spherical SK;
/* -------------------------------------------------------------------------- */
-int main (int argc, char * argv[]) {
+int main(int argc, char * argv[]) {
initialize("", argc, argv);
debug::setDebugLevel(dblError);
Math::setTolerance(1e-10);
Mesh mesh(2), interface_mesh(2, "interface_mesh");
mesh.read("test_geometry_triangle.msh");
MeshSegmentIntersector<2, _triangle_3> intersector(mesh, interface_mesh);
intersector.constructData();
// Testing a segment going out of the mesh
- K::Point_3 a(0, 0.25, 0),
- b(1, 0.25, 0),
- c(0.25, 0, 0),
- d(0.25, 1, 0);
+ K::Point_3 a(0, 0.25, 0), b(1, 0.25, 0), c(0.25, 0, 0), d(0.25, 1, 0);
- K::Segment_3 h_interface(a, b),
- v_interface(c, d);
+ K::Segment_3 h_interface(a, b), v_interface(c, d);
std::list<K::Segment_3> interface_list;
interface_list.push_back(h_interface);
interface_list.push_back(v_interface);
intersector.computeIntersectionQueryList(interface_list);
if (interface_mesh.getNbElement(_segment_2) != 4)
return EXIT_FAILURE;
Vector<Real> bary(2);
Element test;
test.element = 0;
test.type = _segment_2;
-
+
interface_mesh.getBarycenter(test, bary);
Real first_bary[] = {0.125, 0.25};
if (!Math::are_vector_equal(2, bary.storage(), first_bary))
return EXIT_FAILURE;
// Testing a segment completely inside an element
- K::Point_3 e(0.1, 0.33, 0),
- f(0.1, 0.67, 0);
+ K::Point_3 e(0.1, 0.33, 0), f(0.1, 0.67, 0);
K::Segment_3 inside_segment(e, f);
intersector.computeIntersectionQuery(inside_segment);
test.element = interface_mesh.getNbElement(_segment_2) - 1;
interface_mesh.getBarycenter(test, bary);
Real second_bary[] = {0.1, 0.5};
if (!Math::are_vector_equal(2, bary.storage(), second_bary))
return EXIT_FAILURE;
#if 0
// cgal::Spherical kernel testing the addition of nodes
std::cout << "initial mesh size = " << mesh.getNodes().size() << " nodes" << std::endl;
SK::Sphere_3 sphere(SK::Point_3(0, 1, 0), 0.2*0.2);
SK::Sphere_3 sphere2(SK::Point_3(1, 0, 0), 0.4999999999);
MeshSphereIntersector<2, _triangle_3> intersector_sphere(mesh);
intersector_sphere.constructData();
std::list<SK::Sphere_3> sphere_list;
sphere_list.push_back(sphere);
sphere_list.push_back(sphere2);
intersector_sphere.computeIntersectionQueryList(sphere_list);
std::cout << "final mesh size = " << mesh.getNodes().size() << std::endl;
const Array<UInt> new_node_triangle_3 = intersector_sphere.getNewNodePerElem();
const Array<Real> & nodes = mesh.getNodes();
std::cout << "New nodes :" << std::endl;
std::cout << "node 5, x=" << nodes(4,0) << ", y=" << nodes(4,1) << std::endl;
std::cout << "node 6, x=" << nodes(5,0) << ", y=" << nodes(5,1) << std::endl;
std::cout << "node 7, x=" << nodes(6,0) << ", y=" << nodes(6,1) << std::endl;
if ( (new_node_triangle_3(0,0) != 1) || (new_node_triangle_3(1,0) != 2)){
for(UInt k=0; k != new_node_triangle_3.size(); ++k){
std::cout << new_node_triangle_3(k,0) << " new nodes in element " << k << ", node(s): "
<< new_node_triangle_3(k,1) << ", " << new_node_triangle_3(k,3)
<< ", on segment(s):" << new_node_triangle_3(k,2) << ", "
<< new_node_triangle_3(k,4) << std::endl;
}
return EXIT_FAILURE;
}
#endif
finalize();
return EXIT_SUCCESS;
}
-
-
diff --git a/test/test_gtest_main.cc b/test/test_gtest_main.cc
index 3c8574cce..32018c506 100644
--- a/test/test_gtest_main.cc
+++ b/test/test_gtest_main.cc
@@ -1,53 +1,53 @@
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#if defined(AKANTU_TEST_USE_PYBIND11)
#include <pybind11/embed.h>
namespace py = pybind11;
#endif
/* -------------------------------------------------------------------------- */
namespace {
class AkaEnvironment : public ::testing::Environment {
public:
AkaEnvironment(int & argc, char **& argv) : argc(argc), argv(argv) {}
// Override this to define how to set up the environment.
void SetUp() override {
::akantu::initialize(argc, argv);
#if defined(AKANTU_USE_PYBIND11)
- //py::initialize_interpreter();
+// py::initialize_interpreter();
#endif
}
// Override this to define how to tear down the environment.
void TearDown() override {
::akantu::finalize();
#if defined(AKANTU_USE_PYBIND11)
- //py::finalize_interpreter();
+// py::finalize_interpreter();
#endif
}
protected:
int & argc;
char **& argv;
};
}
int main(int argc, char ** argv) {
#if defined(AKANTU_TEST_USE_PYBIND11)
py::scoped_interpreter guard{};
#endif
::testing::InitGoogleTest(&argc, argv);
::testing::AddGlobalTestEnvironment(new AkaEnvironment(argc, argv));
- ::testing::TestEventListeners& listeners =
- ::testing::UnitTest::GetInstance()->listeners();
+ ::testing::TestEventListeners & listeners =
+ ::testing::UnitTest::GetInstance()->listeners();
if (::akantu::Communicator::getStaticCommunicator().whoAmI() != 0) {
delete listeners.Release(listeners.default_result_printer());
}
return RUN_ALL_TESTS();
}
diff --git a/test/test_gtest_utils.hh b/test/test_gtest_utils.hh
index 1a00ca79e..995b8c8e3 100644
--- a/test/test_gtest_utils.hh
+++ b/test/test_gtest_utils.hh
@@ -1,203 +1,203 @@
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_iterators.hh"
/* -------------------------------------------------------------------------- */
#include <boost/preprocessor.hpp>
#include <gtest/gtest.h>
#include <tuple>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TEST_GTEST_UTILS_HH__
#define __AKANTU_TEST_GTEST_UTILS_HH__
namespace {
/* -------------------------------------------------------------------------- */
template <::akantu::ElementType t>
using element_type_t = std::integral_constant<::akantu::ElementType, t>;
/* -------------------------------------------------------------------------- */
template <typename... T> struct gtest_list {};
template <typename... Ts> struct gtest_list<std::tuple<Ts...>> {
using type = ::testing::Types<Ts...>;
};
template <typename... T> using gtest_list_t = typename gtest_list<T...>::type;
/* -------------------------------------------------------------------------- */
template <typename... T> struct tuple_concat {};
template <typename... T1s, typename... T2s>
struct tuple_concat<std::tuple<T1s...>, std::tuple<T2s...>> {
using type = std::tuple<T1s..., T2s...>;
};
template <typename... T>
using tuple_concat_t = typename tuple_concat<T...>::type;
/* -------------------------------------------------------------------------- */
template <template <typename> class Pred, typename... Ts>
struct tuple_filter {};
template <template <typename> class Pred, typename T>
struct tuple_filter<Pred, std::tuple<T>> {
using type = std::conditional_t<Pred<T>::value, std::tuple<T>, std::tuple<>>;
};
template <template <typename> class Pred, typename T, typename... Ts>
struct tuple_filter<Pred, std::tuple<T, Ts...>> {
using type =
tuple_concat_t<typename tuple_filter<Pred, std::tuple<T>>::type,
typename tuple_filter<Pred, std::tuple<Ts...>>::type>;
};
template <template <typename> class Pred, typename... Ts>
using tuple_filter_t = typename tuple_filter<Pred, Ts...>::type;
/* -------------------------------------------------------------------------- */
template <size_t N, typename... Ts> struct tuple_split {};
template <size_t N, typename T, typename... Ts>
struct tuple_split<N, std::tuple<T, Ts...>> {
protected:
using split = tuple_split<N - 1, std::tuple<Ts...>>;
public:
using type = tuple_concat_t<std::tuple<T>, typename split::type>;
using type_tail = typename split::type_tail;
};
template <typename T, typename... Ts>
struct tuple_split<1, std::tuple<T, Ts...>> {
using type = std::tuple<T>;
using type_tail = std::tuple<Ts...>;
};
template <size_t N, typename... T>
using tuple_split_t = typename tuple_split<N, T...>::type;
template <size_t N, typename... T>
using tuple_split_tail_t = typename tuple_split<N, T...>::type_tail;
/* -------------------------------------------------------------------------- */
template <typename... T> struct cross_product {};
template <typename... T2s>
struct cross_product<std::tuple<>, std::tuple<T2s...>> {
using type = std::tuple<>;
};
template <typename T1, typename... T1s, typename... T2s>
struct cross_product<std::tuple<T1, T1s...>, std::tuple<T2s...>> {
using type = tuple_concat_t<
std::tuple<std::tuple<T1, T2s>...>,
typename cross_product<std::tuple<T1s...>, std::tuple<T2s...>>::type>;
};
template <typename... T>
using cross_product_t = typename cross_product<T...>::type;
/* -------------------------------------------------------------------------- */
#define OP_CAT(s, data, elem) element_type_t<::akantu::elem>
using TestElementTypesAll = std::tuple<BOOST_PP_SEQ_ENUM(
BOOST_PP_SEQ_TRANSFORM(OP_CAT, _, AKANTU_ek_regular_ELEMENT_TYPE))>;
#if defined(AKANTU_COHESIVE_ELEMENT)
using TestCohesiveElementTypes = std::tuple<BOOST_PP_SEQ_ENUM(
BOOST_PP_SEQ_TRANSFORM(OP_CAT, _, AKANTU_ek_cohesive_ELEMENT_TYPE))>;
#endif
#if defined(AKANTU_STRUCTURAL_MECHANICS)
using TestElementTypesStructural = std::tuple<BOOST_PP_SEQ_ENUM(
BOOST_PP_SEQ_TRANSFORM(OP_CAT, _, AKANTU_ek_structural_ELEMENT_TYPE))>;
#endif
} // namespace
-using TestAllDimensions =
- std::tuple<std::integral_constant<unsigned int, 1>, std::integral_constant<unsigned int, 2>,
- std::integral_constant<unsigned int, 3>>;
+using TestAllDimensions = std::tuple<std::integral_constant<unsigned int, 1>,
+ std::integral_constant<unsigned int, 2>,
+ std::integral_constant<unsigned int, 3>>;
template <typename T>
using is_point_1 = std::is_same<T, element_type_t<::akantu::_point_1>>;
template <typename T>
using not_is_point_1 =
aka::negation<std::is_same<T, element_type_t<::akantu::_point_1>>>;
using TestElementTypes = tuple_filter_t<not_is_point_1, TestElementTypesAll>;
#if defined(AKANTU_STRUCTURAL_MECHANICS)
using StructuralTestElementTypes =
tuple_filter_t<not_is_point_1, TestElementTypesStructural>;
#endif
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <size_t degree> class Polynomial {
public:
Polynomial() = default;
Polynomial(std::initializer_list<double> && init) {
for (auto && pair : akantu::zip(init, constants))
std::get<1>(pair) = std::get<0>(pair);
}
double operator()(double x) {
double res = 0.;
for (auto && vals : akantu::enumerate(constants)) {
double a;
int k;
std::tie(k, a) = vals;
res += a * std::pow(x, k);
}
return res;
}
Polynomial extract(size_t pdegree) {
Polynomial<degree> extract(*this);
for (size_t d = pdegree + 1; d < degree + 1; ++d)
extract.constants[d] = 0;
return extract;
}
auto integral() {
Polynomial<degree + 1> integral_;
integral_.set(0, 0.);
;
for (size_t d = 0; d < degree + 1; ++d) {
integral_.set(1 + d, get(d) / double(d + 1));
}
return integral_;
}
auto integrate(double a, double b) {
auto primitive = integral();
return (primitive(b) - primitive(a));
}
double get(int i) const { return constants[i]; }
void set(int i, double a) { constants[i] = a; }
protected:
std::array<double, degree + 1> constants;
};
template <size_t degree>
std::ostream & operator<<(std::ostream & stream, const Polynomial<degree> & p) {
for (size_t d = 0; d < degree + 1; ++d) {
if (d != 0)
stream << " + ";
stream << p.get(degree - d);
if (d != degree)
stream << "x ^ " << degree - d;
}
return stream;
}
/* -------------------------------------------------------------------------- */
#endif /* __AKANTU_TEST_GTEST_UTILS_HH__ */
diff --git a/test/test_io/test_parser/test_parser.cc b/test/test_io/test_parser/test_parser.cc
index 8bede7ca3..76a44171e 100644
--- a/test/test_io/test_parser/test_parser.cc
+++ b/test/test_io/test_parser/test_parser.cc
@@ -1,76 +1,75 @@
/**
* @file test_parser.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Sun Oct 19 2014
*
* @brief test the input file parser
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "parser.hh"
#include "aka_random_generator.hh"
+#include "parser.hh"
#include <iostream>
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("input_file.dat", argc, argv);
const Parser & p = getStaticParser();
-
- std::cout << RandomGenerator<UInt>::seed() <<"==123456" << std::endl;
+ std::cout << RandomGenerator<UInt>::seed() << "==123456" << std::endl;
std::cout << p << std::endl;
Real toto = p.getParameter("toto");
std::cout << toto;
- Real ref = 2*M_PI + std::max(2., 50.);
- if(std::abs(toto - ref) > std::numeric_limits<Real>::epsilon()) {
+ Real ref = 2 * M_PI + std::max(2., 50.);
+ if (std::abs(toto - ref) > std::numeric_limits<Real>::epsilon()) {
std::cout << "!=" << ref << std::endl;
return 1;
}
std::cout << "==" << ref << std::endl;
Vector<Real> vect = p.getParameter("vect");
std::cout << vect << std::endl;
Matrix<Real> mat = p.getParameter("mat");
std::cout << mat << std::endl;
RandomParameter<Real> rand1 = p.getParameter("rand1");
std::cout << rand1 << std::endl;
RandomParameter<Real> rand2 = p.getParameter("rand2");
std::cout << rand2 << std::endl;
RandomParameter<Real> rand3 = p.getParameter("rand3");
std::cout << rand3 << std::endl;
finalize();
return 0;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
index d694a21e8..b80feb758 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
@@ -1,141 +1,150 @@
/**
* @file test_buildfacets_hexahedron_20.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with hexahedrons
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _hexahedron_20;
Mesh mesh(spatial_dimension);
mesh.read("hexahedron_20.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// std::cout << mesh_facets << std::endl;
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
-
+ const Array<std::vector<Element>> & el_to_subel3 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_subfacet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel2(i).size(); ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
- const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
+ const Array<Element> & subel_to_el3 =
+ mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type_facet);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < 6; ++j){
- std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
+ for (UInt j = 0; j < 6; ++j) {
+ std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
index d567d9fb2..b16229df3 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
@@ -1,142 +1,150 @@
/**
* @file test_buildfacets_hexahedron_8.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with hexahedrons
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _hexahedron_8;
Mesh mesh(spatial_dimension);
mesh.read("hexahedron_8.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// std::cout << mesh_facets << std::endl;
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
-
+ const Array<std::vector<Element>> & el_to_subel3 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_subfacet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel2(i).size(); ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
- const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
-
+ const Array<Element> & subel_to_el3 =
+ mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type_facet);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < 6; ++j){
- std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
+ for (UInt j = 0; j < 6; ++j) {
+ std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
index 7ff2e033b..7e06c3da3 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
@@ -1,126 +1,132 @@
/**
* @file test_buildfacets_mixed2d_linear.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Fri Sep 18 2015
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with quadrangles
* and triangles
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type1 = _quadrangle_4;
const ElementType type2 = _triangle_3;
Mesh mesh(spatial_dimension);
mesh.read("mixed2d_linear.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet = mesh.getFacetType(type1);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
-
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type1);
- const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type2);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
-
+ const Array<Element> & subel_to_el2_1 =
+ mesh_facets.getSubelementToElement(type1);
+ const Array<Element> & subel_to_el2_2 =
+ mesh_facets.getSubelementToElement(type2);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.size(); ++i) {
std::cout << type1 << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2_1(i, j).type << " "
+ << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el2_2.size(); ++i) {
std::cout << type2 << " " << i << " connected to ";
- for (UInt j = 0; j < 3; ++j){
- std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
+ for (UInt j = 0; j < 3; ++j) {
+ std::cout << subel_to_el2_2(i, j).type << " "
+ << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
index f46165131..5d468f524 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
@@ -1,126 +1,132 @@
/**
* @file test_buildfacets_mixed2d_quadratic.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Fri Sep 18 2015
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with quadrangles
* and triangles
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type1 = _quadrangle_8;
const ElementType type2 = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("mixed2d_quadratic.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet = mesh.getFacetType(type1);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
-
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type1);
- const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type2);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
-
+ const Array<Element> & subel_to_el2_1 =
+ mesh_facets.getSubelementToElement(type1);
+ const Array<Element> & subel_to_el2_2 =
+ mesh_facets.getSubelementToElement(type2);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.size(); ++i) {
std::cout << type1 << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2_1(i, j).type << " "
+ << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el2_2.size(); ++i) {
std::cout << type2 << " " << i << " connected to ";
- for (UInt j = 0; j < 3; ++j){
- std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
+ for (UInt j = 0; j < 3; ++j) {
+ std::cout << subel_to_el2_2(i, j).type << " "
+ << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
index 12f095e29..e4e49a87b 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
@@ -1,165 +1,181 @@
/**
* @file test_buildfacets_mixed3d_linear.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with hexahedrons
* and pentahedrons
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type1 = _hexahedron_8;
const ElementType type2 = _pentahedron_6;
Mesh mesh(spatial_dimension);
mesh.read("mixed3d_linear.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet1 = mesh.getFacetType(type1);
const ElementType type_facet2 = mesh.getFacetType(type2);
const ElementType type_subfacet = mesh.getFacetType(type_facet1);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel3_1 = mesh_facets.getElementToSubelement(type_facet1);
- const Array< std::vector<Element> > & el_to_subel3_2 = mesh_facets.getElementToSubelement(type_facet2);
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
+ const Array<std::vector<Element>> & el_to_subel3_1 =
+ mesh_facets.getElementToSubelement(type_facet1);
+ const Array<std::vector<Element>> & el_to_subel3_2 =
+ mesh_facets.getElementToSubelement(type_facet2);
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_subfacet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3_1.size(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3_1(i)[j].type << " " << el_to_subel3_1(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3_1(i)[j].type << " "
+ << el_to_subel3_1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < el_to_subel3_2.size(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3_2(i)[j].type << " " << el_to_subel3_2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3_2(i)[j].type << " "
+ << el_to_subel3_2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel2(i).size(); ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el3_1 = mesh_facets.getSubelementToElement(type1);
- const Array<Element> & subel_to_el3_2 = mesh_facets.getSubelementToElement(type2);
- const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type_facet1);
- const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type_facet2);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
+ const Array<Element> & subel_to_el3_1 =
+ mesh_facets.getSubelementToElement(type1);
+ const Array<Element> & subel_to_el3_2 =
+ mesh_facets.getSubelementToElement(type2);
+ const Array<Element> & subel_to_el2_1 =
+ mesh_facets.getSubelementToElement(type_facet1);
+ const Array<Element> & subel_to_el2_2 =
+ mesh_facets.getSubelementToElement(type_facet2);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3_1.size(); ++i) {
std::cout << type1 << " " << i << " connected to ";
- for (UInt j = 0; j < 6; ++j){
- std::cout << subel_to_el3_1(i, j).type << " " << subel_to_el3_1(i, j).element << ", ";
+ for (UInt j = 0; j < 6; ++j) {
+ std::cout << subel_to_el3_1(i, j).type << " "
+ << subel_to_el3_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el3_2.size(); ++i) {
std::cout << type2 << " " << i << " connected to ";
- for (UInt j = 0; j < 5; ++j){
- std::cout << subel_to_el3_2(i, j).type << " " << subel_to_el3_2(i, j).element << ", ";
+ for (UInt j = 0; j < 5; ++j) {
+ std::cout << subel_to_el3_2(i, j).type << " "
+ << subel_to_el3_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.size(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2_1(i, j).type << " "
+ << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el2_2.size(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
- for (UInt j = 0; j < 3; ++j){
- std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
+ for (UInt j = 0; j < 3; ++j) {
+ std::cout << subel_to_el2_2(i, j).type << " "
+ << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
index da7cecee2..b8ef759b1 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
@@ -1,167 +1,182 @@
/**
* @file test_buildfacets_mixed3d_quadratic.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with hexahedrons
* and pentahedrons
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type1 = _hexahedron_20;
const ElementType type2 = _pentahedron_15;
Mesh mesh(spatial_dimension);
mesh.read("mixed3d_quadratic.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet1 = mesh.getFacetType(type1);
const ElementType type_facet2 = mesh.getFacetType(type2);
const ElementType type_subfacet = mesh.getFacetType(type_facet1);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel3_1 = mesh_facets.getElementToSubelement(type_facet1);
- const Array< std::vector<Element> > & el_to_subel3_2 = mesh_facets.getElementToSubelement(type_facet2);
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
+ const Array<std::vector<Element>> & el_to_subel3_1 =
+ mesh_facets.getElementToSubelement(type_facet1);
+ const Array<std::vector<Element>> & el_to_subel3_2 =
+ mesh_facets.getElementToSubelement(type_facet2);
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_subfacet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3_1.size(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3_1(i)[j].type << " " << el_to_subel3_1(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3_1(i)[j].type << " "
+ << el_to_subel3_1(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < el_to_subel3_2.size(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3_2(i)[j].type << " " << el_to_subel3_2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3_2(i)[j].type << " "
+ << el_to_subel3_2(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel2(i).size(); ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el3_1 = mesh_facets.getSubelementToElement(type1);
- const Array<Element> & subel_to_el3_2 = mesh_facets.getSubelementToElement(type2);
- const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type_facet1);
- const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type_facet2);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
+ const Array<Element> & subel_to_el3_1 =
+ mesh_facets.getSubelementToElement(type1);
+ const Array<Element> & subel_to_el3_2 =
+ mesh_facets.getSubelementToElement(type2);
+ const Array<Element> & subel_to_el2_1 =
+ mesh_facets.getSubelementToElement(type_facet1);
+ const Array<Element> & subel_to_el2_2 =
+ mesh_facets.getSubelementToElement(type_facet2);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3_1.size(); ++i) {
std::cout << type1 << " " << i << " connected to ";
- for (UInt j = 0; j < 6; ++j){
- std::cout << subel_to_el3_1(i, j).type << " " << subel_to_el3_1(i, j).element << ", ";
+ for (UInt j = 0; j < 6; ++j) {
+ std::cout << subel_to_el3_1(i, j).type << " "
+ << subel_to_el3_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
for (UInt i = 0; i < subel_to_el3_2.size(); ++i) {
std::cout << type2 << " " << i << " connected to ";
- for (UInt j = 0; j < 5; ++j){
- std::cout << subel_to_el3_2(i, j).type << " " << subel_to_el3_2(i, j).element << ", ";
+ for (UInt j = 0; j < 5; ++j) {
+ std::cout << subel_to_el3_2(i, j).type << " "
+ << subel_to_el3_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_1.size(); ++i) {
std::cout << type_facet1 << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2_1(i, j).type << " "
+ << subel_to_el2_1(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
-
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2_2.size(); ++i) {
std::cout << type_facet2 << " " << i << " connected to ";
- for (UInt j = 0; j < 3; ++j){
- std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
+ for (UInt j = 0; j < 3; ++j) {
+ std::cout << subel_to_el2_2(i, j).type << " "
+ << subel_to_el2_2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
index b71d11010..b8ea2cfab 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
@@ -1,146 +1,154 @@
/**
* @file test_buildfacets_pentahedron_15.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Mon Sep 28 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _pentahedron_15;
Mesh mesh(spatial_dimension);
mesh.read("pentahedron_15.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
Vector<const ElementType> types_facet(mesh.getAllFacetTypes(type));
const ElementType type_subfacet = mesh.getFacetType(types_facet(0));
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
- Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
+ Array<std::vector<Element>> & el_to_subel3 =
+ mesh_facets.getElementToSubelement(type_facet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3(i)[j].type << " "
+ << el_to_subel3(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
}
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_subfacet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel2(i).size(); ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el3 =
+ mesh_facets.getSubelementToElement(type);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j){
- std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
+ for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j) {
+ std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
- Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
+ Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j) {
+ std::cout << subel_to_el2(i, j).type << " "
+ << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
}
-
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_subfacet);
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
index 4a1ab09ed..7354ce7ef 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
@@ -1,146 +1,154 @@
/**
* @file test_buildfacets_pentahedron_6.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Mon Sep 28 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _pentahedron_6;
Mesh mesh(spatial_dimension);
mesh.read("pentahedron_6.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
Vector<const ElementType> types_facet(mesh.getAllFacetTypes(type));
const ElementType type_subfacet = mesh.getFacetType(types_facet(0));
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
- Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
+ Array<std::vector<Element>> & el_to_subel3 =
+ mesh_facets.getElementToSubelement(type_facet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3(i)[j].type << " "
+ << el_to_subel3(i)[j].element << ", ";
}
std::cout << " " << std::endl;
}
}
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_subfacet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel2(i).size(); ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el3 =
+ mesh_facets.getSubelementToElement(type);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j){
- std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
+ for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j) {
+ std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
for (UInt ft = 0; ft < types_facet.size(); ++ft) {
ElementType type_facet = types_facet(ft);
- Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
+ Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j) {
+ std::cout << subel_to_el2(i, j).type << " "
+ << subel_to_el2(i, j).element << ", ";
}
std::cout << " " << std::endl;
}
}
-
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_subfacet);
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
index 9f49a22f7..ed9a9969b 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
@@ -1,114 +1,119 @@
/**
* @file test_buildfacets_quadrangle_4.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Fri Sep 18 2015
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with quadrangles
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _quadrangle_4;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle_4.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
-
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
+ const Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
index a9f1fbe3a..fdc752105 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
@@ -1,114 +1,119 @@
/**
* @file test_buildfacets_quadrangle_8.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Fri Sep 18 2015
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with quadrangles
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _quadrangle_8;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle_8.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
-
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
+ const Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
index 3fb20448e..f1db9c091 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
@@ -1,141 +1,149 @@
/**
* @file test_buildfacets_tetrahedron_10.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Sat Sep 19 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 3;
const ElementType type = _tetrahedron_10;
Mesh mesh(spatial_dimension);
mesh.read("tetrahedron_10.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// std::cout << mesh_facets << std::endl;
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
-
+ const Array<std::vector<Element>> & el_to_subel3 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_subfacet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subsubfacet);
std::cout << "ElementToSubelement3" << std::endl;
for (UInt i = 0; i < el_to_subel3.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel2(i).size(); ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subsubfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
- const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
-
+ const Array<Element> & subel_to_el3 =
+ mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type_facet);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_subfacet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement3" << std::endl;
for (UInt i = 0; i < subel_to_el3.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < 4; ++j){
- std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
+ for (UInt j = 0; j < 4; ++j) {
+ std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 3; ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < 3; ++j) {
+ std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
index f072da165..c98c8d698 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
@@ -1,113 +1,118 @@
/**
* @file test_buildfacets_triangle_3.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Fri Sep 18 2015
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with triangles
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _triangle_3;
Mesh mesh(spatial_dimension);
mesh.read("triangle_3.msh");
const auto & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
-
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
+ const Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < 3; ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < 3; ++j) {
+ std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
index a2bd35184..d300a7cd5 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
@@ -1,114 +1,119 @@
/**
* @file test_buildfacets_triangle_6.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Fri Sep 18 2015
* @date last modification: Sat Sep 19 2015
*
* @brief Test to check the building of the facets. Mesh with triangles
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include <fstream>
#include <iostream>
#include <limits>
-#include <fstream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const ElementType type = _triangle_6;
Mesh mesh(spatial_dimension);
mesh.read("triangle_6.msh");
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
const ElementType type_facet = mesh.getFacetType(type);
const ElementType type_subfacet = mesh.getFacetType(type_facet);
/* ------------------------------------------------------------------------ */
/* Element to Subelement testing */
/* ------------------------------------------------------------------------ */
- const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
- const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
-
+ const Array<std::vector<Element>> & el_to_subel2 =
+ mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & el_to_subel1 =
+ mesh_facets.getElementToSubelement(type_subfacet);
std::cout << "ElementToSubelement2" << std::endl;
for (UInt i = 0; i < el_to_subel2.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "ElementToSubelement1" << std::endl;
for (UInt i = 0; i < el_to_subel1.size(); ++i) {
std::cout << type_subfacet << " " << i << " connected to ";
- for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
- std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
+ for (UInt j = 0; j < el_to_subel1(i).size(); ++j) {
+ std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
/* ------------------------------------------------------------------------ */
/* Subelement to Element testing */
/* ------------------------------------------------------------------------ */
- const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
- const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
+ const Array<Element> & subel_to_el2 =
+ mesh_facets.getSubelementToElement(type);
+ const Array<Element> & subel_to_el1 =
+ mesh_facets.getSubelementToElement(type_facet);
std::cout << " " << std::endl;
std::cout << "SubelementToElement2" << std::endl;
for (UInt i = 0; i < subel_to_el2.size(); ++i) {
std::cout << type << " " << i << " connected to ";
- for (UInt j = 0; j < 3; ++j){
- std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
+ for (UInt j = 0; j < 3; ++j) {
+ std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
std::cout << "SubelementToElement1" << std::endl;
for (UInt i = 0; i < subel_to_el1.size(); ++i) {
std::cout << type_facet << " " << i << " connected to ";
- for (UInt j = 0; j < 2; ++j){
- std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
+ for (UInt j = 0; j < 2; ++j) {
+ std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element
+ << ", ";
}
std::cout << " " << std::endl;
}
-
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc
index 2313f57b8..8b0714510 100644
--- a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc
+++ b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh.cc
@@ -1,54 +1,54 @@
/**
* @file test_mesh_io_msh.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Sun Oct 19 2014
*
* @brief unit test for the MeshIOMSH class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
akantu::MeshIOMSH mesh_io;
akantu::Mesh mesh(3);
mesh_io.read("./cube.msh", mesh);
std::cout << mesh << std::endl;
mesh_io.write("./cube.out", mesh);
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc
index 8139c5d02..ce89b0d3a 100644
--- a/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc
+++ b/test/test_mesh_utils/test_mesh_io/test_mesh_io_msh_physical_names.cc
@@ -1,58 +1,61 @@
/**
* @file test_mesh_io_msh_physical_names.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Fri May 03 2013
* @date last modification: Sun Oct 19 2014
*
* @brief unit test for the MeshIOMSH physical names class
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
-#include <iostream>
-#include <sstream>
#include "aka_common.hh"
#include "mesh.hh"
+#include <iostream>
+#include <sstream>
using namespace akantu;
/* -------------------------------------------------------------------------- */
-int main(int argc, char* argv[]) {
+int main(int argc, char * argv[]) {
UInt spatialDimension(3);
akantu::initialize(argc, argv);
Mesh mesh(spatialDimension);
mesh.read("./cube_physical_names.msh");
std::stringstream sstr;
- for(Mesh::type_iterator type_it = mesh.firstType(); type_it != mesh.lastType(); ++type_it) {
- const Array<std::string> & name_vec = mesh.getData<std::string>("physical_names", *type_it);
- for(UInt i(0); i < name_vec.size(); i++) {
- std::cout << "Element " << i << " (of type " << *type_it << ") has physical name " << name_vec(i) << "." << std::endl;
+ for (Mesh::type_iterator type_it = mesh.firstType();
+ type_it != mesh.lastType(); ++type_it) {
+ const Array<std::string> & name_vec =
+ mesh.getData<std::string>("physical_names", *type_it);
+ for (UInt i(0); i < name_vec.size(); i++) {
+ std::cout << "Element " << i << " (of type " << *type_it
+ << ") has physical name " << name_vec(i) << "." << std::endl;
}
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_iterators.cc b/test/test_mesh_utils/test_mesh_iterators.cc
index ada69c2c0..a3f19ec09 100644
--- a/test/test_mesh_utils/test_mesh_iterators.cc
+++ b/test/test_mesh_utils/test_mesh_iterators.cc
@@ -1,67 +1,68 @@
/**
* @file test_mesh_iterators.cc
*
* @author Nicolas Richart
*
* @date creation Wed Aug 09 2017
*
* @brief Test the mesh iterators
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_iterators.hh"
#include "element_group.hh"
#include "mesh.hh"
#include "mesh_iterators.hh"
#include "node_group.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
initialize(argc, argv);
Mesh mesh(3);
const Mesh & cmesh = mesh;
mesh.read("iterators_mesh.msh");
for (auto && element_group : ElementGroupsIterable(mesh)) {
std::cout << element_group.getName() << std::endl;
}
for (auto && node_group : NodeGroupsIterable(cmesh)) {
std::cout << node_group.getName() << std::endl;
}
for (auto && element_group : enumerate(ElementGroupsIterable(mesh))) {
- std::cout << std::get<0>(element_group) << " " << std::get<1>(element_group).getName() << std::endl;
-
+ std::cout << std::get<0>(element_group) << " "
+ << std::get<1>(element_group).getName() << std::endl;
}
// for (auto && node_group :
// counting(NodeGroupsIterable(cmesh))) {
- // std::cout << std::get<0>(node_group) << " " << std::get<1>(node_group).getName() << std::endl;
+ // std::cout << std::get<0>(node_group) << " " <<
+ // std::get<1>(node_group).getName() << std::endl;
// }
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc b/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc
index 66849f40d..05f8c9748 100644
--- a/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc
+++ b/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc
@@ -1,120 +1,120 @@
/**
* @file test_mesh_partitionate_mesh_data.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Wed May 08 2013
* @date last modification: Mon May 18 2015
*
* @brief test of manual partitioner
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cmath>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_partition_mesh_data.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
-#include "dumper_paraview.hh"
#include "dumper_elemental_field.hh"
+#include "dumper_paraview.hh"
#endif // AKANTU_USE_IOHELPER
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize(argc, argv);
UInt dim = 2;
UInt nb_partitions = 8;
akantu::Mesh mesh(dim);
mesh.read("quad.msh");
ElementTypeMapArray<UInt> partition;
UInt nb_component = 1;
GhostType gt = _not_ghost;
Mesh::type_iterator tit = mesh.firstType(dim, gt);
Mesh::type_iterator tend = mesh.lastType(dim, gt);
for (; tit != tend; ++tit) {
UInt nb_element = mesh.getNbElement(*tit, gt);
partition.alloc(nb_element, nb_component, *tit, gt);
Array<UInt> & type_partition_reference = partition(*tit, gt);
for (UInt i(0); i < nb_element; ++i) {
Vector<Real> barycenter(dim);
Element element{*tit, i, gt};
mesh.getBarycenter(element, barycenter);
Real real_proc = barycenter[0] * nb_partitions;
if (std::abs(real_proc - round(real_proc)) <
10 * std::numeric_limits<Real>::epsilon()) {
type_partition_reference(i) = round(real_proc);
} else {
std::cout << "*";
type_partition_reference(i) = floor(real_proc);
}
std::cout << "Assigned proc " << type_partition_reference(i)
<< " to elem " << i << " (type " << *tit
<< ", barycenter x-coordinate " << barycenter[0] << ")"
<< std::endl;
}
}
akantu::MeshPartitionMeshData * partitioner =
new akantu::MeshPartitionMeshData(mesh, dim);
partitioner->setPartitionMapping(partition);
partitioner->partitionate(nb_partitions);
tit = mesh.firstType(dim, gt);
for (; tit != tend; ++tit) {
UInt nb_element = mesh.getNbElement(*tit, gt);
const Array<UInt> & type_partition_reference = partition(*tit, gt);
const Array<UInt> & type_partition = partitioner->getPartitions()(*tit, gt);
for (UInt i(0); i < nb_element; ++i) {
AKANTU_DEBUG_ASSERT(type_partition(i) == type_partition_reference(i),
"Incorrect partitioning");
}
}
//#define DEBUG_TEST
#ifdef DEBUG_TEST
DumperParaview dumper("test-mesh-data-partition");
dumper::Field * field1 =
new dumper::ElementalField<UInt>(partitioner->getPartitions(), dim);
dumper::Field * field2 = new dumper::ElementalField<UInt>(partition, dim);
dumper.registerMesh(mesh, dim);
dumper.registerField("partitions", field1);
dumper.registerField("partitions_ref", field2);
dumper.dump();
#endif
delete partitioner;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc b/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc
index 995f59257..f873532b7 100644
--- a/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc
+++ b/test/test_mesh_utils/test_pbc_tweak/test_pbc_tweak.cc
@@ -1,69 +1,71 @@
/**
* @file test_pbc_tweak.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Fri Aug 20 2010
* @date last modification: Sun Oct 19 2014
*
* @brief test of internal facet extraction
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[])
-{
+int main(int argc, char * argv[]) {
int dim = 3;
initialize("material.dat", argc, argv);
debug::setDebugLevel(akantu::dblInfo);
Mesh mesh(dim);
mesh.read("cube.msh");
SolidMechanicsModel model(mesh);
- /* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
model.initFull();
- /* -------------------------------------------------------------------------- */
- //model.setPBC(1,1,1);
- //model.initPBC();
+ /* --------------------------------------------------------------------------
+ */
+ // model.setPBC(1,1,1);
+ // model.initPBC();
model.assembleMassLumped();
- /* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
model.setBaseName("test-pbc-tweak");
model.addDumpField("mass");
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_mesh_utils/test_purify_mesh.cc b/test/test_mesh_utils/test_purify_mesh.cc
index cbd019919..10c5f70e1 100644
--- a/test/test_mesh_utils/test_purify_mesh.cc
+++ b/test/test_mesh_utils/test_purify_mesh.cc
@@ -1,62 +1,62 @@
/**
* @file test_purify_mesh.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Sun Oct 19 2014
*
* @brief Test the purifyMesh function from MeshUtils
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh.hh"
-#include "mesh_utils.hh"
#include "mesh_io.hh"
+#include "mesh_utils.hh"
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
-
+
Mesh mesh(2);
mesh.read("purify_mesh.msh");
-
+
MeshUtils::purifyMesh(mesh);
mesh.write("purify_mesh_after.msh");
- if(mesh.getNbNodes() != 21)
- AKANTU_ERROR("The purified mesh does not contain the good number of nodes.");
+ if (mesh.getNbNodes() != 21)
+ AKANTU_ERROR(
+ "The purified mesh does not contain the good number of nodes.");
- if(mesh.getNbElement(_quadrangle_8) != 4)
- AKANTU_ERROR("The purified mesh does not contain the good number of element.");
+ if (mesh.getNbElement(_quadrangle_8) != 4)
+ AKANTU_ERROR(
+ "The purified mesh does not contain the good number of element.");
-
akantu::finalize();
-
+
return EXIT_SUCCESS;
}
-
diff --git a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
index b9f1dea71..56e97dcb9 100644
--- a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
@@ -1,97 +1,96 @@
/**
* @file test_segment_nodetype.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Sep 18 2015
*
* @brief Test to verify that the node type is correctly associated to
* the segments in parallel
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "element_synchronizer.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
initialize(argc, argv);
UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
// partition the mesh
if (prank == 0) {
mesh.read("mesh.msh");
}
mesh.distribute();
// compute the node types for each segment
Mesh & mesh_facets = mesh.initMeshFacets();
MeshUtils::buildSegmentToNodeType(mesh, mesh_facets);
// verify that the number of segments per node type makes sense
std::map<Int, UInt> nb_facets_per_nodetype;
UInt nb_segments = 0;
for (auto ghost_type : ghost_types) {
const Array<Int> & segment_to_nodetype =
mesh_facets.getData<Int>("segment_to_nodetype", _segment_2, ghost_type);
// count the number of segments per node type
for (auto & stn : segment_to_nodetype) {
if (nb_facets_per_nodetype.find(stn) == nb_facets_per_nodetype.end())
nb_facets_per_nodetype[stn] = 1;
else
++nb_facets_per_nodetype[stn];
}
nb_segments += segment_to_nodetype.size();
}
// checking the solution
if (nb_segments != 24)
AKANTU_ERROR("The number of segments is wrong");
if (prank == 0) {
if (nb_facets_per_nodetype[-1] != 3 || nb_facets_per_nodetype[-2] != 9 ||
nb_facets_per_nodetype[-3] != 12)
- AKANTU_ERROR(
- "The segments of processor 0 have the wrong node type");
+ AKANTU_ERROR("The segments of processor 0 have the wrong node type");
if (nb_facets_per_nodetype.size() > 3)
AKANTU_ERROR("Processor 0 cannot have any slave segment");
}
if (prank == psize - 1 &&
nb_facets_per_nodetype.find(-2) != nb_facets_per_nodetype.end())
AKANTU_ERROR("The last processor must not have any master facets");
finalize();
return 0;
}
diff --git a/test/test_model/patch_tests/patch_test_linear_anisotropic_explicit.cc b/test/test_model/patch_tests/patch_test_linear_anisotropic_explicit.cc
index f34a42414..c15435979 100644
--- a/test/test_model/patch_tests/patch_test_linear_anisotropic_explicit.cc
+++ b/test/test_model/patch_tests/patch_test_linear_anisotropic_explicit.cc
@@ -1,114 +1,114 @@
/**
* @file patch_test_explicit_anisotropic.cc
*
* @author Till Junge <till.junge@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Cyprien Wolff <cyprien.wolff@epfl.ch>
*
* @date creation: Sat Apr 16 2011
* @date last modification: Thu Oct 15 2015
*
* @brief patch test for elastic material in solid mechanics model
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "patch_test_linear_solid_mechanics_fixture.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
// Stiffness tensor, rotated by hand
-Real C[3][3][3]
- [3] = {{{{112.93753505, 1.85842452538e-10, -4.47654358027e-10},
- {1.85847317471e-10, 54.2334345331, -3.69840984824},
- {-4.4764768395e-10, -3.69840984824, 56.848605217}},
- {{1.85847781609e-10, 25.429294233, -3.69840984816},
- {25.429294233, 3.31613847493e-10, -8.38797920011e-11},
- {-3.69840984816, -8.38804581349e-11, -1.97875715813e-10}},
- {{-4.47654358027e-10, -3.69840984816, 28.044464917},
- {-3.69840984816, 2.09374961813e-10, 9.4857455224e-12},
- {28.044464917, 9.48308098714e-12, -2.1367885239e-10}}},
- {{{1.85847781609e-10, 25.429294233, -3.69840984816},
- {25.429294233, 3.31613847493e-10, -8.38793479119e-11},
- {-3.69840984816, -8.38795699565e-11, -1.97876381947e-10}},
- {{54.2334345331, 3.31617400207e-10, 2.09372075233e-10},
- {3.3161562385e-10, 115.552705733, -3.15093728886e-10},
- {2.09372075233e-10, -3.15090176173e-10, 54.2334345333}},
- {{-3.69840984824, -8.38795699565e-11, 9.48219280872e-12},
- {-8.38795699565e-11, -3.1509195253e-10, 25.4292942335},
- {9.48441325477e-12, 25.4292942335, 3.69840984851}}},
- {{{-4.47653469848e-10, -3.69840984816, 28.044464917},
- {-3.69840984816, 2.09374073634e-10, 9.48752187924e-12},
- {28.044464917, 9.48552347779e-12, -2.1367885239e-10}},
- {{-3.69840984824, -8.3884899027e-11, 9.48219280872e-12},
- {-8.3884899027e-11, -3.150972816e-10, 25.4292942335},
- {9.48041645188e-12, 25.4292942335, 3.69840984851}},
- {{56.848605217, -1.97875493768e-10, -2.13681516925e-10},
- {-1.97877270125e-10, 54.2334345333, 3.69840984851},
- {-2.13683293282e-10, 3.69840984851, 112.93753505}}}};
+Real C[3][3][3][3] = {
+ {{{112.93753505, 1.85842452538e-10, -4.47654358027e-10},
+ {1.85847317471e-10, 54.2334345331, -3.69840984824},
+ {-4.4764768395e-10, -3.69840984824, 56.848605217}},
+ {{1.85847781609e-10, 25.429294233, -3.69840984816},
+ {25.429294233, 3.31613847493e-10, -8.38797920011e-11},
+ {-3.69840984816, -8.38804581349e-11, -1.97875715813e-10}},
+ {{-4.47654358027e-10, -3.69840984816, 28.044464917},
+ {-3.69840984816, 2.09374961813e-10, 9.4857455224e-12},
+ {28.044464917, 9.48308098714e-12, -2.1367885239e-10}}},
+ {{{1.85847781609e-10, 25.429294233, -3.69840984816},
+ {25.429294233, 3.31613847493e-10, -8.38793479119e-11},
+ {-3.69840984816, -8.38795699565e-11, -1.97876381947e-10}},
+ {{54.2334345331, 3.31617400207e-10, 2.09372075233e-10},
+ {3.3161562385e-10, 115.552705733, -3.15093728886e-10},
+ {2.09372075233e-10, -3.15090176173e-10, 54.2334345333}},
+ {{-3.69840984824, -8.38795699565e-11, 9.48219280872e-12},
+ {-8.38795699565e-11, -3.1509195253e-10, 25.4292942335},
+ {9.48441325477e-12, 25.4292942335, 3.69840984851}}},
+ {{{-4.47653469848e-10, -3.69840984816, 28.044464917},
+ {-3.69840984816, 2.09374073634e-10, 9.48752187924e-12},
+ {28.044464917, 9.48552347779e-12, -2.1367885239e-10}},
+ {{-3.69840984824, -8.3884899027e-11, 9.48219280872e-12},
+ {-8.3884899027e-11, -3.150972816e-10, 25.4292942335},
+ {9.48041645188e-12, 25.4292942335, 3.69840984851}},
+ {{56.848605217, -1.97875493768e-10, -2.13681516925e-10},
+ {-1.97877270125e-10, 54.2334345333, 3.69840984851},
+ {-2.13683293282e-10, 3.69840984851, 112.93753505}}}};
/* -------------------------------------------------------------------------- */
TYPED_TEST(TestPatchTestSMMLinear, AnisotropicExplicit) {
this->initModel(_explicit_lumped_mass, "material_anisotropic.dat");
const auto & coordinates = this->mesh->getNodes();
auto & displacement = this->model->getDisplacement();
// set the position of all nodes to the static solution
for (auto && tuple : zip(make_view(coordinates, this->dim),
make_view(displacement, this->dim))) {
this->setLinearDOF(std::get<1>(tuple), std::get<0>(tuple));
}
for (UInt s = 0; s < 100; ++s) {
this->model->solveStep();
}
auto ekin = this->model->getEnergy("kinetic");
EXPECT_NEAR(0, ekin, 1e-16);
auto & mat = this->model->getMaterial(0);
-
+
this->checkDOFs(displacement);
this->checkGradient(mat.getGradU(this->type), displacement);
+ this->checkResults(
+ [&](const Matrix<Real> & pstrain) {
+ auto strain = (pstrain + pstrain.transpose()) / 2.;
+ decltype(strain) stress(this->dim, this->dim);
- this->checkResults([&](const Matrix<Real> & pstrain) {
- auto strain = (pstrain + pstrain.transpose()) / 2.;
- decltype(strain) stress(this->dim, this->dim);
-
- for (UInt i = 0; i < this->dim; ++i) {
- for (UInt j = 0; j < this->dim; ++j) {
- stress(i, j) = 0;
- for (UInt k = 0; k < this->dim; ++k) {
- for (UInt l = 0; l < this->dim; ++l) {
- stress(i, j) += C[i][j][k][l] * strain(k, l);
+ for (UInt i = 0; i < this->dim; ++i) {
+ for (UInt j = 0; j < this->dim; ++j) {
+ stress(i, j) = 0;
+ for (UInt k = 0; k < this->dim; ++k) {
+ for (UInt l = 0; l < this->dim; ++l) {
+ stress(i, j) += C[i][j][k][l] * strain(k, l);
+ }
+ }
}
}
- }
- }
- return stress;
- },
- mat.getStress(this->type), displacement);
+ return stress;
+ },
+ mat.getStress(this->type), displacement);
}
diff --git a/test/test_model/patch_tests/patch_test_linear_fixture.hh b/test/test_model/patch_tests/patch_test_linear_fixture.hh
index 75c69d91e..ef025387e 100644
--- a/test/test_model/patch_tests/patch_test_linear_fixture.hh
+++ b/test/test_model/patch_tests/patch_test_linear_fixture.hh
@@ -1,150 +1,150 @@
/* -------------------------------------------------------------------------- */
-#include "mesh_utils.hh"
#include "element_group.hh"
+#include "mesh_utils.hh"
#include "model.hh"
#include "test_gtest_utils.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#include <vector>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PATCH_TEST_LINEAR_FIXTURE_HH__
#define __AKANTU_PATCH_TEST_LINEAR_FIXTURE_HH__
//#define DEBUG_TEST
using namespace akantu;
template <typename type_, typename M>
class TestPatchTestLinear : public ::testing::Test {
public:
static constexpr ElementType type = type_::value;
static constexpr size_t dim = ElementClass<type>::getSpatialDimension();
virtual void SetUp() {
mesh = std::make_unique<Mesh>(dim);
mesh->read(aka::to_string(type) + ".msh");
MeshUtils::buildFacets(*mesh);
mesh->createBoundaryGroupFromGeometry();
model = std::make_unique<M>(*mesh);
}
virtual void TearDown() {
model.reset(nullptr);
mesh.reset(nullptr);
}
virtual void initModel(const AnalysisMethod & method,
const std::string & material_file) {
debug::setDebugLevel(dblError);
getStaticParser().parse(material_file);
this->model->initFull(_analysis_method = method);
this->applyBC();
}
virtual void applyBC() {
auto & boundary = this->model->getBlockedDOFs();
for (auto & eg : mesh->getElementGroups()) {
for (const auto & node : eg.second->getNodeGroup()) {
for (UInt s = 0; s < boundary.getNbComponent(); ++s) {
boundary(node, s) = true;
}
}
}
}
virtual void applyBConDOFs(const Array<Real> & dofs) {
const auto & coordinates = this->mesh->getNodes();
for (auto & eg : this->mesh->getElementGroups()) {
for (const auto & node : eg.second->getNodeGroup()) {
this->setLinearDOF(dofs.begin(dofs.getNbComponent())[node],
coordinates.begin(this->dim)[node]);
}
}
}
template <typename V> Matrix<Real> prescribed_gradient(const V & dof) {
Matrix<Real> gradient(dof.getNbComponent(), dim);
for (UInt i = 0; i < gradient.rows(); ++i) {
for (UInt j = 0; j < gradient.cols(); ++j) {
gradient(i, j) = alpha(i, j + 1);
}
}
return gradient;
}
template <typename Gradient, typename DOFs>
void checkGradient(const Gradient & gradient, const DOFs & dofs) {
auto pgrad = prescribed_gradient(dofs);
for (auto & grad :
make_view(gradient, gradient.getNbComponent() / dim, dim)) {
auto diff = grad - pgrad;
auto gradient_error =
diff.template norm<L_inf>() / grad.template norm<L_inf>();
EXPECT_NEAR(0, gradient_error, gradient_tolerance);
}
}
template <typename presult_func_t, typename Result, typename DOFs>
void checkResults(presult_func_t && presult_func, const Result & results,
const DOFs & dofs) {
auto presult = presult_func(prescribed_gradient(dofs));
for (auto & result :
make_view(results, results.getNbComponent() / dim, dim)) {
auto diff = result - presult;
auto result_error =
diff.template norm<L_inf>() / result.template norm<L_inf>();
EXPECT_NEAR(0, result_error, result_tolerance);
}
}
template <typename V1, typename V2>
void setLinearDOF(V1 && dof, V2 && coord) {
for (UInt i = 0; i < dof.size(); ++i) {
dof(i) = this->alpha(i, 0);
for (UInt j = 0; j < coord.size(); ++j) {
dof(i) += this->alpha(i, j + 1) * coord(j);
}
}
}
template <typename V> void checkDOFs(V && dofs) {
const auto & coordinates = mesh->getNodes();
Vector<Real> ref_dof(dofs.getNbComponent());
for (auto && tuple : zip(make_view(coordinates, dim),
make_view(dofs, dofs.getNbComponent()))) {
setLinearDOF(ref_dof, std::get<0>(tuple));
auto diff = std::get<1>(tuple) - ref_dof;
auto dofs_error = diff.template norm<L_inf>();
EXPECT_NEAR(0, dofs_error, dofs_tolerance);
}
}
protected:
std::unique_ptr<Mesh> mesh;
std::unique_ptr<M> model;
Matrix<Real> alpha{{0.01, 0.02, 0.03, 0.04},
{0.05, 0.06, 0.07, 0.08},
{0.09, 0.10, 0.11, 0.12}};
Real gradient_tolerance{1e-14};
Real result_tolerance{1e-14};
Real dofs_tolerance{1e-15};
};
template <typename type_, typename M>
constexpr ElementType TestPatchTestLinear<type_, M>::type;
template <typename tuple_, typename M>
constexpr size_t TestPatchTestLinear<tuple_, M>::dim;
#endif /* __AKANTU_PATCH_TEST_LINEAR_FIXTURE_HH__ */
diff --git a/test/test_model/patch_tests/patch_test_linear_heat_transfer_explicit.cc b/test/test_model/patch_tests/patch_test_linear_heat_transfer_explicit.cc
index 74dc71042..2d2e84457 100644
--- a/test/test_model/patch_tests/patch_test_linear_heat_transfer_explicit.cc
+++ b/test/test_model/patch_tests/patch_test_linear_heat_transfer_explicit.cc
@@ -1,21 +1,21 @@
/* -------------------------------------------------------------------------- */
#include "patch_test_linear_heat_transfer_fixture.hh"
/* -------------------------------------------------------------------------- */
TYPED_TEST(TestPatchTestHTMLinear, Explicit) {
this->initModel(_explicit_lumped_mass, "heat_transfer_input.dat");
const auto & coordinates = this->mesh->getNodes();
auto & temperature = this->model->getTemperature();
// set the position of all nodes to the static solution
- for (auto && tuple : zip(make_view(coordinates, this->dim),
- make_view(temperature, 1))) {
+ for (auto && tuple :
+ zip(make_view(coordinates, this->dim), make_view(temperature, 1))) {
this->setLinearDOF(std::get<1>(tuple), std::get<0>(tuple));
}
for (UInt s = 0; s < 100; ++s) {
this->model->solveStep();
}
this->checkAll();
}
diff --git a/test/test_model/patch_tests/patch_test_linear_heat_transfer_fixture.hh b/test/test_model/patch_tests/patch_test_linear_heat_transfer_fixture.hh
index a67648342..53ce8ebec 100644
--- a/test/test_model/patch_tests/patch_test_linear_heat_transfer_fixture.hh
+++ b/test/test_model/patch_tests/patch_test_linear_heat_transfer_fixture.hh
@@ -1,38 +1,39 @@
/* -------------------------------------------------------------------------- */
#include "heat_transfer_model.hh"
/* -------------------------------------------------------------------------- */
#include "patch_test_linear_fixture.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PATCH_TEST_LINEAR_HEAT_TRANSFER_FIXTURE_HH__
#define __AKANTU_PATCH_TEST_LINEAR_HEAT_TRANSFER_FIXTURE_HH__
/* -------------------------------------------------------------------------- */
template <typename type>
class TestPatchTestHTMLinear
: public TestPatchTestLinear<type, HeatTransferModel> {
using parent = TestPatchTestLinear<type, HeatTransferModel>;
public:
void applyBC() override {
parent::applyBC();
auto & temperature = this->model->getTemperature();
this->applyBConDOFs(temperature);
}
void checkAll() {
auto & temperature = this->model->getTemperature();
Matrix<Real> C = this->model->get("conductivity");
this->checkDOFs(temperature);
this->checkGradient(this->model->getTemperatureGradient(this->type),
temperature);
- this->checkResults([&](const Matrix<Real> & grad_T) { return C * grad_T.transpose(); },
- this->model->getKgradT(this->type), temperature);
+ this->checkResults(
+ [&](const Matrix<Real> & grad_T) { return C * grad_T.transpose(); },
+ this->model->getKgradT(this->type), temperature);
}
};
using types = gtest_list_t<TestElementTypes>;
TYPED_TEST_CASE(TestPatchTestHTMLinear, types);
#endif /* __AKANTU_PATCH_TEST_LINEAR_HEAT_TRANSFER_FIXTURE_HH__ */
diff --git a/test/test_model/patch_tests/patch_test_linear_heat_transfer_implicit.cc b/test/test_model/patch_tests/patch_test_linear_heat_transfer_implicit.cc
index c14e0207b..a587da7dc 100644
--- a/test/test_model/patch_tests/patch_test_linear_heat_transfer_implicit.cc
+++ b/test/test_model/patch_tests/patch_test_linear_heat_transfer_implicit.cc
@@ -1,21 +1,21 @@
/* -------------------------------------------------------------------------- */
#include "patch_test_linear_heat_transfer_fixture.hh"
/* -------------------------------------------------------------------------- */
TYPED_TEST(TestPatchTestHTMLinear, Implicit) {
this->initModel(_implicit_dynamic, "heat_transfer_input.dat");
const auto & coordinates = this->mesh->getNodes();
auto & temperature = this->model->getTemperature();
// set the position of all nodes to the static solution
- for (auto && tuple : zip(make_view(coordinates, this->dim),
- make_view(temperature, 1))) {
+ for (auto && tuple :
+ zip(make_view(coordinates, this->dim), make_view(temperature, 1))) {
this->setLinearDOF(std::get<1>(tuple), std::get<0>(tuple));
}
for (UInt s = 0; s < 100; ++s) {
this->model->solveStep();
}
this->checkAll();
}
diff --git a/test/test_model/patch_tests/patch_test_linear_solid_mechanics_fixture.hh b/test/test_model/patch_tests/patch_test_linear_solid_mechanics_fixture.hh
index 601570839..d3f7242ed 100644
--- a/test/test_model/patch_tests/patch_test_linear_solid_mechanics_fixture.hh
+++ b/test/test_model/patch_tests/patch_test_linear_solid_mechanics_fixture.hh
@@ -1,81 +1,84 @@
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
#include "patch_test_linear_fixture.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PATCH_TEST_LINEAR_SOLID_MECHANICS_FIXTURE_HH__
#define __AKANTU_PATCH_TEST_LINEAR_SOLID_MECHANICS_FIXTURE_HH__
/* -------------------------------------------------------------------------- */
template <typename tuple_>
class TestPatchTestSMMLinear
- : public TestPatchTestLinear<std::tuple_element_t<0, tuple_>, SolidMechanicsModel> {
- using parent = TestPatchTestLinear<std::tuple_element_t<0, tuple_>, SolidMechanicsModel>;
+ : public TestPatchTestLinear<std::tuple_element_t<0, tuple_>,
+ SolidMechanicsModel> {
+ using parent =
+ TestPatchTestLinear<std::tuple_element_t<0, tuple_>, SolidMechanicsModel>;
+
public:
static constexpr bool plane_strain = std::tuple_element_t<1, tuple_>::value;
void applyBC() override {
parent::applyBC();
auto & displacement = this->model->getDisplacement();
this->applyBConDOFs(displacement);
}
void checkAll() {
auto & displacement = this->model->getDisplacement();
auto & mat = this->model->getMaterial(0);
this->checkDOFs(displacement);
this->checkGradient(mat.getGradU(this->type), displacement);
this->checkResults(
[&](const Matrix<Real> & pstrain) {
Real nu = this->model->getMaterial(0).get("nu");
Real E = this->model->getMaterial(0).get("E");
auto strain = (pstrain + pstrain.transpose()) / 2.;
auto trace = strain.trace();
auto lambda = nu * E / ((1 + nu) * (1 - 2 * nu));
auto mu = E / (2 * (1 + nu));
if (not this->plane_strain) {
lambda = nu * E / (1 - nu * nu);
}
decltype(strain) stress(this->dim, this->dim);
if (this->dim == 1) {
stress(0, 0) = E * strain(0, 0);
} else {
for (UInt i = 0; i < this->dim; ++i)
for (UInt j = 0; j < this->dim; ++j)
stress(i, j) =
(i == j) * lambda * trace + 2 * mu * strain(i, j);
}
return stress;
},
mat.getStress(this->type), displacement);
}
};
template <typename tuple_>
constexpr bool TestPatchTestSMMLinear<tuple_>::plane_strain;
template <typename T> struct invalid_plan_stress : std::true_type {};
template <typename type, typename bool_c>
struct invalid_plan_stress<std::tuple<type, bool_c>>
: aka::bool_constant<ElementClass<type::value>::getSpatialDimension() !=
2 and
not bool_c::value> {};
using true_false =
std::tuple<aka::bool_constant<true>, aka::bool_constant<false>>;
template <typename T> using valid_types = aka::negation<invalid_plan_stress<T>>;
using types = gtest_list_t<
tuple_filter_t<valid_types, cross_product_t<TestElementTypes, true_false>>>;
TYPED_TEST_CASE(TestPatchTestSMMLinear, types);
#endif /* __AKANTU_PATCH_TEST_LINEAR_SOLID_MECHANICS_FIXTURE_HH__ */
diff --git a/test/test_model/patch_tests/test_lumped_mass.cc b/test/test_model/patch_tests/test_lumped_mass.cc
index 775e2151d..87cf9cadf 100644
--- a/test/test_model/patch_tests/test_lumped_mass.cc
+++ b/test/test_model/patch_tests/test_lumped_mass.cc
@@ -1,100 +1,101 @@
/**
* @file test_lumped_mass.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Mar 27 2014
* @date last modification: Thu Oct 15 2015
*
* @brief test the lumping of the mass matrix
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "test_gtest_utils.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#include <tuple>
/* -------------------------------------------------------------------------- */
using namespace akantu;
template <typename tuple_>
class TestLumpedMassesFixture : public ::testing::Test {
public:
static constexpr ElementType type = tuple_::value;
static constexpr size_t dim = ElementClass<type>::getSpatialDimension();
void SetUp() override {
debug::setDebugLevel(dblError);
getStaticParser().parse("material_lumped.dat");
std::stringstream element_type;
element_type << type;
mesh = std::make_unique<Mesh>(dim);
mesh->read(element_type.str() + ".msh");
SCOPED_TRACE(element_type.str().c_str());
model = std::make_unique<SolidMechanicsModel>(*mesh);
model->initFull(_analysis_method = _explicit_lumped_mass);
}
void TearDown() override {
model.reset(nullptr);
mesh.reset(nullptr);
}
protected:
std::unique_ptr<Mesh> mesh;
std::unique_ptr<SolidMechanicsModel> model;
};
-template<typename T> constexpr ElementType TestLumpedMassesFixture<T>::type;
-template<typename T> constexpr size_t TestLumpedMassesFixture<T>::dim;
+template <typename T> constexpr ElementType TestLumpedMassesFixture<T>::type;
+template <typename T> constexpr size_t TestLumpedMassesFixture<T>::dim;
using types = gtest_list_t<TestElementTypes>;
TYPED_TEST_CASE(TestLumpedMassesFixture, types);
TYPED_TEST(TestLumpedMassesFixture, TestLumpedMass) {
this->model->assembleMassLumped();
auto rho = this->model->getMaterial(0).getRho();
auto & fem = this->model->getFEEngine();
auto nb_element = this->mesh->getNbElement(this->type);
- auto nb_quadrature_points = fem.getNbIntegrationPoints(this->type) * nb_element;
+ auto nb_quadrature_points =
+ fem.getNbIntegrationPoints(this->type) * nb_element;
Array<Real> rho_on_quad(nb_quadrature_points, 1, rho, "rho_on_quad");
auto mass = fem.integrate(rho_on_quad, this->type);
const auto & masses = this->model->getMass();
Vector<Real> sum(this->dim, 0.);
- for(auto & mass : make_view(masses, this->dim)) {
+ for (auto & mass : make_view(masses, this->dim)) {
sum += mass;
}
- for(UInt s = 0; s < sum.size(); ++s)
- EXPECT_NEAR(0., (mass - sum[s])/mass, 2e-15);
+ for (UInt s = 0; s < sum.size(); ++s)
+ EXPECT_NEAR(0., (mass - sum[s]) / mass, 2e-15);
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc
index 372df63c3..1d8f32dbd 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d.cc
@@ -1,116 +1,116 @@
/**
* @file test_heat_transfer_model_cube3d.cc
*
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
* @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
* @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <fstream>
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "heat_transfer_model.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
UInt spatial_dimension = 3;
ElementType type = _tetrahedron_4;
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
Mesh mesh(spatial_dimension);
mesh.read("cube1.msh");
HeatTransferModel model(mesh);
// initialize everything
model.initFull();
// get and set stable time step
Real time_step = model.getStableTimeStep() * 0.8;
- std::cout << "Stable Time Step is : " << time_step/.8 << std::endl;
+ std::cout << "Stable Time Step is : " << time_step / .8 << std::endl;
std::cout << "time step is:" << time_step << std::endl;
model.setTimeStep(time_step);
/// boundary conditions
const Array<Real> & nodes = mesh.getNodes();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & temperature = model.getTemperature();
UInt nb_nodes = mesh.getNbNodes();
// double t1, t2;
double length;
// t1 = 300.;
// t2 = 100.;
length = 1.;
for (UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
// to insert a heat source
Real dx = nodes(i, 0) - length / 2.;
Real dy = nodes(i, 1) - length / 2.;
Real dz = nodes(i, 2) - length / 2.;
Real d = sqrt(dx * dx + dy * dy + dz * dz);
if (d < 0.1) {
boundary(i) = true;
temperature(i) = 300.;
}
}
model.assembleInternalHeatRate();
model.setBaseName("heat_transfer_cube3d");
model.addDumpField("temperature");
model.addDumpField("temperature_rate");
model.addDumpField("internal_heat_rate");
model.addDumpField("capacity_lumped");
model.dump();
// //for testing
int max_steps = 1000;
for (int i = 0; i < max_steps; i++) {
model.solveStep();
if (i % 100 == 0)
model.dump();
if (i % 10 == 0) {
std::cout << "Step " << i << "/" << max_steps << std::endl;
}
}
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc
index 863406098..374a064ef 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_istropic_conductivity.cc
@@ -1,120 +1,121 @@
/**
* @file test_heat_transfer_model_cube3d_istropic_conductivity.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
* @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "heat_transfer_model.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
-#include "heat_transfer_model.hh"
-#include <iostream>
#include <fstream>
+#include <iostream>
#include <string.h>
using namespace std;
/* -------------------------------------------------------------------------- */
akantu::UInt spatial_dimension = 3;
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
+int main(int argc, char * argv[]) {
akantu::initialize("material.dat", argc, argv);
akantu::Mesh mesh(spatial_dimension);
akantu::MeshIOMSH mesh_io;
mesh_io.read("cube1.msh", mesh);
akantu::HeatTransferModel model(mesh);
- //initialize everything
+ // initialize everything
model.initFull();
- //assemble the lumped capacity
+ // assemble the lumped capacity
model.assembleCapacityLumped();
- //get stable time step
- akantu::Real time_step = model.getStableTimeStep()*0.8;
- cout<<"time step is:"<<time_step<<endl;
+ // get stable time step
+ akantu::Real time_step = model.getStableTimeStep() * 0.8;
+ cout << "time step is:" << time_step << endl;
model.setTimeStep(time_step);
/// boundary conditions
const akantu::Array<akantu::Real> & nodes = mesh.getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
akantu::Real eps = 1e-15;
double length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
- //temperature(i) = t1 - (t1 - t2) * sin(nodes(i, 0) * M_PI / length);
+ // temperature(i) = t1 - (t1 - t2) * sin(nodes(i, 0) * M_PI / length);
temperature(i) = 100.;
- if(nodes(i,0) < eps) {
+ if (nodes(i, 0) < eps) {
boundary(i) = true;
temperature(i) = 300.;
}
- //set the second boundary condition
- if(std::abs(nodes(i,0) - length) < eps) {
+ // set the second boundary condition
+ if (std::abs(nodes(i, 0) - length) < eps) {
boundary(i) = true;
temperature(i) = 300.;
}
// //to insert a heat source
- // if(std::abs(nodes(i,0) - length/2.) < 0.025 && std::abs(nodes(i,1) - length/2.) < 0.025 && std::abs(nodes(i,2) - length/2.) < 0.025) {
+ // if(std::abs(nodes(i,0) - length/2.) < 0.025 && std::abs(nodes(i,1) -
+ // length/2.) < 0.025 && std::abs(nodes(i,2) - length/2.) < 0.025) {
// boundary(i) = true;
// temperature(i) = 300.;
// }
}
- //model.updateResidual();
+ // model.updateResidual();
model.setBaseName("heat_transfer_cube3d_istropic_conductivity");
- model.addDumpField("temperature" );
+ model.addDumpField("temperature");
model.addDumpField("temperature_rate");
- model.addDumpField("residual" );
- model.addDumpField("capacity_lumped" );
+ model.addDumpField("residual");
+ model.addDumpField("capacity_lumped");
model.dump();
// //for testing
int max_steps = 1000;
- for(int i=0; i<max_steps; i++) {
- model.solveStep();
+ for (int i = 0; i < max_steps; i++) {
+ model.solveStep();
- if(i % 100 == 0) model.dump();
- if(i % 10000 == 0)
+ if (i % 100 == 0)
+ model.dump();
+ if (i % 10000 == 0)
std::cout << "Step " << i << "/" << max_steps << std::endl;
}
- cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
+ cout << "\n\n Stable Time Step is : " << time_step << "\n \n" << endl;
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc
index 3eb0d4dc6..9959f64fe 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_pbc.cc
@@ -1,121 +1,121 @@
/**
* @file test_heat_transfer_model_cube3d_pbc.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
* @author Rui Wang <rui.wang@epfl.ch>
*
* @date creation: Sun May 01 2011
* @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "mesh.hh"
#include "heat_transfer_model.hh"
+#include "mesh.hh"
/* -------------------------------------------------------------------------- */
-#include <iostream>
#include <fstream>
+#include <iostream>
using namespace std;
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
+int main(int argc, char * argv[]) {
akantu::initialize("material.dat", argc, argv);
akantu::UInt spatial_dimension = 3;
- //create mesh
+ // create mesh
akantu::Mesh mesh(spatial_dimension);
mesh.read("cube_tet4.msh");
akantu::HeatTransferModel model(mesh);
- //initialize everything
+ // initialize everything
model.initFull();
- //initialize PBC
- model.setPBC(1,1,1);
+ // initialize PBC
+ model.setPBC(1, 1, 1);
model.initPBC();
- //assemble the lumped capacity
+ // assemble the lumped capacity
model.assembleCapacityLumped();
- //get stable time step
- akantu::Real time_step = model.getStableTimeStep()*0.8;
- cout<<"time step is:"<<time_step<<endl;
+ // get stable time step
+ akantu::Real time_step = model.getStableTimeStep() * 0.8;
+ cout << "time step is:" << time_step << endl;
model.setTimeStep(time_step);
// boundary conditions
- const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
+ const akantu::Array<akantu::Real> & nodes =
+ model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
// double t1, t2;
double length;
// t1 = 300.;
// t2 = 100.;
length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
- akantu::Real dx = nodes(i,0) - length/4.;
- akantu::Real dy = nodes(i,1) - length/4.;
- akantu::Real dz = nodes(i,2) - length/4.;
+ akantu::Real dx = nodes(i, 0) - length / 4.;
+ akantu::Real dy = nodes(i, 1) - length / 4.;
+ akantu::Real dz = nodes(i, 2) - length / 4.;
- akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
- if(d < 0.1){
+ akantu::Real d = sqrt(dx * dx + dy * dy + dz * dz);
+ if (d < 0.1) {
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_cube3d_pbc");
- model.addDumpField("temperature" );
+ model.addDumpField("temperature");
model.addDumpField("temperature_rate");
- model.addDumpField("residual" );
- model.addDumpField("capacity_lumped" );
+ model.addDumpField("residual");
+ model.addDumpField("capacity_lumped");
model.dump();
/* ------------------------------------------------------------------------ */
// //for testing
int max_steps = 1000;
/* ------------------------------------------------------------------------ */
- for(int i=0; i<max_steps; i++)
- {
- model.explicitPred();
- model.updateResidual();
- model.solveExplicitLumped();
- model.explicitCorr();
+ for (int i = 0; i < max_steps; i++) {
+ model.explicitPred();
+ model.updateResidual();
+ model.solveExplicitLumped();
+ model.explicitCorr();
- if(i % 100 == 0) model.dump();
+ if (i % 100 == 0)
+ model.dump();
- if(i % 10 == 0)
- std::cout << "Step " << i << "/" << max_steps << std::endl;
- }
- cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
+ if (i % 10 == 0)
+ std::cout << "Step " << i << "/" << max_steps << std::endl;
+ }
+ cout << "\n\n Stable Time Step is : " << time_step << "\n \n" << endl;
return 0;
}
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc
index 28112d6fe..2f81470ca 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_pbc.cc
@@ -1,113 +1,115 @@
/**
* @file test_heat_transfer_model_square2d_pbc.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Sun May 01 2011
* @date last modification: Sun Oct 19 2014
*
* @brief test of the class HeatTransferModel on the 3d cube
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "heat_transfer_model.hh"
/* -------------------------------------------------------------------------- */
-#include <iostream>
#include <fstream>
+#include <iostream>
#include <string.h>
using namespace std;
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
+int main(int argc, char * argv[]) {
akantu::UInt spatial_dimension = 2;
akantu::initialize("material.dat", argc, argv);
- //create mesh
+ // create mesh
akantu::Mesh mesh(spatial_dimension);
mesh.read("square_tri3.msh");
akantu::HeatTransferModel model(mesh);
- //initialize everything
+ // initialize everything
model.initFull();
- //initialize PBC
- model.setPBC(1,1,1);
+ // initialize PBC
+ model.setPBC(1, 1, 1);
model.initPBC();
- //assemble the lumped capacity
+ // assemble the lumped capacity
model.assembleCapacityLumped();
- //get stable time step
- akantu::Real time_step = model.getStableTimeStep()*0.8;
- cout<<"time step is:" << time_step << endl;
+ // get stable time step
+ akantu::Real time_step = model.getStableTimeStep() * 0.8;
+ cout << "time step is:" << time_step << endl;
model.setTimeStep(time_step);
- //boundary conditions
- const akantu::Array<akantu::Real> & nodes = model.getFEEngine().getMesh().getNodes();
+ // boundary conditions
+ const akantu::Array<akantu::Real> & nodes =
+ model.getFEEngine().getMesh().getNodes();
akantu::Array<bool> & boundary = model.getBlockedDOFs();
akantu::Array<akantu::Real> & temperature = model.getTemperature();
double length;
length = 1.;
akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
for (akantu::UInt i = 0; i < nb_nodes; ++i) {
temperature(i) = 100.;
- akantu::Real dx = nodes(i,0) - length/4.;
+ akantu::Real dx = nodes(i, 0) - length / 4.;
akantu::Real dy = 0.0;
akantu::Real dz = 0.0;
- if (spatial_dimension > 1) dy = nodes(i,1) - length/4.;
- if (spatial_dimension == 3) dz = nodes(i,2) - length/4.;
- akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
+ if (spatial_dimension > 1)
+ dy = nodes(i, 1) - length / 4.;
+ if (spatial_dimension == 3)
+ dz = nodes(i, 2) - length / 4.;
+ akantu::Real d = sqrt(dx * dx + dy * dy + dz * dz);
// if(dx < 0.0){
- if(d < 0.1){
+ if (d < 0.1) {
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_square_2d_pbc");
- model.addDumpField("temperature" );
+ model.addDumpField("temperature");
model.addDumpField("temperature_rate");
- model.addDumpField("residual" );
- model.addDumpField("capacity_lumped" );
+ model.addDumpField("residual");
+ model.addDumpField("capacity_lumped");
model.dump();
- //main loop
+ // main loop
int max_steps = 1000;
- for(int i=0; i<max_steps; i++)
- {
- model.explicitPred();
- model.updateResidual();
- model.solveExplicitLumped();
- model.explicitCorr();
- if(i % 100 == 0) model.dump();
- if(i % 10 == 0)
+ for (int i = 0; i < max_steps; i++) {
+ model.explicitPred();
+ model.updateResidual();
+ model.solveExplicitLumped();
+ model.explicitCorr();
+ if (i % 100 == 0)
+ model.dump();
+ if (i % 10 == 0)
std::cout << "Step " << i << "/" << max_steps << std::endl;
- }
- cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
+ }
+ cout << "\n\n Stable Time Step is : " << time_step << "\n \n" << endl;
return 0;
}
diff --git a/test/test_model/test_model_solver/test_model_solver.cc b/test/test_model/test_model_solver/test_model_solver.cc
index 4f25998f8..9d30b144c 100644
--- a/test/test_model/test_model_solver/test_model_solver.cc
+++ b/test/test_model/test_model_solver/test_model_solver.cc
@@ -1,150 +1,148 @@
/**
* @file test_dof_manager_default.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Feb 24 12:28:44 2016
*
* @brief Test default dof manager
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_random_generator.hh"
#include "dof_manager.hh"
#include "dof_synchronizer.hh"
#include "mesh.hh"
#include "mesh_accessor.hh"
#include "model_solver.hh"
#include "non_linear_solver.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
#include "test_model_solver_my_model.hh"
/* -------------------------------------------------------------------------- */
#include <cmath>
/* -------------------------------------------------------------------------- */
using namespace akantu;
static void genMesh(Mesh & mesh, UInt nb_nodes);
static void printResults(MyModel & model, UInt nb_nodes);
Real F = -10;
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize(argc, argv);
UInt prank = Communicator::getStaticCommunicator().whoAmI();
std::cout << std::setprecision(7);
UInt global_nb_nodes = 100;
Mesh mesh(1);
RandomGenerator<UInt>::seed(1);
if (prank == 0) {
genMesh(mesh, global_nb_nodes);
}
- //std::cout << prank << RandGenerator<Real>::seed() << std::endl;
+ // std::cout << prank << RandGenerator<Real>::seed() << std::endl;
mesh.distribute();
MyModel model(F, mesh, false);
model.getNewSolver("static", _tsst_static, _nls_newton_raphson);
model.setIntegrationScheme("static", "disp", _ist_pseudo_time);
- NonLinearSolver & solver =
- model.getDOFManager().getNonLinearSolver("static");
+ NonLinearSolver & solver = model.getDOFManager().getNonLinearSolver("static");
solver.set("max_iterations", 2);
-
model.solveStep();
printResults(model, global_nb_nodes);
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void genMesh(Mesh & mesh, UInt nb_nodes) {
MeshAccessor mesh_accessor(mesh);
Array<Real> & nodes = mesh_accessor.getNodes();
Array<UInt> & conn = mesh_accessor.getConnectivity(_segment_2);
nodes.resize(nb_nodes);
mesh_accessor.setNbGlobalNodes(nb_nodes);
for (UInt n = 0; n < nb_nodes; ++n) {
nodes(n, _x) = n * (1. / (nb_nodes - 1));
}
conn.resize(nb_nodes - 1);
for (UInt n = 0; n < nb_nodes - 1; ++n) {
conn(n, 0) = n;
conn(n, 1) = n + 1;
}
}
/* -------------------------------------------------------------------------- */
void printResults(MyModel & model, UInt nb_nodes) {
UInt prank = model.mesh.getCommunicator().whoAmI();
auto & sync = dynamic_cast<DOFManagerDefault &>(model.getDOFManager())
- .getSynchronizer();
+ .getSynchronizer();
if (prank == 0) {
Array<Real> global_displacement(nb_nodes);
Array<Real> global_forces(nb_nodes);
Array<bool> global_blocked(nb_nodes);
sync.gather(model.forces, global_forces);
sync.gather(model.displacement, global_displacement);
sync.gather(model.blocked, global_blocked);
auto force_it = global_forces.begin();
auto disp_it = global_displacement.begin();
auto blocked_it = global_blocked.begin();
std::cout << "node"
<< ", " << std::setw(8) << "disp"
<< ", " << std::setw(8) << "force"
<< ", " << std::setw(8) << "blocked" << std::endl;
UInt node = 0;
for (; disp_it != global_displacement.end();
++disp_it, ++force_it, ++blocked_it, ++node) {
std::cout << node << ", " << std::setw(8) << *disp_it << ", "
<< std::setw(8) << *force_it << ", " << std::setw(8)
<< *blocked_it << std::endl;
std::cout << std::flush;
}
} else {
sync.gather(model.forces);
sync.gather(model.displacement);
sync.gather(model.blocked);
}
}
diff --git a/test/test_model/test_model_solver/test_model_solver_dynamic.cc b/test/test_model/test_model_solver/test_model_solver_dynamic.cc
index fea1fc63a..3e8ba052e 100644
--- a/test/test_model/test_model_solver/test_model_solver_dynamic.cc
+++ b/test/test_model/test_model_solver/test_model_solver_dynamic.cc
@@ -1,171 +1,171 @@
/**
* @file test_dof_manager_default.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Feb 24 12:28:44 2016
*
* @brief Test default dof manager
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
+#include "communicator.hh"
#include "data_accessor.hh"
#include "dof_manager.hh"
#include "dof_manager_default.hh"
#include "element_synchronizer.hh"
#include "mesh.hh"
#include "mesh_accessor.hh"
#include "model_solver.hh"
#include "non_linear_solver.hh"
#include "sparse_matrix.hh"
-#include "communicator.hh"
#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
#include "test_model_solver_my_model.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
#ifndef EXPLICIT
#define EXPLICIT true
#endif
using namespace akantu;
static void genMesh(Mesh & mesh, UInt nb_nodes);
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize(argc, argv);
UInt prank = Communicator::getStaticCommunicator().whoAmI();
UInt global_nb_nodes = 201;
UInt max_steps = 200;
Real time_step = 0.001;
Mesh mesh(1);
Real F = -9.81;
bool _explicit = EXPLICIT;
if (prank == 0)
genMesh(mesh, global_nb_nodes);
mesh.distribute();
MyModel model(F, mesh, _explicit);
if (!_explicit) {
model.getNewSolver("dynamic", _tsst_dynamic, _nls_newton_raphson);
model.setIntegrationScheme("dynamic", "disp", _ist_trapezoidal_rule_2,
IntegrationScheme::_displacement);
} else {
model.getNewSolver("dynamic", _tsst_dynamic_lumped, _nls_lumped);
model.setIntegrationScheme("dynamic", "disp", _ist_central_difference,
IntegrationScheme::_acceleration);
}
model.setTimeStep(time_step);
// #if EXPLICIT == true
// std::ofstream output("output_dynamic_explicit.csv");
// #else
// std::ofstream output("output_dynamic_implicit.csv");
// #endif
if (prank == 0) {
std::cout << std::scientific;
std::cout << std::setw(14) << "time"
<< "," << std::setw(14) << "wext"
<< "," << std::setw(14) << "epot"
<< "," << std::setw(14) << "ekin"
<< "," << std::setw(14) << "total" << std::endl;
}
Real wext = 0.;
model.getDOFManager().clearResidual();
model.assembleResidual();
- Real epot = 0;//model.getPotentialEnergy();
- Real ekin = 0;//model.getKineticEnergy();
+ Real epot = 0; // model.getPotentialEnergy();
+ Real ekin = 0; // model.getKineticEnergy();
Real einit = ekin + epot;
Real etot = ekin + epot - wext - einit;
if (prank == 0) {
std::cout << std::setw(14) << 0. << "," << std::setw(14) << wext << ","
<< std::setw(14) << epot << "," << std::setw(14) << ekin << ","
<< std::setw(14) << etot << std::endl;
}
#if EXPLICIT == false
NonLinearSolver & solver =
model.getDOFManager().getNonLinearSolver("dynamic");
solver.set("max_iterations", 20);
#endif
for (UInt i = 1; i < max_steps + 1; ++i) {
model.solveStep("dynamic");
#if EXPLICIT == false
- //int nb_iter = solver.get("nb_iterations");
- //Real error = solver.get("error");
- //bool converged = solver.get("converged");
- //if (prank == 0)
- // std::cerr << error << " " << nb_iter << " -> " << converged << std::endl;
+// int nb_iter = solver.get("nb_iterations");
+// Real error = solver.get("error");
+// bool converged = solver.get("converged");
+// if (prank == 0)
+// std::cerr << error << " " << nb_iter << " -> " << converged << std::endl;
#endif
epot = model.getPotentialEnergy();
ekin = model.getKineticEnergy();
wext += model.getExternalWorkIncrement();
etot = ekin + epot - wext - einit;
if (prank == 0) {
std::cout << std::setw(14) << time_step * i << "," << std::setw(14)
<< wext << "," << std::setw(14) << epot << "," << std::setw(14)
<< ekin << "," << std::setw(14) << etot << std::endl;
}
if (std::abs(etot) > 1e-1) {
AKANTU_ERROR("The total energy of the system is not conserved!");
}
}
// output.close();
finalize();
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void genMesh(Mesh & mesh, UInt nb_nodes) {
MeshAccessor mesh_accessor(mesh);
Array<Real> & nodes = mesh_accessor.getNodes();
Array<UInt> & conn = mesh_accessor.getConnectivity(_segment_2);
nodes.resize(nb_nodes);
for (UInt n = 0; n < nb_nodes; ++n) {
nodes(n, _x) = n * (1. / (nb_nodes - 1));
}
conn.resize(nb_nodes - 1);
for (UInt n = 0; n < nb_nodes - 1; ++n) {
conn(n, 0) = n;
conn(n, 1) = n + 1;
}
}
diff --git a/test/test_model/test_model_solver/test_model_solver_my_model.hh b/test/test_model/test_model_solver/test_model_solver_my_model.hh
index 9512d53d9..05fa0dc89 100644
--- a/test/test_model/test_model_solver/test_model_solver_my_model.hh
+++ b/test/test_model/test_model_solver/test_model_solver_my_model.hh
@@ -1,468 +1,469 @@
/**
* @file test_dof_manager_default.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Feb 24 12:28:44 2016
*
* @brief Test default dof manager
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_iterators.hh"
+#include "communicator.hh"
#include "data_accessor.hh"
#include "dof_manager_default.hh"
#include "element_synchronizer.hh"
#include "mesh.hh"
#include "model_solver.hh"
#include "sparse_matrix.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
#ifndef __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__
#define __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__
/**
* =\o-----o-----o-> F
* | |
* |---- L ----|
*/
class MyModel : public ModelSolver, public DataAccessor<Element> {
public:
MyModel(Real F, Mesh & mesh, bool lumped)
- : ModelSolver(mesh, ModelType::_model, "model_solver", 0), nb_dofs(mesh.getNbNodes()),
- nb_elements(mesh.getNbElement()), E(1.), A(1.), rho(1.), lumped(lumped),
- mesh(mesh), displacement(nb_dofs, 1, "disp"),
- velocity(nb_dofs, 1, "velo"), acceleration(nb_dofs, 1, "accel"),
- blocked(nb_dofs, 1, "blocked"), forces(nb_dofs, 1, "force_ext"),
+ : ModelSolver(mesh, ModelType::_model, "model_solver", 0),
+ nb_dofs(mesh.getNbNodes()), nb_elements(mesh.getNbElement()), E(1.),
+ A(1.), rho(1.), lumped(lumped), mesh(mesh),
+ displacement(nb_dofs, 1, "disp"), velocity(nb_dofs, 1, "velo"),
+ acceleration(nb_dofs, 1, "accel"), blocked(nb_dofs, 1, "blocked"),
+ forces(nb_dofs, 1, "force_ext"),
internal_forces(nb_dofs, 1, "force_int"),
stresses(nb_elements, 1, "stress"), strains(nb_elements, 1, "strain"),
initial_lengths(nb_elements, 1, "L0") {
this->initDOFManager();
this->getDOFManager().registerDOFs("disp", displacement, _dst_nodal);
this->getDOFManager().registerDOFsDerivative("disp", 1, velocity);
this->getDOFManager().registerDOFsDerivative("disp", 2, acceleration);
this->getDOFManager().registerBlockedDOFs("disp", blocked);
displacement.set(0.);
velocity.set(0.);
acceleration.set(0.);
forces.set(0.);
blocked.set(false);
UInt global_nb_nodes = mesh.getNbGlobalNodes();
for (auto && n : arange(nb_dofs)) {
auto global_id = mesh.getNodeGlobalId(n);
if (global_id == (global_nb_nodes - 1))
forces(n, _x) = F;
if (global_id == 0)
blocked(n, _x) = true;
}
auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
auto cend = this->mesh.getConnectivity(_segment_2).end(2);
auto L_it = this->initial_lengths.begin();
for (; cit != cend; ++cit, ++L_it) {
const Vector<UInt> & conn = *cit;
UInt n1 = conn(0);
UInt n2 = conn(1);
Real p1 = this->mesh.getNodes()(n1, _x);
Real p2 = this->mesh.getNodes()(n2, _x);
*L_it = std::abs(p2 - p1);
}
this->registerDataAccessor(*this);
this->registerSynchronizer(
const_cast<ElementSynchronizer &>(this->mesh.getElementSynchronizer()),
_gst_user_1);
}
void assembleLumpedMass() {
Array<Real> & M = this->getDOFManager().getLumpedMatrix("M");
M.clear();
this->assembleLumpedMass(_not_ghost);
if (this->mesh.getNbElement(_segment_2, _ghost) > 0)
this->assembleLumpedMass(_ghost);
is_lumped_mass_assembled = true;
}
void assembleLumpedMass(const GhostType & ghost_type) {
Array<Real> & M = this->getDOFManager().getLumpedMatrix("M");
Array<Real> m_all_el(this->mesh.getNbElement(_segment_2, ghost_type), 2);
auto m_it = m_all_el.begin(2);
auto cit = this->mesh.getConnectivity(_segment_2, ghost_type).begin(2);
auto cend = this->mesh.getConnectivity(_segment_2, ghost_type).end(2);
for (; cit != cend; ++cit, ++m_it) {
const Vector<UInt> & conn = *cit;
UInt n1 = conn(0);
UInt n2 = conn(1);
Real p1 = this->mesh.getNodes()(n1, _x);
Real p2 = this->mesh.getNodes()(n2, _x);
Real L = std::abs(p2 - p1);
Real M_n = rho * A * L / 2;
(*m_it)(0) = (*m_it)(1) = M_n;
}
this->getDOFManager().assembleElementalArrayLocalArray(
m_all_el, M, _segment_2, ghost_type);
}
void assembleMass() {
SparseMatrix & M = this->getDOFManager().getMatrix("M");
M.clear();
Array<Real> m_all_el(this->nb_elements, 4);
Array<Real>::matrix_iterator m_it = m_all_el.begin(2, 2);
auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
auto cend = this->mesh.getConnectivity(_segment_2).end(2);
Matrix<Real> m(2, 2);
m(0, 0) = m(1, 1) = 2;
m(0, 1) = m(1, 0) = 1;
// under integrated
// m(0, 0) = m(1, 1) = 3./2.;
// m(0, 1) = m(1, 0) = 3./2.;
// lumping the mass matrix
// m(0, 0) += m(0, 1);
// m(1, 1) += m(1, 0);
// m(0, 1) = m(1, 0) = 0;
for (; cit != cend; ++cit, ++m_it) {
const Vector<UInt> & conn = *cit;
UInt n1 = conn(0);
UInt n2 = conn(1);
Real p1 = this->mesh.getNodes()(n1, _x);
Real p2 = this->mesh.getNodes()(n2, _x);
Real L = std::abs(p2 - p1);
Matrix<Real> & m_el = *m_it;
m_el = m;
m_el *= rho * A * L / 6.;
}
this->getDOFManager().assembleElementalMatricesToMatrix(
"M", "disp", m_all_el, _segment_2);
is_mass_assembled = true;
}
MatrixType getMatrixType(const ID &) { return _symmetric; }
void assembleMatrix(const ID & matrix_id) {
if (matrix_id == "K") {
if (not is_stiffness_assembled)
this->assembleStiffness();
} else if (matrix_id == "M") {
if (not is_mass_assembled)
this->assembleMass();
} else if (matrix_id == "C") {
// pass, no damping matrix
} else {
AKANTU_EXCEPTION("This solver does not know what to do with a matrix "
<< matrix_id);
}
}
void assembleLumpedMatrix(const ID & matrix_id) {
if (matrix_id == "M") {
if (not is_lumped_mass_assembled)
this->assembleLumpedMass();
} else {
AKANTU_EXCEPTION("This solver does not know what to do with a matrix "
<< matrix_id);
}
}
void assembleStiffness() {
SparseMatrix & K = this->getDOFManager().getMatrix("K");
K.clear();
Matrix<Real> k(2, 2);
k(0, 0) = k(1, 1) = 1;
k(0, 1) = k(1, 0) = -1;
Array<Real> k_all_el(this->nb_elements, 4);
auto k_it = k_all_el.begin(2, 2);
auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
auto cend = this->mesh.getConnectivity(_segment_2).end(2);
for (; cit != cend; ++cit, ++k_it) {
const auto & conn = *cit;
UInt n1 = conn(0);
UInt n2 = conn(1);
Real p1 = this->mesh.getNodes()(n1, _x);
Real p2 = this->mesh.getNodes()(n2, _x);
Real L = std::abs(p2 - p1);
auto & k_el = *k_it;
k_el = k;
k_el *= E * A / L;
}
this->getDOFManager().assembleElementalMatricesToMatrix(
"K", "disp", k_all_el, _segment_2);
is_stiffness_assembled = true;
}
void assembleResidual() {
this->getDOFManager().assembleToResidual("disp", forces);
internal_forces.clear();
this->assembleResidual(_not_ghost);
this->synchronize(_gst_user_1);
this->getDOFManager().assembleToResidual("disp", internal_forces, -1.);
// auto & comm = Communicator::getStaticCommunicator();
// const auto & dof_manager_default =
// dynamic_cast<DOFManagerDefault &>(this->getDOFManager());
// const auto & residual = dof_manager_default.getResidual();
// int prank = comm.whoAmI();
// int psize = comm.getNbProc();
// for (int p = 0; p < psize; ++p) {
// if (prank == p) {
// UInt local_dof = 0;
// for (auto res : residual) {
// UInt global_dof =
// dof_manager_default.localToGlobalEquationNumber(local_dof);
// std::cout << local_dof << " [" << global_dof << " - "
// << dof_manager_default.getDOFType(local_dof) << "]: " <<
// res
// << std::endl;
// ++local_dof;
// }
// std::cout << std::flush;
// }
// comm.barrier();
// }
// comm.barrier();
// if(prank == 0) std::cout << "===========================" << std::endl;
}
void assembleResidual(const GhostType & ghost_type) {
Array<Real> forces_internal_el(
this->mesh.getNbElement(_segment_2, ghost_type), 2);
auto cit = this->mesh.getConnectivity(_segment_2, ghost_type).begin(2);
auto cend = this->mesh.getConnectivity(_segment_2, ghost_type).end(2);
auto f_it = forces_internal_el.begin(2);
auto strain_it = this->strains.begin();
auto stress_it = this->stresses.begin();
auto L_it = this->initial_lengths.begin();
for (; cit != cend; ++cit, ++f_it, ++strain_it, ++stress_it, ++L_it) {
const auto & conn = *cit;
UInt n1 = conn(0);
UInt n2 = conn(1);
Real u1 = this->displacement(n1, _x);
Real u2 = this->displacement(n2, _x);
*strain_it = (u2 - u1) / *L_it;
*stress_it = E * *strain_it;
Real f_n = A * *stress_it;
Vector<Real> & f = *f_it;
f(0) = -f_n;
f(1) = f_n;
}
this->getDOFManager().assembleElementalArrayLocalArray(
forces_internal_el, internal_forces, _segment_2, ghost_type);
}
Real getPotentialEnergy() {
Real res = 0;
if (!lumped) {
res = this->mulVectMatVect(this->displacement,
this->getDOFManager().getMatrix("K"),
this->displacement);
} else {
auto strain_it = this->strains.begin();
auto stress_it = this->stresses.begin();
auto strain_end = this->strains.end();
auto L_it = this->initial_lengths.begin();
for (; strain_it != strain_end; ++strain_it, ++stress_it, ++L_it) {
res += *strain_it * *stress_it * A * *L_it;
}
mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
}
return res / 2.;
}
Real getKineticEnergy() {
Real res = 0;
if (!lumped) {
res = this->mulVectMatVect(
this->velocity, this->getDOFManager().getMatrix("M"), this->velocity);
} else {
auto & m = this->getDOFManager().getLumpedMatrix("M");
auto it = velocity.begin();
auto end = velocity.end();
auto m_it = m.begin();
for (UInt node = 0; it != end; ++it, ++m_it, ++node) {
if (mesh.isLocalOrMasterNode(node))
res += *m_it * *it * *it;
}
mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
}
return res / 2.;
}
Real getExternalWorkIncrement() {
Real res = 0;
auto it = velocity.begin();
auto end = velocity.end();
auto if_it = internal_forces.begin();
auto ef_it = forces.begin();
auto b_it = blocked.begin();
for (UInt node = 0; it != end; ++it, ++if_it, ++ef_it, ++b_it, ++node) {
if (mesh.isLocalOrMasterNode(node))
res += (*b_it ? -*if_it : *ef_it) * *it;
}
mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
return res * this->getTimeStep();
}
Real mulVectMatVect(const Array<Real> & x, const SparseMatrix & A,
const Array<Real> & y) {
Array<Real> Ay(this->nb_dofs, 1, 0.);
A.matVecMul(y, Ay);
Real res = 0.;
Array<Real>::const_scalar_iterator it = Ay.begin();
Array<Real>::const_scalar_iterator end = Ay.end();
Array<Real>::const_scalar_iterator x_it = x.begin();
for (UInt node = 0; it != end; ++it, ++x_it, ++node) {
if (mesh.isLocalOrMasterNode(node))
res += *x_it * *it;
}
mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
return res;
}
void predictor() {}
void corrector() {}
/* ------------------------------------------------------------------------ */
UInt getNbData(const Array<Element> & elements,
const SynchronizationTag &) const {
return elements.size() * sizeof(Real);
}
void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
const SynchronizationTag & tag) const {
if (tag == _gst_user_1) {
for (const auto & el : elements) {
buffer << this->stresses(el.element);
}
}
}
void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
const SynchronizationTag & tag) {
if (tag == _gst_user_1) {
auto cit = this->mesh.getConnectivity(_segment_2, _ghost).begin(2);
for (const auto & el : elements) {
Real stress;
buffer >> stress;
Real f = A * stress;
Vector<UInt> conn = cit[el.element];
this->internal_forces(conn(0), _x) += -f;
this->internal_forces(conn(1), _x) += f;
}
}
}
private:
UInt nb_dofs;
UInt nb_elements;
Real E, A, rho;
bool lumped;
bool is_stiffness_assembled{false};
bool is_mass_assembled{false};
bool is_lumped_mass_assembled{false};
public:
Mesh & mesh;
Array<Real> displacement;
Array<Real> velocity;
Array<Real> acceleration;
Array<bool> blocked;
Array<Real> forces;
Array<Real> internal_forces;
Array<Real> stresses;
Array<Real> strains;
Array<Real> initial_lengths;
};
#endif /* __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__ */
} // akantu
diff --git a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
index 64de9a4ba..68e0b5ea6 100644
--- a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
+++ b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
@@ -1,191 +1,192 @@
/**
* @file test_build_neighborhood_parallel.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Wed Nov 25 2015
*
* @brief test in parallel for the class NonLocalNeighborhood
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_iohelper_paraview.hh"
#include "non_local_neighborhood_base.hh"
#include "solid_mechanics_model.hh"
#include "test_material.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
akantu::initialize("material_parallel_test.dat", argc, argv);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
// some configuration variables
const UInt spatial_dimension = 2;
// mesh creation and read
Mesh mesh(spatial_dimension);
if (prank == 0) {
mesh.read("parallel_test.msh");
}
mesh.distribute();
/// model creation
SolidMechanicsModel model(mesh);
/// dump the ghost elements before the non-local part is intialized
DumperParaview dumper_ghost("ghost_elements");
dumper_ghost.registerMesh(mesh, spatial_dimension, _ghost);
if (psize > 1) {
dumper_ghost.dump();
}
/// creation of material selector
- auto && mat_selector = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
+ auto && mat_selector =
+ std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
+ model);
model.setMaterialSelector(mat_selector);
/// dump material index in paraview
model.addDumpField("partitions");
model.dump();
/// model initialization changed to use our material
model.initFull();
/// dump the ghost elements after ghosts for non-local have been added
if (psize > 1)
dumper_ghost.dump();
model.addDumpField("grad_u");
model.addDumpField("grad_u non local");
model.addDumpField("material_index");
/// apply constant strain field everywhere in the plate
Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
applied_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
applied_strain(i, i) = 2.;
ElementType element_type = _triangle_3;
GhostType ghost_type = _not_ghost;
/// apply constant grad_u field in all elements
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
auto & mat = model.getMaterial(m);
auto & grad_u = const_cast<Array<Real> &>(
mat.getInternal<Real>("grad_u")(element_type, ghost_type));
auto grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
auto grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
for (; grad_u_it != grad_u_end; ++grad_u_it)
(*grad_u_it) = -1. * applied_strain;
}
/// double the strain in the center: find the closed gauss point to the center
/// compute the quadrature points
ElementTypeMapReal quad_coords("quad_coords");
quad_coords.initialize(mesh, _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension,
_with_nb_element = true);
model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
Vector<Real> center(spatial_dimension, 0.);
Mesh::type_iterator it =
mesh.firstType(spatial_dimension, _not_ghost, _ek_regular);
Mesh::type_iterator last_type =
mesh.lastType(spatial_dimension, _not_ghost, _ek_regular);
Real min_distance = 2;
IntegrationPoint q_min;
for (; it != last_type; ++it) {
ElementType type = *it;
UInt nb_elements = mesh.getNbElement(type, _not_ghost);
UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(type);
Array<Real> & coords = quad_coords(type, _not_ghost);
- auto coord_it =
- coords.begin(spatial_dimension);
+ auto coord_it = coords.begin(spatial_dimension);
for (UInt e = 0; e < nb_elements; ++e) {
for (UInt q = 0; q < nb_quads; ++q, ++coord_it) {
Real dist = center.distance(*coord_it);
if (dist < min_distance) {
min_distance = dist;
q_min.element = e;
q_min.num_point = q;
q_min.global_num = nb_elements * nb_quads + q;
q_min.type = type;
}
}
}
}
Real global_min = min_distance;
comm.allReduce(global_min, SynchronizerOperation::_min);
if (Math::are_float_equal(global_min, min_distance)) {
UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost)
.begin()[q_min.element];
Material & mat = model.getMaterial(mat_index);
UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
UInt local_el_index =
model.getMaterialLocalNumbering(q_min.type, _not_ghost)
.begin()[q_min.element];
UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
Array<Real> & grad_u = const_cast<Array<Real> &>(
mat.getInternal<Real>("grad_u")(q_min.type, _not_ghost));
Array<Real>::iterator<Matrix<Real>> grad_u_it =
grad_u.begin(spatial_dimension, spatial_dimension);
grad_u_it += local_num;
Matrix<Real> & g_u = *grad_u_it;
g_u += applied_strain;
}
/// compute the non-local strains
model.assembleInternalForces();
model.dump();
/// damage the element with higher grad_u completely, so that it is
/// not taken into account for the averaging
if (Math::are_float_equal(global_min, min_distance)) {
UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost)
.begin()[q_min.element];
Material & mat = model.getMaterial(mat_index);
UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
UInt local_el_index =
model.getMaterialLocalNumbering(q_min.type, _not_ghost)
.begin()[q_min.element];
UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
Array<Real> & damage = const_cast<Array<Real> &>(
mat.getInternal<Real>("damage")(q_min.type, _not_ghost));
Real * dam_ptr = damage.storage();
dam_ptr += local_num;
*dam_ptr = 0.9;
}
/// compute the non-local strains
model.assembleInternalForces();
model.dump();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_non_local_toolbox/test_material.cc b/test/test_model/test_non_local_toolbox/test_material.cc
index 09ddac51c..e15add8ae 100644
--- a/test/test_model/test_non_local_toolbox/test_material.cc
+++ b/test/test_model/test_non_local_toolbox/test_material.cc
@@ -1,56 +1,56 @@
/**
* @file test_material.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Wed Nov 25 2015
*
* @brief Implementation of test material for the non-local neighborhood base
* test
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_material.hh"
/* -------------------------------------------------------------------------- */
template <UInt dim>
TestMaterial<dim>::TestMaterial(SolidMechanicsModel & model, const ID & id)
: Parent(model, id), grad_u_nl("grad_u non local", *this) {
this->is_non_local = true;
this->grad_u_nl.initialize(dim * dim);
}
/* -------------------------------------------------------------------------- */
-template <UInt dim>
-void TestMaterial<dim>::registerNonLocalVariables() {
+template <UInt dim> void TestMaterial<dim>::registerNonLocalVariables() {
this->model.getNonLocalManager().registerNonLocalVariable(
this->gradu.getName(), grad_u_nl.getName(), dim * dim);
- this->model.getNonLocalManager().getNeighborhood(this->getNeighborhoodName())
+ this->model.getNonLocalManager()
+ .getNeighborhood(this->getNeighborhoodName())
.registerNonLocalVariable(grad_u_nl.getName());
}
/* -------------------------------------------------------------------------- */
// Instantiate the material for the 3 dimensions
INSTANTIATE_MATERIAL(test_material, TestMaterial);
/* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_non_local_toolbox/test_material_damage.cc b/test/test_model/test_non_local_toolbox/test_material_damage.cc
index 43d788cc0..26871e6ca 100644
--- a/test/test_model/test_non_local_toolbox/test_material_damage.cc
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.cc
@@ -1,56 +1,56 @@
/**
* @file test_material_damage.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Thu Oct 15 2015
*
* @brief Implementation of test material damage
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_material_damage.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template <UInt dim>
TestMaterialDamage<dim>::TestMaterialDamage(SolidMechanicsModel & model,
const ID & id)
: Parent(model, id), grad_u_nl("grad_u non local", *this) {
this->is_non_local = true;
this->grad_u_nl.initialize(dim * dim);
}
/* -------------------------------------------------------------------------- */
template <UInt dim> void TestMaterialDamage<dim>::registerNonLocalVariables() {
this->model.getNonLocalManager().registerNonLocalVariable(
this->gradu.getName(), grad_u_nl.getName(), dim * dim);
this->model.getNonLocalManager()
- .getNeighborhood(this->getNeighborhoodName())
+ .getNeighborhood(this->getNeighborhoodName())
.registerNonLocalVariable(grad_u_nl.getName());
}
/* -------------------------------------------------------------------------- */
// Instantiate the material for the 3 dimensions
INSTANTIATE_MATERIAL(test_material, TestMaterialDamage);
/* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_non_local_toolbox/test_material_damage.hh b/test/test_model/test_non_local_toolbox/test_material_damage.hh
index 34fd74407..a31f4e7d5 100644
--- a/test/test_model/test_non_local_toolbox/test_material_damage.hh
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.hh
@@ -1,72 +1,73 @@
/**
* @file test_material_damage.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Thu Oct 15 2015
*
* @brief test material damage for the non-local remove damage test
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_damage.hh"
#include "material_damage_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __TEST_MATERIAL_DAMAGE_HH__
#define __TEST_MATERIAL_DAMAGE_HH__
using namespace akantu;
template <UInt dim>
class TestMaterialDamage
: public MaterialDamageNonLocal<dim, MaterialDamage<dim, MaterialElastic>> {
- using Parent = MaterialDamageNonLocal<dim, MaterialDamage<dim, MaterialElastic>>;
+ using Parent =
+ MaterialDamageNonLocal<dim, MaterialDamage<dim, MaterialElastic>>;
/* ------------------------------------------------------------------------ */
/* Constructor/Destructor */
/* ------------------------------------------------------------------------ */
public:
TestMaterialDamage(SolidMechanicsModel & model, const ID & id);
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void registerNonLocalVariables() override final;
- void computeNonLocalStress(ElementType, GhostType) override final {};
+ void computeNonLocalStress(ElementType, GhostType) override final{};
void insertQuadsInNeighborhoods(GhostType ghost_type);
protected:
- //ID getNeighborhoodName() override { return "test_region"; }
+ // ID getNeighborhoodName() override { return "test_region"; }
/* ------------------------------------------------------------------------ */
/* Members */
/* ------------------------------------------------------------------------ */
private:
InternalField<Real> grad_u_nl;
};
#endif /* __TEST_MATERIAL_DAMAGE_HH__ */
diff --git a/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
index 52cddaf69..a5dc2fa9a 100644
--- a/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
+++ b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
@@ -1,112 +1,114 @@
/**
* @file test_non_local_averaging.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Wed Oct 07 2015
*
* @brief test for non-local averaging of strain
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_paraview.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "solid_mechanics_model.hh"
#include "test_material.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
akantu::initialize("material_avg.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
ElementType element_type = _quadrangle_4;
GhostType ghost_type = _not_ghost;
// mesh creation and read
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// creation of material selector
- auto && mat_selector = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
+ auto && mat_selector =
+ std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
+ model);
model.setMaterialSelector(mat_selector);
/// model initialization changed to use our material
model.initFull();
/// dump material index in paraview
model.addDumpField("material_index");
model.addDumpField("grad_u");
model.addDumpField("grad_u non local");
model.dump();
/// apply constant strain field everywhere in the plate
Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
applied_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
applied_strain(i, i) = 2.;
/// apply constant grad_u field in all elements
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
auto & mat = model.getMaterial(m);
auto & grad_u = const_cast<Array<Real> &>(
mat.getInternal<Real>("eigen_grad_u")(element_type, ghost_type));
auto grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
auto grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
for (; grad_u_it != grad_u_end; ++grad_u_it)
(*grad_u_it) = -1. * applied_strain;
}
/// compute the non-local strains
model.assembleInternalForces();
model.dump();
/// verify the result: non-local averaging over constant field must
/// yield same constant field
Real test_result = 0.;
Matrix<Real> difference(spatial_dimension, spatial_dimension, 0.);
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
auto & mat = model.getMaterial(m);
auto & grad_u_nl =
mat.getInternal<Real>("grad_u non local")(element_type, ghost_type);
auto grad_u_nl_it = grad_u_nl.begin(spatial_dimension, spatial_dimension);
auto grad_u_nl_end = grad_u_nl.end(spatial_dimension, spatial_dimension);
for (; grad_u_nl_it != grad_u_nl_end; ++grad_u_nl_it) {
difference = (*grad_u_nl_it) - applied_strain;
test_result += difference.norm<L_2>();
}
}
if (test_result > 10.e-13) {
std::cout << "the total norm is: " << test_result << std::endl;
std::terminate();
}
return 0;
}
diff --git a/test/test_model/test_non_local_toolbox/test_pair_computation.cc b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
index d70a01ea5..b77a0603d 100644
--- a/test/test_model/test_non_local_toolbox/test_pair_computation.cc
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
@@ -1,224 +1,226 @@
/**
* @file test_pair_computation.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Wed Nov 25 2015
*
* @brief test the weight computation with and without grid
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_paraview.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "solid_mechanics_model.hh"
#include "test_material_damage.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
typedef std::vector<std::pair<IntegrationPoint, IntegrationPoint>> PairList;
/* -------------------------------------------------------------------------- */
void computePairs(SolidMechanicsModel & model, PairList * pair_list);
int main(int argc, char * argv[]) {
akantu::initialize("material_remove_damage.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
const auto & comm = Communicator::getStaticCommunicator();
Int prank = comm.whoAmI();
// mesh creation and read
Mesh mesh(spatial_dimension);
if (prank == 0) {
mesh.read("pair_test.msh");
}
mesh.distribute();
/// model creation
SolidMechanicsModel model(mesh);
/// creation of material selector
- auto && mat_selector = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
+ auto && mat_selector =
+ std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
+ model);
model.setMaterialSelector(mat_selector);
/// model initialization changed to use our material
model.initFull();
/// dump material index in paraview
model.addDumpField("material_index");
model.dump();
/// compute the pairs by looping over all the quadrature points
PairList pair_list[2];
computePairs(model, pair_list);
- const PairList * pairs_mat_1 = model.getNonLocalManager().getNeighborhood("mat_1").getPairLists();
- const PairList * pairs_mat_2 = model.getNonLocalManager().getNeighborhood("mat_2").getPairLists();
+ const PairList * pairs_mat_1 =
+ model.getNonLocalManager().getNeighborhood("mat_1").getPairLists();
+ const PairList * pairs_mat_2 =
+ model.getNonLocalManager().getNeighborhood("mat_2").getPairLists();
/// compare the number of pairs
UInt nb_not_ghost_pairs_grid = pairs_mat_1[0].size() + pairs_mat_2[0].size();
UInt nb_ghost_pairs_grid = pairs_mat_1[1].size() + pairs_mat_2[1].size();
UInt nb_not_ghost_pairs_no_grid = pair_list[0].size();
UInt nb_ghost_pairs_no_grid = pair_list[1].size();
if ((nb_not_ghost_pairs_grid != nb_not_ghost_pairs_no_grid) ||
(nb_ghost_pairs_grid != nb_ghost_pairs_no_grid)) {
std::cout << "The number of pairs is not correct: TEST FAILED!!!"
<< std::endl;
finalize();
return EXIT_FAILURE;
}
for (UInt i = 0; i < pairs_mat_1[0].size(); ++i) {
PairList::const_iterator it = std::find(
pair_list[0].begin(), pair_list[0].end(), (pairs_mat_1[0])[i]);
if (it == pair_list[0].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
for (UInt i = 0; i < pairs_mat_2[0].size(); ++i) {
PairList::const_iterator it = std::find(
pair_list[0].begin(), pair_list[0].end(), (pairs_mat_2[0])[i]);
if (it == pair_list[0].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
for (UInt i = 0; i < pairs_mat_1[1].size(); ++i) {
PairList::const_iterator it = std::find(
pair_list[1].begin(), pair_list[1].end(), (pairs_mat_1[1])[i]);
if (it == pair_list[1].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
for (UInt i = 0; i < pairs_mat_2[1].size(); ++i) {
PairList::const_iterator it = std::find(
pair_list[1].begin(), pair_list[1].end(), (pairs_mat_2[1])[i]);
if (it == pair_list[1].end()) {
std::cout << "The pairs are not correct" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
finalize();
return 0;
}
/* -------------------------------------------------------------------------- */
void computePairs(SolidMechanicsModel & model, PairList * pair_list) {
ElementKind kind = _ek_regular;
Mesh & mesh = model.getMesh();
UInt spatial_dimension = model.getSpatialDimension();
/// compute the quadrature points
ElementTypeMapReal quad_coords("quad_coords");
quad_coords.initialize(mesh, _nb_component = spatial_dimension,
_spatial_dimension = spatial_dimension,
_with_nb_element = true);
model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
/// loop in a n^2 way over all the quads to generate the pairs
Real neighborhood_radius = 0.5;
Mesh::type_iterator it_1 =
mesh.firstType(spatial_dimension, _not_ghost, kind);
Mesh::type_iterator last_type_1 =
mesh.lastType(spatial_dimension, _not_ghost, kind);
IntegrationPoint q1;
IntegrationPoint q2;
GhostType ghost_type_1 = _not_ghost;
q1.ghost_type = ghost_type_1;
Vector<Real> q1_coords(spatial_dimension);
Vector<Real> q2_coords(spatial_dimension);
for (; it_1 != last_type_1; ++it_1) {
ElementType type_1 = *it_1;
q1.type = type_1;
UInt nb_elements_1 = mesh.getNbElement(type_1, ghost_type_1);
UInt nb_quads_1 = model.getFEEngine().getNbIntegrationPoints(type_1);
Array<Real> & quad_coords_1 = quad_coords(q1.type, q1.ghost_type);
- auto coord_it_1 =
- quad_coords_1.begin(spatial_dimension);
+ auto coord_it_1 = quad_coords_1.begin(spatial_dimension);
for (UInt e_1 = 0; e_1 < nb_elements_1; ++e_1) {
q1.element = e_1;
UInt mat_index_1 = model.getMaterialByElement(q1.type, q1.ghost_type)
.begin()[q1.element];
for (UInt q_1 = 0; q_1 < nb_quads_1; ++q_1) {
q1.global_num = nb_quads_1 * e_1 + q_1;
q1.num_point = q_1;
q1_coords = coord_it_1[q1.global_num];
/// loop over all other quads and create pairs for this given quad
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type_2 = *gt;
q2.ghost_type = ghost_type_2;
Mesh::type_iterator it_2 =
mesh.firstType(spatial_dimension, ghost_type_2, kind);
Mesh::type_iterator last_type_2 =
mesh.lastType(spatial_dimension, ghost_type_2, kind);
for (; it_2 != last_type_2; ++it_2) {
ElementType type_2 = *it_2;
q2.type = type_2;
UInt nb_elements_2 = mesh.getNbElement(type_2, ghost_type_2);
UInt nb_quads_2 =
model.getFEEngine().getNbIntegrationPoints(type_2);
Array<Real> & quad_coords_2 = quad_coords(q2.type, q2.ghost_type);
- auto coord_it_2 =
- quad_coords_2.begin(spatial_dimension);
+ auto coord_it_2 = quad_coords_2.begin(spatial_dimension);
for (UInt e_2 = 0; e_2 < nb_elements_2; ++e_2) {
q2.element = e_2;
UInt mat_index_2 =
model.getMaterialByElement(q2.type, q2.ghost_type)
.begin()[q2.element];
for (UInt q_2 = 0; q_2 < nb_quads_2; ++q_2) {
q2.global_num = nb_quads_2 * e_2 + q_2;
q2.num_point = q_2;
q2_coords = coord_it_2[q2.global_num];
Real distance = q1_coords.distance(q2_coords);
if (mat_index_1 != mat_index_2)
continue;
else if (distance <=
neighborhood_radius + Math::getTolerance() &&
(q2.ghost_type == _ghost ||
(q2.ghost_type == _not_ghost &&
q1.global_num <=
q2.global_num))) { // storing only half lists
pair_list[q2.ghost_type].push_back(std::make_pair(q1, q2));
}
}
}
}
}
}
}
}
}
diff --git a/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
index 1a3642b92..ffeebb2de 100644
--- a/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
+++ b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
@@ -1,188 +1,189 @@
/**
* @file test_remove_damage_weight_function.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Wed Oct 07 2015
*
* @brief Test the damage weight funcion for non local computations
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dumper_paraview.hh"
#include "non_local_manager.hh"
#include "non_local_neighborhood.hh"
#include "solid_mechanics_model.hh"
#include "test_material_damage.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
akantu::initialize("material_remove_damage.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
ElementType element_type = _quadrangle_4;
GhostType ghost_type = _not_ghost;
// mesh creation and read
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
SolidMechanicsModel model(mesh);
/// creation of material selector
- auto &&
- mat_selector = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
+ auto && mat_selector =
+ std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
+ model);
model.setMaterialSelector(mat_selector);
/// model initialization changed to use our material
model.initFull();
/// dump material index in paraview
model.addDumpField("material_index");
model.addDumpField("grad_u");
model.addDumpField("grad_u non local");
model.addDumpField("damage");
model.dump();
/// apply constant strain field in all elements except element 3 and 15
Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
applied_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
applied_strain(i, i) = 2.;
/// apply different strain in element 3 and 15
Matrix<Real> modified_strain(spatial_dimension, spatial_dimension);
modified_strain.clear();
for (UInt i = 0; i < spatial_dimension; ++i)
modified_strain(i, i) = 1.;
/// apply constant grad_u field in all elements
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
Material & mat = model.getMaterial(m);
Array<Real> & grad_u = const_cast<Array<Real> &>(
mat.getInternal<Real>("eigen_grad_u")(element_type, ghost_type));
auto grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
auto grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
UInt element_counter = 0;
for (; grad_u_it != grad_u_end; ++grad_u_it, ++element_counter)
if (element_counter == 12 || element_counter == 13 ||
element_counter == 14 || element_counter == 15)
(*grad_u_it) = -1. * modified_strain;
else
(*grad_u_it) = -1. * applied_strain;
}
/// compute the non-local strains
model.assembleInternalForces();
model.dump();
/// save the weights in a file
auto & neighborhood_1 = model.getNonLocalManager().getNeighborhood("mat_1");
auto & neighborhood_2 = model.getNonLocalManager().getNeighborhood("mat_2");
neighborhood_1.saveWeights("before_0");
neighborhood_2.saveWeights("before_1");
for (UInt n = 0; n < 2; ++n) {
/// print results to screen for validation
std::stringstream sstr;
sstr << "before_" << n << ".0";
std::ifstream weights;
weights.open(sstr.str());
std::string current_line;
while (getline(weights, current_line))
std::cout << current_line << std::endl;
weights.close();
}
/// apply damage to not have the elements with lower strain impact the
/// averaging
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
auto & mat =
dynamic_cast<MaterialDamage<spatial_dimension> &>(model.getMaterial(m));
auto & damage = const_cast<Array<Real> &>(
mat.getInternal<Real>("damage")(element_type, ghost_type));
auto dam_it = damage.begin();
auto dam_end = damage.end();
UInt element_counter = 0;
for (; dam_it != dam_end; ++dam_it, ++element_counter)
if (element_counter == 12 || element_counter == 13 ||
element_counter == 14 || element_counter == 15)
*dam_it = 0.9;
}
/// compute the non-local strains
model.assembleInternalForces();
neighborhood_1.saveWeights("after_0");
neighborhood_2.saveWeights("after_1");
for (UInt n = 0; n < 2; ++n) {
/// print results to screen for validation
std::stringstream sstr;
sstr << "after_" << n << ".0";
std::ifstream weights;
weights.open(sstr.str());
std::string current_line;
while (getline(weights, current_line))
std::cout << current_line << std::endl;
weights.close();
}
model.dump();
/// verify the result: non-local averaging over constant field must
/// yield same constant field
Real test_result = 0.;
Matrix<Real> difference(spatial_dimension, spatial_dimension, 0.);
Matrix<Real> difference_in_damaged_elements(spatial_dimension,
spatial_dimension, 0.);
for (UInt m = 0; m < model.getNbMaterials(); ++m) {
difference_in_damaged_elements.clear();
auto & mat = model.getMaterial(m);
auto & grad_u_nl = const_cast<Array<Real> &>(
mat.getInternal<Real>("grad_u non local")(element_type, ghost_type));
auto grad_u_nl_it = grad_u_nl.begin(spatial_dimension, spatial_dimension);
auto grad_u_nl_end = grad_u_nl.end(spatial_dimension, spatial_dimension);
UInt element_counter = 0;
for (; grad_u_nl_it != grad_u_nl_end; ++grad_u_nl_it, ++element_counter) {
if (element_counter == 12 || element_counter == 13 ||
element_counter == 14 || element_counter == 15)
difference_in_damaged_elements += (*grad_u_nl_it);
else
difference = (*grad_u_nl_it) - applied_strain;
test_result += difference.norm<L_2>();
}
difference_in_damaged_elements *= (1 / 4.);
difference_in_damaged_elements -= (1.41142 * modified_strain);
test_result += difference_in_damaged_elements.norm<L_2>();
}
if (test_result > 10.e-5) {
std::cout << "the total norm is: " << test_result << std::endl;
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_non_local_toolbox/test_weight_computation.cc b/test/test_model/test_non_local_toolbox/test_weight_computation.cc
index a2b5034de..823a31c8a 100644
--- a/test/test_model/test_non_local_toolbox/test_weight_computation.cc
+++ b/test/test_model/test_non_local_toolbox/test_weight_computation.cc
@@ -1,68 +1,68 @@
/**
* @file test_weight_computation.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Sat Sep 26 2015
* @date last modification: Wed Oct 07 2015
*
* @brief test for the weight computation with base weight function
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "my_model.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
akantu::initialize("material_weight_computation.dat", argc, argv);
// some configuration variables
const UInt spatial_dimension = 2;
// mesh creation and read
Mesh mesh(spatial_dimension);
mesh.read("plate.msh");
/// model creation
MyModel model(mesh, spatial_dimension);
/// save the weights in a file
const auto & neighborhood =
- model.getNonLocalManager().getNeighborhood("test_region");
+ model.getNonLocalManager().getNeighborhood("test_region");
neighborhood.saveWeights("weights");
/// print results to screen for validation
std::ifstream weights;
weights.open("weights.0");
std::string current_line;
while (getline(weights, current_line))
std::cout << current_line << std::endl;
weights.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
index 86f7f65f4..2c2ee62f3 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
@@ -1,103 +1,103 @@
/**
* @file test_cohesive_1d_element.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 14 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Test for 1D cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt max_steps = 2000;
const Real strain_rate = 5;
UInt spatial_dimension = 1;
Mesh mesh(spatial_dimension, "mesh");
mesh.read("bar.msh");
Math::setTolerance(1e-7);
SolidMechanicsModelCohesive model(mesh);
model.initFull(_analysis_method = _explicit_lumped_mass,
_is_extrinsic = true);
auto time_step = model.getStableTimeStep() * 0.01;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
auto posx_max = mesh.getUpperBounds()(_x);
auto posx_min = mesh.getLowerBounds()(_x);
/// initial conditions
const auto & position = mesh.getNodes();
auto & velocity = model.getVelocity();
auto nb_nodes = mesh.getNbNodes();
for (UInt n = 0; n < nb_nodes; ++n)
velocity(n) = strain_rate * (position(n) - (posx_max + posx_min) / 2.);
/// boundary conditions
model.applyBC(BC::Dirichlet::FlagOnly(_x), "left");
model.applyBC(BC::Dirichlet::FlagOnly(_x), "right");
auto disp_increment = strain_rate * (posx_max - posx_min) / 2. * time_step;
model.assembleInternalForces();
for (UInt s = 1; s <= max_steps; ++s) {
model.checkCohesiveStress();
model.solveStep();
auto nb_cohesive_elements = mesh.getNbElement(_cohesive_1d_2);
if (s % 10 == 0) {
std::cout << "passing step " << s << "/" << max_steps
<< ", number of cohesive elemets:" << nb_cohesive_elements
<< std::endl;
}
/// update external work and boundary conditions
model.applyBC(BC::Dirichlet::IncrementValue(-disp_increment, _x), "left");
- model.applyBC(BC::Dirichlet::IncrementValue( disp_increment, _x), "right");
+ model.applyBC(BC::Dirichlet::IncrementValue(disp_increment, _x), "right");
}
auto Ed = model.getEnergy("dissipated");
auto Edt = 100. * 3.;
std::cout << Ed << " " << Edt << std::endl;
if (std::abs(Ed - Edt) > 0.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc
index 0b023fb54..abe51c26a 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic.cc
@@ -1,137 +1,136 @@
/**
* @file test_cohesive_extrinsic.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Wed Mar 18 2015
*
* @brief Test for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <fstream>
#include <iostream>
#include <limits>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt spatial_dimension = 2;
const UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initFull(
SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
model.getElementInserter().setLimit(_y, -0.30, -0.20);
model.updateAutomaticInsertion();
mesh.setBaseName("test_cohesive_extrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("mass");
model.addDumpField("velocity");
model.addDumpField("acceleration");
model.addDumpFieldVector("external_force");
model.addDumpFieldVector("internal_force");
model.addDumpField("grad_u");
model.dump();
-
Real time_step = model.getStableTimeStep() * 0.05;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
/// initial conditions
Real loading_rate = 0.5;
Real disp_update = loading_rate * time_step;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
}
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
/// update displacement on extreme nodes
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
displacement(n, 1) += disp_update * position(n, 1);
}
model.checkCohesiveStress();
model.solveStep();
if (s % 100 == 0) {
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
model.dump();
}
Real Ed = model.getEnergy("dissipated");
Real Edt = 200 * std::sqrt(2);
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
std::cout << "OK: test_cohesive_extrinsic was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc
index f486f398c..46baeaf67 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc
@@ -1,243 +1,243 @@
/**
* @file test_cohesive_extrinsic_fatigue.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Feb 20 2015
* @date last modification: Thu Jun 25 2015
*
* @brief Test for the linear fatigue cohesive law
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear_fatigue.hh"
#include "solid_mechanics_model_cohesive.hh"
#include <limits>
/* -------------------------------------------------------------------------- */
using namespace akantu;
// the following class contains an implementation of the 1D linear
// fatigue cohesive law
class MaterialFatigue {
public:
MaterialFatigue(Real delta_f, Real sigma_c, Real delta_c)
: delta_f(delta_f), sigma_c(sigma_c), delta_c(delta_c), delta_prec(0),
traction(sigma_c), delta_max(0),
stiff_plus(std::numeric_limits<Real>::max()),
tolerance(Math::getTolerance()){};
Real computeTraction(Real delta) {
if (delta - delta_c > -tolerance)
traction = 0;
else if (delta_max < tolerance && delta < tolerance)
traction = sigma_c;
else {
Real delta_dot = delta - delta_prec;
if (delta_dot > -tolerance) {
stiff_plus *= 1 - delta_dot / delta_f;
traction += stiff_plus * delta_dot;
Real max_traction = sigma_c * (1 - delta / delta_c);
if (traction - max_traction > -tolerance || delta_max < tolerance) {
traction = max_traction;
stiff_plus = traction / delta;
}
} else {
Real stiff_minus = traction / delta_prec;
stiff_plus += (stiff_plus - stiff_minus) * delta_dot / delta_f;
traction += stiff_minus * delta_dot;
}
}
delta_prec = delta;
delta_max = std::max(delta, delta_max);
return traction;
}
private:
const Real delta_f;
const Real sigma_c;
const Real delta_c;
Real delta_prec;
Real traction;
Real delta_max;
Real stiff_plus;
const Real tolerance;
};
void imposeOpening(SolidMechanicsModelCohesive &, Real);
void arange(Array<Real> &, Real, Real, Real);
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize("material_fatigue.dat", argc, argv);
Math::setTolerance(1e-13);
const UInt spatial_dimension = 2;
const ElementType type = _quadrangle_4;
Mesh mesh(spatial_dimension);
mesh.read("fatigue.msh");
// init stuff
const ElementType type_facet = Mesh::getFacetType(type);
const ElementType type_cohesive =
FEEngine::getCohesiveElementType(type_facet);
SolidMechanicsModelCohesive model(mesh);
model.initFull(
SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
MaterialCohesiveLinearFatigue<2> & numerical_material =
dynamic_cast<MaterialCohesiveLinearFatigue<2> &>(
model.getMaterial("cohesive"));
Real delta_f = numerical_material.getParam("delta_f");
Real delta_c = numerical_material.getParam("delta_c");
Real sigma_c = 1;
const Array<Real> & traction_array =
numerical_material.getTraction(type_cohesive);
MaterialFatigue theoretical_material(delta_f, sigma_c, delta_c);
// model.setBaseName("fatigue");
// model.addDumpFieldVector("displacement");
// model.addDumpField("stress");
// model.dump();
// stretch material
Real strain = 1;
Array<Real> & displacement = model.getDisplacement();
const Array<Real> & position = mesh.getNodes();
for (UInt n = 0; n < mesh.getNbNodes(); ++n)
displacement(n, 0) = position(n, 0) * strain;
model.assembleInternalForces();
// model.dump();
// insert cohesive elements
model.checkCohesiveStress();
// create the displacement sequence
Real increment = 0.01;
Array<Real> openings;
arange(openings, 0, 0.5, increment);
arange(openings, 0.5, 0.1, increment);
arange(openings, 0.1, 0.7, increment);
arange(openings, 0.7, 0.3, increment);
arange(openings, 0.3, 0.6, increment);
arange(openings, 0.6, 0.3, increment);
arange(openings, 0.3, 0.7, increment);
arange(openings, 0.7, 1.3, increment);
const Array<UInt> & switches = numerical_material.getSwitches(type_cohesive);
// std::ofstream edis("fatigue_edis.txt");
// impose openings
for (UInt i = 0; i < openings.size(); ++i) {
// compute numerical traction
imposeOpening(model, openings(i));
model.assembleInternalForces();
// model.dump();
Real numerical_traction = traction_array(0, 0);
// compute theoretical traction
Real theoretical_traction =
theoretical_material.computeTraction(openings(i));
// test traction
if (std::abs(numerical_traction - theoretical_traction) > 1e-13)
AKANTU_ERROR("The numerical traction "
- << numerical_traction << " and theoretical traction "
- << theoretical_traction << " are not coincident");
+ << numerical_traction << " and theoretical traction "
+ << theoretical_traction << " are not coincident");
// edis << model.getEnergy("dissipated") << std::endl;
}
if (switches(0) != 7)
AKANTU_ERROR("The number of switches is wrong");
std::cout << "OK: the test_cohesive_extrinsic_fatigue passed." << std::endl;
return 0;
}
/* -------------------------------------------------------------------------- */
void imposeOpening(SolidMechanicsModelCohesive & model, Real opening) {
UInt spatial_dimension = model.getSpatialDimension();
Mesh & mesh = model.getFEEngine().getMesh();
Array<Real> & position = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
UInt nb_nodes = mesh.getNbNodes();
Array<bool> update(nb_nodes);
update.clear();
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator end = mesh.lastType(spatial_dimension);
for (; it != end; ++it) {
ElementType type = *it;
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Vector<Real> barycenter(spatial_dimension);
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter({type, el, _not_ghost}, barycenter);
if (barycenter(0) > 1) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(el, n);
if (!update(node)) {
displacement(node, 0) = opening + position(node, 0);
update(node) = true;
}
}
}
}
}
}
/* -------------------------------------------------------------------------- */
void arange(Array<Real> & openings, Real begin, Real end, Real increment) {
if (begin < end) {
for (Real opening = begin; opening < end - increment / 2.;
opening += increment)
openings.push_back(opening);
} else {
for (Real opening = begin; opening > end + increment / 2.;
opening -= increment)
openings.push_back(opening);
}
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc
index d06b84f83..f85e2be90 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc
@@ -1,112 +1,113 @@
/**
* @file test_cohesive_insertion_along_physical_surfaces.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Fri Aug 07 2015
*
* @brief Test intrinsic insertion of cohesive elements along physical surfaces
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <fstream>
#include <iostream>
#include <limits>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
#include "material_cohesive.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("input_file.dat", argc, argv);
Math::setTolerance(1e-15);
const UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
mesh.read("3d_spherical_inclusion.msh");
SolidMechanicsModelCohesive model(mesh);
- auto && material_selector = std::make_shared<MeshDataMaterialCohesiveSelector>(model);
+ auto && material_selector =
+ std::make_shared<MeshDataMaterialCohesiveSelector>(model);
material_selector->setFallback(model.getMaterialSelector());
model.setMaterialSelector(material_selector);
model.initFull(_analysis_method = _static);
std::vector<std::string> surfaces_name = {"interface", "coh1", "coh2",
"coh3", "coh4", "coh5"};
UInt nb_surf = surfaces_name.size();
Mesh::type_iterator it =
mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive);
Mesh::type_iterator end =
mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive);
for (; it != end; ++it) {
for (UInt i = 0; i < nb_surf; ++i) {
UInt expected_insertion = mesh.getElementGroup(surfaces_name[i])
.getElements(mesh.getFacetType(*it))
.size();
UInt inserted_elements =
model.getMaterial(surfaces_name[i]).getElementFilter()(*it).size();
AKANTU_DEBUG_ASSERT((expected_insertion == inserted_elements),
std::endl
<< "!!! Mismatch in insertion of surface named "
<< surfaces_name[i] << " --> "
<< inserted_elements
<< " inserted elements out of "
<< expected_insertion << std::endl);
}
}
/*std::string paraview_folder =
"paraview/test_intrinsic_insertion_along_physical_surfaces/";
model.setDirectory(paraview_folder);
model.setBaseName("bulk");
model.addDumpField("partitions");
model.dump();
model.setDirectoryToDumper("cohesive elements", paraview_folder);
model.setBaseNameToDumper("cohesive elements", "one_cohesive_element");
model.addDumpFieldToDumper("cohesive elements", "partitions");
model.addDumpFieldToDumper("cohesive elements", "material_index");
model.dump("cohesive elements");
*/
- //model.assembleStiffnessMatrix();
+ // model.assembleStiffnessMatrix();
- //finalize();
+ // finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc
index c90210373..6e1873c76 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/test_cohesive_intrinsic_quadrangle.cc
@@ -1,209 +1,207 @@
/**
* @file test_cohesive_intrinsic_quadrangle.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Thu Dec 11 2014
*
* @brief Intrinsic cohesive elements' test for quadrangles
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-#include <limits>
#include <fstream>
#include <iostream>
+#include <limits>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-static void updateDisplacement(SolidMechanicsModelCohesive &,
- Array<UInt> &,
- ElementType,
- Real);
+static void updateDisplacement(SolidMechanicsModelCohesive &, Array<UInt> &,
+ ElementType, Real);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 2;
const UInt max_steps = 350;
const ElementType type = _quadrangle_4;
Mesh mesh(spatial_dimension);
mesh.read("quadrangle.msh");
-
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// debug::setDebugLevel(dblWarning);
SolidMechanicsModelCohesive model(mesh);
model.getElementInserter().setLimit(_x, -0.01, 0.01);
/// model initialization
model.initFull();
- Real time_step = model.getStableTimeStep()*0.8;
+ Real time_step = model.getStableTimeStep() * 0.8;
model.setTimeStep(time_step);
model.assembleMassLumped();
-
Array<bool> & boundary = model.getBlockedDOFs();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_element = mesh.getNbElement(type);
/// boundary conditions
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
for (UInt n = 0; n < nb_nodes; ++n) {
boundary(n, dim) = true;
}
}
model.assembleInternalForces();
model.setBaseName("intrinsic_quadrangle");
model.addDumpFieldVector("displacement");
- model.addDumpField("velocity" );
+ model.addDumpField("velocity");
model.addDumpField("acceleration");
- model.addDumpField("internal_force" );
+ model.addDumpField("internal_force");
model.addDumpField("stress");
model.addDumpField("grad_u");
model.addDumpField("external_force");
- model.setBaseNameToDumper("cohesive elements", "cohesive_elements_quadrangle");
+ model.setBaseNameToDumper("cohesive elements",
+ "cohesive_elements_quadrangle");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump();
model.dump("cohesive elements");
/// update displacement
Array<UInt> elements;
Vector<Real> bary(spatial_dimension);
for (UInt el = 0; el < nb_element; ++el) {
mesh.getBarycenter({type, el, _not_ghost}, bary);
- if (bary(_x) > 0.) elements.push_back(el);
+ if (bary(_x) > 0.)
+ elements.push_back(el);
}
Real increment = 0.01;
updateDisplacement(model, elements, type, increment);
// for (UInt n = 0; n < nb_nodes; ++n) {
// if (position(n, 1) + displacement(n, 1) > 0) {
// if (position(n, 0) == 0) {
// displacement(n, 1) -= 0.25;
// }
// if (position(n, 0) == 1) {
// displacement(n, 1) += 0.25;
// }
// }
// }
// std::ofstream edis("edis.txt");
// std::ofstream erev("erev.txt");
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
updateDisplacement(model, elements, type, increment);
- if(s % 1 == 0) {
+ if (s % 1 == 0) {
model.dump();
model.dump("cohesive elements");
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
// // update displacement
// for (UInt n = 0; n < nb_nodes; ++n) {
// if (position(n, 1) + displacement(n, 1) > 0) {
// displacement(n, 0) -= 0.01;
// }
// }
- // Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
- // Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
+ // Real Ed = dynamic_cast<MaterialCohesive&>
+ // (model.getMaterial(1)).getDissipatedEnergy();
+ // Real Er = dynamic_cast<MaterialCohesive&>
+ // (model.getMaterial(1)).getReversibleEnergy();
// edis << s << " "
// << Ed << std::endl;
// erev << s << " "
// << Er << std::endl;
-
}
// edis.close();
// erev.close();
Real Ed = model.getEnergy("dissipated");
Real Edt = 1;
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
finalize();
- std::cout << "OK: test_cohesive_intrinsic_quadrangle was passed!" << std::endl;
+ std::cout << "OK: test_cohesive_intrinsic_quadrangle was passed!"
+ << std::endl;
return EXIT_SUCCESS;
}
-
static void updateDisplacement(SolidMechanicsModelCohesive & model,
- Array<UInt> & elements,
- ElementType type,
- Real increment) {
+ Array<UInt> & elements, ElementType type,
+ Real increment) {
Mesh & mesh = model.getFEEngine().getMesh();
UInt nb_element = elements.size();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
update.clear();
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connectivity(elements(el), n);
if (!update(node)) {
- displacement(node, 0) += increment;
- // displacement(node, 1) += increment;
- update(node) = true;
+ displacement(node, 0) += increment;
+ // displacement(node, 1) += increment;
+ update(node) = true;
}
}
}
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/test_cohesive_friction.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/test_cohesive_friction.cc
index 2888a6511..3b39dcfbb 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/test_cohesive_friction.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/test_cohesive_friction.cc
@@ -1,237 +1,235 @@
/**
* @file test_cohesive_friction.cc
*
* @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date Wed Jan 13 11:56:18 2016
*
* @brief testing the correct behavior of the friction law included in
* the cohesive linear law, in implicit
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
#include <cmath>
-#include <iostream>
#include <fstream>
-#include <time.h>
-#include <string>
#include <iomanip>
+#include <iostream>
+#include <string>
+#include <time.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
Math::setTolerance(1.e-15);
UInt spatial_dimension = 2;
const ElementType type = _cohesive_2d_4;
Mesh mesh(spatial_dimension);
mesh.read("mesh_cohesive_friction.msh");
-
+
// Create the model
SolidMechanicsModelCohesive model(mesh);
// Model initialization
model.initFull(SolidMechanicsModelCohesiveOptions(_static, true));
// CohesiveElementInserter inserter(mesh);
model.limitInsertion(_y, -0.001, 0.001);
model.updateAutomaticInsertion();
Real eps = 1e-10;
Array<Real> & pos = mesh.getNodes();
Array<Real> & disp = model.getDisplacement();
Array<bool> & boun = model.getBlockedDOFs();
const Array<Real> & residual = model.getInternalForce();
- Array<Real> & cohe_opening = const_cast<Array<Real> &>(model.getMaterial("interface").getInternal<Real>("opening")(type));
- Array<Real> & friction_force = const_cast<Array<Real> &>(model.getMaterial("interface").getInternal<Real>("friction_force")(type));
+ Array<Real> & cohe_opening = const_cast<Array<Real> &>(
+ model.getMaterial("interface").getInternal<Real>("opening")(type));
+ Array<Real> & friction_force = const_cast<Array<Real> &>(
+ model.getMaterial("interface").getInternal<Real>("friction_force")(type));
// Boundary conditions
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- if(pos(i,1) < -0.49 || pos(i,1) > 0.49){
- boun(i,0) = true;
- boun(i,1) = true;
+ if (pos(i, 1) < -0.49 || pos(i, 1) > 0.49) {
+ boun(i, 0) = true;
+ boun(i, 1) = true;
}
}
bool passed = true;
Real tolerance = 1e-13;
Real error;
bool load_reduction = false;
Real tol_increase_factor = 1e5;
Real increment = 1.0e-4;
model.synchronizeBoundaries();
model.updateResidual();
/* -------------------------------------------- */
/* LOADING PHASE to introduce cohesive elements */
/* -------------------------------------------- */
- for (UInt nstep = 0; nstep < 100; ++nstep){
+ for (UInt nstep = 0; nstep < 100; ++nstep) {
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (pos(n,1) > 0.49)
- disp(n,1) += increment;
+ if (pos(n, 1) > 0.49)
+ disp(n, 1) += increment;
}
- model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(
+ tolerance, error, 25, load_reduction, tol_increase_factor);
- if (error > tolerance){
+ if (error > tolerance) {
AKANTU_ERROR("Convergence not reached in the mode I loading phase");
passed = false;
}
-
}
/* --------------------------------------------------------- */
/* UNLOADING PHASE to bring cohesive elements in compression */
/* --------------------------------------------------------- */
- for (UInt nstep = 0; nstep < 110; ++nstep){
+ for (UInt nstep = 0; nstep < 110; ++nstep) {
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (pos(n,1) > 0.49)
- disp(n,1) -= increment;
+ if (pos(n, 1) > 0.49)
+ disp(n, 1) -= increment;
}
- model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(
+ tolerance, error, 25, load_reduction, tol_increase_factor);
- if (error > tolerance){
+ if (error > tolerance) {
AKANTU_ERROR("Convergence not reached in the mode I unloading phase");
passed = false;
}
-
}
-
/* -------------------------------------------------- */
/* SHEAR PHASE - displacement towards right */
/* -------------------------------------------------- */
increment *= 2;
- for (UInt nstep = 0; nstep < 30; ++nstep){
+ for (UInt nstep = 0; nstep < 30; ++nstep) {
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (pos(n,1) > 0.49)
- disp(n,0) += increment;
+ if (pos(n, 1) > 0.49)
+ disp(n, 0) += increment;
}
- model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(
+ tolerance, error, 25, load_reduction, tol_increase_factor);
- if (error > tolerance){
+ if (error > tolerance) {
AKANTU_ERROR("Convergence not reached in the shear loading phase");
passed = false;
}
-
}
/* ---------------------------------------------------*/
/* Check the horizontal component of the reaction */
/* ---------------------------------------------------*/
// Friction + mode II cohesive behavior
Real reac_X = 0.;
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- if (pos(i,1) > 0.49)
- reac_X += residual(i,0);
+ if (pos(i, 1) > 0.49)
+ reac_X += residual(i, 0);
}
if (std::abs(reac_X - (-13.987451183762181)) > eps)
passed = false;
// Only friction
- Real friction = friction_force(0,0) + friction_force(1,0);
+ Real friction = friction_force(0, 0) + friction_force(1, 0);
if (std::abs(friction - (-12.517967866999832)) > eps)
passed = false;
-
/* -------------------------------------------------- */
/* SHEAR PHASE - displacement back to zero */
/* -------------------------------------------------- */
- for (UInt nstep = 0; nstep < 30; ++nstep){
+ for (UInt nstep = 0; nstep < 30; ++nstep) {
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (pos(n,1) > 0.49)
- disp(n,0) -= increment;
+ if (pos(n, 1) > 0.49)
+ disp(n, 0) -= increment;
}
- model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(
+ tolerance, error, 25, load_reduction, tol_increase_factor);
- if (error > tolerance){
+ if (error > tolerance) {
AKANTU_ERROR("Convergence not reached in the shear unloading phase");
passed = false;
}
-
}
-
/* ------------------------------------------------------- */
/* Check the horizontal component of the reaction and */
/* the residual relative sliding in the cohesive elements */
/* ------------------------------------------------------- */
// Friction + mode II cohesive behavior
reac_X = 0.;
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- if (pos(i,1) > 0.49)
- reac_X += residual(i,0);
+ if (pos(i, 1) > 0.49)
+ reac_X += residual(i, 0);
}
if (std::abs(reac_X - 12.400313187122208) > eps)
passed = false;
// Only friction
friction = 0.;
- friction = friction_force(0,0) + friction_force(1,0);
+ friction = friction_force(0, 0) + friction_force(1, 0);
if (std::abs(friction - 12.523300983293165) > eps)
passed = false;
// Residual sliding
Real sliding[2];
- sliding[0] = cohe_opening(0,0);
- sliding[1] = cohe_opening(1,0);
+ sliding[0] = cohe_opening(0, 0);
+ sliding[1] = cohe_opening(1, 0);
if (std::abs(sliding[0] - (-0.00044246686809147357)) > eps)
passed = false;
-
if (passed)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_fixture.hh b/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_fixture.hh
index 335896535..d51604220 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_fixture.hh
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_fixture.hh
@@ -1,304 +1,306 @@
/**
* @file test_material_cohesive_fixture.hh
*
* @author Nicolas Richart
*
* @date creation Tue Feb 20 2018
*
* @brief Test the traction separations laws for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
#include "test_gtest_utils.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
#include <gtest/gtest.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
//#define debug_
/* -------------------------------------------------------------------------- */
template <template <UInt> class Mat, typename dim_>
class TestMaterialCohesiveFixture : public ::testing::Test {
public:
static constexpr UInt dim = dim_::value;
using Material = Mat<dim>;
void SetUp() override {
mesh = std::make_unique<Mesh>(dim);
model = std::make_unique<SolidMechanicsModelCohesive>(*mesh);
material = std::make_unique<Material>(*model);
material->SetUps();
openings = std::make_unique<Array<Real>>(0, dim);
tractions = std::make_unique<Array<Real>>(0, dim);
reset();
gen.seed(::testing::GTEST_FLAG(random_seed));
normal = getRandomNormal();
tangents = getRandomTangents();
}
void TearDown() override {
material.reset(nullptr);
model.reset(nullptr);
mesh.reset(nullptr);
openings.reset(nullptr);
tractions.reset(nullptr);
}
void reset() {
openings->resize(1, 0.);
tractions->resize(1, 0.);
}
/* ------------------------------------------------------------------------ */
void addOpening(const Vector<Real> & direction, Real start, Real stop,
UInt nb_steps) {
for (auto s : arange(nb_steps)) {
- auto opening = direction * (start + (stop - start) / Real(nb_steps) * Real(s+1));
+ auto opening =
+ direction * (start + (stop - start) / Real(nb_steps) * Real(s + 1));
openings->push_back(opening);
}
tractions->resize(openings->size());
}
/* ------------------------------------------------------------------------ */
Vector<Real> getRandomVector() {
std::uniform_real_distribution<Real> dis;
Vector<Real> vector(dim);
for (auto s : arange(dim))
vector(s) = dis(gen);
return vector;
}
Vector<Real> getRandomNormal() {
auto normal = getRandomVector();
normal.normalize();
#if defined(debug_)
normal.set(0.);
normal(0) = 1.;
#endif
return normal;
}
Matrix<Real> getRandomTangents() {
auto dim = normal.size();
Matrix<Real> tangent(dim, dim - 1);
if (dim == 2) {
Math::normal2(normal.storage(), tangent(0).storage());
}
if (dim == 3) {
auto v = getRandomVector();
tangent(0) = (v - v.dot(normal) * normal).normalize();
Math::normal3(normal.storage(), tangent(0).storage(),
tangent(1).storage());
}
#if defined(debug_)
if (dim == 2)
tangent(0) = Vector<Real>{0., 1};
if (dim == 3)
- tangent = Matrix<Real>{{0., 0.}, {1., 0.}, { 0., 1. }};
+ tangent = Matrix<Real>{{0., 0.}, {1., 0.}, {0., 1.}};
#endif
return tangent;
}
/* ------------------------------------------------------------------------ */
void output_csv() {
const ::testing::TestInfo * const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
std::ofstream cout(std::string(test_info->name()) + ".csv");
auto print_vect_name = [&](auto name) {
for (auto s : arange(dim)) {
if (s != 0) {
cout << ", ";
}
cout << name << "_" << s;
}
};
auto print_vect = [&](const auto & vect) {
cout << vect.dot(normal);
- if(dim > 1)
+ if (dim > 1)
cout << ", " << vect.dot(tangents(0));
- if(dim > 2)
+ if (dim > 2)
cout << ", " << vect.dot(tangents(1));
};
cout << "delta, ";
print_vect_name("opening");
cout << ", ";
print_vect_name("traction");
cout << std::endl;
for (auto && data : zip(make_view(*this->openings, this->dim),
make_view(*this->tractions, this->dim))) {
const auto & opening = std::get<0>(data);
auto & traction = std::get<1>(data);
- cout << this->material->delta(opening, normal) << ", ";
+ cout << this->material->delta(opening, normal) << ", ";
print_vect(opening);
cout << ", ";
print_vect(traction);
cout << std::endl;
}
}
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------ */
Real dissipated() {
Vector<Real> prev_opening(dim, 0.);
Vector<Real> prev_traction(dim, 0.);
Real etot = 0.;
Real erev = 0.;
for (auto && data : zip(make_view(*this->openings, this->dim),
make_view(*this->tractions, this->dim))) {
const auto & opening = std::get<0>(data);
const auto & traction = std::get<1>(data);
etot += (opening - prev_opening).dot(traction + prev_traction) / 2.;
erev = traction.dot(opening) / 2.;
prev_opening = opening;
prev_traction = traction;
}
return etot - erev;
}
/* ------------------------------------------------------------------------ */
void checkModeI(Real max_opening, Real expected_dissipated) {
this->material->insertion_stress_ = this->material->sigma_c_ * normal;
addOpening(normal, 0., max_opening, 100);
this->material->computeTractions(*openings, normal, *tractions);
for (auto && data : zip(make_view(*this->openings, this->dim),
make_view(*this->tractions, this->dim))) {
const auto & opening = std::get<0>(data);
auto & traction = std::get<1>(data);
auto T = traction.dot(normal);
EXPECT_NEAR(0, (traction - T * normal).norm(), 1e-9);
auto T_expected =
this->material->tractionModeI(opening, normal).dot(normal);
EXPECT_NEAR(T_expected, T, 1e-9);
}
EXPECT_NEAR(expected_dissipated, dissipated(), 1e-5);
this->output_csv();
}
/* ------------------------------------------------------------------------ */
void checkModeII(Real max_opening) {
if (this->dim == 1) {
SUCCEED();
return;
}
std::uniform_real_distribution<Real> dis;
auto direction = Vector<Real>(tangents(0));
auto alpha = dis(gen) + 0.1;
auto beta = dis(gen) + 0.2;
#ifndef debug_
- direction =
- alpha * Vector<Real>(tangents(0));
- if (dim > 2) direction += beta * Vector<Real>(tangents(1));
+ direction = alpha * Vector<Real>(tangents(0));
+ if (dim > 2)
+ direction += beta * Vector<Real>(tangents(1));
direction = direction.normalize();
#endif
this->material->insertion_stress_ = Vector<Real>(dim, 0.);
addOpening(direction, 0., max_opening, 100);
this->material->computeTractions(*openings, normal, *tractions);
for (auto && data : zip(make_view(*this->openings, this->dim),
make_view(*this->tractions, this->dim))) {
const auto & opening = std::get<0>(data);
const auto & traction = std::get<1>(data);
// In ModeII normal traction should be 0
ASSERT_NEAR(0, traction.dot(normal), 1e-9);
// Normal opening is null
ASSERT_NEAR(0, opening.dot(normal), 1e-16);
auto T = traction.dot(direction);
auto T_expected =
this->material->tractionModeII(opening, normal).dot(direction);
EXPECT_NEAR(T_expected, T, 1e-9);
}
- //EXPECT_NEAR(expected_dissipated, dissipated(), 1e-5);
+ // EXPECT_NEAR(expected_dissipated, dissipated(), 1e-5);
this->output_csv();
}
protected:
Vector<Real> normal;
Matrix<Real> tangents;
std::unique_ptr<Mesh> mesh;
std::unique_ptr<SolidMechanicsModelCohesive> model;
std::unique_ptr<Material> material;
std::unique_ptr<Array<Real>> openings;
std::unique_ptr<Array<Real>> tractions;
std::mt19937 gen;
};
template <template <UInt> class Mat, UInt dim>
struct TestMaterialCohesive : public Mat<dim> {
- TestMaterialCohesive(SolidMechanicsModel & model) : Mat<dim>(model, "test"), insertion_stress_(dim, 0.) {}
+ TestMaterialCohesive(SolidMechanicsModel & model)
+ : Mat<dim>(model, "test"), insertion_stress_(dim, 0.) {}
virtual void SetUp() {}
virtual void resetInternal() {}
void SetUps() {
this->initMaterial();
this->SetUp();
this->updateInternalParameters();
this->resetInternals();
}
void resetInternals() { this->resetInternal(); }
virtual void computeTractions(Array<Real> & /*openings*/,
const Vector<Real> & /*normal*/,
Array<Real> & /*tractions*/) {}
Vector<Real> insertion_stress_;
Real sigma_c_{0};
bool is_extrinsic{true};
};
template <template <UInt> class Mat, typename dim_>
constexpr UInt TestMaterialCohesiveFixture<Mat, dim_>::dim;
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc
index 247777c75..dda4c3f23 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc
@@ -1,181 +1,181 @@
/**
* @file test_material_cohesive_linear.cc
*
* @author Nicolas Richart
*
* @date creation Tue Feb 20 2018
*
* @brief Test material cohesive linear
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_material_cohesive_fixture.hh"
/* -------------------------------------------------------------------------- */
#include "material_cohesive_linear.hh"
/* -------------------------------------------------------------------------- */
template <UInt dim>
struct TestMaterialCohesiveLinear
: public TestMaterialCohesive<MaterialCohesiveLinear, dim> {
TestMaterialCohesiveLinear(SolidMechanicsModel & model)
: TestMaterialCohesive<MaterialCohesiveLinear, dim>(model) {}
void SetUp() override {
this->is_extrinsic = true;
this->beta = 2.;
this->kappa = 2;
this->G_c = 10.;
this->sigma_c_ = 1e6;
this->penalty = 1e11;
this->delta_c_ = 2. * this->G_c / this->sigma_c_;
}
void resetInternal() override {
normal_opening = Vector<Real>(dim, 0.);
tangential_opening = Vector<Real>(dim, 0.);
contact_traction = Vector<Real>(dim, 0.);
contact_opening = Vector<Real>(dim, 0.);
}
- void computeTractions(Array<Real> & openings,
- const Vector<Real> & normal,
+ void computeTractions(Array<Real> & openings, const Vector<Real> & normal,
Array<Real> & tractions) override {
for (auto && data :
zip(make_view(openings, dim), make_view(tractions, dim))) {
auto & opening = std::get<0>(data);
auto & traction = std::get<1>(data);
this->computeTractionOnQuad(
traction, opening, normal, delta_max, this->delta_c_,
this->insertion_stress_, this->sigma_c_, normal_opening,
tangential_opening, normal_opening_norm, tangential_opening_norm,
damage, penetration, contact_traction, contact_opening);
opening += contact_opening;
traction += contact_traction;
}
}
Real delta(const Vector<Real> & opening, const Vector<Real> & normal) {
auto beta = this->beta;
auto kappa = this->kappa;
auto normal_opening = opening.dot(normal) * normal;
auto tangential_opening = opening - normal_opening;
return std::sqrt(std::pow(normal_opening.norm(), 2) +
std::pow(tangential_opening.norm() * beta / kappa, 2));
}
Vector<Real> traction(const Vector<Real> & opening,
const Vector<Real> & normal) {
auto delta_c = this->delta_c_;
auto sigma_c = this->sigma_c_;
auto beta = this->beta;
auto kappa = this->kappa;
auto normal_opening = opening.dot(normal) * normal;
auto tangential_opening = opening - normal_opening;
auto delta_ = this->delta(opening, normal);
if (delta_ < 1e-16) {
return this->insertion_stress_;
}
- if (opening.dot(normal)/delta_c < -Math::getTolerance()) {
+ if (opening.dot(normal) / delta_c < -Math::getTolerance()) {
ADD_FAILURE() << "This is contact";
return Vector<Real>(dim, 0.);
}
auto T = sigma_c * (delta_c - delta_) / delta_c / delta_ *
(normal_opening + tangential_opening * beta * beta / kappa);
return T;
}
Vector<Real> tractionModeI(const Vector<Real> & opening,
const Vector<Real> & normal) {
return traction(opening, normal);
}
Vector<Real> tractionModeII(const Vector<Real> & opening,
const Vector<Real> & normal) {
return traction(opening, normal);
}
public:
Real delta_c_{0};
Real delta_max{0.};
Real normal_opening_norm{0};
Real tangential_opening_norm{0};
Real damage{0};
bool penetration{false};
Vector<Real> normal_opening;
Vector<Real> tangential_opening;
Vector<Real> contact_traction;
Vector<Real> contact_opening;
};
template <typename dim_>
using TestMaterialCohesiveLinearFixture =
TestMaterialCohesiveFixture<TestMaterialCohesiveLinear, dim_>;
using types = gtest_list_t<TestAllDimensions>;
TYPED_TEST_CASE(TestMaterialCohesiveLinearFixture, types);
TYPED_TEST(TestMaterialCohesiveLinearFixture, ModeI) {
this->checkModeI(this->material->delta_c_, this->material->get("G_c"));
}
TYPED_TEST(TestMaterialCohesiveLinearFixture, ModeII) {
this->checkModeII(this->material->delta_c_);
}
TYPED_TEST(TestMaterialCohesiveLinearFixture, Cycles) {
auto delta_c = this->material->delta_c_;
auto sigma_c = this->material->sigma_c_;
this->material->insertion_stress_ = this->normal * sigma_c;
this->addOpening(this->normal, 0, 0.1 * delta_c, 100);
this->addOpening(this->normal, 0.1 * delta_c, 0., 100);
this->addOpening(this->normal, 0., 0.5 * delta_c, 100);
this->addOpening(this->normal, 0.5 * delta_c, -1.e-5, 100);
this->addOpening(this->normal, -1.e-5, 0.9 * delta_c, 100);
this->addOpening(this->normal, 0.9 * delta_c, 0., 100);
this->addOpening(this->normal, 0., delta_c, 100);
- this->material->computeTractions(*this->openings, this->normal, *this->tractions);
+ this->material->computeTractions(*this->openings, this->normal,
+ *this->tractions);
Real penalty = this->material->get("penalty");
std::cout << penalty << std::endl;
Real G_c = this->material->get("G_c");
EXPECT_NEAR(G_c, this->dissipated(), 1e-3);
this->output_csv();
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc
index a9a04a914..19ff78392 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc
@@ -1,205 +1,198 @@
/**
* @file test_cohesive_facet_stress_synchronizer.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief Test for facet stress synchronizer
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include <limits>
#include <fstream>
#include <iostream>
-
+#include <limits>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
Real function(Real constant, Real x, Real y, Real z) {
return constant + 2. * x + 3. * y + 4 * z;
}
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 3;
ElementType type = _tetrahedron_10;
ElementType type_facet = Mesh::getFacetType(type);
Math::setTolerance(1.e-11);
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
// Read the mesh
mesh.read("tetrahedron.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModelCohesive model(mesh);
model.initParallel(partition, NULL, true);
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
Array<Real> & position = mesh.getNodes();
/* ------------------------------------------------------------------------ */
/* Facet part */
/* ------------------------------------------------------------------------ */
/// compute quadrature points positions on facets
const Mesh & mesh_facets = model.getMeshFacets();
UInt nb_facet = mesh_facets.getNbElement(type_facet);
- UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
+ UInt nb_quad_per_facet =
+ model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
- model.getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position,
- quad_facets,
- spatial_dimension,
- type_facet);
+ model.getFEEngine("FacetsFEEngine")
+ .interpolateOnIntegrationPoints(position, quad_facets, spatial_dimension,
+ type_facet);
/* ------------------------------------------------------------------------ */
/* End of facet part */
/* ------------------------------------------------------------------------ */
-
/// compute quadrature points position of the elements
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
UInt nb_element = mesh.getNbElement(type);
UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
-
- model.getFEEngine().interpolateOnIntegrationPoints(position,
- quad_elements,
- spatial_dimension,
- type);
+ model.getFEEngine().interpolateOnIntegrationPoints(position, quad_elements,
+ spatial_dimension, type);
/// assign some values to stresses
- Array<Real> & stress
- = const_cast<Array<Real>&>(model.getMaterial(0).getStress(type));
+ Array<Real> & stress =
+ const_cast<Array<Real> &>(model.getMaterial(0).getStress(type));
- Array<Real>::iterator<Matrix<Real> > stress_it
- = stress.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::iterator<Matrix<Real>> stress_it =
+ stress.begin(spatial_dimension, spatial_dimension);
for (UInt q = 0; q < nb_tot_quad_el; ++q, ++stress_it) {
/// compute values
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = i; j < spatial_dimension; ++j) {
- UInt index = i * spatial_dimension + j;
- (*stress_it)(i, j) = function(index,
- quad_elements(q, 0),
- quad_elements(q, 1),
- quad_elements(q, 2));
+ UInt index = i * spatial_dimension + j;
+ (*stress_it)(i, j) = function(index, quad_elements(q, 0),
+ quad_elements(q, 1), quad_elements(q, 2));
}
}
/// fill symmetrical part
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < i; ++j) {
- (*stress_it)(i, j) = (*stress_it)(j, i);
+ (*stress_it)(i, j) = (*stress_it)(j, i);
}
}
// stress_it->clear();
// for (UInt i = 0; i < spatial_dimension; ++i)
// (*stress_it)(i, i) = sigma_c * 5;
}
-
/// compute and communicate stress on facets
model.checkCohesiveStress();
/* ------------------------------------------------------------------------ */
/* Check facet stress */
/* ------------------------------------------------------------------------ */
const Array<Real> & facet_stress = model.getStressOnFacets(type_facet);
- const Array<bool> & facet_check
- = model.getElementInserter().getCheckFacets(type_facet);
- const Array<std::vector<Element> > & elements_to_facet
- = model.getMeshFacets().getElementToSubelement(type_facet);
+ const Array<bool> & facet_check =
+ model.getElementInserter().getCheckFacets(type_facet);
+ const Array<std::vector<Element>> & elements_to_facet =
+ model.getMeshFacets().getElementToSubelement(type_facet);
- Array<Real>::iterator<Vector<Real> > quad_facet_it
- = quad_facets.begin(spatial_dimension);
- Array<Real>::const_iterator<Matrix<Real> > facet_stress_it
- = facet_stress.begin(spatial_dimension, spatial_dimension * 2);
+ Array<Real>::iterator<Vector<Real>> quad_facet_it =
+ quad_facets.begin(spatial_dimension);
+ Array<Real>::const_iterator<Matrix<Real>> facet_stress_it =
+ facet_stress.begin(spatial_dimension, spatial_dimension * 2);
Matrix<Real> current_stress(spatial_dimension, spatial_dimension);
for (UInt f = 0; f < nb_facet; ++f) {
- if (!facet_check(f) ||
- (elements_to_facet(f)[0].ghost_type == _not_ghost &&
- elements_to_facet(f)[1].ghost_type == _not_ghost)) {
+ if (!facet_check(f) || (elements_to_facet(f)[0].ghost_type == _not_ghost &&
+ elements_to_facet(f)[1].ghost_type == _not_ghost)) {
quad_facet_it += nb_quad_per_facet;
facet_stress_it += nb_quad_per_facet;
continue;
}
- for (UInt q = 0; q < nb_quad_per_facet; ++q, ++quad_facet_it, ++facet_stress_it) {
+ for (UInt q = 0; q < nb_quad_per_facet;
+ ++q, ++quad_facet_it, ++facet_stress_it) {
/// compute current_stress
for (UInt i = 0; i < spatial_dimension; ++i) {
- for (UInt j = i; j < spatial_dimension; ++j) {
- UInt index = i * spatial_dimension + j;
- current_stress(i, j) = function(index,
- (*quad_facet_it)(0),
- (*quad_facet_it)(1),
- (*quad_facet_it)(2));
- }
+ for (UInt j = i; j < spatial_dimension; ++j) {
+ UInt index = i * spatial_dimension + j;
+ current_stress(i, j) =
+ function(index, (*quad_facet_it)(0), (*quad_facet_it)(1),
+ (*quad_facet_it)(2));
+ }
}
/// fill symmetrical part
for (UInt i = 0; i < spatial_dimension; ++i) {
- for (UInt j = 0; j < i; ++j) {
- current_stress(i, j) = current_stress(j, i);
- }
+ for (UInt j = 0; j < i; ++j) {
+ current_stress(i, j) = current_stress(j, i);
+ }
}
/// compare it to interpolated one
for (UInt s = 0; s < 2; ++s) {
- Matrix<Real> stress_to_check(facet_stress_it->storage()
- + s * spatial_dimension * spatial_dimension,
- spatial_dimension,
- spatial_dimension);
-
-
- for (UInt i = 0; i < spatial_dimension; ++i) {
- for (UInt j = 0; j < spatial_dimension; ++j) {
- if (!Math::are_float_equal(stress_to_check(i, j), current_stress(i, j))) {
- std::cout << "Stress doesn't match" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
- }
- }
+ Matrix<Real> stress_to_check(facet_stress_it->storage() +
+ s * spatial_dimension *
+ spatial_dimension,
+ spatial_dimension, spatial_dimension);
+
+ for (UInt i = 0; i < spatial_dimension; ++i) {
+ for (UInt j = 0; j < spatial_dimension; ++j) {
+ if (!Math::are_float_equal(stress_to_check(i, j),
+ current_stress(i, j))) {
+ std::cout << "Stress doesn't match" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
+ }
+ }
+ }
}
}
}
finalize();
if (prank == 0)
- std::cout << "OK: test_cohesive_facet_stress_synchronizer passed!" << std::endl;
+ std::cout << "OK: test_cohesive_facet_stress_synchronizer passed!"
+ << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
index f6e248d39..9108af13a 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
@@ -1,432 +1,441 @@
/**
* @file test_cohesive_parallel_buildfragments.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief Test to build fragments in parallel
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include <limits>
-#include <fstream>
-#include <iostream>
#include <algorithm>
+#include <fstream>
#include <functional>
+#include <iostream>
+#include <limits>
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_cohesive.hh"
-#include "material_cohesive.hh"
#include "fragment_manager.hh"
+#include "material_cohesive.hh"
+#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
void verticalInsertionLimit(SolidMechanicsModelCohesive &);
void displaceElements(SolidMechanicsModelCohesive &, const Real, const Real);
bool isInertiaEqual(const Vector<Real> &, const Vector<Real> &);
void rotateArray(Array<Real> & array, Real angle);
UInt getNbBigFragments(FragmentManager &, UInt);
const UInt spatial_dimension = 3;
const UInt total_nb_fragment = 4;
const Real rotation_angle = M_PI / 4.;
const Real global_tolerance = 1.e-9;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
Math::setTolerance(global_tolerance);
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
// Read the mesh
mesh.read("mesh.msh");
/// partition the mesh
MeshUtils::purifyMesh(mesh);
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModelCohesive model(mesh);
model.initParallel(partition, NULL, true);
delete partition;
/// model initialization
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
mesh.computeBoundingBox();
Real L = mesh.getUpperBounds()(0) - mesh.getLowerBounds()(0);
Real h = mesh.getUpperBounds()(1) - mesh.getLowerBounds()(1);
Real rho = model.getMaterial("bulk").getParam<Real>("rho");
Real theoretical_mass = L * h * h * rho;
Real frag_theo_mass = theoretical_mass / total_nb_fragment;
- UInt nb_element = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_regular);
+ UInt nb_element =
+ mesh.getNbElement(spatial_dimension, _not_ghost, _ek_regular);
comm.allReduce(&nb_element, 1, _so_sum);
UInt nb_element_per_fragment = nb_element / total_nb_fragment;
FragmentManager fragment_manager(model);
fragment_manager.computeAllData();
getNbBigFragments(fragment_manager, nb_element_per_fragment + 1);
model.setBaseName("extrinsic");
model.addDumpFieldVector("displacement");
model.addDumpField("velocity");
model.addDumpField("stress");
model.addDumpField("partitions");
model.addDumpField("fragments");
model.addDumpField("fragments mass");
model.addDumpField("moments of inertia");
model.addDumpField("elements per fragment");
model.dump();
model.setBaseNameToDumper("cohesive elements", "cohesive_elements_test");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump("cohesive elements");
/// set check facets
verticalInsertionLimit(model);
model.assembleMassLumped();
model.synchronizeBoundaries();
/// impose initial displacement
Array<Real> & displacement = model.getDisplacement();
Array<Real> & velocity = model.getVelocity();
const Array<Real> & position = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
for (UInt n = 0; n < nb_nodes; ++n) {
displacement(n, 0) = position(n, 0) * 0.1;
velocity(n, 0) = position(n, 0);
}
rotateArray(mesh.getNodes(), rotation_angle);
// rotateArray(displacement, rotation_angle);
// rotateArray(velocity, rotation_angle);
model.updateResidual();
model.checkCohesiveStress();
model.dump();
model.dump("cohesive elements");
const Array<Real> & fragment_mass = fragment_manager.getMass();
const Array<Real> & fragment_center = fragment_manager.getCenterOfMass();
Real el_size = L / total_nb_fragment;
- Real lim = -L/2 + el_size * 0.99;
+ Real lim = -L / 2 + el_size * 0.99;
/// define theoretical inertia moments
Vector<Real> small_frag_inertia(spatial_dimension);
- small_frag_inertia(0) = frag_theo_mass * (h*h + h*h) / 12.;
- small_frag_inertia(1) = frag_theo_mass * (el_size*el_size + h*h) / 12.;
- small_frag_inertia(2) = frag_theo_mass * (el_size*el_size + h*h) / 12.;
+ small_frag_inertia(0) = frag_theo_mass * (h * h + h * h) / 12.;
+ small_frag_inertia(1) = frag_theo_mass * (el_size * el_size + h * h) / 12.;
+ small_frag_inertia(2) = frag_theo_mass * (el_size * el_size + h * h) / 12.;
std::sort(small_frag_inertia.storage(),
- small_frag_inertia.storage() + spatial_dimension,
- std::greater<Real>());
+ small_frag_inertia.storage() + spatial_dimension,
+ std::greater<Real>());
const Array<Real> & inertia_moments = fragment_manager.getMomentsOfInertia();
- Array<Real>::const_iterator< Vector<Real> > inertia_moments_begin
- = inertia_moments.begin(spatial_dimension);
+ Array<Real>::const_iterator<Vector<Real>> inertia_moments_begin =
+ inertia_moments.begin(spatial_dimension);
/// displace one fragment each time
for (UInt frag = 1; frag <= total_nb_fragment; ++frag) {
if (prank == 0)
std::cout << "Generating fragment: " << frag << std::endl;
fragment_manager.computeAllData();
/// check number of big fragments
- UInt nb_big_fragment = getNbBigFragments(fragment_manager,
- nb_element_per_fragment + 1);
+ UInt nb_big_fragment =
+ getNbBigFragments(fragment_manager, nb_element_per_fragment + 1);
model.dump();
model.dump("cohesive elements");
-
if (frag < total_nb_fragment) {
if (nb_big_fragment != 1) {
- AKANTU_ERROR("The number of big fragments is wrong: " << nb_big_fragment);
- return EXIT_FAILURE;
+ AKANTU_ERROR(
+ "The number of big fragments is wrong: " << nb_big_fragment);
+ return EXIT_FAILURE;
}
- }
- else {
+ } else {
if (nb_big_fragment != 0) {
- AKANTU_ERROR("The number of big fragments is wrong: " << nb_big_fragment);
- return EXIT_FAILURE;
+ AKANTU_ERROR(
+ "The number of big fragments is wrong: " << nb_big_fragment);
+ return EXIT_FAILURE;
}
}
/// check number of fragments
UInt nb_fragment_num = fragment_manager.getNbFragment();
if (nb_fragment_num != frag) {
- AKANTU_ERROR("The number of fragments is wrong! Numerical: " << nb_fragment_num << " Theoretical: " << frag);
+ AKANTU_ERROR("The number of fragments is wrong! Numerical: "
+ << nb_fragment_num << " Theoretical: " << frag);
return EXIT_FAILURE;
}
/// check mass computation
if (frag < total_nb_fragment) {
Real total_mass = 0.;
UInt small_fragments = 0;
for (UInt f = 0; f < nb_fragment_num; ++f) {
- const Vector<Real> & current_inertia = inertia_moments_begin[f];
-
- if (Math::are_float_equal(fragment_mass(f, 0), frag_theo_mass)) {
-
- /// check center of mass
- if (fragment_center(f, 0) > (L * frag / total_nb_fragment - L / 2)) {
- AKANTU_ERROR("Fragment center is wrong!");
- return EXIT_FAILURE;
- }
-
- /// check moment of inertia
- if (!isInertiaEqual(current_inertia, small_frag_inertia)) {
- AKANTU_ERROR("Inertia moments are wrong");
- return EXIT_FAILURE;
- }
-
- ++small_fragments;
- total_mass += frag_theo_mass;
- }
- else {
- /// check the moment of inertia for the biggest fragment
- Real big_frag_mass = frag_theo_mass * (total_nb_fragment - frag + 1);
- Real big_frag_size = el_size * (total_nb_fragment - frag + 1);
-
- Vector<Real> big_frag_inertia(spatial_dimension);
- big_frag_inertia(0) = big_frag_mass * (h*h + h*h) / 12.;
- big_frag_inertia(1)
- = big_frag_mass * (big_frag_size*big_frag_size + h*h) / 12.;
- big_frag_inertia(2)
- = big_frag_mass * (big_frag_size*big_frag_size + h*h) / 12.;
-
- std::sort(big_frag_inertia.storage(),
- big_frag_inertia.storage() + spatial_dimension,
- std::greater<Real>());
-
- if (!isInertiaEqual(current_inertia, big_frag_inertia)) {
- AKANTU_ERROR("Inertia moments are wrong");
- return EXIT_FAILURE;
- }
-
- }
+ const Vector<Real> & current_inertia = inertia_moments_begin[f];
+
+ if (Math::are_float_equal(fragment_mass(f, 0), frag_theo_mass)) {
+
+ /// check center of mass
+ if (fragment_center(f, 0) > (L * frag / total_nb_fragment - L / 2)) {
+ AKANTU_ERROR("Fragment center is wrong!");
+ return EXIT_FAILURE;
+ }
+
+ /// check moment of inertia
+ if (!isInertiaEqual(current_inertia, small_frag_inertia)) {
+ AKANTU_ERROR("Inertia moments are wrong");
+ return EXIT_FAILURE;
+ }
+
+ ++small_fragments;
+ total_mass += frag_theo_mass;
+ } else {
+ /// check the moment of inertia for the biggest fragment
+ Real big_frag_mass = frag_theo_mass * (total_nb_fragment - frag + 1);
+ Real big_frag_size = el_size * (total_nb_fragment - frag + 1);
+
+ Vector<Real> big_frag_inertia(spatial_dimension);
+ big_frag_inertia(0) = big_frag_mass * (h * h + h * h) / 12.;
+ big_frag_inertia(1) =
+ big_frag_mass * (big_frag_size * big_frag_size + h * h) / 12.;
+ big_frag_inertia(2) =
+ big_frag_mass * (big_frag_size * big_frag_size + h * h) / 12.;
+
+ std::sort(big_frag_inertia.storage(),
+ big_frag_inertia.storage() + spatial_dimension,
+ std::greater<Real>());
+
+ if (!isInertiaEqual(current_inertia, big_frag_inertia)) {
+ AKANTU_ERROR("Inertia moments are wrong");
+ return EXIT_FAILURE;
+ }
+ }
}
if (small_fragments != nb_fragment_num - 1) {
- AKANTU_ERROR("The number of small fragments is wrong!");
- return EXIT_FAILURE;
+ AKANTU_ERROR("The number of small fragments is wrong!");
+ return EXIT_FAILURE;
}
if (!Math::are_float_equal(total_mass,
- small_fragments * frag_theo_mass)) {
- AKANTU_ERROR("The mass of small fragments is wrong!");
- return EXIT_FAILURE;
+ small_fragments * frag_theo_mass)) {
+ AKANTU_ERROR("The mass of small fragments is wrong!");
+ return EXIT_FAILURE;
}
}
-
/// displace fragments
rotateArray(mesh.getNodes(), -rotation_angle);
// rotateArray(displacement, -rotation_angle);
displaceElements(model, lim, el_size * 2);
rotateArray(mesh.getNodes(), rotation_angle);
// rotateArray(displacement, rotation_angle);
model.updateResidual();
lim += el_size;
}
model.dump();
model.dump("cohesive elements");
/// check centers
const Array<Real> & fragment_velocity = fragment_manager.getVelocity();
Real initial_position = -L / 2. + el_size / 2.;
for (UInt frag = 0; frag < total_nb_fragment; ++frag) {
Real theoretical_center = initial_position + el_size * frag;
UInt f_index = 0;
- while (f_index < total_nb_fragment &&
- !Math::are_float_equal(fragment_center(f_index, 0), theoretical_center))
+ while (
+ f_index < total_nb_fragment &&
+ !Math::are_float_equal(fragment_center(f_index, 0), theoretical_center))
++f_index;
if (f_index == total_nb_fragment) {
AKANTU_ERROR("The fragments' center is wrong!");
return EXIT_FAILURE;
}
f_index = 0;
while (f_index < total_nb_fragment &&
- !Math::are_float_equal(fragment_velocity(f_index, 0),
- theoretical_center))
+ !Math::are_float_equal(fragment_velocity(f_index, 0),
+ theoretical_center))
++f_index;
if (f_index == total_nb_fragment) {
AKANTU_ERROR("The fragments' velocity is wrong!");
return EXIT_FAILURE;
}
}
finalize();
if (prank == 0)
std::cout << "OK: test_cohesive_buildfragments was passed!" << std::endl;
return EXIT_SUCCESS;
}
void verticalInsertionLimit(SolidMechanicsModelCohesive & model) {
UInt spatial_dimension = model.getSpatialDimension();
const Mesh & mesh_facets = model.getMeshFacets();
const Array<Real> & position = mesh_facets.getNodes();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
- Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
- for(; it != end; ++it) {
+ Mesh::type_iterator it =
+ mesh_facets.firstType(spatial_dimension - 1, ghost_type);
+ Mesh::type_iterator end =
+ mesh_facets.lastType(spatial_dimension - 1, ghost_type);
+ for (; it != end; ++it) {
ElementType type = *it;
- Array<bool> & check_facets
- = model.getElementInserter().getCheckFacets(type, ghost_type);
+ Array<bool> & check_facets =
+ model.getElementInserter().getCheckFacets(type, ghost_type);
- const Array<UInt> & connectivity = mesh_facets.getConnectivity(type, ghost_type);
+ const Array<UInt> & connectivity =
+ mesh_facets.getConnectivity(type, ghost_type);
UInt nb_nodes_per_facet = connectivity.getNbComponent();
for (UInt f = 0; f < check_facets.getSize(); ++f) {
- if (!check_facets(f)) continue;
+ if (!check_facets(f))
+ continue;
- UInt nb_aligned_nodes = 1;
- Real first_node_pos = position(connectivity(f, 0), 0);
+ UInt nb_aligned_nodes = 1;
+ Real first_node_pos = position(connectivity(f, 0), 0);
- for (; nb_aligned_nodes < nb_nodes_per_facet; ++nb_aligned_nodes) {
- Real other_node_pos = position(connectivity(f, nb_aligned_nodes), 0);
+ for (; nb_aligned_nodes < nb_nodes_per_facet; ++nb_aligned_nodes) {
+ Real other_node_pos = position(connectivity(f, nb_aligned_nodes), 0);
- if (! Math::are_float_equal(first_node_pos, other_node_pos))
- break;
- }
+ if (!Math::are_float_equal(first_node_pos, other_node_pos))
+ break;
+ }
- if (nb_aligned_nodes != nb_nodes_per_facet) {
- check_facets(f) = false;
- }
+ if (nb_aligned_nodes != nb_nodes_per_facet) {
+ check_facets(f) = false;
+ }
}
}
}
}
-void displaceElements(SolidMechanicsModelCohesive & model,
- const Real lim,
- const Real amount) {
+void displaceElements(SolidMechanicsModelCohesive & model, const Real lim,
+ const Real amount) {
UInt spatial_dimension = model.getSpatialDimension();
Array<Real> & displacement = model.getDisplacement();
Mesh & mesh = model.getMesh();
UInt nb_nodes = mesh.getNbNodes();
Array<bool> displaced(nb_nodes);
displaced.clear();
Vector<Real> barycenter(spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
ElementType type = *it;
const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
UInt nb_element = connectivity.getSize();
UInt nb_nodes_per_element = connectivity.getNbComponent();
- Array<UInt>::const_vector_iterator conn_el
- = connectivity.begin(nb_nodes_per_element);
+ Array<UInt>::const_vector_iterator conn_el =
+ connectivity.begin(nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el) {
- mesh.getBarycenter(el, type, barycenter.storage(), ghost_type);
-
- if (barycenter(0) < lim) {
- const Vector<UInt> & conn = conn_el[el];
-
- for (UInt n = 0; n < nb_nodes_per_element; ++n) {
- UInt node = conn(n);
- if (!displaced(node)) {
- displacement(node, 0) -= amount;
- displaced(node) = true;
- }
- }
- }
+ mesh.getBarycenter(el, type, barycenter.storage(), ghost_type);
+
+ if (barycenter(0) < lim) {
+ const Vector<UInt> & conn = conn_el[el];
+
+ for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+ UInt node = conn(n);
+ if (!displaced(node)) {
+ displacement(node, 0) -= amount;
+ displaced(node) = true;
+ }
+ }
+ }
}
}
}
}
bool isInertiaEqual(const Vector<Real> & a, const Vector<Real> & b) {
UInt nb_terms = a.size();
UInt equal_terms = 0;
while (equal_terms < nb_terms &&
- std::abs(a(equal_terms) - b(equal_terms)) / a(equal_terms) < Math::getTolerance())
+ std::abs(a(equal_terms) - b(equal_terms)) / a(equal_terms) <
+ Math::getTolerance())
++equal_terms;
return equal_terms == nb_terms;
}
void rotateArray(Array<Real> & array, Real angle) {
UInt spatial_dimension = array.getNbComponent();
- Real rotation_values[] = {std::cos(angle), std::sin(angle), 0,
- -std::sin(angle), std::cos(angle), 0,
- 0, 0, 1};
+ Real rotation_values[] = {std::cos(angle),
+ std::sin(angle),
+ 0,
+ -std::sin(angle),
+ std::cos(angle),
+ 0,
+ 0,
+ 0,
+ 1};
Matrix<Real> rotation(rotation_values, spatial_dimension, spatial_dimension);
RVector displaced_node(spatial_dimension);
auto node_it = array.begin(spatial_dimension);
auto node_end = array.end(spatial_dimension);
for (; node_it != node_end; ++node_it) {
displaced_node.mul<false>(rotation, *node_it);
*node_it = displaced_node;
}
}
UInt getNbBigFragments(FragmentManager & fragment_manager,
- UInt minimum_nb_elements) {
+ UInt minimum_nb_elements) {
fragment_manager.computeNbElementsPerFragment();
- const Array<UInt> & nb_elements_per_fragment
- = fragment_manager.getNbElementsPerFragment();
+ const Array<UInt> & nb_elements_per_fragment =
+ fragment_manager.getNbElementsPerFragment();
UInt nb_fragment = fragment_manager.getNbFragment();
UInt nb_big_fragment = 0;
for (UInt frag = 0; frag < nb_fragment; ++frag) {
if (nb_elements_per_fragment(frag) >= minimum_nb_elements) {
++nb_big_fragment;
}
}
return nb_big_fragment;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc
index ece21b065..463e02267 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc
@@ -1,172 +1,172 @@
/**
* @file test_cohesive_parallel_extrinsic.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief parallel test for cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_cohesive.hh"
#include "dumper_paraview.hh"
+#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt max_steps = 500;
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
// Read the mesh
mesh.read("mesh.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
// debug::setDebugLevel(dblDump);
partition->partitionate(psize);
// debug::setDebugLevel(dblWarning);
}
SolidMechanicsModelCohesive model(mesh);
model.initParallel(partition, NULL, true);
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// debug::setDebugLevel(dblWarning);
-
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
model.limitInsertion(_y, -0.30, -0.20);
model.updateAutomaticInsertion();
// debug::setDebugLevel(dblDump);
// std::cout << mesh_facets << std::endl;
// debug::setDebugLevel(dblWarning);
- Real time_step = model.getStableTimeStep()*0.1;
+ Real time_step = model.getStableTimeStep() * 0.1;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
-
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
/// initial conditions
Real loading_rate = 0.5;
Real disp_update = loading_rate * time_step;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
}
model.synchronizeBoundaries();
model.updateResidual();
model.setBaseName("extrinsic_parallel");
model.addDumpFieldVector("displacement");
- model.addDumpField("velocity" );
+ model.addDumpField("velocity");
model.addDumpField("acceleration");
- model.addDumpField("residual" );
+ model.addDumpField("residual");
model.addDumpField("stress");
model.addDumpField("grad_u");
model.addDumpField("partitions");
// model.getDumper().getDumper().setMode(iohelper::BASE64);
model.dump();
model.setBaseNameToDumper("cohesive elements",
- "extrinsic_parallel_cohesive_elements");
+ "extrinsic_parallel_cohesive_elements");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump("cohesive elements");
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
/// update displacement on extreme nodes
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
- displacement(n, 1) += disp_update * position(n, 1);
+ displacement(n, 1) += disp_update * position(n, 1);
}
model.checkCohesiveStress();
model.solveStep();
// model.dump();
- if(s % 10 == 0) {
- if(prank == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
+ if (s % 10 == 0) {
+ if (prank == 0)
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
// // update displacement
// for (UInt n = 0; n < nb_nodes; ++n) {
// if (position(n, 1) + displacement(n, 1) > 0) {
// displacement(n, 0) -= 0.01;
// }
// }
- // Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
- // Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
+ // Real Ed = dynamic_cast<MaterialCohesive&>
+ // (model.getMaterial(1)).getDissipatedEnergy();
+ // Real Er = dynamic_cast<MaterialCohesive&>
+ // (model.getMaterial(1)).getReversibleEnergy();
// edis << s << " "
// << Ed << std::endl;
// erev << s << " "
// << Er << std::endl;
-
}
model.dump();
model.dump("cohesive elements");
// edis.close();
// erev.close();
Real Ed = model.getEnergy("dissipated");
Real Edt = 200 * sqrt(2);
-
- if(prank == 0) {
+ if (prank == 0) {
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc
index 256c12b66..822687df8 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc
@@ -1,230 +1,229 @@
/**
* @file test_cohesive_parallel_extrinsic_tetrahedron.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief 3D extrinsic cohesive elements test
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive_linear.hh"
+#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
Real function(Real constant, Real x, Real y, Real z) {
return constant + 2. * x + 3. * y + 4 * z;
}
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
// const UInt max_steps = 1000;
// Real increment = 0.005;
const UInt spatial_dimension = 3;
Math::setTolerance(1.e-12);
ElementType type = _tetrahedron_10;
ElementType type_facet = Mesh::getFacetType(type);
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
// Read the mesh
mesh.read("tetrahedron.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initParallel(partition, NULL, true);
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
- const MaterialCohesiveLinear<3> & mat_cohesive
- = dynamic_cast < const MaterialCohesiveLinear<3> & > (model.getMaterial(1));
+ const MaterialCohesiveLinear<3> & mat_cohesive =
+ dynamic_cast<const MaterialCohesiveLinear<3> &>(model.getMaterial(1));
- const Real sigma_c = mat_cohesive.getParam< RandomInternalField<Real, FacetInternalField> >("sigma_c");
+ const Real sigma_c =
+ mat_cohesive.getParam<RandomInternalField<Real, FacetInternalField>>(
+ "sigma_c");
const Real beta = mat_cohesive.getParam<Real>("beta");
// const Real G_cI = mat_cohesive.getParam<Real>("G_cI");
Array<Real> & position = mesh.getNodes();
/* ------------------------------------------------------------------------ */
/* Facet part */
/* ------------------------------------------------------------------------ */
/// compute quadrature points positions on facets
const Mesh & mesh_facets = model.getMeshFacets();
UInt nb_facet = mesh_facets.getNbElement(type_facet);
- UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
+ UInt nb_quad_per_facet =
+ model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
- model.getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position,
- quad_facets,
- spatial_dimension,
- type_facet);
+ model.getFEEngine("FacetsFEEngine")
+ .interpolateOnIntegrationPoints(position, quad_facets, spatial_dimension,
+ type_facet);
/* ------------------------------------------------------------------------ */
/* End of facet part */
/* ------------------------------------------------------------------------ */
-
/// compute quadrature points position of the elements
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
UInt nb_element = mesh.getNbElement(type);
UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
-
- model.getFEEngine().interpolateOnIntegrationPoints(position,
- quad_elements,
- spatial_dimension,
- type);
+ model.getFEEngine().interpolateOnIntegrationPoints(position, quad_elements,
+ spatial_dimension, type);
/// assign some values to stresses
- Array<Real> & stress
- = const_cast<Array<Real>&>(model.getMaterial(0).getStress(type));
+ Array<Real> & stress =
+ const_cast<Array<Real> &>(model.getMaterial(0).getStress(type));
- Array<Real>::iterator<Matrix<Real> > stress_it
- = stress.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::iterator<Matrix<Real>> stress_it =
+ stress.begin(spatial_dimension, spatial_dimension);
for (UInt q = 0; q < nb_tot_quad_el; ++q, ++stress_it) {
/// compute values
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = i; j < spatial_dimension; ++j) {
- UInt index = i * spatial_dimension + j;
- (*stress_it)(i, j) = index * function(sigma_c * 5,
- quad_elements(q, 0),
- quad_elements(q, 1),
- quad_elements(q, 2));
+ UInt index = i * spatial_dimension + j;
+ (*stress_it)(i, j) =
+ index * function(sigma_c * 5, quad_elements(q, 0),
+ quad_elements(q, 1), quad_elements(q, 2));
}
}
/// fill symmetrical part
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < i; ++j) {
- (*stress_it)(i, j) = (*stress_it)(j, i);
+ (*stress_it)(i, j) = (*stress_it)(j, i);
}
}
}
-
/// compute stress on facet quads
Array<Real> stress_facets(nb_tot_quad, spatial_dimension * spatial_dimension);
- Array<Real>::iterator<Matrix<Real> > stress_facets_it
- = stress_facets.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::iterator<Matrix<Real>> stress_facets_it =
+ stress_facets.begin(spatial_dimension, spatial_dimension);
for (UInt q = 0; q < nb_tot_quad; ++q, ++stress_facets_it) {
/// compute values
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = i; j < spatial_dimension; ++j) {
- UInt index = i * spatial_dimension + j;
- (*stress_facets_it)(i, j) = index * function(sigma_c * 5,
- quad_facets(q, 0),
- quad_facets(q, 1),
- quad_facets(q, 2));
+ UInt index = i * spatial_dimension + j;
+ (*stress_facets_it)(i, j) =
+ index * function(sigma_c * 5, quad_facets(q, 0), quad_facets(q, 1),
+ quad_facets(q, 2));
}
}
/// fill symmetrical part
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < i; ++j) {
- (*stress_facets_it)(i, j) = (*stress_facets_it)(j, i);
+ (*stress_facets_it)(i, j) = (*stress_facets_it)(j, i);
}
}
}
-
/// insert cohesive elements
model.checkCohesiveStress();
-
/// check insertion stress
- const Array<Real> & normals =
- model.getFEEngine("FacetsFEEngine").getNormalsOnIntegrationPoints(type_facet);
+ const Array<Real> & normals = model.getFEEngine("FacetsFEEngine")
+ .getNormalsOnIntegrationPoints(type_facet);
const Array<Real> & tangents = model.getTangents(type_facet);
- const Array<Real> & sigma_c_eff = mat_cohesive.getInsertionTraction(type_cohesive);
+ const Array<Real> & sigma_c_eff =
+ mat_cohesive.getInsertionTraction(type_cohesive);
Vector<Real> normal_stress(spatial_dimension);
- const Array<std::vector<Element> > & coh_element_to_facet
- = mesh_facets.getElementToSubelement(type_facet);
+ const Array<std::vector<Element>> & coh_element_to_facet =
+ mesh_facets.getElementToSubelement(type_facet);
- Array<Real>::iterator<Matrix<Real> > quad_facet_stress
- = stress_facets.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::iterator<Matrix<Real>> quad_facet_stress =
+ stress_facets.begin(spatial_dimension, spatial_dimension);
- Array<Real>::const_iterator<Vector<Real> > quad_normal
- = normals.begin(spatial_dimension);
+ Array<Real>::const_iterator<Vector<Real>> quad_normal =
+ normals.begin(spatial_dimension);
- Array<Real>::const_iterator<Vector<Real> > quad_tangents
- = tangents.begin(tangents.getNbComponent());
+ Array<Real>::const_iterator<Vector<Real>> quad_tangents =
+ tangents.begin(tangents.getNbComponent());
for (UInt f = 0; f < nb_facet; ++f) {
const Element & cohesive_element = coh_element_to_facet(f)[1];
- for (UInt q = 0; q < nb_quad_per_facet; ++q, ++quad_facet_stress,
- ++quad_normal, ++quad_tangents) {
- if (cohesive_element == ElementNull) continue;
+ for (UInt q = 0; q < nb_quad_per_facet;
+ ++q, ++quad_facet_stress, ++quad_normal, ++quad_tangents) {
+ if (cohesive_element == ElementNull)
+ continue;
normal_stress.mul<false>(*quad_facet_stress, *quad_normal);
Real normal_contrib = normal_stress.dot(*quad_normal);
Real first_tangent_contrib = 0;
for (UInt dim = 0; dim < spatial_dimension; ++dim)
- first_tangent_contrib += normal_stress(dim) * (*quad_tangents)(dim);
+ first_tangent_contrib += normal_stress(dim) * (*quad_tangents)(dim);
Real second_tangent_contrib = 0;
for (UInt dim = 0; dim < spatial_dimension; ++dim)
- second_tangent_contrib
- += normal_stress(dim) * (*quad_tangents)(dim + spatial_dimension);
+ second_tangent_contrib +=
+ normal_stress(dim) * (*quad_tangents)(dim + spatial_dimension);
- Real tangent_contrib = std::sqrt(first_tangent_contrib * first_tangent_contrib +
- second_tangent_contrib * second_tangent_contrib);
+ Real tangent_contrib =
+ std::sqrt(first_tangent_contrib * first_tangent_contrib +
+ second_tangent_contrib * second_tangent_contrib);
normal_contrib = std::max(0., normal_contrib);
- Real effective_norm = std::sqrt(normal_contrib * normal_contrib
- + tangent_contrib * tangent_contrib / beta / beta);
+ Real effective_norm =
+ std::sqrt(normal_contrib * normal_contrib +
+ tangent_contrib * tangent_contrib / beta / beta);
- if (effective_norm < sigma_c) continue;
+ if (effective_norm < sigma_c)
+ continue;
- if (!Math::are_float_equal(effective_norm,
- sigma_c_eff(cohesive_element.element
- * nb_quad_per_facet + q))) {
- std::cout << "Insertion tractions do not match" << std::endl;
- finalize();
- return EXIT_FAILURE;
+ if (!Math::are_float_equal(
+ effective_norm,
+ sigma_c_eff(cohesive_element.element * nb_quad_per_facet + q))) {
+ std::cout << "Insertion tractions do not match" << std::endl;
+ finalize();
+ return EXIT_FAILURE;
}
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
index 70404b8ef..55c90eba6 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
@@ -1,395 +1,389 @@
/**
* @file test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief Displacement test for 3D cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_cohesive.hh"
#include "dumper_paraview.hh"
#include "material_cohesive_linear.hh"
+#include "solid_mechanics_model_cohesive.hh"
#ifdef AKANTU_USE_IOHELPER
-# include "dumper_paraview.hh"
+#include "dumper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
using namespace akantu;
-bool checkDisplacement(SolidMechanicsModelCohesive & model,
- ElementType type,
- std::ofstream & error_output,
- UInt step,
- bool barycenters);
+bool checkDisplacement(SolidMechanicsModelCohesive & model, ElementType type,
+ std::ofstream & error_output, UInt step,
+ bool barycenters);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt max_steps = 500;
Math::setTolerance(1.e-12);
UInt spatial_dimension = 3;
ElementType type = _tetrahedron_10;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
// Read the mesh
mesh.read("tetrahedron.msh");
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
// debug::setDebugLevel(dblDump);
partition->partitionate(psize);
// debug::setDebugLevel(dblWarning);
}
SolidMechanicsModelCohesive model(mesh);
model.initParallel(partition, NULL, true);
// debug::setDebugLevel(dblDump);
// std::cout << mesh << std::endl;
// debug::setDebugLevel(dblWarning);
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
/* ------------------------------------------------------------------------ */
/* Facet part */
/* ------------------------------------------------------------------------ */
// Array<Real> limits(spatial_dimension, 2);
// limits(0, 0) = -0.01;
// limits(0, 1) = 0.01;
// limits(1, 0) = -100;
// limits(1, 1) = 100;
// limits(2, 0) = -100;
// limits(2, 1) = 100;
// model.enableFacetsCheckOnArea(limits);
/* ------------------------------------------------------------------------ */
/* End of facet part */
/* ------------------------------------------------------------------------ */
// debug::setDebugLevel(dblDump);
// std::cout << mesh_facets << std::endl;
// debug::setDebugLevel(dblWarning);
- Real time_step = model.getStableTimeStep()*0.1;
+ Real time_step = model.getStableTimeStep() * 0.1;
model.setTimeStep(time_step);
std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
-
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
if (position(n, 0) > 0.99 || position(n, 0) < -0.99) {
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- boundary(n, dim) = true;
+ boundary(n, dim) = true;
}
}
if (position(n, 0) > 0.99 || position(n, 0) < -0.99) {
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- boundary(n, dim) = true;
+ boundary(n, dim) = true;
}
}
}
-// #if defined (AKANTU_DEBUG_TOOLS)
-// Vector<Real> facet_center(spatial_dimension);
-// facet_center(0) = 0;
-// facet_center(1) = -0.16666667;
-// facet_center(2) = 0.5;
+ // #if defined (AKANTU_DEBUG_TOOLS)
+ // Vector<Real> facet_center(spatial_dimension);
+ // facet_center(0) = 0;
+ // facet_center(1) = -0.16666667;
+ // facet_center(2) = 0.5;
-// debug::element_manager.setMesh(mesh);
-// debug::element_manager.addModule(debug::_dm_material_cohesive);
-// debug::element_manager.addModule(debug::_dm_debug_tools);
-// //debug::element_manager.addModule(debug::_dm_integrator);
-// #endif
+ // debug::element_manager.setMesh(mesh);
+ // debug::element_manager.addModule(debug::_dm_material_cohesive);
+ // debug::element_manager.addModule(debug::_dm_debug_tools);
+ // //debug::element_manager.addModule(debug::_dm_integrator);
+ // #endif
/// initial conditions
Real loading_rate = 1;
Real disp_update = loading_rate * time_step;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 0) = loading_rate * position(n, 0);
velocity(n, 1) = loading_rate * position(n, 0);
}
model.synchronizeBoundaries();
model.updateResidual();
std::stringstream paraview_output;
paraview_output << "extrinsic_parallel_tetrahedron_" << psize;
model.setBaseName(paraview_output.str());
model.addDumpFieldVector("displacement");
- model.addDumpFieldVector("velocity" );
+ model.addDumpFieldVector("velocity");
model.addDumpFieldVector("acceleration");
- model.addDumpFieldVector("residual" );
+ model.addDumpFieldVector("residual");
model.addDumpFieldTensor("stress");
model.addDumpFieldTensor("grad_u");
model.addDumpField("partitions");
// model.getDumper().getDumper().setMode(iohelper::BASE64);
model.dump();
-
model.setBaseNameToDumper("cohesive elements",
- paraview_output.str()+"_cohesive_elements");
+ paraview_output.str() + "_cohesive_elements");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump("cohesive elements");
-
std::stringstream error_stream;
- error_stream << "error" << ".csv";
+ error_stream << "error"
+ << ".csv";
std::ofstream error_output;
error_output.open(error_stream.str().c_str());
error_output << "# Step, Average, Max, Min" << std::endl;
- if (checkDisplacement(model, type, error_output, 0, true)) {}
+ if (checkDisplacement(model, type, error_output, 0, true)) {
+ }
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
/// update displacement on extreme nodes
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (position(n, 0) > 0.99 || position(n, 0) < -0.99) {
- displacement(n, 0) += disp_update * position(n, 0);
- displacement(n, 1) += disp_update * position(n, 0);
+ displacement(n, 0) += disp_update * position(n, 0);
+ displacement(n, 1) += disp_update * position(n, 0);
}
}
model.checkCohesiveStress();
model.solveStep();
- if(s % 100 == 0) {
- if(prank == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
+ if (s % 100 == 0) {
+ if (prank == 0)
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
}
model.dump();
model.dump("cohesive elements");
if (!checkDisplacement(model, type, error_output, max_steps, false)) {
finalize();
return EXIT_FAILURE;
}
finalize();
return EXIT_SUCCESS;
}
-bool checkDisplacement(SolidMechanicsModelCohesive & model,
- ElementType type,
- std::ofstream & error_output,
- UInt step,
- bool barycenters) {
+bool checkDisplacement(SolidMechanicsModelCohesive & model, ElementType type,
+ std::ofstream & error_output, UInt step,
+ bool barycenters) {
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
const Array<UInt> & connectivity = mesh.getConnectivity(type);
const Array<Real> & displacement = model.getDisplacement();
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_elem = Mesh::getNbNodesPerElement(type);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
if (psize == 1) {
std::stringstream displacement_file;
- displacement_file << "displacement/displacement_"
- << std::setfill('0') << std::setw(6)
- << step;
+ displacement_file << "displacement/displacement_" << std::setfill('0')
+ << std::setw(6) << step;
std::ofstream displacement_output;
displacement_output.open(displacement_file.str().c_str());
for (UInt el = 0; el < nb_element; ++el) {
for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
- UInt node = connectivity(el, n);
+ UInt node = connectivity(el, n);
- for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- displacement_output << std::setprecision(15)
- << displacement(node, dim) << " ";
- }
- displacement_output << std::endl;
+ for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+ displacement_output << std::setprecision(15)
+ << displacement(node, dim) << " ";
+ }
+ displacement_output << std::endl;
}
}
displacement_output.close();
if (barycenters) {
std::stringstream barycenter_file;
barycenter_file << "displacement/barycenters";
std::ofstream barycenter_output;
barycenter_output.open(barycenter_file.str().c_str());
Element element(type, 0);
Vector<Real> bary(spatial_dimension);
for (UInt el = 0; el < nb_element; ++el) {
- element.element = el;
- mesh.getBarycenter(element, bary);
-
- for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- barycenter_output << std::setprecision(15)
- << bary(dim) << " ";
- }
- barycenter_output << std::endl;
+ element.element = el;
+ mesh.getBarycenter(element, bary);
+
+ for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+ barycenter_output << std::setprecision(15) << bary(dim) << " ";
+ }
+ barycenter_output << std::endl;
}
barycenter_output.close();
}
- }
- else {
+ } else {
- if (barycenters) return true;
+ if (barycenters)
+ return true;
/// read data
std::stringstream displacement_file;
- displacement_file << "displacement/displacement_"
- << std::setfill('0') << std::setw(6)
- << step;
+ displacement_file << "displacement/displacement_" << std::setfill('0')
+ << std::setw(6) << step;
std::ifstream displacement_input;
displacement_input.open(displacement_file.str().c_str());
Array<Real> displacement_serial(0, spatial_dimension);
Vector<Real> disp_tmp(spatial_dimension);
while (displacement_input.good()) {
for (UInt i = 0; i < spatial_dimension; ++i)
- displacement_input >> disp_tmp(i);
+ displacement_input >> disp_tmp(i);
displacement_serial.push_back(disp_tmp);
}
std::stringstream barycenter_file;
barycenter_file << "displacement/barycenters";
std::ifstream barycenter_input;
barycenter_input.open(barycenter_file.str().c_str());
Array<Real> barycenter_serial(0, spatial_dimension);
while (barycenter_input.good()) {
for (UInt dim = 0; dim < spatial_dimension; ++dim)
- barycenter_input >> disp_tmp(dim);
+ barycenter_input >> disp_tmp(dim);
barycenter_serial.push_back(disp_tmp);
}
Element element(type, 0);
Vector<Real> bary(spatial_dimension);
- Array<Real>::iterator<Vector<Real> > it;
- Array<Real>::iterator<Vector<Real> > begin
- = barycenter_serial.begin(spatial_dimension);
- Array<Real>::iterator<Vector<Real> > end
- = barycenter_serial.end(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> it;
+ Array<Real>::iterator<Vector<Real>> begin =
+ barycenter_serial.begin(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> end =
+ barycenter_serial.end(spatial_dimension);
- Array<Real>::const_iterator<Vector<Real> > disp_it;
- Array<Real>::iterator<Vector<Real> > disp_serial_it;
+ Array<Real>::const_iterator<Vector<Real>> disp_it;
+ Array<Real>::iterator<Vector<Real>> disp_serial_it;
Vector<Real> difference(spatial_dimension);
Array<Real> error;
/// compute error
for (UInt el = 0; el < nb_element; ++el) {
element.element = el;
mesh.getBarycenter(element, bary);
/// find element
for (it = begin; it != end; ++it) {
- UInt matched_dim = 0;
+ UInt matched_dim = 0;
- while (matched_dim < spatial_dimension &&
- Math::are_float_equal(bary(matched_dim), (*it)(matched_dim)))
- ++matched_dim;
+ while (matched_dim < spatial_dimension &&
+ Math::are_float_equal(bary(matched_dim), (*it)(matched_dim)))
+ ++matched_dim;
- if (matched_dim == spatial_dimension) break;
+ if (matched_dim == spatial_dimension)
+ break;
}
if (it == end) {
- std::cout << "Element barycenter not found!" << std::endl;
- return false;
+ std::cout << "Element barycenter not found!" << std::endl;
+ return false;
}
UInt matched_el = it - begin;
- disp_serial_it = displacement_serial.begin(spatial_dimension)
- + matched_el * nb_nodes_per_elem;
+ disp_serial_it = displacement_serial.begin(spatial_dimension) +
+ matched_el * nb_nodes_per_elem;
for (UInt n = 0; n < nb_nodes_per_elem; ++n, ++disp_serial_it) {
- UInt node = connectivity(el, n);
- if (!mesh.isLocalOrMasterNode(node)) continue;
+ UInt node = connectivity(el, n);
+ if (!mesh.isLocalOrMasterNode(node))
+ continue;
- disp_it = displacement.begin(spatial_dimension) + node;
+ disp_it = displacement.begin(spatial_dimension) + node;
- difference = *disp_it;
- difference -= *disp_serial_it;
+ difference = *disp_it;
+ difference -= *disp_serial_it;
- error.push_back(difference.norm());
+ error.push_back(difference.norm());
}
}
/// compute average error
Real average_error = std::accumulate(error.begin(), error.end(), 0.);
comm.allReduce(&average_error, 1, _so_sum);
UInt error_size = error.getSize();
comm.allReduce(&error_size, 1, _so_sum);
average_error /= error_size;
/// compute maximum and minimum
Real max_error = *std::max_element(error.begin(), error.end());
comm.allReduce(&max_error, 1, _so_max);
Real min_error = *std::min_element(error.begin(), error.end());
comm.allReduce(&min_error, 1, _so_min);
/// output data
if (prank == 0) {
- error_output << step << ", "
- << average_error << ", "
- << max_error << ", "
- << min_error << std::endl;
+ error_output << step << ", " << average_error << ", " << max_error << ", "
+ << min_error << std::endl;
}
if (max_error > 1.e-9) {
std::cout << "Displacement error is too big!" << std::endl;
return false;
}
}
return true;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc
index e5aba2874..fa506ff5d 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc
@@ -1,295 +1,301 @@
/**
* @file test_cohesive_parallel_extrinsic_IG_TG.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief Test for considering different cohesive properties for
* intergranular (IG) and transgranular (TG) fractures in extrinsic
* cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include <limits>
#include <fstream>
#include <iostream>
-
+#include <limits>
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_cohesive.hh"
#include "material_cohesive_linear.hh"
+#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
class MultiGrainMaterialSelector : public DefaultMaterialCohesiveSelector {
public:
- MultiGrainMaterialSelector(const SolidMechanicsModelCohesive & model, const ID & transgranular_id, const ID & intergranular_id) :
- DefaultMaterialCohesiveSelector(model),
- transgranular_id(transgranular_id),
- intergranular_id(intergranular_id),
- model(model),
- mesh(model.getMesh()),
- mesh_facets(model.getMeshFacets()),
- spatial_dimension(model.getSpatialDimension()),
- nb_IG(0), nb_TG(0) {
- }
+ MultiGrainMaterialSelector(const SolidMechanicsModelCohesive & model,
+ const ID & transgranular_id,
+ const ID & intergranular_id)
+ : DefaultMaterialCohesiveSelector(model),
+ transgranular_id(transgranular_id), intergranular_id(intergranular_id),
+ model(model), mesh(model.getMesh()), mesh_facets(model.getMeshFacets()),
+ spatial_dimension(model.getSpatialDimension()), nb_IG(0), nb_TG(0) {}
UInt operator()(const Element & element) {
- if(mesh_facets.getSpatialDimension(element.type) == (spatial_dimension - 1)) {
- const std::vector<Element> & element_to_subelement = mesh_facets.getElementToSubelement(element.type, element.ghost_type)(element.element);
+ if (mesh_facets.getSpatialDimension(element.type) ==
+ (spatial_dimension - 1)) {
+ const std::vector<Element> & element_to_subelement =
+ mesh_facets.getElementToSubelement(element.type, element.ghost_type)(
+ element.element);
const Element & el1 = element_to_subelement[0];
const Element & el2 = element_to_subelement[1];
- UInt grain_id1 = mesh.getData<UInt>("tag_0", el1.type, el1.ghost_type)(el1.element);
- if(el2 != ElementNull) {
- UInt grain_id2 = mesh.getData<UInt>("tag_0", el2.type, el2.ghost_type)(el2.element);
- if (grain_id1 == grain_id2){
- //transgranular = 0 indicator
- nb_TG++;
- return model.getMaterialIndex(transgranular_id);
- } else {
- //intergranular = 1 indicator
- nb_IG++;
- return model.getMaterialIndex(intergranular_id);
- }
+ UInt grain_id1 =
+ mesh.getData<UInt>("tag_0", el1.type, el1.ghost_type)(el1.element);
+ if (el2 != ElementNull) {
+ UInt grain_id2 =
+ mesh.getData<UInt>("tag_0", el2.type, el2.ghost_type)(el2.element);
+ if (grain_id1 == grain_id2) {
+ // transgranular = 0 indicator
+ nb_TG++;
+ return model.getMaterialIndex(transgranular_id);
+ } else {
+ // intergranular = 1 indicator
+ nb_IG++;
+ return model.getMaterialIndex(intergranular_id);
+ }
} else {
- //transgranular = 0 indicator
- nb_TG++;
- return model.getMaterialIndex(transgranular_id);
+ // transgranular = 0 indicator
+ nb_TG++;
+ return model.getMaterialIndex(transgranular_id);
}
} else {
return DefaultMaterialCohesiveSelector::operator()(element);
}
}
private:
ID transgranular_id, intergranular_id;
const SolidMechanicsModelCohesive & model;
const Mesh & mesh;
const Mesh & mesh_facets;
UInt spatial_dimension;
UInt nb_IG;
UInt nb_TG;
};
/* -------------------------------------------------------------------------- */
void limitInsertion(SolidMechanicsModelCohesive & model) {
Real tolerance = 0.1;
const Mesh & mesh = model.getMesh();
const Mesh & mesh_facets = model.getMeshFacets();
CohesiveElementInserter & inserter = model.getElementInserter();
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> bary_facet(spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
- Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
- for(; it != end; ++it) {
+ Mesh::type_iterator it =
+ mesh_facets.firstType(spatial_dimension - 1, ghost_type);
+ Mesh::type_iterator end =
+ mesh_facets.lastType(spatial_dimension - 1, ghost_type);
+ for (; it != end; ++it) {
ElementType type = *it;
Array<bool> & f_check = inserter.getCheckFacets(type, ghost_type);
UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
for (UInt f = 0; f < nb_facet; ++f) {
- if (f_check(f)) {
+ if (f_check(f)) {
- mesh_facets.getBarycenter(f, type, bary_facet.storage(), ghost_type);
+ mesh_facets.getBarycenter(f, type, bary_facet.storage(), ghost_type);
- if ( !(bary_facet(0) > -tolerance && bary_facet(0) < tolerance) &&
- !(bary_facet(1) > -tolerance && bary_facet(1) < tolerance) )
- f_check(f) = false;
- }
+ if (!(bary_facet(0) > -tolerance && bary_facet(0) < tolerance) &&
+ !(bary_facet(1) > -tolerance && bary_facet(1) < tolerance))
+ f_check(f) = false;
+ }
}
}
}
model.updateAutomaticInsertion();
}
-
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt spatial_dimension = 2;
const UInt max_steps = 600;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("square.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
SolidMechanicsModelCohesive model(mesh);
/// model initialization
model.initParallel(partition, NULL, true);
delete partition;
- MultiGrainMaterialSelector material_selector(model, "TG_cohesive", "IG_cohesive");
+ MultiGrainMaterialSelector material_selector(model, "TG_cohesive",
+ "IG_cohesive");
model.setMaterialSelector(material_selector);
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
- Real time_step = model.getStableTimeStep()*0.1;
+ Real time_step = model.getStableTimeStep() * 0.1;
model.setTimeStep(time_step);
// std::cout << "Time step: " << time_step << std::endl;
limitInsertion(model);
// std::cout << mesh << std::endl;
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
Array<Real> & displacement = model.getDisplacement();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
/// boundary conditions
for (UInt n = 0; n < nb_nodes; ++n) {
- if (position(n, 1) > 0.99|| position(n, 1) < -0.99)
+ if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
boundary(n, 1) = true;
if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
boundary(n, 0) = true;
}
model.synchronizeBoundaries();
model.updateResidual();
model.setBaseName("extrinsic");
model.addDumpFieldVector("displacement");
- model.addDumpField("velocity" );
+ model.addDumpField("velocity");
model.addDumpField("acceleration");
- model.addDumpField("residual" );
+ model.addDumpField("residual");
model.addDumpField("stress");
model.addDumpField("strain");
model.addDumpField("partitions");
model.setBaseNameToDumper("cohesive elements", "extrinsic_cohesive");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
model.dump();
model.dump("cohesive elements");
/// initial conditions
Real loading_rate = 0.1;
// bar_height = 2
- Real VI = loading_rate * 2* 0.5;
+ Real VI = loading_rate * 2 * 0.5;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 1) = loading_rate * position(n, 1);
velocity(n, 0) = loading_rate * position(n, 0);
}
// std::ofstream edis("edis.txt");
// std::ofstream erev("erev.txt");
// Array<Real> & residual = model.getResidual();
// model.dump();
// const Array<Real> & stress = model.getMaterial(0).getStress(type);
Real dispy = 0;
// UInt nb_coh_elem = 0;
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
dispy += VI * time_step;
/// update displacement on extreme nodes
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (position(n, 1) > 0.99){
- displacement(n, 1) = dispy;
- velocity(n,1) = VI;}
- if (position(n, 1) < -0.99){
- displacement(n, 1) = -dispy;
- velocity(n,1) = -VI;}
- if (position(n, 0) > 0.99){
- displacement(n, 0) = dispy;
- velocity(n,0) = VI;}
- if (position(n, 0) < -0.99){
- displacement(n, 0) = -dispy;
- velocity(n,0) = -VI;}
+ if (position(n, 1) > 0.99) {
+ displacement(n, 1) = dispy;
+ velocity(n, 1) = VI;
+ }
+ if (position(n, 1) < -0.99) {
+ displacement(n, 1) = -dispy;
+ velocity(n, 1) = -VI;
+ }
+ if (position(n, 0) > 0.99) {
+ displacement(n, 0) = dispy;
+ velocity(n, 0) = VI;
+ }
+ if (position(n, 0) < -0.99) {
+ displacement(n, 0) = -dispy;
+ velocity(n, 0) = -VI;
+ }
}
model.checkCohesiveStress();
model.solveStep();
- if(s % 10 == 0) {
- if(prank == 0)
- std::cout << "passing step " << s << "/" << max_steps << std::endl;
+ if (s % 10 == 0) {
+ if (prank == 0)
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
// model.dump();
// model.dump("cohesive elements");
}
// Real Ed = model.getEnergy("dissipated");
// edis << s << " "
// << Ed << std::endl;
// erev << s << " "
// << Er << std::endl;
}
model.dump();
model.dump("cohesive elements");
// edis.close();
// erev.close();
// mesh.write("mesh_final.msh");
Real Ed = model.getEnergy("dissipated");
Real Edt = 40;
- if(prank == 0)
+ if (prank == 0)
std::cout << Ed << " " << Edt << std::endl;
if (Ed < Edt * 0.99 || Ed > Edt * 1.01 || std::isnan(Ed)) {
- if(prank == 0)
+ if (prank == 0)
std::cout << "The dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
// for (UInt n = 0; n < position.getSize(); ++n) {
// for (UInt s = 0; s < spatial_dimension; ++s) {
// position(n, s) += displacement(n, s);
// }
// }
-
finalize();
- if(prank == 0)
+ if (prank == 0)
std::cout << "OK: test_cohesive_extrinsic_IG_TG was passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc
index b37321c1b..0087b7408 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc
@@ -1,118 +1,130 @@
/**
* @file test_cohesive_insertion_along_physical_surfaces.cc
* @author Fabian Barras <fabian.barras@epfl.ch>
* @date Fri Aug 7 09:07:44 2015
*
- * @brief Test parallel intrinsic insertion of cohesive elements along physical surfaces
+ * @brief Test parallel intrinsic insertion of cohesive elements along physical
+ * surfaces
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <limits>
#include <fstream>
#include <iostream>
+#include <limits>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "material.hh"
+#include "material_cohesive.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model_cohesive.hh"
-#include "material.hh"
-#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("input_file.dat", argc, argv);
Math::setTolerance(1e-15);
-
+
const UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank==0){
+ if (prank == 0) {
mesh.read("3d_spherical_inclusion.msh");
-
+
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
-
}
SolidMechanicsModelCohesive model(mesh);
model.initParallel(partition);
mesh.createGroupsFromMeshData<std::string>("physical_names");
model.initFull(SolidMechanicsModelCohesiveOptions(_static));
-
- std::vector<std::string> surfaces_name = {"interface", "coh1", "coh2", "coh3", "coh4", "coh5"};
+
+ std::vector<std::string> surfaces_name = {"interface", "coh1", "coh2",
+ "coh3", "coh4", "coh5"};
UInt nb_surf = surfaces_name.size();
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
std::string ghost_str;
-
- if(*gt == 1) ghost_str = "ghost";
- else ghost_str = "not ghost";
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, *gt, _ek_cohesive);
- Mesh::type_iterator end = mesh.lastType(spatial_dimension, *gt, _ek_cohesive);
+ if (*gt == 1)
+ ghost_str = "ghost";
+ else
+ ghost_str = "not ghost";
+
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, *gt, _ek_cohesive);
+ Mesh::type_iterator end =
+ mesh.lastType(spatial_dimension, *gt, _ek_cohesive);
+
+ for (; it != end; ++it) {
+
+ Array<UInt> & material_id = mesh.getMeshFacets().getData<UInt>(
+ "physical_names")(mesh.getFacetType(*it), *gt);
- for(; it != end; ++it) {
-
- Array<UInt> & material_id = mesh.getMeshFacets().getData<UInt>("physical_names")(mesh.getFacetType(*it), *gt);
-
for (UInt i = 0; i < nb_surf; ++i) {
- UInt expected_insertion = 0;
-
- for(UInt m = 0; m<material_id.getSize();++m) {
- if(material_id(m)==model.SolidMechanicsModel::getMaterialIndex(surfaces_name[i])) ++expected_insertion;
- }
-
- UInt inserted_elements;
-
- inserted_elements = model.getMaterial(surfaces_name[i]).getElementFilter()(*it,*gt).getSize();
- if (expected_insertion != inserted_elements) {
- std::cerr << std::endl << "!!! Mismatch in insertion of surface named "
- << surfaces_name[i] << " in proc n° " << prank
- << " --> " << inserted_elements << " inserted elements of type " << ghost_str
- << " out of "
- << expected_insertion << std::endl;
- return EXIT_FAILURE;
- }
- }
+ UInt expected_insertion = 0;
+
+ for (UInt m = 0; m < material_id.getSize(); ++m) {
+ if (material_id(m) ==
+ model.SolidMechanicsModel::getMaterialIndex(surfaces_name[i]))
+ ++expected_insertion;
+ }
+
+ UInt inserted_elements;
+
+ inserted_elements = model.getMaterial(surfaces_name[i])
+ .getElementFilter()(*it, *gt)
+ .getSize();
+ if (expected_insertion != inserted_elements) {
+ std::cerr << std::endl
+ << "!!! Mismatch in insertion of surface named "
+ << surfaces_name[i] << " in proc n° " << prank << " --> "
+ << inserted_elements << " inserted elements of type "
+ << ghost_str << " out of " << expected_insertion
+ << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
}
}
model.assembleStiffnessMatrix();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc
index ad60ef2ef..7ce43830c 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc
@@ -1,270 +1,303 @@
/**
* @file test_cohesive_parallel_intrinsic_implicit_insertion.cc
* @author Fabian Barras <fabian.barras@epfl.ch>
* @date Fri Aug 5 17:05:59 2016
*
- * @brief Verifying the proper insertion and synchronization of intrinsic cohesive elements
+ * @brief Verifying the proper insertion and synchronization of intrinsic
+ * cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <limits>
#include <fstream>
#include <iostream>
+#include <limits>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "material.hh"
+#include "material_cohesive.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh.hh"
#include "mesh_utils.hh"
#include "solid_mechanics_model_cohesive.hh"
-#include "material.hh"
-#include "material_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
std::ofstream output;
/* -------------------------------------------------------------------------- */
void printMeshContent(Mesh & mesh) {
const auto & comm = Communicator::getStaticCommunicator();
Int prank = comm.whoAmI();
comm.barrier();
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
-
- Mesh::type_iterator first = mesh.firstType(_all_dimensions, *gt, _ek_not_defined);
- Mesh::type_iterator last = mesh.lastType(_all_dimensions, *gt, _ek_not_defined);
-
- for(; first != last; ++first) {
- UInt nb_element = mesh.getNbElement(*first,*gt);
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+
+ Mesh::type_iterator first =
+ mesh.firstType(_all_dimensions, *gt, _ek_not_defined);
+ Mesh::type_iterator last =
+ mesh.lastType(_all_dimensions, *gt, _ek_not_defined);
+
+ for (; first != last; ++first) {
+ UInt nb_element = mesh.getNbElement(*first, *gt);
output << std::endl
- << "Element type: " << *first << ", " << *gt << ": "
- << nb_element << " in the mesh of processor " << prank << std::endl;
- Array<UInt> & conn = mesh.getConnectivity(*first,*gt);
+ << "Element type: " << *first << ", " << *gt << ": " << nb_element
+ << " in the mesh of processor " << prank << std::endl;
+ Array<UInt> & conn = mesh.getConnectivity(*first, *gt);
for (UInt i = 0; i < conn.getSize(); ++i) {
- output << "Element no " << i << " ";
- for (UInt j = 0; j < conn.getNbComponent(); ++j) {
- output << conn(i,j) << " ";
- }
- output << std::endl;
+ output << "Element no " << i << " ";
+ for (UInt j = 0; j < conn.getNbComponent(); ++j) {
+ output << conn(i, j) << " ";
+ }
+ output << std::endl;
}
}
}
}
/* -------------------------------------------------------------------------- */
void printNodeList(Mesh & mesh) {
Array<double> & nodes = mesh.getNodes();
- output << "Number of nodes: " << mesh.getNbNodes()<< std::endl;
+ output << "Number of nodes: " << mesh.getNbNodes() << std::endl;
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- output<<"Node # " << i
- << ", x-coord: "
- << nodes(i,0)
- << ", y-coord: "
- << nodes(i,1)
- << ", of type: " << mesh.getNodeType(i) << std::endl;
+ output << "Node # " << i << ", x-coord: " << nodes(i, 0)
+ << ", y-coord: " << nodes(i, 1)
+ << ", of type: " << mesh.getNodeType(i) << std::endl;
}
output << std::endl;
}
/* -------------------------------------------------------------------------- */
void getGlobalIDs(Mesh & mesh) {
const Array<UInt> & glob_id = mesh.getGlobalNodesIds();
- if(&glob_id) {
+ if (&glob_id) {
output << "Global nodes ID: " << std::endl;
for (UInt i = 0; i < glob_id.getSize(); ++i) {
output << i << " " << glob_id(i) << std::endl;
}
}
output << std::endl;
}
/* -------------------------------------------------------------------------- */
void printSynchroinfo(Mesh & mesh, const DistributedSynchronizer & synch) {
const auto & comm = Communicator::getStaticCommunicator();
Int prank = comm.whoAmI();
Int psize = comm.getNbProc();
- if(comm.getNbProc()==1)
+ if (comm.getNbProc() == 1)
return;
-
+
for (Int p = 0; p < psize; ++p) {
- if (p==prank)
+ if (p == prank)
continue;
output << "From processor " << prank << " to processor " << p << std::endl;
- const Array<Element> & sele = *(synch.getSendElement()+p);
+ const Array<Element> & sele = *(synch.getSendElement() + p);
output << " Sending element(s): " << std::endl;
for (UInt i = 0; i < sele.getSize(); ++i) {
output << sele(i) << std::endl;
}
- const Array<Element> & rele = *(synch.getReceiveElement()+p);
- output <<" Receiving element(s): " << std::endl;
+ const Array<Element> & rele = *(synch.getReceiveElement() + p);
+ output << " Receiving element(s): " << std::endl;
for (UInt i = 0; i < rele.getSize(); ++i) {
output << rele(i) << std::endl;
}
}
output << std::endl;
}
/* -------------------------------------------------------------------------- */
void printDOF(SolidMechanicsModelCohesive & model) {
const auto & comm = Communicator::getStaticCommunicator();
- if(comm.getNbProc()==1)
+ if (comm.getNbProc() == 1)
return;
Int prank = comm.whoAmI();
- const DOFSynchronizer & dof = model.getDOFSynchronizer();
+ const DOFSynchronizer & dof = model.getDOFSynchronizer();
- output << "Number of global dofs " << dof.getNbGlobalDOFs() << " for processor "<< prank << std::endl;
+ output << "Number of global dofs " << dof.getNbGlobalDOFs()
+ << " for processor " << prank << std::endl;
const Array<UInt> & dof_global_ids = dof.getDOFGlobalIDs();
for (UInt i = 0; i < dof_global_ids.getSize(); ++i) {
-
- output << "Local dof " << i << ", global id: " << dof_global_ids(i) << std::endl;
+
+ output << "Local dof " << i << ", global id: " << dof_global_ids(i)
+ << std::endl;
}
output << std::endl;
}
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
- std::string input_file = "input_file_iii.dat";
+ std::string input_file = "input_file_iii.dat";
std::string mesh_file = "2d_basic_interface.msh";
std::string dir = "output_dir/";
initialize(input_file, argc, argv);
-
+
debug::setDebugLevel(dbl0);
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
std::stringstream filename;
- filename << dir.c_str() << "output_from_proc_" << prank << "_out_of_" << psize << ".out";
+ filename << dir.c_str() << "output_from_proc_" << prank << "_out_of_" << psize
+ << ".out";
output.open(filename.str());
- if(prank==0){
+ if (prank == 0) {
- mesh.read(mesh_file);
+ mesh.read(mesh_file);
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
const ElementTypeMapArray<UInt> & partitions = partition->getPartitions();
- output << "The root processor read the mesh." << std::endl
- << "Only GMSH physical objects are created in the mesh." <<std::endl;
+ output << "The root processor read the mesh." << std::endl
+ << "Only GMSH physical objects are created in the mesh."
+ << std::endl;
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
-
Mesh::type_iterator first = mesh.firstType(_all_dimensions, *gt);
- Mesh::type_iterator last = mesh.lastType(_all_dimensions, *gt);
-
- for(; first != last; ++first) {
-
- output << "Element type: " << *first << " ghost type: " << *gt << std::endl;
- UInt nb_element = mesh.getNbElement(*first,*gt);
- output << nb_element << " to partitionate between " << psize << " processsors" << std::endl;
-
- Array<UInt> part = partitions(*first, *gt);
-
- for (UInt i = 0; i < part.getSize(); ++i) {
- output << i << " " << part(i) << std::endl;
- }
+ Mesh::type_iterator last = mesh.lastType(_all_dimensions, *gt);
+
+ for (; first != last; ++first) {
+
+ output << "Element type: " << *first << " ghost type: " << *gt
+ << std::endl;
+ UInt nb_element = mesh.getNbElement(*first, *gt);
+ output << nb_element << " to partitionate between " << psize
+ << " processsors" << std::endl;
+
+ Array<UInt> part = partitions(*first, *gt);
+
+ for (UInt i = 0; i < part.getSize(); ++i) {
+ output << i << " " << part(i) << std::endl;
+ }
}
}
-
- output << "Nodes are also read and set with type -1 (normal node)" << std::endl;
+
+ output << "Nodes are also read and set with type -1 (normal node)"
+ << std::endl;
printNodeList(mesh);
}
-
+
SolidMechanicsModelCohesive model(mesh);
-
- output << "Before initParallel(), non-root processors have empty Mesh object" << std::endl;
+
+ output << "Before initParallel(), non-root processors have empty Mesh object"
+ << std::endl;
printMeshContent(mesh);
-
+
model.initParallel(partition);
-
- output << "After initParallel(), Mesh object on each processor is a local partionated mesh containing ghost elements" << std::endl;
+
+ output << "After initParallel(), Mesh object on each processor is a local "
+ "partionated mesh containing ghost elements"
+ << std::endl;
printMeshContent(mesh);
-
- output << "Nodes are also partionated and new node types are defined:" << std::endl;
+
+ output << "Nodes are also partionated and new node types are defined:"
+ << std::endl;
printNodeList(mesh);
output << "-3: pure ghost node -> not a local node" << std::endl
- << "-2: master node -> node shared with other processor(s) -> local and global node" <<std::endl
- << ">0: slave node -> -> node shared with other processor(s) -> only local node (its id is the rank of the processor owning the master node)" <<std::endl;
-
- output << "Each local node has a corresponding global id used during assembly: " <<std::endl;
+ << "-2: master node -> node shared with other processor(s) -> local "
+ "and global node"
+ << std::endl
+ << ">0: slave node -> -> node shared with other processor(s) -> only "
+ "local node (its id is the rank of the processor owning the master "
+ "node)"
+ << std::endl;
+
+ output
+ << "Each local node has a corresponding global id used during assembly: "
+ << std::endl;
getGlobalIDs(mesh);
-
- Mesh & mesh_facets = mesh.getMeshFacets();
-
- output << "Within cohesive element model, initParallel() creates a second Mesh object usually called mesh_facet" << std::endl
- << "This Mesh object contains all sub-dimensional elements where potential cohesive element can be inserted" << std::endl;
+
+ Mesh & mesh_facets = mesh.getMeshFacets();
+
+ output << "Within cohesive element model, initParallel() creates a second "
+ "Mesh object usually called mesh_facet"
+ << std::endl
+ << "This Mesh object contains all sub-dimensional elements where "
+ "potential cohesive element can be inserted"
+ << std::endl;
printMeshContent(mesh_facets);
-
-
-
- const DistributedSynchronizer & synch_model = model.getSynchronizer();
- output << "The distributed synchronizer of solid mechanics model is used to synchronize fields with ghost element:" << std::endl;
+
+ const DistributedSynchronizer & synch_model = model.getSynchronizer();
+ output << "The distributed synchronizer of solid mechanics model is used to "
+ "synchronize fields with ghost element:"
+ << std::endl;
printSynchroinfo(mesh, synch_model);
-
+
mesh.createGroupsFromMeshData<std::string>("physical_names");
model.initFull(SolidMechanicsModelCohesiveOptions(_static));
-
- output << "In case of insertion along physical objects, cohesive elements are created during initFull()" << std::endl;
+
+ output << "In case of insertion along physical objects, cohesive elements "
+ "are created during initFull()"
+ << std::endl;
output << "Elements list after insertion" << std::endl;
printMeshContent(mesh);
-
- output << "Node list after insertion: (Total number of nodes " << mesh.getNbNodes()<< ")"<< std::endl;
+
+ output << "Node list after insertion: (Total number of nodes "
+ << mesh.getNbNodes() << ")" << std::endl;
printNodeList(mesh);
-
- output << "Node global ids after insertion: (Total number of nodes " << mesh.getNbGlobalNodes()<< ")"<< std::endl;
+
+ output << "Node global ids after insertion: (Total number of nodes "
+ << mesh.getNbGlobalNodes() << ")" << std::endl;
getGlobalIDs(mesh);
-
- const DistributedSynchronizer & coh_synch_model = *(model.getCohesiveSynchronizer());
- output << "Solid mechanics model cohesive has its own distributed synchronizer to handle ghost cohesive element:" << std::endl;
+
+ const DistributedSynchronizer & coh_synch_model =
+ *(model.getCohesiveSynchronizer());
+ output << "Solid mechanics model cohesive has its own distributed "
+ "synchronizer to handle ghost cohesive element:"
+ << std::endl;
printSynchroinfo(mesh, coh_synch_model);
- output << "A synchronizer dedicated to degrees of freedom (DOFs) is used by the solver to build matrices in parallel:"
- << std::endl
- << "This DOFSynchronizer is built based on nodes global id " << std::endl;
+ output << "A synchronizer dedicated to degrees of freedom (DOFs) is used by "
+ "the solver to build matrices in parallel:"
+ << std::endl
+ << "This DOFSynchronizer is built based on nodes global id "
+ << std::endl;
printDOF(model);
-
+
output.close();
-
+
finalize();
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc
index f4d854bf0..937d12b44 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc
@@ -1,160 +1,160 @@
/**
* @file test_cohesive_parallel_intrinsic.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief parallel test for intrinsic cohesive elements
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material.dat", argc, argv);
const UInt max_steps = 350;
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
// Read the mesh
mesh.read("mesh.msh");
// /// insert cohesive elements
// CohesiveElementInserter inserter(mesh);
// inserter.setLimit('x', -0.26, -0.24);
// inserter.insertIntrinsicElements();
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
// debug::setDebugLevel(dblDump);
partition->partitionate(psize);
// debug::setDebugLevel(dblWarning);
}
SolidMechanicsModelCohesive model(mesh);
model.initParallel(partition);
model.initFull();
model.limitInsertion(_x, -0.26, -0.24);
model.insertIntrinsicElements();
debug::setDebugLevel(dblDump);
std::cout << mesh << std::endl;
debug::setDebugLevel(dblWarning);
- Real time_step = model.getStableTimeStep()*0.8;
+ Real time_step = model.getStableTimeStep() * 0.8;
model.setTimeStep(time_step);
// std::cout << "Time step: " << time_step << std::endl;
model.assembleMassLumped();
-
Array<Real> & position = mesh.getNodes();
Array<Real> & velocity = model.getVelocity();
Array<bool> & boundary = model.getBlockedDOFs();
// Array<Real> & displacement = model.getDisplacement();
// const Array<Real> & residual = model.getResidual();
UInt nb_nodes = mesh.getNbNodes();
Real epsilon = std::numeric_limits<Real>::epsilon();
for (UInt n = 0; n < nb_nodes; ++n) {
if (std::abs(position(n, 0) - 1.) < epsilon)
boundary(n, 0) = true;
}
model.synchronizeBoundaries();
model.updateResidual();
model.setBaseName("intrinsic_parallel");
model.addDumpFieldVector("displacement");
- model.addDumpField("velocity" );
+ model.addDumpField("velocity");
model.addDumpField("acceleration");
- model.addDumpField("residual" );
+ model.addDumpField("residual");
model.addDumpField("stress");
model.addDumpField("strain");
model.addDumpField("partitions");
model.addDumpField("force");
model.dump();
-
model.setBaseNameToDumper("cohesive elements",
- "cohesive_elements_parallel_intrinsic");
+ "cohesive_elements_parallel_intrinsic");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.dump("cohesive elements");
/// initial conditions
Real loading_rate = .2;
for (UInt n = 0; n < nb_nodes; ++n) {
velocity(n, 0) = loading_rate * position(n, 0);
}
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
- if(s % 20 == 0) {
+ if (s % 20 == 0) {
model.dump();
model.dump("cohesive elements");
- if(prank == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
+ if (prank == 0)
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
// // update displacement
// for (UInt n = 0; n < nb_nodes; ++n) {
// if (position(n, 1) + displacement(n, 1) > 0) {
// displacement(n, 0) -= 0.01;
// }
// }
- // Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
- // Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
+ // Real Ed = dynamic_cast<MaterialCohesive&>
+ // (model.getMaterial(1)).getDissipatedEnergy();
+ // Real Er = dynamic_cast<MaterialCohesive&>
+ // (model.getMaterial(1)).getReversibleEnergy();
// edis << s << " "
// << Ed << std::endl;
// erev << s << " "
// << Er << std::endl;
-
}
// edis.close();
// erev.close();
Real Ed = model.getEnergy("dissipated");
Real Edt = 2 * sqrt(2);
-
- if(prank == 0) {
+ if (prank == 0) {
std::cout << Ed << " " << Edt << std::endl;
if (std::abs((Ed - Edt) / Edt) > 0.01 || std::isnan(Ed)) {
std::cout << "The dissipated energy is incorrect" << std::endl;
return EXIT_FAILURE;
}
}
finalize();
- if(prank == 0) std::cout << "OK: Test passed!" << std::endl;
+ if (prank == 0)
+ std::cout << "OK: Test passed!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc
index 983104b34..9a99b4b88 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc
@@ -1,704 +1,698 @@
/**
* @file test_cohesive_parallel_intrinsic_tetrahedron.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief Test for 3D intrinsic cohesive elements simulation in parallel
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_cohesive.hh"
#include "dumper_paraview.hh"
#include "material_cohesive.hh"
+#include "solid_mechanics_model_cohesive.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
void updateDisplacement(SolidMechanicsModelCohesive & model,
- const ElementTypeMapArray<UInt> & elements,
- Vector<Real> & increment);
+ const ElementTypeMapArray<UInt> & elements,
+ Vector<Real> & increment);
-bool checkTractions(SolidMechanicsModelCohesive & model,
- Vector<Real> & opening,
- Vector<Real> & theoretical_traction,
- Matrix<Real> & rotation);
+bool checkTractions(SolidMechanicsModelCohesive & model, Vector<Real> & opening,
+ Vector<Real> & theoretical_traction,
+ Matrix<Real> & rotation);
void findNodesToCheck(const Mesh & mesh,
- const ElementTypeMapArray<UInt> & elements,
- Array<UInt> & nodes_to_check,
- Int psize);
+ const ElementTypeMapArray<UInt> & elements,
+ Array<UInt> & nodes_to_check, Int psize);
-bool checkEquilibrium(const Mesh & mesh,
- const Array<Real> & residual);
+bool checkEquilibrium(const Mesh & mesh, const Array<Real> & residual);
-bool checkResidual(const Array<Real> & residual,
- const Vector<Real> & traction,
- const Array<UInt> & nodes_to_check,
- const Matrix<Real> & rotation);
+bool checkResidual(const Array<Real> & residual, const Vector<Real> & traction,
+ const Array<UInt> & nodes_to_check,
+ const Matrix<Real> & rotation);
void findElementsToDisplace(const Mesh & mesh,
- ElementTypeMapArray<UInt> & elements);
+ ElementTypeMapArray<UInt> & elements);
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material_tetrahedron.dat", argc, argv);
const UInt spatial_dimension = 3;
const UInt max_steps = 60;
const Real increment_constant = 0.01;
ElementType type = _tetrahedron_10;
Math::setTolerance(1.e-10);
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
UInt nb_nodes_to_check_serial = 0;
UInt total_nb_nodes = 0;
UInt nb_elements_check_serial = 0;
akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
+ if (prank == 0) {
// Read the mesh
mesh.read("tetrahedron.msh");
/// count nodes with zero position
const Array<Real> & position = mesh.getNodes();
for (UInt n = 0; n < position.getSize(); ++n) {
if (std::abs(position(n, 0) - 0.) < 1e-6)
- ++nb_nodes_to_check_serial;
+ ++nb_nodes_to_check_serial;
}
// /// insert cohesive elements
// CohesiveElementInserter inserter(mesh);
// inserter.setLimit(0, -0.01, 0.01);
// inserter.insertIntrinsicElements();
/// find nodes to check in serial
ElementTypeMapArray<UInt> elements_serial("elements_serial", "");
findElementsToDisplace(mesh, elements_serial);
nb_elements_check_serial = elements_serial(type).getSize();
total_nb_nodes = mesh.getNbNodes() + nb_nodes_to_check_serial;
/// partition the mesh
partition = new MeshPartitionScotch(mesh, spatial_dimension);
debug::setDebugLevel(dblDump);
partition->partitionate(psize);
debug::setDebugLevel(dblInfo);
}
comm.broadcast(&nb_nodes_to_check_serial, 1, 0);
comm.broadcast(&nb_elements_check_serial, 1, 0);
SolidMechanicsModelCohesive model(mesh);
model.initParallel(partition);
model.initFull();
model.limitInsertion(_x, -0.01, 0.01);
model.insertIntrinsicElements();
{
comm.broadcast(&total_nb_nodes, 1, 0);
Array<Int> nb_local_nodes(psize);
nb_local_nodes.clear();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (mesh.isLocalOrMasterNode(n)) ++nb_local_nodes(prank);
+ if (mesh.isLocalOrMasterNode(n))
+ ++nb_local_nodes(prank);
}
comm.allGather(nb_local_nodes.storage(), 1);
- UInt total_nb_nodes_parallel = std::accumulate(nb_local_nodes.begin(),
- nb_local_nodes.end(), 0);
+ UInt total_nb_nodes_parallel =
+ std::accumulate(nb_local_nodes.begin(), nb_local_nodes.end(), 0);
Array<UInt> global_nodes_list(total_nb_nodes_parallel);
UInt first_global_node = std::accumulate(nb_local_nodes.begin(),
- nb_local_nodes.begin() + prank, 0);
+ nb_local_nodes.begin() + prank, 0);
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
if (mesh.isLocalOrMasterNode(n)) {
- global_nodes_list(first_global_node) = mesh.getNodeGlobalId(n);
- ++first_global_node;
+ global_nodes_list(first_global_node) = mesh.getNodeGlobalId(n);
+ ++first_global_node;
}
}
comm.allGatherV(global_nodes_list.storage(), nb_local_nodes.storage());
if (prank == 0)
std::cout << "Maximum node index: "
- << *(std::max_element(global_nodes_list.begin(),
- global_nodes_list.end())) << std::endl;
+ << *(std::max_element(global_nodes_list.begin(),
+ global_nodes_list.end()))
+ << std::endl;
Array<UInt> repeated_nodes;
repeated_nodes.resize(0);
for (UInt n = 0; n < total_nb_nodes_parallel; ++n) {
- UInt appearances = std::count(global_nodes_list.begin() + n,
- global_nodes_list.end(),
- global_nodes_list(n));
+ UInt appearances =
+ std::count(global_nodes_list.begin() + n, global_nodes_list.end(),
+ global_nodes_list(n));
if (appearances > 1) {
- std::cout << "Node " << global_nodes_list(n)
- << " appears " << appearances << " times" << std::endl;
+ std::cout << "Node " << global_nodes_list(n) << " appears "
+ << appearances << " times" << std::endl;
- std::cout << " in position: " << n;
+ std::cout << " in position: " << n;
- repeated_nodes.push_back(global_nodes_list(n));
+ repeated_nodes.push_back(global_nodes_list(n));
- UInt * node_position = global_nodes_list.storage() + n;
+ UInt * node_position = global_nodes_list.storage() + n;
- for (UInt i = 1; i < appearances; ++i) {
- node_position = std::find(node_position + 1,
- global_nodes_list.storage()
- + total_nb_nodes_parallel,
- global_nodes_list(n));
+ for (UInt i = 1; i < appearances; ++i) {
+ node_position =
+ std::find(node_position + 1,
+ global_nodes_list.storage() + total_nb_nodes_parallel,
+ global_nodes_list(n));
- UInt current_index = node_position - global_nodes_list.storage();
+ UInt current_index = node_position - global_nodes_list.storage();
- std::cout << ", " << current_index;
- }
- std::cout << std::endl << std::endl;
+ std::cout << ", " << current_index;
+ }
+ std::cout << std::endl << std::endl;
}
}
-
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
UInt global_node = mesh.getNodeGlobalId(n);
- if (std::find(repeated_nodes.begin(), repeated_nodes.end(), global_node)
- != repeated_nodes.end()) {
- std::cout << "Repeated global node " << global_node
- << " corresponds to local node " << n << std::endl;
+ if (std::find(repeated_nodes.begin(), repeated_nodes.end(),
+ global_node) != repeated_nodes.end()) {
+ std::cout << "Repeated global node " << global_node
+ << " corresponds to local node " << n << std::endl;
}
}
-
if (total_nb_nodes != total_nb_nodes_parallel) {
if (prank == 0) {
- std::cout << "Error: total number of nodes is wrong in parallel" << std::endl;
- std::cout << "Serial: " << total_nb_nodes
- << " Parallel: " << total_nb_nodes_parallel << std::endl;
+ std::cout << "Error: total number of nodes is wrong in parallel"
+ << std::endl;
+ std::cout << "Serial: " << total_nb_nodes
+ << " Parallel: " << total_nb_nodes_parallel << std::endl;
}
finalize();
return EXIT_FAILURE;
}
}
model.updateResidual();
model.setBaseName("intrinsic_parallel_tetrahedron");
model.addDumpFieldVector("displacement");
model.addDumpField("residual");
model.addDumpField("partitions");
model.dump();
model.setBaseNameToDumper("cohesive elements",
- "cohesive_elements_parallel_tetrahedron");
+ "cohesive_elements_parallel_tetrahedron");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.dump("cohesive elements");
/// find elements to displace
ElementTypeMapArray<UInt> elements("elements", "");
findElementsToDisplace(mesh, elements);
UInt nb_elements_check = elements(type).getSize();
comm.allReduce(&nb_elements_check, 1, _so_sum);
if (nb_elements_check != nb_elements_check_serial) {
if (prank == 0) {
std::cout << "Error: number of elements to check is wrong" << std::endl;
std::cout << "Serial: " << nb_elements_check_serial
- << " Parallel: " << nb_elements_check << std::endl;
+ << " Parallel: " << nb_elements_check << std::endl;
}
finalize();
return EXIT_FAILURE;
}
/// find nodes to check
Array<UInt> nodes_to_check;
findNodesToCheck(mesh, elements, nodes_to_check, psize);
Vector<Int> nodes_to_check_size(psize);
nodes_to_check_size(prank) = nodes_to_check.getSize();
comm.allGather(nodes_to_check_size.storage(), 1);
- UInt nodes_to_check_global_size = std::accumulate(nodes_to_check_size.storage(),
- nodes_to_check_size.storage()
- + psize, 0);
+ UInt nodes_to_check_global_size = std::accumulate(
+ nodes_to_check_size.storage(), nodes_to_check_size.storage() + psize, 0);
if (nodes_to_check_global_size != nb_nodes_to_check_serial) {
if (prank == 0) {
- std::cout << "Error: number of nodes to check is wrong in parallel" << std::endl;
+ std::cout << "Error: number of nodes to check is wrong in parallel"
+ << std::endl;
std::cout << "Serial: " << nb_nodes_to_check_serial
- << " Parallel: " << nodes_to_check_global_size << std::endl;
+ << " Parallel: " << nodes_to_check_global_size << std::endl;
}
finalize();
return EXIT_FAILURE;
}
/// rotate mesh
Real angle = 1.;
Matrix<Real> rotation(spatial_dimension, spatial_dimension);
rotation.clear();
rotation(0, 0) = std::cos(angle);
rotation(0, 1) = std::sin(angle) * -1.;
rotation(1, 0) = std::sin(angle);
rotation(1, 1) = std::cos(angle);
rotation(2, 2) = 1.;
-
Vector<Real> increment_tmp(spatial_dimension);
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
increment_tmp(dim) = (dim + 1) * increment_constant;
}
Vector<Real> increment(spatial_dimension);
increment.mul<false>(rotation, increment_tmp);
Array<Real> & position = mesh.getNodes();
Array<Real> position_tmp(position);
- Array<Real>::iterator<Vector<Real> > position_it = position.begin(spatial_dimension);
- Array<Real>::iterator<Vector<Real> > position_end = position.end(spatial_dimension);
- Array<Real>::iterator<Vector<Real> > position_tmp_it
- = position_tmp.begin(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> position_it =
+ position.begin(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> position_end =
+ position.end(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> position_tmp_it =
+ position_tmp.begin(spatial_dimension);
for (; position_it != position_end; ++position_it, ++position_tmp_it)
position_it->mul<false>(rotation, *position_tmp_it);
model.dump();
model.dump("cohesive elements");
updateDisplacement(model, elements, increment);
-
Real theoretical_Ed = 0;
Vector<Real> opening(spatial_dimension);
Vector<Real> traction(spatial_dimension);
Vector<Real> opening_old(spatial_dimension);
Vector<Real> traction_old(spatial_dimension);
opening.clear();
traction.clear();
opening_old.clear();
traction_old.clear();
Vector<Real> Dt(spatial_dimension);
Vector<Real> Do(spatial_dimension);
const Array<Real> & residual = model.getResidual();
/// Main loop
for (UInt s = 1; s <= max_steps; ++s) {
model.updateResidual();
opening += increment_tmp;
if (checkTractions(model, opening, traction, rotation) ||
- checkEquilibrium(mesh, residual) ||
- checkResidual(residual, traction, nodes_to_check, rotation)) {
+ checkEquilibrium(mesh, residual) ||
+ checkResidual(residual, traction, nodes_to_check, rotation)) {
finalize();
return EXIT_FAILURE;
}
/// compute energy
Do = opening;
Do -= opening_old;
Dt = traction_old;
Dt += traction;
theoretical_Ed += .5 * Do.dot(Dt);
opening_old = opening;
traction_old = traction;
-
updateDisplacement(model, elements, increment);
- if(s % 10 == 0) {
+ if (s % 10 == 0) {
if (prank == 0)
- std::cout << "passing step " << s << "/" << max_steps << std::endl;
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
model.dump();
model.dump("cohesive elements");
}
}
model.dump();
model.dump("cohesive elements");
Real Ed = model.getEnergy("dissipated");
theoretical_Ed *= 4.;
if (prank == 0)
std::cout << "Dissipated energy: " << Ed
- << ", theoretical value: " << theoretical_Ed << std::endl;
+ << ", theoretical value: " << theoretical_Ed << std::endl;
if (!Math::are_float_equal(Ed, theoretical_Ed) || std::isnan(Ed)) {
if (prank == 0)
std::cout << "Error: the dissipated energy is incorrect" << std::endl;
finalize();
return EXIT_FAILURE;
}
finalize();
- if(prank == 0) std::cout << "OK: Test passed!" << std::endl;
+ if (prank == 0)
+ std::cout << "OK: Test passed!" << std::endl;
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
void updateDisplacement(SolidMechanicsModelCohesive & model,
- const ElementTypeMapArray<UInt> & elements,
- Vector<Real> & increment) {
+ const ElementTypeMapArray<UInt> & elements,
+ Vector<Real> & increment) {
UInt spatial_dimension = model.getSpatialDimension();
Mesh & mesh = model.getFEEngine().getMesh();
UInt nb_nodes = mesh.getNbNodes();
Array<Real> & displacement = model.getDisplacement();
Array<bool> update(nb_nodes);
update.clear();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, ghost_type);
for (; it != last; ++it) {
ElementType type = *it;
const Array<UInt> & elem = elements(type, ghost_type);
const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
UInt nb_nodes_per_element = connectivity.getNbComponent();
for (UInt el = 0; el < elem.getSize(); ++el) {
- for (UInt n = 0; n < nb_nodes_per_element; ++n) {
- UInt node = connectivity(elem(el), n);
- if (!update(node)) {
- Vector<Real> node_disp(displacement.storage() + node * spatial_dimension,
- spatial_dimension);
- node_disp += increment;
- update(node) = true;
- }
- }
+ for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+ UInt node = connectivity(elem(el), n);
+ if (!update(node)) {
+ Vector<Real> node_disp(displacement.storage() +
+ node * spatial_dimension,
+ spatial_dimension);
+ node_disp += increment;
+ update(node) = true;
+ }
+ }
}
}
}
}
/* -------------------------------------------------------------------------- */
-bool checkTractions(SolidMechanicsModelCohesive & model,
- Vector<Real> & opening,
- Vector<Real> & theoretical_traction,
- Matrix<Real> & rotation) {
+bool checkTractions(SolidMechanicsModelCohesive & model, Vector<Real> & opening,
+ Vector<Real> & theoretical_traction,
+ Matrix<Real> & rotation) {
UInt spatial_dimension = model.getSpatialDimension();
const Mesh & mesh = model.getMesh();
- const MaterialCohesive & mat_cohesive
- = dynamic_cast < const MaterialCohesive & > (model.getMaterial(1));
+ const MaterialCohesive & mat_cohesive =
+ dynamic_cast<const MaterialCohesive &>(model.getMaterial(1));
- Real sigma_c = mat_cohesive.getParam< RandomInternalField<Real, FacetInternalField> >("sigma_c");
+ Real sigma_c =
+ mat_cohesive.getParam<RandomInternalField<Real, FacetInternalField>>(
+ "sigma_c");
const Real beta = mat_cohesive.getParam<Real>("beta");
const Real G_cI = mat_cohesive.getParam<Real>("G_c");
// Real G_cII = mat_cohesive.getParam<Real>("G_cII");
const Real delta_0 = mat_cohesive.getParam<Real>("delta_0");
const Real kappa = mat_cohesive.getParam<Real>("kappa");
Real delta_c = 2 * G_cI / sigma_c;
sigma_c *= delta_c / (delta_c - delta_0);
Vector<Real> normal_opening(spatial_dimension);
normal_opening.clear();
normal_opening(0) = opening(0);
Real normal_opening_norm = normal_opening.norm();
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening.clear();
for (UInt dim = 1; dim < spatial_dimension; ++dim)
tangential_opening(dim) = opening(dim);
Real tangential_opening_norm = tangential_opening.norm();
- Real beta2_kappa2 = beta * beta/kappa/kappa;
- Real beta2_kappa = beta * beta/kappa;
+ Real beta2_kappa2 = beta * beta / kappa / kappa;
+ Real beta2_kappa = beta * beta / kappa;
- Real delta = std::sqrt(tangential_opening_norm * tangential_opening_norm
- * beta2_kappa2 +
- normal_opening_norm * normal_opening_norm);
+ Real delta = std::sqrt(tangential_opening_norm * tangential_opening_norm *
+ beta2_kappa2 +
+ normal_opening_norm * normal_opening_norm);
delta = std::max(delta, delta_0);
Real theoretical_damage = std::min(delta / delta_c, 1.);
if (Math::are_float_equal(theoretical_damage, 1.))
theoretical_traction.clear();
else {
- theoretical_traction = tangential_opening;
+ theoretical_traction = tangential_opening;
theoretical_traction *= beta2_kappa;
theoretical_traction += normal_opening;
theoretical_traction *= sigma_c / delta * (1. - theoretical_damage);
}
Vector<Real> theoretical_traction_rotated(spatial_dimension);
theoretical_traction_rotated.mul<false>(rotation, theoretical_traction);
// adjust damage
theoretical_damage = std::max((delta - delta_0) / (delta_c - delta_0), 0.);
theoretical_damage = std::min(theoretical_damage, 1.);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it
- = mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
- Mesh::type_iterator last
- = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
-
+ Mesh::type_iterator it =
+ mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
+ Mesh::type_iterator last =
+ mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
+
for (; it != last; ++it) {
ElementType type = *it;
const Array<Real> & traction = mat_cohesive.getTraction(type, ghost_type);
const Array<Real> & damage = mat_cohesive.getDamage(type, ghost_type);
- UInt nb_quad_per_el
- = model.getFEEngine("CohesiveFEEngine").getNbIntegrationPoints(type);
+ UInt nb_quad_per_el =
+ model.getFEEngine("CohesiveFEEngine").getNbIntegrationPoints(type);
UInt nb_element = model.getMesh().getNbElement(type, ghost_type);
UInt tot_nb_quad = nb_element * nb_quad_per_el;
for (UInt q = 0; q < tot_nb_quad; ++q) {
- for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- if (!Math::are_float_equal(std::abs(theoretical_traction_rotated(dim)),
- std::abs(traction(q, dim)))) {
- std::cout << "Error: tractions are incorrect" << std::endl;
- return 1;
- }
- }
-
- if (ghost_type == _not_ghost)
- if (!Math::are_float_equal(theoretical_damage, damage(q))) {
- std::cout << "Error: damage is incorrect" << std::endl;
- return 1;
- }
+ for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+ if (!Math::are_float_equal(
+ std::abs(theoretical_traction_rotated(dim)),
+ std::abs(traction(q, dim)))) {
+ std::cout << "Error: tractions are incorrect" << std::endl;
+ return 1;
+ }
+ }
+
+ if (ghost_type == _not_ghost)
+ if (!Math::are_float_equal(theoretical_damage, damage(q))) {
+ std::cout << "Error: damage is incorrect" << std::endl;
+ return 1;
+ }
}
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
void findNodesToCheck(const Mesh & mesh,
- const ElementTypeMapArray<UInt> & elements,
- Array<UInt> & nodes_to_check,
- Int psize) {
+ const ElementTypeMapArray<UInt> & elements,
+ Array<UInt> & nodes_to_check, Int psize) {
const auto & comm = Communicator::getStaticCommunicator();
Int prank = comm.whoAmI();
nodes_to_check.resize(0);
Array<UInt> global_nodes_to_check;
UInt spatial_dimension = mesh.getSpatialDimension();
const Array<Real> & position = mesh.getNodes();
UInt nb_nodes = position.getSize();
Array<bool> checked_nodes(nb_nodes);
checked_nodes.clear();
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator last = mesh.lastType(spatial_dimension);
for (; it != last; ++it) {
ElementType type = *it;
const Array<UInt> & elem = elements(type);
const Array<UInt> & connectivity = mesh.getConnectivity(type);
UInt nb_nodes_per_elem = connectivity.getNbComponent();
for (UInt el = 0; el < elem.getSize(); ++el) {
UInt element = elem(el);
Vector<UInt> conn_el(connectivity.storage() + nb_nodes_per_elem * element,
- nb_nodes_per_elem);
+ nb_nodes_per_elem);
for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
- UInt node = conn_el(n);
- if (std::abs(position(node, 0) - 0.) < 1.e-6
- && !checked_nodes(node)) {
- checked_nodes(node) = true;
- nodes_to_check.push_back(node);
- global_nodes_to_check.push_back(mesh.getNodeGlobalId(node));
- }
+ UInt node = conn_el(n);
+ if (std::abs(position(node, 0) - 0.) < 1.e-6 && !checked_nodes(node)) {
+ checked_nodes(node) = true;
+ nodes_to_check.push_back(node);
+ global_nodes_to_check.push_back(mesh.getNodeGlobalId(node));
+ }
}
}
}
std::vector<CommunicationRequest *> requests;
for (Int p = prank + 1; p < psize; ++p) {
requests.push_back(comm.asyncSend(global_nodes_to_check.storage(),
- global_nodes_to_check.getSize(),
- p, prank));
+ global_nodes_to_check.getSize(), p,
+ prank));
}
Array<UInt> recv_nodes;
for (Int p = 0; p < prank; ++p) {
CommunicationStatus status;
comm.probe<UInt>(p, p, status);
UInt recv_nodes_size = recv_nodes.getSize();
recv_nodes.resize(recv_nodes_size + status.getSize());
- comm.receive(recv_nodes.storage() + recv_nodes_size, status.getSize(), p, p);
+ comm.receive(recv_nodes.storage() + recv_nodes_size, status.getSize(), p,
+ p);
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
for (UInt i = 0; i < recv_nodes.getSize(); ++i) {
- Array<UInt>::iterator<UInt> node_position
- = std::find(global_nodes_to_check.begin(),
- global_nodes_to_check.end(),
- recv_nodes(i));
+ Array<UInt>::iterator<UInt> node_position =
+ std::find(global_nodes_to_check.begin(), global_nodes_to_check.end(),
+ recv_nodes(i));
if (node_position != global_nodes_to_check.end()) {
UInt index = node_position - global_nodes_to_check.begin();
nodes_to_check.erase(index);
global_nodes_to_check.erase(index);
}
}
}
/* -------------------------------------------------------------------------- */
-bool checkEquilibrium(const Mesh & mesh,
- const Array<Real> & residual) {
+bool checkEquilibrium(const Mesh & mesh, const Array<Real> & residual) {
UInt spatial_dimension = residual.getNbComponent();
Vector<Real> residual_sum(spatial_dimension);
residual_sum.clear();
- Array<Real>::const_iterator<Vector<Real> > res_it
- = residual.begin(spatial_dimension);
+ Array<Real>::const_iterator<Vector<Real>> res_it =
+ residual.begin(spatial_dimension);
for (UInt n = 0; n < residual.getSize(); ++n, ++res_it) {
if (mesh.isLocalOrMasterNode(n))
residual_sum += *res_it;
}
const auto & comm = Communicator::getStaticCommunicator();
comm.allReduce(residual_sum.storage(), spatial_dimension, _so_sum);
for (UInt s = 0; s < spatial_dimension; ++s) {
if (!Math::are_float_equal(residual_sum(s), 0.)) {
if (comm.whoAmI() == 0)
- std::cout << "Error: system is not in equilibrium!" << std::endl;
+ std::cout << "Error: system is not in equilibrium!" << std::endl;
return 1;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
-bool checkResidual(const Array<Real> & residual,
- const Vector<Real> & traction,
- const Array<UInt> & nodes_to_check,
- const Matrix<Real> & rotation) {
+bool checkResidual(const Array<Real> & residual, const Vector<Real> & traction,
+ const Array<UInt> & nodes_to_check,
+ const Matrix<Real> & rotation) {
UInt spatial_dimension = residual.getNbComponent();
Vector<Real> total_force(spatial_dimension);
total_force.clear();
for (UInt n = 0; n < nodes_to_check.getSize(); ++n) {
UInt node = nodes_to_check(n);
Vector<Real> res(residual.storage() + node * spatial_dimension,
- spatial_dimension);
+ spatial_dimension);
total_force += res;
}
const auto & comm = Communicator::getStaticCommunicator();
comm.allReduce(total_force.storage(), spatial_dimension, _so_sum);
Vector<Real> theoretical_total_force(spatial_dimension);
theoretical_total_force.mul<false>(rotation, traction);
theoretical_total_force *= -1 * 2 * 2;
for (UInt s = 0; s < spatial_dimension; ++s) {
if (!Math::are_float_equal(total_force(s), theoretical_total_force(s))) {
if (comm.whoAmI() == 0)
- std::cout << "Error: total force isn't correct!" << std::endl;
+ std::cout << "Error: total force isn't correct!" << std::endl;
return 1;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
void findElementsToDisplace(const Mesh & mesh,
- ElementTypeMapArray<UInt> & elements) {
+ ElementTypeMapArray<UInt> & elements) {
UInt spatial_dimension = mesh.getSpatialDimension();
mesh.initElementTypeMapArray(elements, 1, spatial_dimension);
Vector<Real> bary(spatial_dimension);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, ghost_type);
for (; it != last; ++it) {
ElementType type = *it;
Array<UInt> & elem = elements(type, ghost_type);
UInt nb_element = mesh.getNbElement(type, ghost_type);
for (UInt el = 0; el < nb_element; ++el) {
- mesh.getBarycenter(el, type, bary.storage(), ghost_type);
- if (bary(0) > 0.0001) elem.push_back(el);
+ mesh.getBarycenter(el, type, bary.storage(), ghost_type);
+ if (bary(0) > 0.0001)
+ elem.push_back(el);
}
}
}
}
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc
index be0eeabd1..4a222cf57 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc
@@ -1,96 +1,99 @@
/**
* @file test_embedded_element_matrix.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Wed Mar 25 2015
* @date last modification: Wed May 13 2015
*
* @brief test of the class EmbeddedInterfaceModel
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "embedded_interface_model.hh"
-#include "sparse_solver.hh"
#include "sparse_matrix_aij.hh"
+#include "sparse_solver.hh"
using namespace akantu;
int main(int argc, char * argv[]) {
debug::setDebugLevel(dblWarning);
initialize("embedded_element.dat", argc, argv);
constexpr UInt dim = 2;
constexpr ElementType type = _segment_2;
const Real height = 0.4;
Mesh mesh(dim);
mesh.read("triangle.msh");
Mesh reinforcement_mesh(dim, "reinforcement_mesh");
auto & nodes = reinforcement_mesh.getNodes();
nodes.push_back(Vector<Real>({0, height}));
nodes.push_back(Vector<Real>({1, height}));
reinforcement_mesh.addConnectivityType(type);
auto & connectivity = reinforcement_mesh.getConnectivity(type);
connectivity.push_back(Vector<UInt>({0, 1}));
Array<std::string> names_vec(1, 1, "reinforcement", "reinforcement_names");
- reinforcement_mesh.registerData<std::string>("physical_names").alloc(1, 1, type);
- reinforcement_mesh.getData<std::string>("physical_names")(type).copy(names_vec);
+ reinforcement_mesh.registerData<std::string>("physical_names")
+ .alloc(1, 1, type);
+ reinforcement_mesh.getData<std::string>("physical_names")(type).copy(
+ names_vec);
EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
model.initFull(_analysis_method = _static);
if (model.getInterfaceMesh().getNbElement(type) != 1)
return EXIT_FAILURE;
if (model.getInterfaceMesh().getSpatialDimension() != 2)
return EXIT_FAILURE;
try { // matrix should be singular
model.solveStep();
} catch (debug::SingularMatrixException & e) {
- std::cerr << "Matrix is singular, relax, everything is fine :)" << std::endl;
+ std::cerr << "Matrix is singular, relax, everything is fine :)"
+ << std::endl;
} catch (debug::Exception & e) {
std::cerr << "Unexpceted error: " << e.what() << std::endl;
throw e;
}
SparseMatrixAIJ & K =
dynamic_cast<SparseMatrixAIJ &>(model.getDOFManager().getMatrix("K"));
K.saveMatrix("stiffness.mtx");
Math::setTolerance(1e-8);
// Testing the assembled stiffness matrix
if (!Math::are_float_equal(K(0, 0), 1. - height) ||
!Math::are_float_equal(K(0, 2), height - 1.) ||
!Math::are_float_equal(K(2, 0), height - 1.) ||
!Math::are_float_equal(K(2, 2), 1. - height))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc
index fd4603895..f92d5445d 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc
@@ -1,103 +1,108 @@
/**
* @file test_embedded_interface_model.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Wed Mar 25 2015
* @date last modification: Thu Jul 09 2015
*
* @brief Embedded model test based on potential energy
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <iostream>
#include "aka_common.hh"
#include "embedded_interface_model.hh"
#include "sparse_matrix.hh"
using namespace akantu;
-int main (int argc, char * argv[]) {
+int main(int argc, char * argv[]) {
debug::setDebugLevel(dblWarning);
initialize("material.dat", argc, argv);
UInt dim = 2;
Math::setTolerance(1e-7);
-
+
// Mesh here is a 1x1 patch
Mesh mesh(dim);
mesh.read("embedded_mesh.msh");
Array<Real> nodes_vec(2, dim, "reinforcement_nodes");
- nodes_vec.storage()[0] = 0; nodes_vec.storage()[1] = 0.5;
- nodes_vec.storage()[2] = 1; nodes_vec.storage()[3] = 0.5;
+ nodes_vec.storage()[0] = 0;
+ nodes_vec.storage()[1] = 0.5;
+ nodes_vec.storage()[2] = 1;
+ nodes_vec.storage()[3] = 0.5;
Array<UInt> conn_vec(1, 2, "reinforcement_connectivity");
- conn_vec.storage()[0] = 0; conn_vec.storage()[1] = 1;
+ conn_vec.storage()[0] = 0;
+ conn_vec.storage()[1] = 1;
Array<std::string> names_vec(1, 1, "reinforcement", "reinforcement_names");
Mesh reinforcement_mesh(dim, "reinforcement_mesh");
reinforcement_mesh.getNodes().copy(nodes_vec);
reinforcement_mesh.addConnectivityType(_segment_2);
reinforcement_mesh.getConnectivity(_segment_2).copy(conn_vec);
- reinforcement_mesh.registerData<std::string>("physical_names").alloc(1, 1, _segment_2);
- reinforcement_mesh.getData<std::string>("physical_names")(_segment_2).copy(names_vec);
+ reinforcement_mesh.registerData<std::string>("physical_names")
+ .alloc(1, 1, _segment_2);
+ reinforcement_mesh.getData<std::string>("physical_names")(_segment_2)
+ .copy(names_vec);
EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
model.initFull(_analysis_method = _static);
- Array<Real> & nodes = mesh.getNodes();
+ Array<Real> & nodes = mesh.getNodes();
Array<Real> & forces = model.getForce();
- Array<bool> & bound = model.getBlockedDOFs();
+ Array<bool> & bound = model.getBlockedDOFs();
forces(2, 0) = -250;
forces(5, 0) = -500;
forces(8, 0) = -250;
- for (UInt i = 0 ; i < mesh.getNbNodes() ; i++) {
+ for (UInt i = 0; i < mesh.getNbNodes(); i++) {
if (Math::are_float_equal(nodes(i, 0), 0.))
bound(i, 0) = true;
if (Math::are_float_equal(nodes(i, 1), 0.))
bound(i, 1) = true;
}
model.addDumpFieldVector("displacement");
model.addDumpFieldTensor("stress");
model.setBaseNameToDumper("reinforcement", "reinforcement");
model.addDumpFieldTensorToDumper("reinforcement", "stress_embedded");
model.solveStep();
model.getDOFManager().getMatrix("K").saveMatrix("matrix_test");
model.dump();
Real pot_energy = model.getEnergy("potential");
if (std::abs(pot_energy - 7.37343e-06) > 1e-5)
return EXIT_FAILURE;
finalize();
return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
index e5b0f00ed..efa3bcb5c 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
@@ -1,224 +1,234 @@
/**
* @file test_embedded_interface_model_prestress.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Tue Apr 28 2015
* @date last modification: Thu Oct 15 2015
*
* @brief Embedded model test for prestressing (bases on stress norm)
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "aka_common.hh"
#include "embedded_interface_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
#define YG 0.483644859
#define I_eq 0.012488874
#define A_eq (1e-2 + 1. / 7. * 1.)
/* -------------------------------------------------------------------------- */
struct StressSolution : public BC::Neumann::FromHigherDim {
Real M;
Real I;
Real yg;
Real pre_stress;
- StressSolution(UInt dim, Real M, Real I, Real yg = 0, Real pre_stress = 0) :
- BC::Neumann::FromHigherDim(Matrix<Real>(dim, dim)),
- M(M), I(I), yg(yg), pre_stress(pre_stress)
- {}
+ StressSolution(UInt dim, Real M, Real I, Real yg = 0, Real pre_stress = 0)
+ : BC::Neumann::FromHigherDim(Matrix<Real>(dim, dim)), M(M), I(I), yg(yg),
+ pre_stress(pre_stress) {}
virtual ~StressSolution() {}
void operator()(const IntegrationPoint & /*quad_point*/, Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
UInt dim = coord.size();
- if (dim < 2) AKANTU_ERROR("Solution not valid for 1D");
+ if (dim < 2)
+ AKANTU_ERROR("Solution not valid for 1D");
- Matrix<Real> stress(dim, dim); stress.clear();
+ Matrix<Real> stress(dim, dim);
+ stress.clear();
stress(0, 0) = this->stress(coord(1));
dual.mul<false>(stress, normals);
}
inline Real stress(Real height) const {
return -M / I * (height - yg) + pre_stress;
}
- inline Real neutral_axis() const {
- return -I * pre_stress / M + yg;
- }
+ inline Real neutral_axis() const { return -I * pre_stress / M + yg; }
};
/* -------------------------------------------------------------------------- */
-int main (int argc, char * argv[]) {
+int main(int argc, char * argv[]) {
initialize("prestress.dat", argc, argv);
debug::setDebugLevel(dblError);
Math::setTolerance(1e-6);
const UInt dim = 2;
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
Mesh mesh(dim);
mesh.read("embedded_mesh_prestress.msh");
// mesh.createGroupsFromMeshData<std::string>("physical_names");
Mesh reinforcement_mesh(dim, "reinforcement_mesh");
try {
reinforcement_mesh.read("embedded_mesh_prestress_reinforcement.msh");
- } catch(debug::Exception & e) {}
+ } catch (debug::Exception & e) {
+ }
// reinforcement_mesh.createGroupsFromMeshData<std::string>("physical_names");
EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
model.initFull(EmbeddedInterfaceModelOptions(_static));
-/* -------------------------------------------------------------------------- */
-/* Computation of analytical residual */
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Computation of analytical residual */
+ /* --------------------------------------------------------------------------
+ */
/*
* q = 1000 N/m
* L = 20 m
* a = 1 m
*/
Real steel_area = model.getMaterial("reinforcement").get("area");
Real pre_stress = model.getMaterial("reinforcement").get("pre_stress");
Real stress_norm = 0.;
- StressSolution * concrete_stress = nullptr, * steel_stress = nullptr;
+ StressSolution *concrete_stress = nullptr, *steel_stress = nullptr;
Real pre_force = pre_stress * steel_area;
Real pre_moment = -pre_force * (YG - 0.25);
Real neutral_axis = YG - I_eq / A_eq * pre_force / pre_moment;
- concrete_stress = new StressSolution(dim, pre_moment, 7. * I_eq, YG, -pre_force / (7. * A_eq));
- steel_stress = new StressSolution(dim, pre_moment, I_eq, YG, pre_stress - pre_force / A_eq);
+ concrete_stress = new StressSolution(dim, pre_moment, 7. * I_eq, YG,
+ -pre_force / (7. * A_eq));
+ steel_stress = new StressSolution(dim, pre_moment, I_eq, YG,
+ pre_stress - pre_force / A_eq);
- stress_norm = std::abs(concrete_stress->stress(1)) * (1 - neutral_axis) * 0.5
- + std::abs(concrete_stress->stress(0)) * neutral_axis * 0.5
- + std::abs(steel_stress->stress(0.25)) * steel_area;
+ stress_norm =
+ std::abs(concrete_stress->stress(1)) * (1 - neutral_axis) * 0.5 +
+ std::abs(concrete_stress->stress(0)) * neutral_axis * 0.5 +
+ std::abs(steel_stress->stress(0.25)) * steel_area;
model.applyBC(*concrete_stress, "XBlocked");
auto end_node = *mesh.getElementGroup("EndNode").getNodeGroup().begin();
Vector<Real> end_node_force = model.getForce().begin(dim)[end_node];
- end_node_force(0) += steel_stress->stress(0.25) * steel_area;
+ end_node_force(0) += steel_stress->stress(0.25) * steel_area;
- Array<Real> analytical_residual(mesh.getNbNodes(), dim, "analytical_residual");
+ Array<Real> analytical_residual(mesh.getNbNodes(), dim,
+ "analytical_residual");
analytical_residual.copy(model.getForce());
model.getForce().clear();
delete concrete_stress;
delete steel_stress;
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "XBlocked");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "YBlocked");
try {
model.solveStep();
} catch (debug::Exception e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
-/* -------------------------------------------------------------------------- */
-/* Computation of FEM residual norm */
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* Computation of FEM residual norm */
+ /* --------------------------------------------------------------------------
+ */
ElementGroup & xblocked = mesh.getElementGroup("XBlocked");
NodeGroup & boundary_nodes = xblocked.getNodeGroup();
- NodeGroup::const_node_iterator
- nodes_it = boundary_nodes.begin(),
- nodes_end = boundary_nodes.end();
+ NodeGroup::const_node_iterator nodes_it = boundary_nodes.begin(),
+ nodes_end = boundary_nodes.end();
model.assembleInternalForces();
Array<Real> residual(mesh.getNbNodes(), dim, "my_residual");
residual.copy(model.getInternalForce());
residual -= model.getForce();
auto com_res = residual.begin(dim);
auto position = mesh.getNodes().begin(dim);
Real res_sum = 0.;
UInt lower_node = -1;
UInt upper_node = -1;
Real lower_dist = 1;
Real upper_dist = 1;
- for (; nodes_it != nodes_end ; ++nodes_it) {
+ for (; nodes_it != nodes_end; ++nodes_it) {
UInt node_number = *nodes_it;
const Vector<Real> res = com_res[node_number];
const Vector<Real> pos = position[node_number];
if (!Math::are_float_equal(pos(1), 0.25)) {
if ((std::abs(pos(1) - 0.25) < lower_dist) && (pos(1) < 0.25)) {
lower_dist = std::abs(pos(1) - 0.25);
lower_node = node_number;
}
if ((std::abs(pos(1) - 0.25) < upper_dist) && (pos(1) > 0.25)) {
upper_dist = std::abs(pos(1) - 0.25);
upper_node = node_number;
}
}
- for (UInt i = 0 ; i < dim ; i++) {
+ for (UInt i = 0; i < dim; i++) {
if (!Math::are_float_equal(pos(1), 0.25)) {
res_sum += std::abs(res(i));
}
}
}
- const Vector<Real> upper_res = com_res[upper_node], lower_res = com_res[lower_node];
+ const Vector<Real> upper_res = com_res[upper_node],
+ lower_res = com_res[lower_node];
const Vector<Real> end_node_res = com_res[end_node];
Vector<Real> delta = upper_res - lower_res;
delta *= lower_dist / (upper_dist + lower_dist);
Vector<Real> concrete_residual = lower_res + delta;
Vector<Real> steel_residual = end_node_res - concrete_residual;
- for (UInt i = 0 ; i < dim ; i++) {
+ for (UInt i = 0; i < dim; i++) {
res_sum += std::abs(concrete_residual(i));
res_sum += std::abs(steel_residual(i));
}
Real relative_error = std::abs(res_sum - stress_norm) / stress_norm;
if (relative_error > 1e-3) {
std::cerr << "Relative error = " << relative_error << std::endl;
return EXIT_FAILURE;
}
finalize();
return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy.cc b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy.cc
index 8894f0b55..a126740d2 100644
--- a/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy.cc
+++ b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_kinetic_energy.cc
@@ -1,92 +1,91 @@
/**
* @file test_solid_mechanics_model_kinetic_energy.cc
*
* @author Tobias Brink <tobias.brink@epfl.ch>
*
* @date creation: Tue Nov 15 2017
* @date last modification: Tue Nov 15 2017
*
* @brief test kinetic energy
*
* @section description
*
* This test uses a linear elastic material with density = 1, Young's
* modulus = 1, and Poisson's ratio = 0 and imposes a uniform velocity
* of 1. The volume of the mesh is 1 and thus we have a mass of 1 and
* therefore a kinetic energy of 0.5*m*v² = 0.5. The kind of
* constitutive law should not matter for this test, so we use linear
* elastic. We perform 5 timesteps and check the solution every time.
*
* @section LICENSE
*
* Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "../test_solid_mechanics_model_fixture.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
void test_body(SolidMechanicsModel & model, AnalysisMethod analysis_method) {
const auto spatial_dimension = model.getSpatialDimension();
getStaticParser().parse("test_solid_mechanics_model_"
"kinetic_energy_material.dat");
model.initFull(SolidMechanicsModelOptions(analysis_method));
model.assembleMassLumped();
/// impose initial velocity of 1, it should remain constant
auto & velo = model.getVelocity();
for (auto && velov : make_view(velo, spatial_dimension)) {
velov(_x) = 1;
}
/// set up timestep
auto time_step = model.getStableTimeStep() * 0.8;
model.setTimeStep(time_step);
/// run five times and look at the kinetic energy
for (uint i = 0; i < 5; ++i) {
/// make a step
model.solveStep();
/// compare energy to analytical solution
const Real E_ref = 0.5;
auto E_kin = model.getEnergy("kinetic");
EXPECT_NEAR(E_ref, E_kin, 1e-8);
}
}
-
TYPED_TEST(TestSMMFixture, KineticEnergyImplicit) {
test_body(*(this->model), _implicit_dynamic);
}
TYPED_TEST(TestSMMFixture, KineticEnergyExplicit) {
test_body(*(this->model), _explicit_lumped_mass);
}
} // namespace
diff --git a/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_quasistatic.cc b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_quasistatic.cc
index ff09faa67..e8873949f 100644
--- a/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_quasistatic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_energies/test_solid_mechanics_model_work_quasistatic.cc
@@ -1,136 +1,136 @@
/**
* @file test_solid_mechanics_model_work_quasistatic.cc
*
* @author Tobias Brink <tobias.brink@epfl.ch>
*
* @date creation: Tue Nov 29 2017
* @date last modification: Tue Nov 29 2017
*
* @brief test work in quasistatic
*
* @section description
*
* Assuming that the potential energy of a linear elastic material
* works correctly, the work in a static simulation must equal the
* potential energy of the material. Since the work in static is an
* infinitesimal work Fds, we need to integrate by increasing F from 0
* to F_final in steps. This test uses one Dirichlet boundary
* condition (with u = 0.0, 0.1, and -0.1) and one Neumann boundary
* condition for F on the opposite side. The final work must be the
* same for all u.
*
* @section LICENSE
*
* Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "../test_solid_mechanics_model_fixture.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
TYPED_TEST(TestSMMFixture, WorkQuasistatic) {
const auto spatial_dimension = this->spatial_dimension;
getStaticParser().parse("test_solid_mechanics_model_"
"work_material.dat");
/// model initialization
MeshUtils::buildFacets(*this->mesh);
this->model->initFull(_analysis_method = _static);
/// Create a node group for Neumann BCs.
auto & apply_force_grp = this->mesh->createNodeGroup("apply_force");
auto & fixed_grp = this->mesh->createNodeGroup("fixed");
const auto & pos = this->mesh->getNodes();
auto & lower = this->mesh->getLowerBounds();
auto & upper = this->mesh->getUpperBounds();
UInt i = 0;
for (auto && posv : make_view(pos, spatial_dimension)) {
if (posv(_x) > upper(_x) - 1e-6) {
apply_force_grp.add(i);
- } else if (posv(_x) < lower(_x) + 1e-6) {
+ } else if (posv(_x) < lower(_x) + 1e-6) {
fixed_grp.add(i);
}
++i;
}
this->mesh->createElementGroupFromNodeGroup("el_apply_force", "apply_force",
spatial_dimension - 1);
this->mesh->createElementGroupFromNodeGroup("el_fixed", "fixed",
spatial_dimension - 1);
std::vector<Real> displacements{0.0, 0.1, -0.1};
for (auto && u : displacements) {
this->model->applyBC(BC::Dirichlet::FixedValue(u, _x), "el_fixed");
Vector<Real> surface_traction(spatial_dimension);
Real work = 0.0;
Real Epot;
static const UInt N = 100;
for (UInt i = 0; i <= N; ++i) {
this->model->getForce().clear(); // reset external forces to zero
surface_traction(_x) = (1.0 * i) / N;
- if (spatial_dimension == 1) { //TODO: this is a hack to work
- // around non-implemented
- // BC::Neumann::FromTraction for 1D
+ if (spatial_dimension == 1) { // TODO: this is a hack to work
+ // around non-implemented
+ // BC::Neumann::FromTraction for 1D
auto & force = this->model->getForce();
for (auto && pair : zip(make_view(pos, spatial_dimension),
make_view(force, spatial_dimension))) {
auto & posv = std::get<0>(pair);
auto & forcev = std::get<1>(pair);
if (posv(_x) > upper(_x) - 1e-6) {
forcev(_x) = surface_traction(_x);
}
}
} else {
this->model->applyBC(BC::Neumann::FromTraction(surface_traction),
"el_apply_force");
}
/// Solve.
this->model->solveStep();
Epot = this->model->getEnergy("potential");
// In static, this is infinitesimal work!
auto Fds = this->model->getEnergy("external work");
work += Fds; // integrate
/// Check that no work was done for zero force.
if (i == 0) {
EXPECT_NEAR(work, 0.0, 1e-12);
}
}
// Due to the finite integration steps, we make a rather large error
// in our work integration, thus the allowed delta is 1e-2.
EXPECT_NEAR(work, Epot, 1e-2);
}
}
} // namespace
diff --git a/test/test_model/test_solid_mechanics_model/test_material_selector.cc b/test/test_model/test_solid_mechanics_model/test_material_selector.cc
index 74be6f0f9..437ff063e 100644
--- a/test/test_model/test_solid_mechanics_model/test_material_selector.cc
+++ b/test/test_model/test_solid_mechanics_model/test_material_selector.cc
@@ -1,63 +1,62 @@
/**
* @file test_material_selector.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Fri May 01 2015
*
* @brief Test for material selector
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char * argv[]) {
initialize("material_selector.dat", argc, argv);
Math::setTolerance(1e-8);
Mesh mesh(1);
mesh.read("material_selector.msh");
SolidMechanicsModel model(mesh);
- auto && selector = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
+ auto && selector = std::make_shared<MeshDataMaterialSelector<std::string>>(
+ "physical_names", model);
model.setMaterialSelector(selector);
model.initFull();
- Material & chocolate = model.getMaterial("chocolate");
- Material & chewing_gum = model.getMaterial("chewing-gum");
- Material & candy = model.getMaterial("candy");
+ Material & chocolate = model.getMaterial("chocolate");
+ Material & chewing_gum = model.getMaterial("chewing-gum");
+ Material & candy = model.getMaterial("candy");
UInt chocolate_element = chocolate.getElementFilter(_segment_2)(0, 0);
UInt chewing_gum_element = chewing_gum.getElementFilter(_segment_2)(0, 0);
UInt candy_element = candy.getElementFilter(_segment_2)(0, 0);
- if (chocolate_element != 0 ||
- chewing_gum_element != 1 ||
- candy_element != 2)
+ if (chocolate_element != 0 || chewing_gum_element != 1 || candy_element != 2)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
index 350f61050..a549423eb 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
@@ -1,183 +1,183 @@
/**
* @file test_interpolate_stress.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Jun 07 2012
* @date last modification: Thu Oct 15 2015
*
* @brief Test for the stress interpolation function
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <fstream>
#include <iostream>
#include <limits>
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
#include "integrator_gauss.hh"
-#include "shape_lagrange.hh"
#include "mesh_utils.hh"
+#include "shape_lagrange.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
Real function(Real x, Real y, Real z) { return 100. + 2. * x + 3. * y + 4 * z; }
int main(int argc, char * argv[]) {
initialize("../material.dat", argc, argv);
debug::setDebugLevel(dblWarning);
const UInt spatial_dimension = 3;
const ElementType type = _tetrahedron_10;
Mesh mesh(spatial_dimension);
mesh.read("interpolation.msh");
const ElementType type_facet = mesh.getFacetType(type);
Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
MeshUtils::buildAllFacets(mesh, mesh_facets);
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Array<Real> & position = mesh.getNodes();
UInt nb_facet = mesh_facets.getNbElement(type_facet);
UInt nb_element = mesh.getNbElement(type);
/// compute quadrature points positions on facets
typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange> MyFEEngineType;
model.registerFEEngineObject<MyFEEngineType>("FacetsFEEngine", mesh_facets,
spatial_dimension - 1);
model.getFEEngine("FacetsFEEngine").initShapeFunctions();
UInt nb_quad_per_facet =
model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
model.getFEEngine("FacetsFEEngine")
.interpolateOnIntegrationPoints(position, quad_facets, spatial_dimension,
type_facet);
Array<Element> & facet_to_element = mesh_facets.getSubelementToElement(type);
UInt nb_facet_per_elem = facet_to_element.getNbComponent();
ElementTypeMapArray<Real> element_quad_facet;
element_quad_facet.alloc(nb_element * nb_facet_per_elem * nb_quad_per_facet,
spatial_dimension, type);
ElementTypeMapArray<Real> interpolated_stress("interpolated_stress", "");
interpolated_stress.initialize(
mesh, _nb_component = spatial_dimension * spatial_dimension,
_spatial_dimension = spatial_dimension);
Array<Real> & interp_stress = interpolated_stress(type);
interp_stress.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet);
Array<Real> & el_q_facet = element_quad_facet(type);
for (UInt el = 0; el < nb_element; ++el) {
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
UInt global_facet = facet_to_element(el, f).element;
for (UInt q = 0; q < nb_quad_per_facet; ++q) {
for (UInt s = 0; s < spatial_dimension; ++s) {
el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
f * nb_quad_per_facet + q,
s) = quad_facets(global_facet * nb_quad_per_facet + q, s);
}
}
}
}
/// compute quadrature points position of the elements
UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
model.getFEEngine().interpolateOnIntegrationPoints(position, quad_elements,
spatial_dimension, type);
/// assign some values to stresses
Array<Real> & stress =
const_cast<Array<Real> &>(model.getMaterial(0).getStress(type));
for (UInt q = 0; q < nb_tot_quad_el; ++q) {
for (UInt s = 0; s < spatial_dimension * spatial_dimension; ++s) {
stress(q, s) = s * function(quad_elements(q, 0), quad_elements(q, 1),
quad_elements(q, 2));
}
}
/// interpolate stresses on facets' quadrature points
model.getMaterial(0).initElementalFieldInterpolation(element_quad_facet);
model.getMaterial(0).interpolateStress(interpolated_stress);
Real tolerance = 1.e-10;
/// check results
for (UInt el = 0; el < nb_element; ++el) {
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
for (UInt q = 0; q < nb_quad_per_facet; ++q) {
for (UInt s = 0; s < spatial_dimension * spatial_dimension; ++s) {
Real x = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
f * nb_quad_per_facet + q,
0);
Real y = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
f * nb_quad_per_facet + q,
1);
Real z = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
f * nb_quad_per_facet + q,
2);
Real theoretical = s * function(x, y, z);
Real numerical =
interp_stress(el * nb_facet_per_elem * nb_quad_per_facet +
f * nb_quad_per_facet + q,
s);
if (std::abs(theoretical - numerical) > tolerance) {
std::cout << "Theoretical and numerical values aren't coincident!"
<< std::endl;
return EXIT_FAILURE;
}
}
}
}
}
std::cout << "OK: Stress interpolation test passed." << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc
index 08c24c94f..fc5616227 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_local_material.cc
@@ -1,120 +1,120 @@
/**
* @file test_local_material.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Wed Aug 04 2010
* @date last modification: Thu Oct 15 2015
*
* @brief test of the class SolidMechanicsModel with custom local damage on a
* notched plate
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "local_material_damage.hh"
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
akantu::initialize("material.dat", argc, argv);
UInt max_steps = 1100;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("mesh_section_gap.msh");
/// model initialization
MaterialFactory::getInstance().registerAllocator(
- "local_damage",
- [](UInt, const ID &, SolidMechanicsModel & model,
- const ID & id) -> std::unique_ptr<Material> {
+ "local_damage", [](UInt, const ID &, SolidMechanicsModel & model,
+ const ID & id) -> std::unique_ptr<Material> {
return std::make_unique<LocalMaterialDamage>(model, id);
});
SolidMechanicsModel model(mesh);
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.addDumpField("damage");
model.addDumpField("strain");
model.addDumpField("stress");
model.addDumpFieldVector("displacement");
model.addDumpFieldVector("external_force");
model.addDumpFieldVector("internal_force");
model.dump();
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step / 2.5);
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed");
// model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed");
Matrix<Real> stress(2, 2);
stress.eye(5e7);
model.applyBC(BC::Neumann::FromHigherDim(stress), "Traction");
- for (UInt s = 0; s < max_steps; ++s) model.solveStep();
+ for (UInt s = 0; s < max_steps; ++s)
+ model.solveStep();
model.dump();
const auto & lower_bounds = mesh.getLowerBounds();
const auto & upper_bounds = mesh.getUpperBounds();
Real L = upper_bounds(_x) - lower_bounds(_x);
Real H = upper_bounds(_y) - lower_bounds(_y);
const auto & filter = model.getMaterial("concrete").getElementFilter();
Vector<Real> barycenter(spatial_dimension);
for (auto & type : filter.elementTypes(spatial_dimension)) {
UInt nb_elem = mesh.getNbElement(type);
const UInt nb_gp = model.getFEEngine().getNbIntegrationPoints(type);
const auto & material_damage_array =
model.getMaterial(0).getArray<Real>("damage", type);
UInt cpt = 0;
for (auto nel : arange(nb_elem)) {
mesh.getBarycenter({type, nel, _not_ghost}, barycenter);
if ((std::abs(barycenter(_x) - (L / 2) + 0.025) < 0.025) &&
(std::abs(barycenter(_y) - (H / 2) + 0.045) < 0.045)) {
if (material_damage_array(cpt, 0) < 0.9) {
std::terminate();
} else {
- std::cout << "element " << nel << " is correctly broken" << std::endl;
+ std::cout << "element " << nel << " is correctly broken" << std::endl;
}
}
cpt += nb_gp;
}
}
akantu::finalize();
return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
index f8487f728..e91430691 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
@@ -1,81 +1,81 @@
/**
* @file custom_non_local_test_material.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Aug 23 2012
* @date last modification: Thu Oct 15 2015
*
* @brief Custom material to test the non local implementation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_elastic.hh"
#include "material_non_local.hh"
/* -------------------------------------------------------------------------- */
#ifndef __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__
#define __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__
namespace akantu {
template <UInt dim>
class CustomNonLocalTestMaterial
: public MaterialNonLocal<dim, MaterialElastic<dim>> {
public:
using MyNonLocalParent = MaterialNonLocal<dim, MaterialElastic<dim>>;
CustomNonLocalTestMaterial(SolidMechanicsModel & model, const ID & id);
/* ------------------------------------------------------------------------ */
void initMaterial() override;
void computeNonLocalStress(ElementType el_type, GhostType ghost_type);
void computeStress(ElementType el_type, GhostType ghost_type) override;
-protected:
+protected:
void registerNonLocalVariables() override;
/* ------------------------------------------------------------------------ */
void computeNonLocalStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
for (auto & type : this->element_filter.elementTypes(dim, ghost_type)) {
computeNonLocalStress(type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
public:
void setDamage(Real dam) { this->local_damage.setDefaultValue(dam); }
protected:
InternalField<Real> local_damage;
InternalField<Real> damage;
};
} // namespace akantu
#endif /* __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__ */
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc
index 29c1262e8..1e0845d77 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local.cc
@@ -1,118 +1,117 @@
/**
* @file test_material_damage_non_local.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Clement Roux <clement.roux@epfl.ch>
*
* @date creation: Wed Aug 04 2010
* @date last modification: Thu Oct 15 2015
*
* @brief test for non-local damage materials on a 2D plate with a section gap
* the sample should break at the notch
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
debug::setDebugLevel(dblWarning);
akantu::initialize("material_damage_non_local.dat", argc, argv);
UInt max_steps = 1100;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("mesh_section_gap.msh");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step / 2.5);
std::cout << model << std::endl;
model.applyBC(BC::Dirichlet::FixedValue(0.0), "Fixed");
// Boundary condition (Neumann)
Matrix<Real> stress(2, 2);
stress.eye(5e8);
model.applyBC(BC::Neumann::FromHigherDim(stress), "Traction");
model.setBaseName("damage_non_local");
model.addDumpFieldVector("displacement");
- model.addDumpField("velocity" );
+ model.addDumpField("velocity");
model.addDumpField("acceleration");
model.addDumpFieldVector("external_force");
model.addDumpFieldVector("internal_force");
- model.addDumpField("damage" );
- model.addDumpField("stress" );
- model.addDumpField("strain" );
+ model.addDumpField("damage");
+ model.addDumpField("stress");
+ model.addDumpField("strain");
model.dump();
for (UInt s = 0; s < max_steps; ++s) {
model.solveStep();
// if(s % 100 == 0) std::cout << "Step " << s+1 << "/" << max_steps
// <<std::endl; if(s % 100 == 0) model.dump();
}
model.dump();
const auto & lower_bounds = mesh.getLowerBounds();
const auto & upper_bounds = mesh.getUpperBounds();
Real L = upper_bounds(0) - lower_bounds(0);
Real H = upper_bounds(1) - lower_bounds(1);
const auto & mat = model.getMaterial(0);
const auto & filter = mat.getElementFilter();
Vector<Real> barycenter(spatial_dimension);
for (auto & type : filter.elementTypes(spatial_dimension)) {
UInt nb_elem = mesh.getNbElement(type);
const UInt nb_gp = model.getFEEngine().getNbIntegrationPoints(type);
- auto & material_damage_array =
- mat.getArray<Real>("damage", type);
+ auto & material_damage_array = mat.getArray<Real>("damage", type);
UInt cpt = 0;
for (UInt nel = 0; nel < nb_elem; ++nel) {
mesh.getBarycenter({type, nel, _not_ghost}, barycenter);
if ((std::abs(barycenter(0) - (L / 2) + 0.025) < 0.025) &&
(std::abs(barycenter(1) - (H / 2) + 0.025) < 0.025)) {
if (material_damage_array(cpt, 0) < 0.9) {
std::terminate();
}
}
cpt += nb_gp;
}
}
return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
index 8353c4b9b..ce1c9239f 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
@@ -1,99 +1,100 @@
/**
* @file test_material_orthotropic.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 04 2010
* @date last modification: Tue Sep 01 2015
*
* @brief test of the class SolidMechanicsModel
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
// akantu::initialize("orthotropic.dat", argc, argv);
akantu::initialize("orthotropic.dat", argc, argv);
UInt max_steps = 1000;
Real epot, ekin;
Mesh mesh(2);
mesh.read("square.msh");
mesh.createBoundaryGroupFromGeometry();
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
Real time_step = model.getStableTimeStep();
- model.setTimeStep(time_step/10.);
+ model.setTimeStep(time_step / 10.);
model.assembleMassLumped();
std::cout << model << std::endl;
// Boundary condition (Neumann)
- Matrix<Real> stress(2,2);
+ Matrix<Real> stress(2, 2);
stress.eye(Real(1e3));
model.applyBC(BC::Neumann::FromHigherDim(stress), "boundary_0");
- model.setBaseName ("square-orthotrope" );
+ model.setBaseName("square-orthotrope");
model.addDumpFieldVector("displacement");
- model.addDumpField ("mass" );
- model.addDumpField ("velocity" );
- model.addDumpField ("acceleration");
+ model.addDumpField("mass");
+ model.addDumpField("velocity");
+ model.addDumpField("acceleration");
model.addDumpFieldVector("external_force");
model.addDumpFieldVector("internal_force");
- model.addDumpField ("stress" );
- model.addDumpField ("grad_u" );
+ model.addDumpField("stress");
+ model.addDumpField("grad_u");
model.dump();
std::ofstream energy;
energy.open("energy.csv");
energy << "id,epot,ekin,tot" << std::endl;
- for(UInt s = 0; s < max_steps; ++s) {
+ for (UInt s = 0; s < max_steps; ++s) {
model.solveStep();
epot = model.getEnergy("potential");
ekin = model.getEnergy("kinetic");
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
energy << s << "," << epot << "," << ekin << "," << epot + ekin
- << std::endl;
+ << std::endl;
- if(s % 100 == 0) model.dump();
+ if (s % 100 == 0)
+ model.dump();
}
energy.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
index 5f1aa6d5e..bd575a1ad 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
@@ -1,76 +1,75 @@
/* -------------------------------------------------------------------------- */
#include "material_thermal.hh"
#include "solid_mechanics_model.hh"
#include "test_material_fixtures.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#include <type_traits>
/* -------------------------------------------------------------------------- */
using namespace akantu;
-using types = ::testing::Types<
- Traits<MaterialThermal, 1>, Traits<MaterialThermal, 2>,
- Traits<MaterialThermal, 3>>;
+using types =
+ ::testing::Types<Traits<MaterialThermal, 1>, Traits<MaterialThermal, 2>,
+ Traits<MaterialThermal, 3>>;
/* -------------------------------------------------------------------------- */
template <> void FriendMaterial<MaterialThermal<3>>::testComputeStress() {
Real E = 1.;
Real nu = .3;
Real alpha = 2;
setParam("E", E);
setParam("nu", nu);
setParam("alpha", alpha);
Real deltaT = 1;
Real sigma = 0;
this->computeStressOnQuad(sigma, deltaT);
- Real solution = -E / (1 - 2*nu) * alpha * deltaT;
+ Real solution = -E / (1 - 2 * nu) * alpha * deltaT;
auto error = std::abs(sigma - solution);
ASSERT_NEAR(error, 0, 1e-14);
}
template <> void FriendMaterial<MaterialThermal<2>>::testComputeStress() {
Real E = 1.;
Real nu = .3;
Real alpha = 2;
setParam("E", E);
setParam("nu", nu);
setParam("alpha", alpha);
Real deltaT = 1;
Real sigma = 0;
this->computeStressOnQuad(sigma, deltaT);
- Real solution = -E / (1 - 2*nu) * alpha * deltaT;
+ Real solution = -E / (1 - 2 * nu) * alpha * deltaT;
auto error = std::abs(sigma - solution);
ASSERT_NEAR(error, 0, 1e-14);
}
template <> void FriendMaterial<MaterialThermal<1>>::testComputeStress() {
Real E = 1.;
Real nu = .3;
Real alpha = 2;
setParam("E", E);
setParam("nu", nu);
setParam("alpha", alpha);
Real deltaT = 1;
Real sigma = 0;
this->computeStressOnQuad(sigma, deltaT);
Real solution = -E * alpha * deltaT;
auto error = std::abs(sigma - solution);
ASSERT_NEAR(error, 0, 1e-14);
}
namespace {
template <typename T>
class TestMaterialThermalFixture : public ::TestMaterialFixture<T> {};
TYPED_TEST_CASE(TestMaterialThermalFixture, types);
TYPED_TEST(TestMaterialThermalFixture, ThermalComputeStress) {
this->material->testComputeStress();
}
-
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc
index 178c63af5..ab1444715 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc
@@ -1,171 +1,172 @@
/**
* @file test_material_standard_linear_solid_deviatoric_relaxation.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
*
* @date creation: Mon Aug 09 2010
* @date last modification: Sun Oct 19 2014
*
* @brief test of the viscoelastic material: relaxation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <fstream>
#include <iostream>
#include <limits>
#include <sstream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
int main(int argc, char * argv[]) {
akantu::initialize("material_standard_linear_solid_deviatoric_relaxation.dat",
argc, argv);
akantu::debug::setDebugLevel(akantu::dblWarning);
// sim data
Real T = 10.;
Real eps = 0.001;
const UInt dim = 2;
Real sim_time = 25.;
Real time_factor = 0.1;
Real tolerance = 1e-7;
Mesh mesh(dim);
mesh.read("test_material_standard_linear_solid_deviatoric_relaxation.msh");
const ElementType element_type = _quadrangle_4;
SolidMechanicsModel model(mesh);
/* ------------------------------------------------------------------------ */
/* Initialization */
/* ------------------------------------------------------------------------ */
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
std::stringstream filename_sstr;
filename_sstr
<< "test_material_standard_linear_solid_deviatoric_relaxation.out";
std::ofstream output_data;
output_data.open(filename_sstr.str().c_str());
output_data << "#[1]-time [2]-sigma_analytic [3+]-sigma_measurements"
<< std::endl;
Material & mat = model.getMaterial(0);
const Array<Real> & stress = mat.getStress(element_type);
Real Eta = mat.get("Eta");
Real EV = mat.get("Ev");
Real Einf = mat.get("Einf");
Real nu = mat.get("nu");
Real Ginf = Einf / (2 * (1 + nu));
Real G = EV / (2 * (1 + nu));
Real G0 = G + Ginf;
Real gamma = G / G0;
Real tau = Eta / EV;
Real gammainf = Ginf / G0;
UInt nb_nodes = mesh.getNbNodes();
const Array<Real> & coordinate = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
/// Setting time step
Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
UInt max_steps = sim_time / time_step;
UInt out_interval = 1;
Real time = 0.;
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
for (UInt s = 0; s <= max_steps; ++s) {
if (s % 1000 == 0)
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
time = s * time_step;
// impose displacement
Real epsilon = 0.;
if (time < T) {
epsilon = eps * time / T;
} else {
epsilon = eps;
}
for (UInt n = 0; n < nb_nodes; ++n) {
displacement(n, 0) = epsilon * coordinate(n, 1);
displacement(n, 1) = epsilon * coordinate(n, 0);
}
// compute stress
model.assembleInternalForces();
// print output
if (s % out_interval == 0) {
// analytical solution
Real solution = 0.;
if (time < T) {
solution = 2 * G0 * eps / T *
(gammainf * time + gamma * tau * (1 - exp(-time / tau)));
} else {
- solution = 2 * G0 * eps *
- (gammainf + gamma * tau / T *
- (exp((T - time) / tau) - exp(-time / tau)));
+ solution =
+ 2 * G0 * eps *
+ (gammainf +
+ gamma * tau / T * (exp((T - time) / tau) - exp(-time / tau)));
}
output_data << s * time_step << " " << solution;
// data output
Array<Real>::const_matrix_iterator stress_it = stress.begin(dim, dim);
Array<Real>::const_matrix_iterator stress_end = stress.end(dim, dim);
for (; stress_it != stress_end; ++stress_it) {
output_data << " " << (*stress_it)(0, 1) << " " << (*stress_it)(1, 0);
// test error
Real rel_error_1 = std::abs(((*stress_it)(0, 1) - solution) / solution);
Real rel_error_2 = std::abs(((*stress_it)(1, 0) - solution) / solution);
if (rel_error_1 > tolerance || rel_error_2 > tolerance) {
std::cerr << "Relative error: " << rel_error_1 << " " << rel_error_2
<< std::endl;
return EXIT_FAILURE;
}
}
output_data << std::endl;
}
}
finalize();
std::cout << "Test successful!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
index 948442f07..a6724ab94 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
@@ -1,174 +1,181 @@
/**
* @file test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Aug 09 2010
* @date last modification: Sun Oct 19 2014
*
* @brief test of the viscoelastic material: relaxation
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <limits>
#include <fstream>
-#include <sstream>
#include <iostream>
+#include <limits>
+#include <sstream>
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
using namespace akantu;
-int main(int argc, char *argv[])
-{
- akantu::initialize("material_standard_linear_solid_deviatoric_relaxation.dat", argc, argv);
+int main(int argc, char * argv[]) {
+ akantu::initialize("material_standard_linear_solid_deviatoric_relaxation.dat",
+ argc, argv);
// sim data
Real T = 10.;
Real eps = 0.001;
// const UInt dim = 3;
const UInt dim = 2;
Real sim_time = 25.;
- //Real sim_time = 250.;
+ // Real sim_time = 250.;
Real time_factor = 0.1;
Real tolerance = 1e-5;
Mesh mesh(dim);
mesh.read("test_material_standard_linear_solid_deviatoric_relaxation.msh");
// mesh_io.read("hexa_structured.msh",mesh);
- //const ElementType element_type = _hexahedron_8;
+ // const ElementType element_type = _hexahedron_8;
const ElementType element_type = _quadrangle_4;
SolidMechanicsModel model(mesh);
/* ------------------------------------------------------------------------ */
/* Initialization */
/* ------------------------------------------------------------------------ */
model.initFull();
std::cout << model.getMaterial(0) << std::endl;
model.assembleMassLumped();
model.assembleInternalForces();
model.getMaterial(0).setToSteadyState();
std::stringstream filename_sstr;
- filename_sstr << "test_material_standard_linear_solid_deviatoric_relaxation_tension.out";
+ filename_sstr << "test_material_standard_linear_solid_deviatoric_relaxation_"
+ "tension.out";
std::ofstream output_data;
output_data.open(filename_sstr.str().c_str());
- output_data << "#[1]-time [2]-sigma_analytic [3+]-sigma_measurements" << std::endl;
+ output_data << "#[1]-time [2]-sigma_analytic [3+]-sigma_measurements"
+ << std::endl;
Material & mat = model.getMaterial(0);
const Array<Real> & stress = mat.getStress(element_type);
- Real Eta = mat.get("Eta");
- Real EV = mat.get("Ev");
+ Real Eta = mat.get("Eta");
+ Real EV = mat.get("Ev");
Real Einf = mat.get("Einf");
- Real E0 = mat.get("E");
-
+ Real E0 = mat.get("E");
+
Real kpa = mat.get("kapa");
- Real mu = mat.get("mu");
+ Real mu = mat.get("mu");
- Real gamma = EV/E0;
- Real gammainf = Einf/E0;
+ Real gamma = EV / E0;
+ Real gammainf = Einf / E0;
Real tau = Eta / EV;
std::cout << "relaxation time = " << tau << std::endl;
UInt nb_nodes = mesh.getNbNodes();
const Array<Real> & coordinate = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
/// Setting time step
Real time_step = model.getStableTimeStep() * time_factor;
std::cout << "Time Step = " << time_step << "s" << std::endl;
model.setTimeStep(time_step);
UInt max_steps = sim_time / time_step;
UInt out_interval = 1;
Real time = 0.;
/* ------------------------------------------------------------------------ */
/* Main loop */
/* ------------------------------------------------------------------------ */
- for(UInt s = 0; s <= max_steps; ++s) {
+ for (UInt s = 0; s <= max_steps; ++s) {
- if(s % 1000 == 0)
+ if (s % 1000 == 0)
std::cerr << "passing step " << s << "/" << max_steps << std::endl;
time = s * time_step;
// impose displacement
Real epsilon = 0.;
if (time < T) {
epsilon = eps * time / T;
- }
- else {
+ } else {
epsilon = eps;
}
- for (UInt n=0; n<nb_nodes; ++n) {
- for (UInt d=0; d<dim; ++d)
- displacement(n,d) = epsilon * coordinate(n,d);
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ for (UInt d = 0; d < dim; ++d)
+ displacement(n, d) = epsilon * coordinate(n, d);
}
// compute stress
model.assembleInternalForces();
// print output
- if(s % out_interval == 0) {
+ if (s % out_interval == 0) {
// analytical solution
Real epskk = dim * eps;
- Real solution= 0.;
+ Real solution = 0.;
if (time < T) {
- solution = 2 * mu * (eps - epskk/3.) / T * (gammainf * time + gamma * tau * (1 - exp(-time/tau))) + gammainf * kpa * epskk * time / T;
- }
- else {
- solution = 2 * mu * (eps - epskk/3.) * (gammainf + gamma * tau / T *(exp((T-time)/tau) - exp(-time/tau))) + gammainf * kpa * epskk;
+ solution =
+ 2 * mu * (eps - epskk / 3.) / T *
+ (gammainf * time + gamma * tau * (1 - exp(-time / tau))) +
+ gammainf * kpa * epskk * time / T;
+ } else {
+ solution =
+ 2 * mu * (eps - epskk / 3.) *
+ (gammainf +
+ gamma * tau / T * (exp((T - time) / tau) - exp(-time / tau))) +
+ gammainf * kpa * epskk;
}
- output_data << s*time_step << " " << solution;
+ output_data << s * time_step << " " << solution;
// data output
Array<Real>::const_matrix_iterator stress_it = stress.begin(dim, dim);
Array<Real>::const_matrix_iterator stress_end = stress.end(dim, dim);
- for(;stress_it != stress_end; ++stress_it) {
- output_data << " " << (*stress_it)(1,1);
-
- // test error
- Real rel_error_1 = std::abs(((*stress_it)(1,1) - solution) / solution);
- if (rel_error_1 > tolerance) {
- std::cerr << "Relative error: " << rel_error_1 << std::endl;
- return EXIT_FAILURE;
- }
+ for (; stress_it != stress_end; ++stress_it) {
+ output_data << " " << (*stress_it)(1, 1);
+
+ // test error
+ Real rel_error_1 = std::abs(((*stress_it)(1, 1) - solution) / solution);
+ if (rel_error_1 > tolerance) {
+ std::cerr << "Relative error: " << rel_error_1 << std::endl;
+ return EXIT_FAILURE;
+ }
}
output_data << std::endl;
}
}
finalize();
std::cout << "Test successful!" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc
index a2bcaf733..c1c4c3bf2 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc
@@ -1,92 +1,97 @@
-#include <solid_mechanics_model.hh>
#include "non_linear_solver.hh"
+#include <solid_mechanics_model.hh>
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("test_multi_material_elastic.dat", argc, argv);
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("test_multi_material_elastic.msh");
SolidMechanicsModel model(mesh);
- auto && mat_sel = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
+ auto && mat_sel = std::make_shared<MeshDataMaterialSelector<std::string>>(
+ "physical_names", model);
model.setMaterialSelector(mat_sel);
model.initFull(_analysis_method = _static);
model.applyBC(BC::Dirichlet::FlagOnly(_y), "ground");
model.applyBC(BC::Dirichlet::FlagOnly(_x), "corner");
Vector<Real> trac(spatial_dimension, 0.);
trac(_y) = 1.;
model.applyBC(BC::Neumann::FromTraction(trac), "air");
model.addDumpField("external_force");
model.addDumpField("internal_force");
model.addDumpField("blocked_dofs");
model.addDumpField("displacement");
model.addDumpField("stress");
model.addDumpField("grad_u");
- //model.dump();
+ // model.dump();
auto & solver = model.getNonLinearSolver("static");
solver.set("max_iterations", 1);
solver.set("threshold", 1e-8);
solver.set("convergence_type", _scc_residual);
model.solveStep();
- //model.dump();
+ // model.dump();
std::map<std::string, Matrix<Real>> ref_strain;
ref_strain["strong"] = Matrix<Real>(spatial_dimension, spatial_dimension, 0.);
ref_strain["strong"](_y, _y) = .5;
ref_strain["weak"] = Matrix<Real>(spatial_dimension, spatial_dimension, 0.);
ref_strain["weak"](_y, _y) = 1;
Matrix<Real> ref_stress(spatial_dimension, spatial_dimension, 0.);
ref_stress(_y, _y) = 1.;
std::vector<std::string> mats = {"strong", "weak"};
typedef Array<Real>::const_matrix_iterator mat_it;
auto check = [](mat_it it, mat_it end, const Matrix<Real> & ref) -> bool {
- for(;it != end; ++it) {
+ for (; it != end; ++it) {
Real dist = (*it - ref).norm<L_2>();
- //std::cout << *it << " " << dist << " " << (dist < 1e-10 ? "OK" : "Not OK") << std::endl;
+ // std::cout << *it << " " << dist << " " << (dist < 1e-10 ? "OK" : "Not
+ // OK") << std::endl;
- if (dist > 1e-10) return false;
+ if (dist > 1e-10)
+ return false;
}
return true;
};
auto tit = mesh.firstType(spatial_dimension);
auto tend = mesh.lastType(spatial_dimension);
for (; tit != tend; ++tit) {
auto & type = *tit;
- for(auto mat_id : mats) {
+ for (auto mat_id : mats) {
auto & stress = model.getMaterial(mat_id).getStress(type);
auto & grad_u = model.getMaterial(mat_id).getGradU(type);
auto sit = stress.begin(spatial_dimension, spatial_dimension);
auto send = stress.end(spatial_dimension, spatial_dimension);
auto git = grad_u.begin(spatial_dimension, spatial_dimension);
auto gend = grad_u.end(spatial_dimension, spatial_dimension);
- if(!check(sit, send, ref_stress)) AKANTU_ERROR("The stresses are not correct");
- if(!check(git, gend, ref_strain[mat_id])) AKANTU_ERROR("The grad_u are not correct");
+ if (!check(sit, send, ref_stress))
+ AKANTU_ERROR("The stresses are not correct");
+ if (!check(git, gend, ref_strain[mat_id]))
+ AKANTU_ERROR("The grad_u are not correct");
}
}
finalize();
- return 0;
+ return 0;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
index fb0bfad88..36b9be9d6 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
@@ -1,314 +1,315 @@
/**
* @file test_solid_mechanics_model_cube3d.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Wed Aug 04 2010
* @date last modification: Thu Aug 06 2015
*
* @brief test of the class SolidMechanicsModel on the 3d cube
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "boundary_condition_functor.hh"
#include "test_solid_mechanics_model_fixture.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
namespace {
const Real A = 1e-1;
const Real E = 1.;
const Real poisson = 3. / 10;
const Real lambda = E * poisson / (1 + poisson) / (1 - 2 * poisson);
const Real mu = E / 2 / (1. + poisson);
const Real rho = 1.;
const Real cp = std::sqrt((lambda + 2 * mu) / rho);
const Real cs = std::sqrt(mu / rho);
const Real c = std::sqrt(E / rho);
const Vector<Real> k = {.5, 0., 0.};
const Vector<Real> psi1 = {0., 0., 1.};
const Vector<Real> psi2 = {0., 1., 0.};
const Real knorm = k.norm();
/* -------------------------------------------------------------------------- */
template <UInt dim> struct Verification {};
/* -------------------------------------------------------------------------- */
template <> struct Verification<1> {
void displacement(Vector<Real> & disp, const Vector<Real> & coord,
Real current_time) {
const auto & x = coord(_x);
const Real omega = c * k[0];
disp(_x) = A * cos(k[0] * x - omega * current_time);
}
void velocity(Vector<Real> & vel, const Vector<Real> & coord,
Real current_time) {
const auto & x = coord(_x);
const Real omega = c * k[0];
vel(_x) = omega * A * sin(k[0] * x - omega * current_time);
}
};
/* -------------------------------------------------------------------------- */
template <> struct Verification<2> {
void displacement(Vector<Real> & disp, const Vector<Real> & X,
Real current_time) {
Vector<Real> kshear = {k[1], k[0]};
Vector<Real> kpush = {k[0], k[1]};
const Real omega_p = knorm * cp;
const Real omega_s = knorm * cs;
Real phase_p = X.dot(kpush) - omega_p * current_time;
Real phase_s = X.dot(kpush) - omega_s * current_time;
disp = A * (kpush * cos(phase_p) + kshear * cos(phase_s));
}
void velocity(Vector<Real> & vel, const Vector<Real> & X, Real current_time) {
Vector<Real> kshear = {k[1], k[0]};
Vector<Real> kpush = {k[0], k[1]};
const Real omega_p = knorm * cp;
const Real omega_s = knorm * cs;
Real phase_p = X.dot(kpush) - omega_p * current_time;
Real phase_s = X.dot(kpush) - omega_s * current_time;
vel =
A * (kpush * omega_p * cos(phase_p) + kshear * omega_s * cos(phase_s));
}
};
/* -------------------------------------------------------------------------- */
template <> struct Verification<3> {
void displacement(Vector<Real> & disp, const Vector<Real> & coord,
Real current_time) {
const auto & X = coord;
Vector<Real> kpush = k;
Vector<Real> kshear1(3);
Vector<Real> kshear2(3);
kshear1.crossProduct(k, psi1);
kshear2.crossProduct(k, psi2);
const Real omega_p = knorm * cp;
const Real omega_s = knorm * cs;
Real phase_p = X.dot(kpush) - omega_p * current_time;
Real phase_s = X.dot(kpush) - omega_s * current_time;
disp = A * (kpush * cos(phase_p) + kshear1 * cos(phase_s) +
kshear2 * cos(phase_s));
}
void velocity(Vector<Real> & vel, const Vector<Real> & coord,
Real current_time) {
const auto & X = coord;
Vector<Real> kpush = k;
Vector<Real> kshear1(3);
Vector<Real> kshear2(3);
kshear1.crossProduct(k, psi1);
kshear2.crossProduct(k, psi2);
const Real omega_p = knorm * cp;
const Real omega_s = knorm * cs;
Real phase_p = X.dot(kpush) - omega_p * current_time;
Real phase_s = X.dot(kpush) - omega_s * current_time;
vel =
A * (kpush * omega_p * cos(phase_p) + kshear1 * omega_s * cos(phase_s) +
kshear2 * omega_s * cos(phase_s));
}
};
/* -------------------------------------------------------------------------- */
template <ElementType _type>
class SolutionFunctor : public BC::Dirichlet::DirichletFunctor {
public:
SolutionFunctor(Real current_time, SolidMechanicsModel & model)
: current_time(current_time), model(model) {}
public:
static constexpr UInt dim = ElementClass<_type>::getSpatialDimension();
inline void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal,
const Vector<Real> & coord) const {
flags(0) = true;
auto & vel = model.getVelocity();
auto it = vel.begin(model.getSpatialDimension());
Vector<Real> v = it[node];
Verification<dim> verif;
verif.displacement(primal, coord, current_time);
verif.velocity(v, coord, current_time);
}
private:
Real current_time;
SolidMechanicsModel & model;
};
/* -------------------------------------------------------------------------- */
// This fixture uses somewhat finer meshes representing bars.
template <typename type_>
class TestSMMFixtureBar
: public TestSMMFixture<std::tuple_element_t<0, type_>> {
using parent = TestSMMFixture<std::tuple_element_t<0, type_>>;
public:
void SetUp() override {
- this->mesh_file = "../patch_tests/data/bar" + aka::to_string(this->type) + ".msh";
+ this->mesh_file =
+ "../patch_tests/data/bar" + aka::to_string(this->type) + ".msh";
parent::SetUp();
getStaticParser().parse("test_solid_mechanics_model_"
"dynamics_material.dat");
auto analysis_method = std::tuple_element_t<1, type_>::value;
this->model->initFull(_analysis_method = analysis_method);
if (this->dump_paraview) {
std::stringstream base_name;
base_name << "bar" << analysis_method << this->type;
this->model->setBaseName(base_name.str());
this->model->addDumpFieldVector("displacement");
this->model->addDumpField("mass");
this->model->addDumpField("velocity");
this->model->addDumpField("acceleration");
this->model->addDumpFieldVector("external_force");
this->model->addDumpFieldVector("internal_force");
this->model->addDumpField("stress");
this->model->addDumpField("strain");
}
time_step = this->model->getStableTimeStep() / 10.;
this->model->setTimeStep(time_step);
// std::cout << "timestep: " << time_step << std::endl;
const auto & position = this->mesh->getNodes();
auto & displacement = this->model->getDisplacement();
auto & velocity = this->model->getVelocity();
constexpr auto dim = parent::spatial_dimension;
Verification<dim> verif;
for (auto && tuple :
zip(make_view(position, dim), make_view(displacement, dim),
make_view(velocity, dim))) {
verif.displacement(std::get<1>(tuple), std::get<0>(tuple), 0.);
verif.velocity(std::get<2>(tuple), std::get<0>(tuple), 0.);
}
if (dump_paraview)
this->model->dump();
/// boundary conditions
this->model->applyBC(SolutionFunctor<parent::type>(0., *this->model), "BC");
wave_velocity = 1.; // sqrt(E/rho) = sqrt(1/1) = 1
simulation_time = 5 / wave_velocity;
max_steps = simulation_time / time_step; // 100
auto ndump = 50;
dump_freq = max_steps / ndump;
}
protected:
Real time_step;
Real wave_velocity;
Real simulation_time;
UInt max_steps;
UInt dump_freq;
bool dump_paraview{false};
};
template <AnalysisMethod t>
using analysis_method_t = std::integral_constant<AnalysisMethod, t>;
#ifdef AKANTU_IMPLICIT
-using TestAnalysisTypes =
- std::tuple<analysis_method_t<_implicit_dynamic>, analysis_method_t<_explicit_lumped_mass>>;
+using TestAnalysisTypes = std::tuple<analysis_method_t<_implicit_dynamic>,
+ analysis_method_t<_explicit_lumped_mass>>;
#else
using TestAnalysisTypes = std::tuple<analysis_method_t<_explicit_lumped_mass>>;
#endif
using TestTypes =
gtest_list_t<cross_product_t<TestElementTypes, TestAnalysisTypes>>;
TYPED_TEST_CASE(TestSMMFixtureBar, TestTypes);
/* -------------------------------------------------------------------------- */
TYPED_TEST(TestSMMFixtureBar, DynamicsExplicit) {
constexpr auto dim = TestFixture::spatial_dimension;
Real current_time = 0.;
const auto & position = this->mesh->getNodes();
const auto & displacement = this->model->getDisplacement();
UInt nb_nodes = this->mesh->getNbNodes();
UInt nb_global_nodes = this->mesh->getNbGlobalNodes();
Real max_error{0.};
Array<Real> displacement_solution(nb_nodes, dim);
Verification<dim> verif;
for (UInt s = 0; s < this->max_steps; ++s, current_time += this->time_step) {
if (s % this->dump_freq == 0 && this->dump_paraview)
this->model->dump();
/// boundary conditions
this->model->applyBC(
SolutionFunctor<TestFixture::type>(current_time, *this->model), "BC");
// compute the disp solution
for (auto && tuple :
zip(make_view(position, dim), make_view(displacement_solution, dim))) {
verif.displacement(std::get<1>(tuple), std::get<0>(tuple), current_time);
}
// compute the error solution
Real disp_error = 0.;
for (auto && tuple : zip(make_view(displacement, dim),
make_view(displacement_solution, dim))) {
auto diff = std::get<1>(tuple) - std::get<0>(tuple);
disp_error += diff.dot(diff);
}
this->mesh->getCommunicator().allReduce(disp_error,
SynchronizerOperation::_sum);
disp_error = sqrt(disp_error) / nb_global_nodes;
max_error = std::max(disp_error, max_error);
ASSERT_NEAR(disp_error, 0., 2e-3);
this->model->solveStep();
}
// std::cout << "max error: " << max_error << std::endl;
}
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh
index ff2979628..bc06c1355 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_fixture.hh
@@ -1,55 +1,56 @@
/* -------------------------------------------------------------------------- */
+#include "communicator.hh"
#include "solid_mechanics_model.hh"
#include "test_gtest_utils.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#include <vector>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_TEST_SOLID_MECHANICS_MODEL_FIXTURE_HH__
#define __AKANTU_TEST_SOLID_MECHANICS_MODEL_FIXTURE_HH__
using namespace akantu;
// This fixture uses very small meshes with a volume of 1.
template <typename type_> class TestSMMFixture : public ::testing::Test {
public:
static constexpr ElementType type = type_::value;
static constexpr size_t spatial_dimension =
ElementClass<type>::getSpatialDimension();
void SetUp() override {
this->mesh = std::make_unique<Mesh>(this->spatial_dimension);
- if(Communicator::getStaticCommunicator().whoAmI() == 0) {
+ if (Communicator::getStaticCommunicator().whoAmI() == 0) {
this->mesh->read(this->mesh_file);
}
mesh->distribute();
SCOPED_TRACE(aka::to_string(this->type).c_str());
model = std::make_unique<SolidMechanicsModel>(*mesh, _all_dimensions,
aka::to_string(this->type));
}
void TearDown() override {
model.reset(nullptr);
mesh.reset(nullptr);
}
protected:
std::string mesh_file{aka::to_string(this->type) + ".msh"};
std::unique_ptr<Mesh> mesh;
std::unique_ptr<SolidMechanicsModel> model;
};
template <typename type_> constexpr ElementType TestSMMFixture<type_>::type;
-template <typename type_> constexpr size_t TestSMMFixture<type_>::spatial_dimension;
+template <typename type_>
+constexpr size_t TestSMMFixture<type_>::spatial_dimension;
using gtest_element_types = gtest_list_t<TestElementTypes>;
TYPED_TEST_CASE(TestSMMFixture, gtest_element_types);
#endif /* __AKANTU_TEST_SOLID_MECHANICS_MODEL_FIXTURE_HH__ */
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
index 7dc6ca207..f970ddc4d 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
@@ -1,203 +1,203 @@
/**
* @file test_solid_mechanics_model_material_eigenstrain.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sat Apr 16 2011
* @date last modification: Wed Aug 12 2015
*
* @brief test the internal field prestrain
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
-#include "non_linear_solver.hh"
#include "mesh_utils.hh"
+#include "non_linear_solver.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
-
-
using namespace akantu;
-Real alpha [3][4] = { { 0.01, 0.02, 0.03, 0.04 },
- { 0.05, 0.06, 0.07, 0.08 },
- { 0.09, 0.10, 0.11, 0.12 } };
+Real alpha[3][4] = {{0.01, 0.02, 0.03, 0.04},
+ {0.05, 0.06, 0.07, 0.08},
+ {0.09, 0.10, 0.11, 0.12}};
/* -------------------------------------------------------------------------- */
-template<ElementType type>
-static Matrix<Real> prescribed_strain() {
+template <ElementType type> static Matrix<Real> prescribed_strain() {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> strain(spatial_dimension, spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
strain(i, j) = alpha[i][j + 1];
}
}
return strain;
}
-template<ElementType type>
+template <ElementType type>
static Matrix<Real> prescribed_stress(Matrix<Real> prescribed_eigengradu) {
UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
Matrix<Real> stress(spatial_dimension, spatial_dimension);
- //plane strain in 2d
+ // plane strain in 2d
Matrix<Real> strain(spatial_dimension, spatial_dimension);
Matrix<Real> pstrain;
pstrain = prescribed_strain<type>();
Real nu = 0.3;
- Real E = 2.1e11;
+ Real E = 2.1e11;
Real trace = 0;
/// symetric part of the strain tensor
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j)
- strain(i,j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
+ strain(i, j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
// elastic strain is equal to elastic strain minus the eigenstrain
strain -= prescribed_eigengradu;
- for (UInt i = 0; i < spatial_dimension; ++i) trace += strain(i,i);
+ for (UInt i = 0; i < spatial_dimension; ++i)
+ trace += strain(i, i);
- Real lambda = nu * E / ((1 + nu) * (1 - 2*nu));
- Real mu = E / (2 * (1 + nu));
+ Real lambda = nu * E / ((1 + nu) * (1 - 2 * nu));
+ Real mu = E / (2 * (1 + nu));
- if(spatial_dimension == 1) {
- stress(0, 0) = E * strain(0, 0);
+ if (spatial_dimension == 1) {
+ stress(0, 0) = E * strain(0, 0);
} else {
for (UInt i = 0; i < spatial_dimension; ++i)
for (UInt j = 0; j < spatial_dimension; ++j) {
- stress(i, j) = (i == j)*lambda*trace + 2*mu*strain(i, j);
+ stress(i, j) = (i == j) * lambda * trace + 2 * mu * strain(i, j);
}
}
return stress;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize("material_elastic_plane_strain.dat", argc, argv);
UInt dim = 3;
const ElementType element_type = _tetrahedron_4;
Matrix<Real> prescribed_eigengradu(dim, dim);
prescribed_eigengradu.set(0.1);
/// load mesh
Mesh mesh(dim);
mesh.read("cube_3d_tet_4.msh");
/// declaration of model
- SolidMechanicsModel model(mesh);
+ SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(_analysis_method = _static);
- //model.getNewSolver("static", _tsst_static, _nls_newton_raphson_modified);
+ // model.getNewSolver("static", _tsst_static, _nls_newton_raphson_modified);
auto & solver = model.getNonLinearSolver("static");
solver.set("threshold", 2e-4);
solver.set("max_iterations", 2);
solver.set("convergence_type", _scc_residual);
const Array<Real> & coordinates = mesh.getNodes();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
MeshUtils::buildFacets(mesh);
mesh.createBoundaryGroupFromGeometry();
// Loop over (Sub)Boundar(ies)
- for(GroupManager::const_element_group_iterator it(mesh.element_group_begin());
- it != mesh.element_group_end(); ++it) {
- for(const auto & n : it->second->getNodeGroup()) {
+ for (GroupManager::const_element_group_iterator it(
+ mesh.element_group_begin());
+ it != mesh.element_group_end(); ++it) {
+ for (const auto & n : it->second->getNodeGroup()) {
std::cout << "Node " << n << std::endl;
for (UInt i = 0; i < dim; ++i) {
displacement(n, i) = alpha[i][0];
for (UInt j = 0; j < dim; ++j) {
displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
}
boundary(n, i) = true;
}
}
}
/* ------------------------------------------------------------------------ */
- /* Apply eigenstrain in each element */
+ /* Apply eigenstrain in each element */
/* ------------------------------------------------------------------------ */
Array<Real> & eigengradu_vect =
- model.getMaterial(0).getInternal<Real>("eigen_grad_u")(element_type);
+ model.getMaterial(0).getInternal<Real>("eigen_grad_u")(element_type);
auto eigengradu_it = eigengradu_vect.begin(dim, dim);
auto eigengradu_end = eigengradu_vect.end(dim, dim);
for (; eigengradu_it != eigengradu_end; ++eigengradu_it) {
*eigengradu_it = prescribed_eigengradu;
}
/* ------------------------------------------------------------------------ */
/* Static solve */
/* ------------------------------------------------------------------------ */
model.solveStep();
- std::cout << "Converged in " << Int(solver.get("nb_iterations"))
- << " (" << Real(solver.get("error")) << ")" << std::endl;
+ std::cout << "Converged in " << Int(solver.get("nb_iterations")) << " ("
+ << Real(solver.get("error")) << ")" << std::endl;
/* ------------------------------------------------------------------------ */
/* Checks */
/* ------------------------------------------------------------------------ */
- const Array<Real> & stress_vect = model.getMaterial(0).getStress(element_type);
+ const Array<Real> & stress_vect =
+ model.getMaterial(0).getStress(element_type);
auto stress_it = stress_vect.begin(dim, dim);
auto stress_end = stress_vect.end(dim, dim);
Matrix<Real> presc_stress;
presc_stress = prescribed_stress<element_type>(prescribed_eigengradu);
Real stress_tolerance = 1e-13;
for (; stress_it != stress_end; ++stress_it) {
const auto & stress = *stress_it;
Matrix<Real> diff(dim, dim);
- diff = stress;
+ diff = stress;
diff -= presc_stress;
Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
- if(stress_error > stress_tolerance) {
- std::cerr << "stress error: " << stress_error
- << " > " << stress_tolerance << std::endl;
+ if (stress_error > stress_tolerance) {
+ std::cerr << "stress error: " << stress_error << " > " << stress_tolerance
+ << std::endl;
std::cerr << "stress: " << stress << std::endl
<< "prescribed stress: " << presc_stress << std::endl;
return EXIT_FAILURE;
} // else {
// std::cerr << "stress error: " << stress_error
// << " < " << stress_tolerance << std::endl;
// }
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc
index a2d5c741b..360a37a8b 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc
@@ -1,212 +1,210 @@
/**
* @file test_solid_mechanics_model_reassign_material.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Mon Feb 10 2014
* @date last modification: Wed Feb 25 2015
*
* @brief test the function reassign material
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_grid_dynamic.hh"
-#include "material.hh"
-#include "solid_mechanics_model.hh"
#include "communicator.hh"
+#include "material.hh"
#include "mesh_utils.hh"
+#include "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
-
-
using namespace akantu;
class StraightInterfaceMaterialSelector : public MaterialSelector {
public:
StraightInterfaceMaterialSelector(SolidMechanicsModel & model,
const std::string & mat_1_material,
const std::string & mat_2_material,
bool & horizontal, Real & pos_interface)
: model(model), mat_1_material(mat_1_material),
mat_2_material(mat_2_material), horizontal(horizontal),
pos_interface(pos_interface) {
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
/// store barycenters of all elements
barycenters.initialize(mesh, _spatial_dimension = spatial_dimension,
- _nb_component = spatial_dimension);
+ _nb_component = spatial_dimension);
- for (auto ghost_type : ghost_types) {
+ for (auto ghost_type : ghost_types) {
Element e;
e.ghost_type = ghost_type;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type =
mesh.lastType(spatial_dimension, ghost_type);
for (; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
e.type = *it;
Array<Real> & barycenter = barycenters(*it, ghost_type);
barycenter.resize(nb_element);
Array<Real>::iterator<Vector<Real>> bary_it =
barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem) {
e.element = elem;
mesh.getBarycenter(e, *bary_it);
++bary_it;
}
}
}
}
UInt operator()(const Element & elem) {
UInt spatial_dimension = model.getSpatialDimension();
const Vector<Real> & bary = barycenters(elem.type, elem.ghost_type)
.begin(spatial_dimension)[elem.element];
/// check for a given element on which side of the material interface plane
/// the bary center lies and assign corresponding material
if (bary(!horizontal) < pos_interface) {
return model.getMaterialIndex(mat_1_material);
;
}
return model.getMaterialIndex(mat_2_material);
;
}
bool isConditonVerified() {
/// check if material has been (re)-assigned correctly
Mesh & mesh = model.getMesh();
UInt spatial_dimension = mesh.getSpatialDimension();
GhostType ghost_type = _not_ghost;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type =
mesh.lastType(spatial_dimension, ghost_type);
for (; it != last_type; ++it) {
Array<UInt> & mat_indexes = model.getMaterialByElement(*it, ghost_type);
UInt nb_element = mesh.getNbElement(*it, ghost_type);
Array<Real>::iterator<Vector<Real>> bary =
barycenters(*it, ghost_type).begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem, ++bary) {
/// compare element_index_by material to material index that should be
/// assigned due to the geometry of the interface
UInt mat_index;
if ((*bary)(!horizontal) < pos_interface)
mat_index = model.getMaterialIndex(mat_1_material);
else
mat_index = model.getMaterialIndex(mat_2_material);
if (mat_indexes(elem) != mat_index)
/// wrong material index, make test fail
return false;
}
}
return true;
}
void moveInterface(Real & pos_new, bool & horizontal_new) {
/// update position and orientation of material interface plane
pos_interface = pos_new;
horizontal = horizontal_new;
model.reassignMaterial();
}
protected:
SolidMechanicsModel & model;
ElementTypeMapArray<Real> barycenters;
std::string mat_1_material;
std::string mat_2_material;
bool horizontal;
Real pos_interface;
};
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
bool test_passed;
debug::setDebugLevel(dblWarning);
initialize("two_materials.dat", argc, argv);
/// specify position and orientation of material interface plane
bool horizontal = true;
Real pos_interface = 0.;
UInt spatial_dimension = 3;
- const auto & comm =
- Communicator::getStaticCommunicator();
+ const auto & comm = Communicator::getStaticCommunicator();
Int prank = comm.whoAmI();
Mesh mesh(spatial_dimension);
- if (prank == 0) mesh.read("cube_two_materials.msh");
+ if (prank == 0)
+ mesh.read("cube_two_materials.msh");
mesh.distribute();
/// model creation
SolidMechanicsModel model(mesh);
/// assign the two different materials using the
/// StraightInterfaceMaterialSelector
auto && mat_selector = std::make_shared<StraightInterfaceMaterialSelector>(
model, "mat_1", "mat_2", horizontal, pos_interface);
model.setMaterialSelector(mat_selector);
model.initFull(_analysis_method = _static);
MeshUtils::buildFacets(mesh);
/// check if different materials have been assigned correctly
test_passed = mat_selector->isConditonVerified();
if (!test_passed) {
AKANTU_ERROR("materials not correctly assigned");
return EXIT_FAILURE;
}
/// change orientation of material interface plane
horizontal = false;
mat_selector->moveInterface(pos_interface, horizontal);
// model.dump();
/// test if material has been reassigned correctly
test_passed = mat_selector->isConditonVerified();
if (!test_passed) {
AKANTU_ERROR("materials not correctly reassigned");
return EXIT_FAILURE;
}
finalize();
if (prank == 0)
std::cout << "OK: test passed!" << std::endl;
return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc
index 8337bb9c2..034fd2589 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_2.cc
@@ -1,114 +1,114 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_2.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Sun Oct 19 2014
*
* @brief Computation of the analytical exemple 1.1 in the TGC vol 6
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_structural_mechanics_model_fixture.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
using namespace akantu;
/* -------------------------------------------------------------------------- */
class TestStructBernoulli2
: public TestStructuralFixture<element_type_t<_bernoulli_beam_2>> {
using parent = TestStructuralFixture<element_type_t<_bernoulli_beam_2>>;
public:
void addMaterials() override {
mat.E = 3e10;
mat.I = 0.0025;
mat.A = 0.01;
this->model->addMaterial(mat);
mat.E = 3e10;
mat.I = 0.00128;
mat.A = 0.01;
this->model->addMaterial(mat);
}
void assignMaterials() override {
auto & materials = this->model->getElementMaterial(parent::type);
materials(0) = 0;
materials(1) = 1;
}
void setDirichlets() override {
auto boundary = this->model->getBlockedDOFs().begin(parent::ndof);
// clang-format off
*boundary = {true, true, true}; ++boundary;
*boundary = {false, true, false}; ++boundary;
*boundary = {false, true, false}; ++boundary;
// clang-format on
}
void setNeumanns() override {
Real M = 3600; // Nm
Real q = -6000; // kN/m
Real L = 10; // m
auto & forces = this->model->getExternalForce();
forces(2, 2) = -M; // moment on last node
-#if 1 // as long as integration is not available
+#if 1 // as long as integration is not available
forces(0, 1) = q * L / 2;
forces(0, 2) = q * L * L / 12;
forces(1, 1) = q * L / 2;
forces(1, 2) = -q * L * L / 12;
#else
auto & group = mesh.createElementGroup("lin_force");
group.add({type, 0, _not_ghost});
Vector<Real> lin_force = {0, q, 0};
// a linear force is not actually a *boundary* condition
// it is equivalent to a volume force
model.applyBC(BC::Neumann::FromSameDim(lin_force), group);
#endif
forces(2, 0) = mat.E * mat.A / 18;
}
protected:
StructuralMaterial mat;
};
/* -------------------------------------------------------------------------- */
TEST_F(TestStructBernoulli2, TestDisplacements) {
model->solveStep();
auto d1 = model->getDisplacement()(1, 2);
auto d2 = model->getDisplacement()(2, 2);
auto d3 = model->getDisplacement()(1, 0);
Real tol = Math::getTolerance();
EXPECT_NEAR(d1, 5.6 / 4800, tol); // first rotation
EXPECT_NEAR(d2, -3.7 / 4800, tol); // second rotation
EXPECT_NEAR(d3, 10. / 18, tol); // axial deformation
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc
index b3e649e5e..0c5058d50 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_3.cc
@@ -1,100 +1,102 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_3.cc
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @date creation: Mon Jan 22 2018
*
* @brief Computation of the analytical exemple 1.1 in the TGC vol 6
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_structural_mechanics_model_fixture.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
/* -------------------------------------------------------------------------- */
using namespace akantu;
class TestStructBernoulli3
: public TestStructuralFixture<element_type_t<_bernoulli_beam_3>> {
using parent = TestStructuralFixture<element_type_t<_bernoulli_beam_3>>;
public:
void readMesh(std::string filename) override {
parent::readMesh(filename);
auto & normals =
this->mesh->registerData<Real>("extra_normal")
.alloc(0, parent::spatial_dimension, parent::type, _not_ghost);
Vector<Real> normal = {0, 0, 1};
normals.push_back(normal);
normal = {0, 0, 1};
normals.push_back(normal);
}
void addMaterials() override {
StructuralMaterial mat;
mat.E = 1;
mat.Iz = 1;
mat.Iy = 1;
mat.A = 1;
mat.GJ = 1;
this->model->addMaterial(mat);
}
void setDirichlets() {
// Boundary conditions (blocking all DOFs of nodes 2 & 3)
auto boundary = ++this->model->getBlockedDOFs().begin(parent::ndof);
// clang-format off
*boundary = {true, true, true, true, true, true}; ++boundary;
*boundary = {true, true, true, true, true, true}; ++boundary;
// clang-format on
}
void setNeumanns() override {
// Forces
Real P = 1; // N
auto & forces = this->model->getExternalForce();
forces.clear();
forces(0, 2) = -P; // vertical force on first node
}
- void assignMaterials() override { model->getElementMaterial(parent::type).set(0); }
+ void assignMaterials() override {
+ model->getElementMaterial(parent::type).set(0);
+ }
};
/* -------------------------------------------------------------------------- */
TEST_F(TestStructBernoulli3, TestDisplacements) {
model->solveStep();
auto vz = model->getDisplacement()(0, 2);
auto thy = model->getDisplacement()(0, 4);
auto thx = model->getDisplacement()(0, 3);
auto thz = model->getDisplacement()(0, 5);
Real tol = Math::getTolerance();
EXPECT_NEAR(vz, -5. / 48, tol);
EXPECT_NEAR(thy, -std::sqrt(2) / 8, tol);
EXPECT_NEAR(thz, 0, tol);
EXPECT_NEAR(thx, 0, tol);
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc
index 1c60226cc..578b53c79 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_dynamics.cc
@@ -1,206 +1,207 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_dynamics.cc
*
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
*
* @date creation: Mon Jul 07 2014
* @date last modification: Sun Oct 19 2014
*
* @brief Test for _bernouilli_beam in dynamic
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include <limits>
#include <fstream>
+#include <limits>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "material.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_io_msh_struct.hh"
#include "structural_mechanics_model.hh"
-#include "material.hh"
#include <iostream>
using namespace akantu;
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_2
static Real analytical_solution(Real time, Real L, Real rho, Real E,
__attribute__((unused)) Real A, Real I,
Real F) {
Real omega = M_PI * M_PI / L / L * sqrt(E * I / rho);
Real sum = 0.;
UInt i = 5;
for (UInt n = 1; n <= i; n += 2) {
sum += (1. - cos(n * n * omega * time)) / pow(n, 4);
}
return 2. * F * pow(L, 3) / pow(M_PI, 4) / E / I * sum;
}
// load
const Real F = 0.5e4;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize(argc, argv);
Mesh beams(2);
debug::setDebugLevel(dblWarning);
const ElementType type = _bernoulli_beam_2;
/* --------------------------------------------------------------------------
*/
// Mesh
UInt nb_element = 8;
UInt nb_nodes = nb_element + 1;
Real total_length = 10.;
Real length = total_length / nb_element;
Real heigth = 1.;
Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
nodes.resize(nb_nodes);
beams.addConnectivityType(type);
Array<UInt> & connectivity =
const_cast<Array<UInt> &>(beams.getConnectivity(type));
connectivity.resize(nb_element);
beams.initNormals();
Array<Real> & normals = const_cast<Array<Real> &>(beams.getNormals(type));
normals.resize(nb_element);
for (UInt i = 0; i < nb_nodes; ++i) {
nodes(i, 0) = i * length;
nodes(i, 1) = 0;
}
for (UInt i = 0; i < nb_element; ++i) {
connectivity(i, 0) = i;
connectivity(i, 1) = i + 1;
}
/* --------------------------------------------------------------------------
*/
// Materials
StructuralMechanicsModel model(beams);
StructuralMaterial mat1;
mat1.E = 120e6;
mat1.rho = 1000;
mat1.A = heigth;
mat1.I = heigth * heigth * heigth / 12;
model.addMaterial(mat1);
/* --------------------------------------------------------------------------
*/
// Forces
// model.initFull();
model.initFull(StructuralMechanicsModelOptions(_implicit_dynamic));
const Array<Real> & position = beams.getNodes();
Array<Real> & forces = model.getForce();
Array<Real> & displacement = model.getDisplacement();
Array<bool> & boundary = model.getBlockedDOFs();
UInt node_to_print = -1;
forces.clear();
displacement.clear();
// boundary.clear();
// model.getElementMaterial(type)(i,0) = 0;
// model.getElementMaterial(type)(i,0) = 1;
for (UInt i = 0; i < nb_element; ++i) {
model.getElementMaterial(type)(i, 0) = 0;
}
for (UInt n = 0; n < nb_nodes; ++n) {
Real x = position(n, 0);
// Real y = position(n, 1);
if (Math::are_float_equal(x, total_length / 2.)) {
forces(n, 1) = F;
node_to_print = n;
}
}
std::ofstream pos;
pos.open("position.csv");
if (!pos.good()) {
std::cerr << "Cannot open file" << std::endl;
exit(EXIT_FAILURE);
}
pos << "id,time,position,solution" << std::endl;
// model.computeForcesFromFunction<type>(load, _bft_traction)
/* --------------------------------------------------------------------------
*/
// Boundary conditions
// true ~ displacement is blocked
boundary(0, 0) = true;
boundary(0, 1) = true;
boundary(nb_nodes - 1, 1) = true;
/* --------------------------------------------------------------------------
*/
// "Solve"
Real time = 0;
model.assembleStiffnessMatrix();
model.assembleMass();
model.dump();
model.getStiffnessMatrix().saveMatrix("K.mtx");
model.getMassMatrix().saveMatrix("M.mt");
Real time_step = 1e-4;
model.setTimeStep(time_step);
std::cout << "Time"
<< " | "
<< "Mid-Span Displacement" << std::endl;
/// time loop
for (UInt s = 1; time < 0.64; ++s) {
model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(1e-12, 1000);
pos << s << "," << time << "," << displacement(node_to_print, 1) << ","
<< analytical_solution(s * time_step, total_length, mat1.rho, mat1.E,
- mat1.A, mat1.I, F) << std::endl;
+ mat1.A, mat1.I, F)
+ << std::endl;
// pos << s << "," << time << "," << displacement(node_to_print, 1) <<
// "," << analytical_solution(s*time_step) << std::endl;
time += time_step;
if (s % 100 == 0)
std::cout << time << " | " << displacement(node_to_print, 1)
<< std::endl;
model.dump();
}
pos.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc
index 21864217a..924edc9ed 100644
--- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_discrete_kirchhoff_triangle_18.cc
@@ -1,112 +1,113 @@
/**
* @file test_structural_mechanics_model_bernoulli_beam_2.cc
*
* @author Fabian Barras <fabian.barras@epfl.ch>
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Sun Oct 19 2014
*
* @brief Computation of the analytical exemple 1.1 in the TGC vol 6
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "test_structural_mechanics_model_fixture.hh"
#include "sparse_matrix.hh"
+#include "test_structural_mechanics_model_fixture.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
using namespace akantu;
/* -------------------------------------------------------------------------- */
-class TestStructDKT18
- : public TestStructuralFixture<element_type_t<_discrete_kirchhoff_triangle_18>> {
- using parent = TestStructuralFixture<element_type_t<_discrete_kirchhoff_triangle_18>>;
+class TestStructDKT18 : public TestStructuralFixture<
+ element_type_t<_discrete_kirchhoff_triangle_18>> {
+ using parent =
+ TestStructuralFixture<element_type_t<_discrete_kirchhoff_triangle_18>>;
public:
void addMaterials() override {
mat.E = 1;
mat.t = 1;
mat.nu = 0.3;
this->model->addMaterial(mat);
}
void assignMaterials() override {
auto & materials = this->model->getElementMaterial(parent::type);
std::fill(materials.begin(), materials.end(), 0);
}
void setDirichlets() override {
this->model->getBlockedDOFs().set(true);
auto center_node = this->model->getBlockedDOFs().end(parent::ndof) - 1;
*center_node = {false, false, false, false, false, true};
this->model->getDisplacement().clear();
auto disp = ++this->model->getDisplacement().begin(parent::ndof);
// Displacement field from Batoz Vol. 2 p. 392
// with theta to beta correction from discrete Kirchhoff condition
// see also the master thesis of Michael Lozano
// clang-format off
// This displacement field tests membrane and bending modes
*disp = {40, 20, -800 , -20, 40, 0}; ++disp;
*disp = {50, 40, -1400, -40, 50, 0}; ++disp;
*disp = {10, 20, -200 , -20, 10, 0}; ++disp;
// This displacement tests the bending mode
// *disp = {0, 0, -800 , -20, 40, 0}; ++disp;
// *disp = {0, 0, -1400, -40, 50, 0}; ++disp;
// *disp = {0, 0, -200 , -20, 10, 0}; ++disp;
// This displacement tests the membrane mode
// *disp = {40, 20, 0, 0, 0, 0}; ++disp;
// *disp = {50, 40, 0, 0, 0, 0}; ++disp;
// *disp = {10, 20, 0, 0, 0, 0}; ++disp;
// clang-format on
}
void setNeumanns() override {}
protected:
StructuralMaterial mat;
};
/* -------------------------------------------------------------------------- */
// Batoz Vol 2. patch test, ISBN 2-86601-259-3
TEST_F(TestStructDKT18, TestDisplacements) {
model->solveStep();
Vector<Real> solution = {22.5, 22.5, -337.5, -22.5, 22.5, 0};
auto nb_nodes = this->model->getDisplacement().size();
Vector<Real> center_node_disp =
model->getDisplacement().begin(solution.size())[nb_nodes - 1];
auto error = solution - center_node_disp;
EXPECT_NEAR(error.norm<L_2>(), 0., 1e-12);
}
diff --git a/test/test_solver/test_petsc_matrix_apply_boundary.cc b/test/test_solver/test_petsc_matrix_apply_boundary.cc
index c89eebdf2..98f6e28fa 100644
--- a/test/test_solver/test_petsc_matrix_apply_boundary.cc
+++ b/test/test_solver/test_petsc_matrix_apply_boundary.cc
@@ -1,144 +1,149 @@
/**
* @file test_petsc_matrix_apply_boundary.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Mon Oct 13 2014
* @date last modification: Wed Oct 28 2015
*
* @brief test the applyBoundary method of the PETScMatrix class
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
/* -------------------------------------------------------------------------- */
-#include "communicator.hh"
#include "aka_common.hh"
#include "aka_csr.hh"
+#include "communicator.hh"
+#include "dof_synchronizer.hh"
+#include "element_synchronizer.hh"
+#include "fe_engine.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_utils.hh"
-#include "element_synchronizer.hh"
#include "petsc_matrix.hh"
-#include "fe_engine.hh"
-#include "dof_synchronizer.hh"
#include "mesh_partition_scotch.hh"
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const ElementType element_type = _triangle_3;
- const GhostType ghost_type = _not_ghost;
+ const GhostType ghost_type = _not_ghost;
UInt spatial_dimension = 2;
-
const auto & comm = akantu::Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partition it
Mesh mesh(spatial_dimension);
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
ElementSynchronizer * communicator = NULL;
- if(prank == 0) {
+ if (prank == 0) {
/// creation mesh
mesh.read("triangle.msh");
- MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ MeshPartitionScotch * partition =
+ new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
-
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
+ FEEngine * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>(
+ mesh, spatial_dimension, "my_fem");
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
UInt nb_global_nodes = mesh.getNbGlobalNodes();
dof_synchronizer.initGlobalDOFEquationNumbers();
- // fill the matrix with
+ // fill the matrix with
UInt nb_element = mesh.getNbElement(element_type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
SparseMatrix K(nb_global_nodes * spatial_dimension, _symmetric);
K.buildProfile(mesh, dof_synchronizer, spatial_dimension);
Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1);
- Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
- Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
- Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
-
- for(; K_e_it != K_e_end; ++K_e_it)
+ Array<Real> K_e =
+ Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
+ Array<Real>::matrix_iterator K_e_it =
+ K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
+ Array<Real>::matrix_iterator K_e_end =
+ K_e.end(nb_dofs_per_element, nb_dofs_per_element);
+
+ for (; K_e_it != K_e_end; ++K_e_it)
*K_e_it = element_input;
// assemble the test matrix
fem->assembleMatrix(K_e, K, spatial_dimension, element_type, ghost_type);
// create petsc matrix
PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
-
+
// add stiffness matrix to petsc matrix
petsc_matrix.add(K, 1);
-
+
// create boundary array: block all dofs
UInt nb_nodes = mesh.getNbNodes();
Array<bool> boundary = Array<bool>(nb_nodes, spatial_dimension, true);
// apply boundary
petsc_matrix.applyBoundary(boundary);
// test if all entries except the diagonal ones have been zeroed
Real test_passed = 0;
- for (UInt i = 0; i < nb_nodes * spatial_dimension; ++i) {
+ for (UInt i = 0; i < nb_nodes * spatial_dimension; ++i) {
if (dof_synchronizer.isLocalOrMasterDOF(i)) {
for (UInt j = 0; j < nb_nodes * spatial_dimension; ++j) {
- if (dof_synchronizer.isLocalOrMasterDOF(j)) {
- if (i == j)
- test_passed += petsc_matrix(i, j) - 1;
- else
- test_passed += petsc_matrix(i, j) - 0;
- }
+ if (dof_synchronizer.isLocalOrMasterDOF(j)) {
+ if (i == j)
+ test_passed += petsc_matrix(i, j) - 1;
+ else
+ test_passed += petsc_matrix(i, j) - 0;
+ }
}
}
}
if (std::abs(test_passed) > Math::getTolerance()) {
finalize();
return EXIT_FAILURE;
}
delete communicator;
finalize();
return EXIT_SUCCESS;
-
}
diff --git a/test/test_solver/test_petsc_matrix_diagonal.cc b/test/test_solver/test_petsc_matrix_diagonal.cc
index 145105038..2fae54030 100644
--- a/test/test_solver/test_petsc_matrix_diagonal.cc
+++ b/test/test_solver/test_petsc_matrix_diagonal.cc
@@ -1,151 +1,162 @@
/**
* @file test_petsc_matrix_diagonal.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Mon Oct 13 2014
* @date last modification: Fri Jan 15 2016
*
* @brief test the connectivity is correctly represented in the PETScMatrix
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
-#include "communicator.hh"
#include "aka_common.hh"
#include "aka_csr.hh"
+#include "communicator.hh"
+#include "dof_synchronizer.hh"
+#include "dumper_paraview.hh"
+#include "element_synchronizer.hh"
+#include "fe_engine.hh"
#include "mesh.hh"
#include "mesh_io.hh"
+#include "mesh_partition_scotch.hh"
#include "mesh_utils.hh"
-#include "element_synchronizer.hh"
#include "petsc_matrix.hh"
-#include "fe_engine.hh"
-#include "dof_synchronizer.hh"
-#include "dumper_paraview.hh"
-#include "mesh_partition_scotch.hh"
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const ElementType element_type = _triangle_3;
- const GhostType ghost_type = _not_ghost;
+ const GhostType ghost_type = _not_ghost;
UInt spatial_dimension = 2;
-
const auto & comm = akantu::Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partition it
Mesh mesh(spatial_dimension);
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
ElementSynchronizer * communicator = NULL;
- if(prank == 0) {
+ if (prank == 0) {
/// creation mesh
mesh.read("triangle.msh");
- MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ MeshPartitionScotch * partition =
+ new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
-
+
// DumperParaview mesh_dumper("mesh_dumper");
// mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
// mesh_dumper.dump();
/// initialize the FEEngine and the dof_synchronizer
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
+ FEEngine * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>(
+ mesh, spatial_dimension, "my_fem");
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
UInt nb_global_nodes = mesh.getNbGlobalNodes();
dof_synchronizer.initGlobalDOFEquationNumbers();
- // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh
+ // construct an Akantu sparse matrix, build the profile and fill the matrix
+ // for the given mesh
UInt nb_element = mesh.getNbElement(element_type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric);
K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension);
/// use as elemental matrices a matrix with values equal to 1 every where
Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
- Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
- Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
- Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
-
- for(; K_e_it != K_e_end; ++K_e_it)
+ Array<Real> K_e =
+ Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
+ Array<Real>::matrix_iterator K_e_it =
+ K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
+ Array<Real>::matrix_iterator K_e_end =
+ K_e.end(nb_dofs_per_element, nb_dofs_per_element);
+
+ for (; K_e_it != K_e_end; ++K_e_it)
*K_e_it = element_input;
// assemble the test matrix
- fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type);
-
+ fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type,
+ ghost_type);
+
/// construct a PETSc matrix
PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric);
/// build the profile of the PETSc matrix for the mesh of this example
K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension);
/// add an Akantu sparse matrix to a PETSc sparse matrix
K_petsc.add(K_akantu, 1);
/// check to how many elements each node is connected
CSR<Element> node_to_elem;
MeshUtils::buildNode2Elements(mesh, node_to_elem, spatial_dimension);
/// test the diagonal of the PETSc matrix: the diagonal entries
/// of the PETSc matrix correspond to the number of elements
- /// connected to the node of the dof. Note: for an Akantu matrix this is only true for the serial case
+ /// connected to the node of the dof. Note: for an Akantu matrix this is only
+ /// true for the serial case
Real error = 0.;
/// loop over all diagonal values of the matrix
- for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
UInt dof = i * spatial_dimension + j;
/// for PETSc matrix only DOFs on the processor and be accessed
if (dof_synchronizer.isLocalOrMasterDOF(dof)) {
- UInt global_dof = dof_synchronizer.getDOFGlobalID(dof);
- std::cout << "Number of elements connected: " << node_to_elem.getNbCols(i) << std::endl;
- std::cout << "K_petsc(" << global_dof << "," << global_dof << ")=" << K_petsc(dof,dof) << std::endl;
- error += std::abs(K_petsc(dof, dof) - node_to_elem.getNbCols(i));
+ UInt global_dof = dof_synchronizer.getDOFGlobalID(dof);
+ std::cout << "Number of elements connected: "
+ << node_to_elem.getNbCols(i) << std::endl;
+ std::cout << "K_petsc(" << global_dof << "," << global_dof
+ << ")=" << K_petsc(dof, dof) << std::endl;
+ error += std::abs(K_petsc(dof, dof) - node_to_elem.getNbCols(i));
}
}
}
- if(error > Math::getTolerance() ) {
+ if (error > Math::getTolerance()) {
std::cout << "error in the stiffness matrix!!!" << std::endl;
finalize();
return EXIT_FAILURE;
}
delete communicator;
finalize();
-
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_petsc_matrix_profile.cc b/test/test_solver/test_petsc_matrix_profile.cc
index 391f22855..ddfff6561 100644
--- a/test/test_solver/test_petsc_matrix_profile.cc
+++ b/test/test_solver/test_petsc_matrix_profile.cc
@@ -1,134 +1,142 @@
/**
* @file test_petsc_matrix_profile.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Mon Oct 13 2014
* @date last modification: Tue Apr 28 2015
*
* @brief test the profile generation of the PETScMatrix class
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
/* -------------------------------------------------------------------------- */
-#include "communicator.hh"
#include "aka_common.hh"
#include "aka_csr.hh"
+#include "communicator.hh"
+#include "dof_synchronizer.hh"
+#include "element_synchronizer.hh"
+#include "fe_engine.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_utils.hh"
-#include "element_synchronizer.hh"
#include "petsc_matrix.hh"
-#include "fe_engine.hh"
-#include "dof_synchronizer.hh"
/// #include "dumper_paraview.hh"
#include "mesh_partition_scotch.hh"
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const ElementType element_type = _triangle_3;
- const GhostType ghost_type = _not_ghost;
+ const GhostType ghost_type = _not_ghost;
UInt spatial_dimension = 2;
-
const auto & comm = akantu::Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partition it
Mesh mesh(spatial_dimension);
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
ElementSynchronizer * communicator = NULL;
- if(prank == 0) {
+ if (prank == 0) {
/// creation mesh
mesh.read("square.msh");
- MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ MeshPartitionScotch * partition =
+ new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
// dump mesh in paraview
// DumperParaview mesh_dumper("mesh_dumper");
// mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
// mesh_dumper.dump();
/// initialize the FEEngine and the dof_synchronizer
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
+ FEEngine * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>(
+ mesh, spatial_dimension, "my_fem");
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
UInt nb_global_nodes = mesh.getNbGlobalNodes();
dof_synchronizer.initGlobalDOFEquationNumbers();
- // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh
+ // construct an Akantu sparse matrix, build the profile and fill the matrix
+ // for the given mesh
UInt nb_element = mesh.getNbElement(element_type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric);
K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension);
/// use as elemental matrices a matrix with values equal to 1 every where
Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
- Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
- Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
- Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
-
- for(; K_e_it != K_e_end; ++K_e_it)
+ Array<Real> K_e =
+ Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
+ Array<Real>::matrix_iterator K_e_it =
+ K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
+ Array<Real>::matrix_iterator K_e_end =
+ K_e.end(nb_dofs_per_element, nb_dofs_per_element);
+
+ for (; K_e_it != K_e_end; ++K_e_it)
*K_e_it = element_input;
// assemble the test matrix
- fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type);
-
+ fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type,
+ ghost_type);
+
/// construct a PETSc matrix
PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric);
/// build the profile of the PETSc matrix for the mesh of this example
K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension);
/// add an Akantu sparse matrix to a PETSc sparse matrix
K_petsc.add(K_akantu, 1);
/// save the profile
K_petsc.saveMatrix("profile.txt");
/// print the matrix to screen
std::ifstream profile;
profile.open("profile.txt");
std::string current_line;
- while(getline(profile, current_line))
+ while (getline(profile, current_line))
std::cout << current_line << std::endl;
profile.close();
delete communicator;
finalize();
-
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_petsc_matrix_profile_parallel.cc b/test/test_solver/test_petsc_matrix_profile_parallel.cc
index b638a3c23..05795ba9c 100644
--- a/test/test_solver/test_petsc_matrix_profile_parallel.cc
+++ b/test/test_solver/test_petsc_matrix_profile_parallel.cc
@@ -1,135 +1,143 @@
/**
* @file test_petsc_matrix_profile_parallel.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Mon Oct 13 2014
* @date last modification: Tue Apr 28 2015
*
* @brief test the profile generation of the PETScMatrix class in parallel
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
#include <fstream>
/* -------------------------------------------------------------------------- */
-#include "communicator.hh"
#include "aka_common.hh"
#include "aka_csr.hh"
+#include "communicator.hh"
+#include "dof_synchronizer.hh"
+#include "element_synchronizer.hh"
+#include "fe_engine.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_utils.hh"
-#include "element_synchronizer.hh"
#include "petsc_matrix.hh"
-#include "fe_engine.hh"
-#include "dof_synchronizer.hh"
/// #include "dumper_paraview.hh"
#include "mesh_partition_scotch.hh"
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const ElementType element_type = _triangle_3;
- const GhostType ghost_type = _not_ghost;
+ const GhostType ghost_type = _not_ghost;
UInt spatial_dimension = 2;
-
const auto & comm = akantu::Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partition it
Mesh mesh(spatial_dimension);
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
ElementSynchronizer * communicator = NULL;
- if(prank == 0) {
+ if (prank == 0) {
/// creation mesh
mesh.read("square.msh");
- MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ MeshPartitionScotch * partition =
+ new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
// dump mesh in paraview
// DumperParaview mesh_dumper("mesh_dumper");
// mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
// mesh_dumper.dump();
/// initialize the FEEngine and the dof_synchronizer
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
+ FEEngine * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>(
+ mesh, spatial_dimension, "my_fem");
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
UInt nb_global_nodes = mesh.getNbGlobalNodes();
dof_synchronizer.initGlobalDOFEquationNumbers();
- // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh
+ // construct an Akantu sparse matrix, build the profile and fill the matrix
+ // for the given mesh
UInt nb_element = mesh.getNbElement(element_type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric);
K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension);
/// use as elemental matrices a matrix with values equal to 1 every where
Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
- Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
- Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
- Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
-
- for(; K_e_it != K_e_end; ++K_e_it)
+ Array<Real> K_e =
+ Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
+ Array<Real>::matrix_iterator K_e_it =
+ K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
+ Array<Real>::matrix_iterator K_e_end =
+ K_e.end(nb_dofs_per_element, nb_dofs_per_element);
+
+ for (; K_e_it != K_e_end; ++K_e_it)
*K_e_it = element_input;
// assemble the test matrix
- fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type);
-
+ fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type,
+ ghost_type);
+
/// construct a PETSc matrix
PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric);
/// build the profile of the PETSc matrix for the mesh of this example
K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension);
/// add an Akantu sparse matrix to a PETSc sparse matrix
K_petsc.add(K_akantu, 1);
/// save the profile
K_petsc.saveMatrix("profile_parallel.txt");
/// print the matrix to screen
- if(prank == 0) {
+ if (prank == 0) {
std::ifstream profile;
profile.open("profile_parallel.txt");
std::string current_line;
- while(getline(profile, current_line))
+ while (getline(profile, current_line))
std::cout << current_line << std::endl;
profile.close();
}
delete communicator;
finalize();
-
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_solver_petsc.cc b/test/test_solver/test_solver_petsc.cc
index 4c754b6cc..288629417 100644
--- a/test/test_solver/test_solver_petsc.cc
+++ b/test/test_solver/test_solver_petsc.cc
@@ -1,165 +1,172 @@
/**
* @file test_solver_petsc.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Mon Oct 13 2014
* @date last modification: Wed Oct 28 2015
*
* @brief test the PETSc solver interface
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include <cstdlib>
/* -------------------------------------------------------------------------- */
-#include "communicator.hh"
#include "aka_common.hh"
#include "aka_csr.hh"
+#include "communicator.hh"
+#include "dof_synchronizer.hh"
+#include "element_synchronizer.hh"
+#include "fe_engine.hh"
#include "mesh.hh"
#include "mesh_io.hh"
#include "mesh_utils.hh"
-#include "element_synchronizer.hh"
#include "petsc_matrix.hh"
#include "solver_petsc.hh"
-#include "fe_engine.hh"
-#include "dof_synchronizer.hh"
#include "mesh_partition_scotch.hh"
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const ElementType element_type = _segment_2;
- const GhostType ghost_type = _not_ghost;
+ const GhostType ghost_type = _not_ghost;
UInt spatial_dimension = 1;
-
const auto & comm = akantu::Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
/// read the mesh and partition it
Mesh mesh(spatial_dimension);
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
ElementSynchronizer * communicator = NULL;
- if(prank == 0) {
+ if (prank == 0) {
/// creation mesh
mesh.read("1D_bar.msh");
- MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ MeshPartitionScotch * partition =
+ new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
-
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
+ FEEngine * fem =
+ new FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>(
+ mesh, spatial_dimension, "my_fem");
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
UInt nb_global_nodes = mesh.getNbGlobalNodes();
dof_synchronizer.initGlobalDOFEquationNumbers();
- // fill the matrix with
+ // fill the matrix with
UInt nb_element = mesh.getNbElement(element_type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
SparseMatrix K(nb_global_nodes * spatial_dimension, _symmetric);
K.buildProfile(mesh, dof_synchronizer, spatial_dimension);
Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 0);
for (UInt i = 0; i < nb_dofs_per_element; ++i) {
for (UInt j = 0; j < nb_dofs_per_element; ++j) {
- element_input(i, j) = ((i == j) ? 1 : -1);
+ element_input(i, j) = ((i == j) ? 1 : -1);
}
}
- Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
- Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
- Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
-
- for(; K_e_it != K_e_end; ++K_e_it)
+ Array<Real> K_e =
+ Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
+ Array<Real>::matrix_iterator K_e_it =
+ K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
+ Array<Real>::matrix_iterator K_e_end =
+ K_e.end(nb_dofs_per_element, nb_dofs_per_element);
+
+ for (; K_e_it != K_e_end; ++K_e_it)
*K_e_it = element_input;
// assemble the test matrix
fem->assembleMatrix(K_e, K, spatial_dimension, element_type, ghost_type);
// apply boundary: block first node
const Array<Real> & position = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
Array<bool> boundary = Array<bool>(nb_nodes, spatial_dimension, false);
for (UInt i = 0; i < nb_nodes; ++i) {
- if (std::abs(position(i, 0)) < Math::getTolerance() )
+ if (std::abs(position(i, 0)) < Math::getTolerance())
boundary(i, 0) = true;
}
K.applyBoundary(boundary);
/// create the PETSc matrix for the solve step
PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
-
+
/// copy the stiffness matrix into the petsc matrix
petsc_matrix.add(K, 1);
- // initialize internal forces: they are zero because imposed displacement is zero
+ // initialize internal forces: they are zero because imposed displacement is
+ // zero
Array<Real> internal_forces(nb_nodes, spatial_dimension, 0.);
// compute residual: apply nodal force on last node
Array<Real> residual(nb_nodes, spatial_dimension, 0.);
-
+
for (UInt i = 0; i < nb_nodes; ++i) {
- if (std::abs(position(i, 0) - 10) < Math::getTolerance() )
+ if (std::abs(position(i, 0) - 10) < Math::getTolerance())
residual(i, 0) += 2;
}
residual -= internal_forces;
-
+
/// initialize solver and solution
Array<Real> solution(nb_nodes, spatial_dimension, 0.);
SolverPETSc solver(petsc_matrix);
solver.initialize();
solver.setOperators();
solver.setRHS(residual);
solver.solve(solution);
/// verify solution
Math::setTolerance(1e-11);
for (UInt i = 0; i < nb_nodes; ++i) {
- if (!dof_synchronizer.isPureGhostDOF(i) && !Math::are_float_equal(2 * position(i, 0), solution(i, 0))) {
+ if (!dof_synchronizer.isPureGhostDOF(i) &&
+ !Math::are_float_equal(2 * position(i, 0), solution(i, 0))) {
std::cout << "The solution is not correct!!!!" << std::endl;
finalize();
return EXIT_FAILURE;
}
}
delete communicator;
finalize();
-
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_sparse_matrix_assemble.cc b/test/test_solver/test_sparse_matrix_assemble.cc
index f3333536b..5ac8c1253 100644
--- a/test/test_solver/test_sparse_matrix_assemble.cc
+++ b/test/test_solver/test_sparse_matrix_assemble.cc
@@ -1,85 +1,86 @@
/**
* @file test_sparse_matrix_assemble.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Sun Oct 19 2014
*
* @brief test the assembling method of the SparseMatrix class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <cstdlib>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_io.hh"
-#include "sparse_matrix.hh"
#include "dof_synchronizer.hh"
+#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
UInt nb_nodes = mesh.getNbNodes();
-
DOFManagerDefault dof_manager(mesh, "test_dof_manager");
Array<Real> test_synchronize(nb_nodes, spatial_dimension, "Test vector");
dof_manager.registerDOFs("test_synchronize", test_synchronize, _dst_nodal);
auto & A = dof_manager.getNewMatrix("A", _symmetric);
- // const akantu::Mesh::ConnectivityTypeList & type_list = mesh.getConnectivityTypeList();
+ // const akantu::Mesh::ConnectivityTypeList & type_list =
+ // mesh.getConnectivityTypeList();
// akantu::Mesh::ConnectivityTypeList::const_iterator it;
// for(it = type_list.begin(); it != type_list.end(); ++it) {
// if(mesh.getSpatialDimension(*it) != spatial_dimension) continue;
// akantu::UInt nb_element = mesh.getNbElement(*it);
// akantu::UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
// akantu::Element element(*it);
// akantu::UInt m = nb_nodes_per_element * spatial_dimension;
// akantu::Array<akantu::Real> local_mat(m, m, 1, "local_mat");
// for(akantu::UInt e = 0; e < nb_element; ++e) {
// element.element = e;
- // sparse_matrix.addToMatrix(local_mat.storage(), element, nb_nodes_per_element);
+ // sparse_matrix.addToMatrix(local_mat.storage(), element,
+ // nb_nodes_per_element);
// }
// }
A.saveMatrix("matrix.mtx");
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_sparse_matrix_product.cc b/test/test_solver/test_sparse_matrix_product.cc
index ce24921de..23d80c8dc 100644
--- a/test/test_solver/test_sparse_matrix_product.cc
+++ b/test/test_solver/test_sparse_matrix_product.cc
@@ -1,115 +1,119 @@
/**
* @file test_sparse_matrix_product.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
* @date last modification: Sun Oct 19 2014
*
* @brief test the matrix vector product in parallel
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "dof_synchronizer.hh"
+#include "element_synchronizer.hh"
#include "mesh.hh"
#include "mesh_partition_scotch.hh"
-#include "element_synchronizer.hh"
#include "sparse_matrix.hh"
-#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const UInt spatial_dimension = 2;
const UInt nb_dof = 2;
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
Mesh mesh(spatial_dimension);
mesh.read("bar.msh");
mesh.distribute();
UInt nb_nodes = mesh.getNbNodes();
DOFManagerDefault dof_manager(mesh, "test_dof_manager");
Array<Real> test_synchronize(nb_nodes, nb_dof, "Test vector");
dof_manager.registerDOFs("test_synchronize", test_synchronize, _dst_nodal);
- if (prank == 0) std::cout << "Creating a SparseMatrix" << std::endl;
+ if (prank == 0)
+ std::cout << "Creating a SparseMatrix" << std::endl;
auto & A = dof_manager.getNewMatrix("A", _symmetric);
Array<Real> dof_vector(nb_nodes, nb_dof, "vector");
- if (prank == 0) std::cout << "Filling the matrix" << std::endl;
+ if (prank == 0)
+ std::cout << "Filling the matrix" << std::endl;
- for (UInt i = 0; i < nb_nodes*nb_dof; ++i) {
- if(dof_manager.isLocalOrMasterDOF(i))
+ for (UInt i = 0; i < nb_nodes * nb_dof; ++i) {
+ if (dof_manager.isLocalOrMasterDOF(i))
A.add(i, i, 2.);
}
- std::stringstream str; str << "Matrix_" << prank << ".mtx";
+ std::stringstream str;
+ str << "Matrix_" << prank << ".mtx";
A.saveMatrix(str.str());
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt d = 0; d < nb_dof; ++d) {
dof_vector(n, d) = 1.;
}
}
- if (prank == 0) std::cout << "Computing x = A * x" << std::endl;
+ if (prank == 0)
+ std::cout << "Computing x = A * x" << std::endl;
dof_vector *= A;
- auto & sync = dynamic_cast<DOFManagerDefault &>(dof_manager)
- .getSynchronizer();
+ auto & sync =
+ dynamic_cast<DOFManagerDefault &>(dof_manager).getSynchronizer();
- if (prank == 0) std::cout << "Gathering the results on proc 0" << std::endl;
- if(psize > 1) {
- if(prank == 0) {
+ if (prank == 0)
+ std::cout << "Gathering the results on proc 0" << std::endl;
+ if (psize > 1) {
+ if (prank == 0) {
Array<Real> gathered;
sync.gather(dof_vector, gathered);
debug::setDebugLevel(dblTest);
std::cout << gathered << std::endl;
debug::setDebugLevel(dblWarning);
} else {
sync.gather(dof_vector);
}
} else {
debug::setDebugLevel(dblTest);
std::cout << dof_vector << std::endl;
debug::setDebugLevel(dblWarning);
}
finalize();
return 0;
}
diff --git a/test/test_solver/test_sparse_matrix_profile.cc b/test/test_solver/test_sparse_matrix_profile.cc
index 8c267c29b..a1389c502 100644
--- a/test/test_solver/test_sparse_matrix_profile.cc
+++ b/test/test_solver/test_sparse_matrix_profile.cc
@@ -1,77 +1,76 @@
/**
* @file test_sparse_matrix_profile.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Sun Oct 19 2014
*
* @brief test the profile generation of the SparseMatrix class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dof_manager_default.hh"
#include "mesh.hh"
#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
#include <cstdlib>
/* -------------------------------------------------------------------------- */
using namespace akantu;
/* -------------------------------------------------------------------------- */
int main(int argc, char * argv[]) {
initialize(argc, argv);
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("triangle.msh");
UInt nb_nodes = mesh.getNbNodes();
DOFManagerDefault dof_manager(mesh, "test_dof_manager");
Array<Real> test_synchronize(nb_nodes, spatial_dimension, "Test vector");
dof_manager.registerDOFs("test_synchronize", test_synchronize, _dst_nodal);
auto & A = dof_manager.getNewMatrix("A", _symmetric);
for (UInt i = 0; i < 10; ++i) {
A.add(i, i);
}
A.add(0, 9);
A.saveProfile("profile_hand.mtx");
for (UInt i = 0; i < 10; ++i) {
A.add(i, i, i * 10);
}
A.add(0, 9, 100);
-
A.saveMatrix("matrix_hand.mtx");
/* ------------------------------------------------------------------------ */
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_solver/test_sparse_matrix_profile_parallel.cc b/test/test_solver/test_sparse_matrix_profile_parallel.cc
index 67682f43b..0fd38c8dd 100644
--- a/test/test_solver/test_sparse_matrix_profile_parallel.cc
+++ b/test/test_solver/test_sparse_matrix_profile_parallel.cc
@@ -1,114 +1,114 @@
/**
* @file test_sparse_matrix_profile_parallel.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 12 2010
* @date last modification: Sun Oct 19 2014
*
* @brief test the sparse matrix class in parallel
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "communicator.hh"
#include "mesh.hh"
#include "mesh_io_msh.hh"
#include "mesh_partition_scotch.hh"
-#include "communicator.hh"
-#include "sparse_matrix.hh"
#include "solver_mumps.hh"
+#include "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
-
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
int dim = 2;
//#ifdef AKANTU_USE_IOHELPER
- //akantu::ElementType type = akantu::_triangle_6;
+ // akantu::ElementType type = akantu::_triangle_6;
//#endif //AKANTU_USE_IOHELPER
akantu::Mesh mesh(dim);
// akantu::debug::setDebugLevel(akantu::dblDump);
- akantu::StaticCommunicator * comm = akantu::Communicator::getStaticCommunicator();
+ akantu::StaticCommunicator * comm =
+ akantu::Communicator::getStaticCommunicator();
akantu::Int psize = comm->getNbProc();
akantu::Int prank = comm->whoAmI();
akantu::UInt n = 0;
-
-
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
akantu::Communicator * communicator;
- if(prank == 0) {
+ if (prank == 0) {
akantu::MeshIOMSH mesh_io;
mesh_io.read("triangle.msh", mesh);
akantu::MeshPartition * partition =
- new akantu::MeshPartitionScotch(mesh, dim);
+ new akantu::MeshPartitionScotch(mesh, dim);
// partition->reorder();
mesh_io.write("triangle_reorder.msh", mesh);
n = mesh.getNbNodes();
partition->partitionate(psize);
- communicator = akantu::Communicator::createCommunicatorDistributeMesh(mesh, partition);
+ communicator =
+ akantu::Communicator::createCommunicatorDistributeMesh(mesh, partition);
delete partition;
} else {
- communicator = akantu::Communicator::createCommunicatorDistributeMesh(mesh, NULL);
+ communicator =
+ akantu::Communicator::createCommunicatorDistributeMesh(mesh, NULL);
}
-
- std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA " << mesh.getNbGlobalNodes() << std::endl;
+ std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
+ << mesh.getNbGlobalNodes() << std::endl;
akantu::SparseMatrix sparse_matrix(mesh, akantu::_symmetric, 2, "mesh");
sparse_matrix.buildProfile();
akantu::Solver * solver = new akantu::SolverMumps(sparse_matrix);
- if(prank == 0) {
- for(akantu::UInt i = 0; i < n; ++i) {
+ if (prank == 0) {
+ for (akantu::UInt i = 0; i < n; ++i) {
solver->getRHS().storage()[i] = 1.;
}
}
akantu::debug::setDebugLevel(akantu::dblDump);
solver->initialize();
- std::stringstream sstr; sstr << "profile_" << prank << ".mtx";
+ std::stringstream sstr;
+ sstr << "profile_" << prank << ".mtx";
sparse_matrix.saveProfile(sstr.str());
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_static_memory/test_static_memory.cc b/test/test_static_memory/test_static_memory.cc
index f1a05e9bd..30f88e1a2 100644
--- a/test/test_static_memory/test_static_memory.cc
+++ b/test/test_static_memory/test_static_memory.cc
@@ -1,58 +1,58 @@
/**
* @file test_static_memory.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Sun Oct 19 2014
*
* @brief unit test for the StaticMemory class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <iostream>
/* -------------------------------------------------------------------------- */
-#include "aka_static_memory.hh"
#include "aka_array.hh"
+#include "aka_static_memory.hh"
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
akantu::StaticMemory & st_mem = akantu::StaticMemory::getStaticMemory();
akantu::Array<int> & test_int = st_mem.smalloc<int>(0, "test_int", 1000, 3);
test_int.resize(1050);
test_int.resize(2000);
std::cout << st_mem << std::endl;
st_mem.sfree(0, "test_int");
akantu::finalize();
exit(EXIT_SUCCESS);
}
diff --git a/test/test_synchronizer/test_data_accessor.hh b/test/test_synchronizer/test_data_accessor.hh
index fbab621f5..aa59d7c5b 100644
--- a/test/test_synchronizer/test_data_accessor.hh
+++ b/test/test_synchronizer/test_data_accessor.hh
@@ -1,125 +1,124 @@
/**
* @file test_data_accessor.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Thu Apr 11 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Data Accessor class for testing
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "data_accessor.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
/* -------------------------------------------------------------------------- */
-
using namespace akantu;
/* -------------------------------------------------------------------------- */
class TestAccessor : public DataAccessor<Element> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
inline TestAccessor(const Mesh & mesh,
const ElementTypeMapArray<Real> & barycenters);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Barycenter, barycenters, Real);
/* ------------------------------------------------------------------------ */
/* Ghost Synchronizer inherited members */
/* ------------------------------------------------------------------------ */
protected:
inline UInt getNbData(const Array<Element> & elements,
const SynchronizationTag & tag) const;
inline void packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag) const;
inline void unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag & tag);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
const ElementTypeMapArray<Real> & barycenters;
const Mesh & mesh;
};
/* -------------------------------------------------------------------------- */
/* TestSynchronizer implementation */
/* -------------------------------------------------------------------------- */
inline TestAccessor::TestAccessor(const Mesh & mesh,
const ElementTypeMapArray<Real> & barycenters)
: barycenters(barycenters), mesh(mesh) {}
inline UInt TestAccessor::getNbData(const Array<Element> & elements,
const SynchronizationTag &) const {
if (elements.size())
// return Mesh::getSpatialDimension(elements(0).type) * sizeof(Real) *
// elements.size();
return mesh.getSpatialDimension() * sizeof(Real) * elements.size();
else
return 0;
}
inline void TestAccessor::packData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag &) const {
UInt spatial_dimension = mesh.getSpatialDimension();
Array<Element>::const_iterator<Element> bit = elements.begin();
Array<Element>::const_iterator<Element> bend = elements.end();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> bary(
this->barycenters(element.type, element.ghost_type).storage() +
element.element * spatial_dimension,
spatial_dimension);
buffer << bary;
}
}
inline void TestAccessor::unpackData(CommunicationBuffer & buffer,
const Array<Element> & elements,
const SynchronizationTag &) {
UInt spatial_dimension = mesh.getSpatialDimension();
- for(const auto & element : elements) {
+ for (const auto & element : elements) {
Vector<Real> barycenter_loc(
this->barycenters(element.type, element.ghost_type).storage() +
element.element * spatial_dimension,
spatial_dimension);
Vector<Real> bary(spatial_dimension);
buffer >> bary;
auto dist = (barycenter_loc - bary).template norm<L_inf>();
EXPECT_NEAR(0, dist, 1e-15);
}
}
diff --git a/test/test_synchronizer/test_data_distribution.cc b/test/test_synchronizer/test_data_distribution.cc
index 55ff32aaf..431a9bab8 100644
--- a/test/test_synchronizer/test_data_distribution.cc
+++ b/test/test_synchronizer/test_data_distribution.cc
@@ -1,73 +1,74 @@
/**
* @file test_data_distribution.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Sep 05 2014
* @date last modification: Sun Oct 19 2014
*
* @brief Test the mesh distribution on creation of a distributed synchonizer
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_synchronizers_fixture.hh"
/* -------------------------------------------------------------------------- */
TEST_F(TestSynchronizerFixture, DataDistribution) {
auto & barycenters = this->mesh->registerData<Real>("barycenters");
auto spatial_dimension = this->mesh->getSpatialDimension();
barycenters.initialize(*this->mesh, _spatial_dimension = _all_dimensions,
_nb_component = spatial_dimension);
this->initBarycenters(barycenters, *this->mesh);
this->distribute();
for (auto && ghost_type : ghost_types) {
for (const auto & type :
this->mesh->elementTypes(_all_dimensions, ghost_type)) {
auto & barycenters =
this->mesh->getData<Real>("barycenters", type, ghost_type);
- for (auto && data : enumerate(make_view(barycenters, spatial_dimension))) {
+ for (auto && data :
+ enumerate(make_view(barycenters, spatial_dimension))) {
Element element{type, UInt(std::get<0>(data)), ghost_type};
Vector<Real> barycenter(spatial_dimension);
this->mesh->getBarycenter(element, barycenter);
auto dist = (std::get<1>(data) - barycenter).template norm<L_inf>();
EXPECT_NEAR(dist, 0, 1e-7);
}
}
}
}
TEST_F(TestSynchronizerFixture, DataDistributionTags) {
this->distribute();
for (const auto & type : this->mesh->elementTypes(_all_dimensions)) {
auto & tags = this->mesh->getData<UInt>("tag_0", type);
Array<UInt>::const_vector_iterator tags_it = tags.begin(1);
Array<UInt>::const_vector_iterator tags_end = tags.end(1);
// The number of tags should match the number of elements on rank"
EXPECT_EQ(this->mesh->getNbElement(type), tags.size());
}
}
diff --git a/test/test_synchronizer/test_dof_data_accessor.hh b/test/test_synchronizer/test_dof_data_accessor.hh
index e5308ea40..e00b82e2f 100644
--- a/test/test_synchronizer/test_dof_data_accessor.hh
+++ b/test/test_synchronizer/test_dof_data_accessor.hh
@@ -1,117 +1,116 @@
/**
* @file test_dof_data_accessor.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Tue Dec 09 2014
*
* @brief data accessor class for testing the
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "data_accessor.hh"
-
/* -------------------------------------------------------------------------- */
namespace akantu {
class TestDOFAccessor : public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
inline TestDOFAccessor(const Array<Int> & global_dof_equation_numbers);
-
/* ------------------------------------------------------------------------ */
/* Ghost Synchronizer inherited members */
/* ------------------------------------------------------------------------ */
protected:
inline UInt getNbDataForDOFs(const Array<UInt> & dofs,
- SynchronizationTag tag) const;
+ SynchronizationTag tag) const;
inline void packDOFData(CommunicationBuffer & buffer,
- const Array<UInt> & dofs,
- SynchronizationTag tag) const;
+ const Array<UInt> & dofs,
+ SynchronizationTag tag) const;
inline void unpackDOFData(CommunicationBuffer & buffer,
- const Array<UInt> & dofs,
- SynchronizationTag tag);
+ const Array<UInt> & dofs, SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
const Array<Int> & global_dof_equation_numbers;
};
-
/* -------------------------------------------------------------------------- */
-/* TestDOFSynchronizer implementation */
+/* TestDOFSynchronizer implementation */
/* -------------------------------------------------------------------------- */
-inline TestDOFAccessor::TestDOFAccessor(const Array<Int> & global_dof_equation_numbers)
- : global_dof_equation_numbers(global_dof_equation_numbers) { }
+inline TestDOFAccessor::TestDOFAccessor(
+ const Array<Int> & global_dof_equation_numbers)
+ : global_dof_equation_numbers(global_dof_equation_numbers) {}
inline UInt TestDOFAccessor::getNbDataForDOFs(const Array<UInt> & dofs,
- __attribute__ ((unused)) SynchronizationTag tag) const {
- if(dofs.size())
- // return Mesh::getSpatialDimension(elements(0).type) * sizeof(Real) * elements.size();
+ __attribute__((unused))
+ SynchronizationTag tag) const {
+ if (dofs.size())
+ // return Mesh::getSpatialDimension(elements(0).type) * sizeof(Real) *
+ // elements.size();
return sizeof(Int) * dofs.size();
else
return 0;
}
inline void TestDOFAccessor::packDOFData(CommunicationBuffer & buffer,
- const Array<UInt> & dofs,
- __attribute__ ((unused)) SynchronizationTag tag) const {
- Array<UInt>::const_scalar_iterator bit = dofs.begin();
+ const Array<UInt> & dofs,
+ __attribute__((unused))
+ SynchronizationTag tag) const {
+ Array<UInt>::const_scalar_iterator bit = dofs.begin();
Array<UInt>::const_scalar_iterator bend = dofs.end();
for (; bit != bend; ++bit) {
buffer << this->global_dof_equation_numbers[*bit];
}
}
inline void TestDOFAccessor::unpackDOFData(CommunicationBuffer & buffer,
- const Array<UInt> & dofs,
- __attribute__ ((unused)) SynchronizationTag tag) {
- Array<UInt>::const_scalar_iterator bit = dofs.begin();
+ const Array<UInt> & dofs,
+ __attribute__((unused))
+ SynchronizationTag tag) {
+ Array<UInt>::const_scalar_iterator bit = dofs.begin();
Array<UInt>::const_scalar_iterator bend = dofs.end();
for (; bit != bend; ++bit) {
Int global_dof_eq_nb_local = global_dof_equation_numbers[*bit];
Int global_dof_eq_nb = 0;
buffer >> global_dof_eq_nb;
std::cout << *bit << global_dof_eq_nb_local << std::endl;
Real tolerance = Math::getTolerance();
- if(!(std::abs(global_dof_eq_nb - global_dof_eq_nb_local) <= tolerance))
- AKANTU_ERROR("Unpacking an unknown value for the dof: "
- << *bit
- << "(global_dof_equation_number = " << global_dof_eq_nb_local
- << " and buffer = " << global_dof_eq_nb << ") - tag: " << tag);
+ if (!(std::abs(global_dof_eq_nb - global_dof_eq_nb_local) <= tolerance))
+ AKANTU_ERROR(
+ "Unpacking an unknown value for the dof: "
+ << *bit << "(global_dof_equation_number = " << global_dof_eq_nb_local
+ << " and buffer = " << global_dof_eq_nb << ") - tag: " << tag);
}
}
-
} // namespace akantu
diff --git a/test/test_synchronizer/test_dof_synchronizer.cc b/test/test_synchronizer/test_dof_synchronizer.cc
index aab3c5d66..13d2e5642 100644
--- a/test/test_synchronizer/test_dof_synchronizer.cc
+++ b/test/test_synchronizer/test_dof_synchronizer.cc
@@ -1,149 +1,148 @@
/**
* @file test_dof_synchronizer.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
* @date last modification: Sun Oct 19 2014
*
* @brief Test the functionality of the DOFSynchronizer class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
+#include "communicator.hh"
#include "dof_synchronizer.hh"
#include "element_synchronizer.hh"
#include "mesh_io.hh"
#include "mesh_partition_scotch.hh"
-#include "communicator.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
#include "io_helper.hh"
#endif // AKANTU_USE_IOHELPER
/* -------------------------------------------------------------------------- */
using namespace akantu;
int main(int argc, char * argv[]) {
const UInt spatial_dimension = 2;
initialize(argc, argv);
- const auto & comm =
- akantu::Communicator::getStaticCommunicator();
+ const auto & comm = akantu::Communicator::getStaticCommunicator();
Int prank = comm.whoAmI();
Mesh mesh(spatial_dimension);
if (prank == 0)
mesh.read("bar.msh");
mesh.distribute();
DOFManagerDefault dof_manager(mesh, "test_dof_manager");
UInt nb_nodes = mesh.getNbNodes();
/* ------------------------------------------------------------------------ */
/* test the synchronization */
/* ------------------------------------------------------------------------ */
Array<Real> test_synchronize(nb_nodes, spatial_dimension, "Test vector");
dof_manager.registerDOFs("test_synchronize", test_synchronize, _dst_nodal);
auto & equation_number =
dof_manager.getLocalEquationNumbers("test_synchronize");
DOFSynchronizer & dof_synchronizer = dof_manager.getSynchronizer();
std::cout << "Synchronizing a dof vector" << std::endl;
Array<Int> local_data_array(dof_manager.getLocalSystemSize(), 2);
auto it_data = local_data_array.begin(2);
for (UInt local_dof = 0; local_dof < dof_manager.getLocalSystemSize();
++local_dof) {
UInt equ_number = equation_number(local_dof);
Vector<Int> val;
if (dof_manager.isLocalOrMasterDOF(equ_number)) {
UInt global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
val = {0, 1};
val += global_dof * 2;
} else {
val = {-1, -1};
}
Vector<Int> data = it_data[local_dof];
data = val;
}
dof_synchronizer.synchronize(local_data_array);
auto test_data = [&]() -> void {
auto it_data = local_data_array.begin(2);
for (UInt local_dof = 0; local_dof < dof_manager.getLocalSystemSize();
++local_dof) {
UInt equ_number = equation_number(local_dof);
Vector<Int> exp_val;
UInt global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
if (dof_manager.isLocalOrMasterDOF(equ_number) ||
dof_manager.isSlaveDOF(equ_number)) {
exp_val = {0, 1};
exp_val += global_dof * 2;
} else {
exp_val = {-1, -1};
}
Vector<Int> val = it_data[local_dof];
if (exp_val != val) {
std::cerr << "Failed !" << prank << " DOF: " << global_dof << " - l"
<< local_dof << " value:" << val << " expected: " << exp_val
<< std::endl;
exit(1);
}
}
};
test_data();
if (prank == 0) {
Array<Int> test_gathered(dof_manager.getSystemSize(), 2);
dof_synchronizer.gather(local_data_array, test_gathered);
local_data_array.set(-1);
dof_synchronizer.scatter(local_data_array, test_gathered);
} else {
dof_synchronizer.gather(local_data_array);
local_data_array.set(-1);
dof_synchronizer.scatter(local_data_array);
}
test_data();
finalize();
return 0;
}
diff --git a/test/test_synchronizer/test_dof_synchronizer_communication.cc b/test/test_synchronizer/test_dof_synchronizer_communication.cc
index dd6245ff9..c0696e319 100644
--- a/test/test_synchronizer/test_dof_synchronizer_communication.cc
+++ b/test/test_synchronizer/test_dof_synchronizer_communication.cc
@@ -1,102 +1,106 @@
/**
* @file test_dof_synchronizer_communication.cc
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Tue Dec 09 2014
*
* @brief test to synchronize global equation numbers
*
* @section LICENSE
*
* Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
* (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
-#include "element_synchronizer.hh"
#include "dof_synchronizer.hh"
-#include "synchronizer_registry.hh"
+#include "element_synchronizer.hh"
#include "mesh.hh"
#include "mesh_partition_scotch.hh"
+#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
-# include "dumper_paraview.hh"
-#endif //AKANTU_USE_IOHELPER
+#include "dumper_paraview.hh"
+#endif // AKANTU_USE_IOHELPER
#include "test_dof_data_accessor.hh"
-
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
+int main(int argc, char * argv[]) {
initialize(argc, argv);
UInt spatial_dimension = 3;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
- bool wait=true;
- if(argc >1) {
- if(prank == 0)
- while(wait);
+ bool wait = true;
+ if (argc > 1) {
+ if (prank == 0)
+ while (wait)
+ ;
}
ElementSynchronizer * communicator = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("cube.msh");
- MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ MeshPartition * partition =
+ new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
- communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ communicator =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
-/* -------------------------------------------------------------------------- */
-/* test the communications of the dof synchronizer */
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* test the communications of the dof synchronizer */
+ /* --------------------------------------------------------------------------
+ */
std::cout << "Initializing the synchronizer" << std::endl;
DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
dof_synchronizer.initGlobalDOFEquationNumbers();
AKANTU_DEBUG_INFO("Creating TestDOFAccessor");
- TestDOFAccessor test_dof_accessor(dof_synchronizer.getGlobalDOFEquationNumbers());
+ TestDOFAccessor test_dof_accessor(
+ dof_synchronizer.getGlobalDOFEquationNumbers());
SynchronizerRegistry synch_registry(test_dof_accessor);
- synch_registry.registerSynchronizer(dof_synchronizer,_gst_test);
+ synch_registry.registerSynchronizer(dof_synchronizer, _gst_test);
AKANTU_DEBUG_INFO("Synchronizing tag");
synch_registry.synchronize(_gst_test);
delete communicator;
finalize();
return EXIT_SUCCESS;
}
-
diff --git a/test/test_synchronizer/test_facet_synchronizer.cc b/test/test_synchronizer/test_facet_synchronizer.cc
index 961f03a12..8b8865a82 100644
--- a/test/test_synchronizer/test_facet_synchronizer.cc
+++ b/test/test_synchronizer/test_facet_synchronizer.cc
@@ -1,77 +1,78 @@
/**
* @file test_facet_synchronizer.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
*
* @brief Facet synchronizer test
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
*/
/* -------------------------------------------------------------------------- */
-#include "test_synchronizers_fixture.hh"
#include "test_data_accessor.hh"
+#include "test_synchronizers_fixture.hh"
/* -------------------------------------------------------------------------- */
#include "element_synchronizer.hh"
/* -------------------------------------------------------------------------- */
-#include <random>
#include <chrono>
+#include <random>
#include <thread>
/* -------------------------------------------------------------------------- */
class TestFacetSynchronizerFixture : public TestSynchronizerFixture {
public:
void SetUp() override {
TestSynchronizerFixture::SetUp();
this->distribute();
this->mesh->initMeshFacets();
/// compute barycenter for each element
- barycenters = std::make_unique<ElementTypeMapArray<Real>>("barycenters", "", 0);
+ barycenters =
+ std::make_unique<ElementTypeMapArray<Real>>("barycenters", "", 0);
this->initBarycenters(*barycenters, this->mesh->getMeshFacets());
- test_accessor = std::make_unique<TestAccessor>(*this->mesh, *this->barycenters);
+ test_accessor =
+ std::make_unique<TestAccessor>(*this->mesh, *this->barycenters);
}
void TearDown() override {
barycenters.reset(nullptr);
test_accessor.reset(nullptr);
}
protected:
std::unique_ptr<ElementTypeMapArray<Real>> barycenters;
std::unique_ptr<TestAccessor> test_accessor;
};
-
/* -------------------------------------------------------------------------- */
TEST_F(TestFacetSynchronizerFixture, SynchroneOnce) {
auto & synchronizer = this->mesh->getMeshFacets().getElementSynchronizer();
synchronizer.synchronizeOnce(*this->test_accessor, _gst_test);
}
/* -------------------------------------------------------------------------- */
TEST_F(TestFacetSynchronizerFixture, Synchrone) {
auto & synchronizer = this->mesh->getMeshFacets().getElementSynchronizer();
synchronizer.synchronize(*this->test_accessor, _gst_test);
}
/* -------------------------------------------------------------------------- */
TEST_F(TestFacetSynchronizerFixture, Asynchrone) {
auto & synchronizer = this->mesh->getMeshFacets().getElementSynchronizer();
synchronizer.asynchronousSynchronize(*this->test_accessor, _gst_test);
std::random_device r;
std::default_random_engine engine(r());
std::uniform_int_distribution<int> uniform_dist(10, 100);
std::chrono::microseconds delay(uniform_dist(engine));
std::this_thread::sleep_for(delay);
synchronizer.waitEndSynchronize(*this->test_accessor, _gst_test);
}
diff --git a/test/test_synchronizer/test_grid_synchronizer.cc b/test/test_synchronizer/test_grid_synchronizer.cc
index 135ff3452..05d06f0cf 100644
--- a/test/test_synchronizer/test_grid_synchronizer.cc
+++ b/test/test_synchronizer/test_grid_synchronizer.cc
@@ -1,299 +1,310 @@
/**
* @file test_grid_synchronizer.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 01 2010
* @date last modification: Fri Feb 27 2015
*
* @brief test the GridSynchronizer object
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_grid_dynamic.hh"
-#include "mesh.hh"
#include "grid_synchronizer.hh"
+#include "mesh.hh"
#include "mesh_partition.hh"
#include "synchronizer_registry.hh"
#include "test_data_accessor.hh"
#ifdef AKANTU_USE_IOHELPER
-# include "io_helper.hh"
-#endif //AKANTU_USE_IOHELPER
+#include "io_helper.hh"
+#endif // AKANTU_USE_IOHELPER
using namespace akantu;
const UInt spatial_dimension = 2;
typedef std::map<std::pair<Element, Element>, Real> pair_list;
#include "test_grid_tools.hh"
-static void updatePairList(const ElementTypeMapArray<Real> & barycenter,
- const SpatialGrid<Element> & grid,
- Real radius,
- pair_list & neighbors,
- neighbors_map_t<spatial_dimension>::type & neighbors_map) {
+static void
+updatePairList(const ElementTypeMapArray<Real> & barycenter,
+ const SpatialGrid<Element> & grid, Real radius,
+ pair_list & neighbors,
+ neighbors_map_t<spatial_dimension>::type & neighbors_map) {
AKANTU_DEBUG_IN();
GhostType ghost_type = _not_ghost;
Element e;
e.ghost_type = ghost_type;
// generate the pair of neighbor depending of the cell_list
- ElementTypeMapArray<Real>::type_iterator it = barycenter.firstType(_all_dimensions, ghost_type);
- ElementTypeMapArray<Real>::type_iterator last_type = barycenter.lastType(0, ghost_type);
- for(; it != last_type; ++it) {
+ ElementTypeMapArray<Real>::type_iterator it =
+ barycenter.firstType(_all_dimensions, ghost_type);
+ ElementTypeMapArray<Real>::type_iterator last_type =
+ barycenter.lastType(0, ghost_type);
+ for (; it != last_type; ++it) {
// loop over quad points
e.type = *it;
e.element = 0;
const Array<Real> & barycenter_vect = barycenter(*it, ghost_type);
UInt sp = barycenter_vect.getNbComponent();
- Array<Real>::const_iterator< Vector<Real> > bary =
- barycenter_vect.begin(sp);
- Array<Real>::const_iterator< Vector<Real> > bary_end =
- barycenter_vect.end(sp);
+ Array<Real>::const_iterator<Vector<Real>> bary = barycenter_vect.begin(sp);
+ Array<Real>::const_iterator<Vector<Real>> bary_end =
+ barycenter_vect.end(sp);
- for(;bary != bary_end; ++bary, e.element++) {
+ for (; bary != bary_end; ++bary, e.element++) {
#if !defined(AKANTU_NDEBUG)
Point<spatial_dimension> pt1(*bary);
#endif
SpatialGrid<Element>::CellID cell_id = grid.getCellID(*bary);
SpatialGrid<Element>::neighbor_cells_iterator first_neigh_cell =
- grid.beginNeighborCells(cell_id);
+ grid.beginNeighborCells(cell_id);
SpatialGrid<Element>::neighbor_cells_iterator last_neigh_cell =
- grid.endNeighborCells(cell_id);
+ grid.endNeighborCells(cell_id);
// loop over neighbors cells of the one containing the current element
for (; first_neigh_cell != last_neigh_cell; ++first_neigh_cell) {
SpatialGrid<Element>::Cell::const_iterator first_neigh_el =
- grid.beginCell(*first_neigh_cell);
+ grid.beginCell(*first_neigh_cell);
SpatialGrid<Element>::Cell::const_iterator last_neigh_el =
- grid.endCell(*first_neigh_cell);
+ grid.endCell(*first_neigh_cell);
// loop over the quadrature point in the current cell of the cell list
- for (;first_neigh_el != last_neigh_el; ++first_neigh_el){
+ for (; first_neigh_el != last_neigh_el; ++first_neigh_el) {
const Element & elem = *first_neigh_el;
- Array<Real>::const_iterator< Vector<Real> > neigh_it =
- barycenter(elem.type, elem.ghost_type).begin(sp);
+ Array<Real>::const_iterator<Vector<Real>> neigh_it =
+ barycenter(elem.type, elem.ghost_type).begin(sp);
- const Vector<Real> & neigh_bary = neigh_it[elem.element];
+ const Vector<Real> & neigh_bary = neigh_it[elem.element];
Real distance = bary->distance(neigh_bary);
- if(distance <= radius) {
+ if (distance <= radius) {
#if !defined(AKANTU_NDEBUG)
Point<spatial_dimension> pt2(neigh_bary);
neighbors_map[pt1].push_back(pt2);
#endif
std::pair<Element, Element> pair = std::make_pair(e, elem);
pair_list::iterator p = neighbors.find(pair);
- if(p != neighbors.end()) {
- AKANTU_ERROR("Pair already registered [" << e << " " << elem << "] -> " << p->second << " " << distance);
+ if (p != neighbors.end()) {
+ AKANTU_ERROR("Pair already registered ["
+ << e << " " << elem << "] -> " << p->second << " "
+ << distance);
} else {
neighbors[pair] = distance;
}
}
}
}
}
}
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
akantu::initialize(argc, argv);
Real radius = 0.001;
Mesh mesh(spatial_dimension);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
ElementSynchronizer * dist = NULL;
- if(prank == 0) {
+ if (prank == 0) {
mesh.read("bar.msh");
- MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ MeshPartition * partition =
+ new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
- dist = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ dist =
+ ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
delete partition;
} else {
dist = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
}
mesh.computeBoundingBox();
const Vector<Real> & lower_bounds = mesh.getLowerBounds();
const Vector<Real> & upper_bounds = mesh.getUpperBounds();
Vector<Real> center = 0.5 * (upper_bounds + lower_bounds);
Vector<Real> spacing(spatial_dimension);
for (UInt i = 0; i < spatial_dimension; ++i) {
spacing[i] = radius * 1.2;
}
SpatialGrid<Element> grid(spatial_dimension, spacing, center);
GhostType ghost_type = _not_ghost;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
ElementTypeMapArray<Real> barycenters("", "");
- mesh.initElementTypeMapArray(barycenters, spatial_dimension, spatial_dimension);
+ mesh.initElementTypeMapArray(barycenters, spatial_dimension,
+ spatial_dimension);
Element e;
e.ghost_type = ghost_type;
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
e.type = *it;
Array<Real> & barycenter = barycenters(*it, ghost_type);
barycenter.resize(nb_element);
- Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> bary_it =
+ barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem) {
mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
e.element = elem;
grid.insert(e, *bary_it);
++bary_it;
}
}
- std::stringstream sstr; sstr << "mesh_" << prank << ".msh";
+ std::stringstream sstr;
+ sstr << "mesh_" << prank << ".msh";
mesh.write(sstr.str());
Mesh grid_mesh(spatial_dimension, "grid_mesh", 0);
- std::stringstream sstr_grid; sstr_grid << "grid_mesh_" << prank << ".msh";
+ std::stringstream sstr_grid;
+ sstr_grid << "grid_mesh_" << prank << ".msh";
grid.saveAsMesh(grid_mesh);
grid_mesh.write(sstr_grid.str());
-
-
std::cout << "Pouet 1" << std::endl;
AKANTU_DEBUG_INFO("Creating TestAccessor");
TestAccessor test_accessor(mesh, barycenters);
SynchronizerRegistry synch_registry(test_accessor);
- GridSynchronizer * grid_communicator = GridSynchronizer::createGridSynchronizer(mesh, grid);
+ GridSynchronizer * grid_communicator =
+ GridSynchronizer::createGridSynchronizer(mesh, grid);
std::cout << "Pouet 2" << std::endl;
ghost_type = _ghost;
it = mesh.firstType(spatial_dimension, ghost_type);
last_type = mesh.lastType(spatial_dimension, ghost_type);
e.ghost_type = ghost_type;
- for(; it != last_type; ++it) {
+ for (; it != last_type; ++it) {
UInt nb_element = mesh.getNbElement(*it, ghost_type);
e.type = *it;
Array<Real> & barycenter = barycenters(*it, ghost_type);
barycenter.resize(nb_element);
- Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
+ Array<Real>::iterator<Vector<Real>> bary_it =
+ barycenter.begin(spatial_dimension);
for (UInt elem = 0; elem < nb_element; ++elem) {
mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
e.element = elem;
grid.insert(e, *bary_it);
++bary_it;
}
}
Mesh grid_mesh_ghost(spatial_dimension, "grid_mesh_ghost", 0);
- std::stringstream sstr_gridg; sstr_gridg << "grid_mesh_ghost_" << prank << ".msh";
+ std::stringstream sstr_gridg;
+ sstr_gridg << "grid_mesh_ghost_" << prank << ".msh";
grid.saveAsMesh(grid_mesh_ghost);
grid_mesh_ghost.write(sstr_gridg.str());
std::cout << "Pouet 3" << std::endl;
-
neighbors_map_t<spatial_dimension>::type neighbors_map;
pair_list neighbors;
updatePairList(barycenters, grid, radius, neighbors, neighbors_map);
- pair_list::iterator nit = neighbors.begin();
+ pair_list::iterator nit = neighbors.begin();
pair_list::iterator nend = neighbors.end();
- std::stringstream sstrp; sstrp << "pairs_" << prank;
+ std::stringstream sstrp;
+ sstrp << "pairs_" << prank;
std::ofstream fout(sstrp.str().c_str());
- for(;nit != nend; ++nit) {
+ for (; nit != nend; ++nit) {
fout << "[" << nit->first.first << "," << nit->first.second << "] -> "
<< nit->second << std::endl;
}
std::string file = "neighbors_ref";
- std::stringstream sstrf; sstrf << file << "_" << psize << "_" << prank;
+ std::stringstream sstrf;
+ sstrf << file << "_" << psize << "_" << prank;
file = sstrf.str();
std::ofstream nout;
nout.open(file.c_str());
- neighbors_map_t<spatial_dimension>::type::iterator it_n = neighbors_map.begin();
- neighbors_map_t<spatial_dimension>::type::iterator end_n = neighbors_map.end();
- for(;it_n != end_n; ++it_n) {
+ neighbors_map_t<spatial_dimension>::type::iterator it_n =
+ neighbors_map.begin();
+ neighbors_map_t<spatial_dimension>::type::iterator end_n =
+ neighbors_map.end();
+ for (; it_n != end_n; ++it_n) {
std::sort(it_n->second.begin(), it_n->second.end());
- std::vector< Point<spatial_dimension> >::iterator it_v = it_n->second.begin();
- std::vector< Point<spatial_dimension> >::iterator end_v = it_n->second.end();
+ std::vector<Point<spatial_dimension>>::iterator it_v = it_n->second.begin();
+ std::vector<Point<spatial_dimension>>::iterator end_v = it_n->second.end();
nout << "####" << std::endl;
nout << it_n->second.size() << std::endl;
nout << it_n->first << std::endl;
nout << "#" << std::endl;
- for(;it_v != end_v; ++it_v) {
+ for (; it_v != end_v; ++it_v) {
nout << *it_v << std::endl;
}
}
fout.close();
-
synch_registry.registerSynchronizer(*dist, _gst_smm_mass);
synch_registry.registerSynchronizer(*grid_communicator, _gst_test);
AKANTU_DEBUG_INFO("Synchronizing tag on Dist");
synch_registry.synchronize(_gst_smm_mass);
AKANTU_DEBUG_INFO("Synchronizing tag on Grid");
synch_registry.synchronize(_gst_test);
delete grid_communicator;
delete dist;
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc b/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
index 0faf3713a..197b736ae 100644
--- a/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
+++ b/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
@@ -1,122 +1,131 @@
/**
* @file test_grid_synchronizer_check_neighbors.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Mar 11 2013
* @date last modification: Fri Feb 27 2015
*
* @brief Test the generation of neighbors list based on a akaentu::Grid
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <fstream>
#include <iostream>
#include <string>
#include "aka_common.hh"
#include "communicator.hh"
using namespace akantu;
const UInt spatial_dimension = 3;
#include "test_grid_tools.hh"
-void readNeighbors(std::ifstream & nin,
- neighbors_map_t<spatial_dimension>::type & neighbors_map_read) {
+void readNeighbors(
+ std::ifstream & nin,
+ neighbors_map_t<spatial_dimension>::type & neighbors_map_read) {
std::string line;
while (std::getline(nin, line)) {
std::getline(nin, line);
std::istringstream iss(line);
UInt nb_neig;
iss >> nb_neig;
std::getline(nin, line);
Point<spatial_dimension> pt;
pt.read(line);
std::getline(nin, line);
for (UInt i = 0; i < nb_neig; ++i) {
std::getline(nin, line);
Point<spatial_dimension> ne;
ne.read(line);
neighbors_map_read[pt].push_back(ne);
}
}
}
-
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
initialize(argc, argv);
const auto & comm = Communicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
std::string file_ref = "neighbors_ref_1_0";
std::string file = "neighbors_ref";
- std::stringstream sstr; sstr << file << "_" << psize << "_" << prank;
+ std::stringstream sstr;
+ sstr << file << "_" << psize << "_" << prank;
file = sstr.str();
std::ifstream nin;
neighbors_map_t<spatial_dimension>::type neighbors_map_read;
nin.open(file_ref.c_str());
readNeighbors(nin, neighbors_map_read);
nin.close();
neighbors_map_t<spatial_dimension>::type neighbors_map;
nin.open(file.c_str());
readNeighbors(nin, neighbors_map);
nin.close();
- neighbors_map_t<spatial_dimension>::type::iterator it_n = neighbors_map.begin();
- neighbors_map_t<spatial_dimension>::type::iterator end_n = neighbors_map.end();
- for(;it_n != end_n; ++it_n) {
+ neighbors_map_t<spatial_dimension>::type::iterator it_n =
+ neighbors_map.begin();
+ neighbors_map_t<spatial_dimension>::type::iterator end_n =
+ neighbors_map.end();
+ for (; it_n != end_n; ++it_n) {
std::sort(it_n->second.begin(), it_n->second.end());
- std::vector< Point<spatial_dimension> >::iterator it_v = it_n->second.begin();
- std::vector< Point<spatial_dimension> >::iterator end_v = it_n->second.end();
-
- neighbors_map_t<spatial_dimension>::type::iterator it_nr = neighbors_map_read.find(it_n->first);
- if(it_nr == neighbors_map_read.end())
- AKANTU_ERROR("Argh what is this point that is not present in the ref file " << it_n->first);
-
- std::vector< Point<spatial_dimension> >::iterator it_vr = it_nr->second.begin();
- std::vector< Point<spatial_dimension> >::iterator end_vr = it_nr->second.end();
-
- for(;it_v != end_v && it_vr != end_vr; ++it_v, ++it_vr) {
- if(*it_vr != *it_v) AKANTU_ERROR("Neighbors does not match " << *it_v << " != " << *it_vr
- << " neighbor of " << it_n->first);
+ std::vector<Point<spatial_dimension>>::iterator it_v = it_n->second.begin();
+ std::vector<Point<spatial_dimension>>::iterator end_v = it_n->second.end();
+
+ neighbors_map_t<spatial_dimension>::type::iterator it_nr =
+ neighbors_map_read.find(it_n->first);
+ if (it_nr == neighbors_map_read.end())
+ AKANTU_ERROR(
+ "Argh what is this point that is not present in the ref file "
+ << it_n->first);
+
+ std::vector<Point<spatial_dimension>>::iterator it_vr =
+ it_nr->second.begin();
+ std::vector<Point<spatial_dimension>>::iterator end_vr =
+ it_nr->second.end();
+
+ for (; it_v != end_v && it_vr != end_vr; ++it_v, ++it_vr) {
+ if (*it_vr != *it_v)
+ AKANTU_ERROR("Neighbors does not match " << *it_v << " != " << *it_vr
+ << " neighbor of "
+ << it_n->first);
}
- if(it_v == end_v && it_vr != end_vr) {
+ if (it_v == end_v && it_vr != end_vr) {
AKANTU_ERROR("Some neighbors of " << it_n->first << " are missing!");
}
- if(it_v != end_v && it_vr == end_vr)
+ if (it_v != end_v && it_vr == end_vr)
AKANTU_ERROR("Some neighbors of " << it_n->first << " are in excess!");
}
akantu::finalize();
return EXIT_SUCCESS;
}
-
diff --git a/test/test_synchronizer/test_grid_tools.hh b/test/test_synchronizer/test_grid_tools.hh
index e7c9b34ea..0651517f4 100644
--- a/test/test_synchronizer/test_grid_tools.hh
+++ b/test/test_synchronizer/test_grid_tools.hh
@@ -1,109 +1,115 @@
/**
* @file test_grid_tools.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Mar 11 2013
* @date last modification: Sun Oct 19 2014
*
* @brief Tools to help for the akantu::Grid class tests
*
* @section LICENSE
*
* Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <map>
#include "aka_common.hh"
#include "aka_types.hh"
#define TOLERANCE 1e-7
-template<UInt dim>
-class Point {
+template <UInt dim> class Point {
public:
Point() : id(0), tol(TOLERANCE) {
- for (UInt i = 0; i < dim; ++i) pos[i] = 0.;
+ for (UInt i = 0; i < dim; ++i)
+ pos[i] = 0.;
}
Point(const Point & pt) : id(pt.id), tol(pt.tol) {
- for (UInt i = 0; i < dim; ++i) pos[i] = pt.pos[i];
+ for (UInt i = 0; i < dim; ++i)
+ pos[i] = pt.pos[i];
}
Point(const Vector<Real> & pt, UInt id = 0) : id(id), tol(TOLERANCE) {
- for (UInt i = 0; i < dim; ++i) pos[i] = pt(i);
+ for (UInt i = 0; i < dim; ++i)
+ pos[i] = pt(i);
}
bool operator==(const Point & pt) const {
for (UInt i = 0; i < dim; ++i) {
- // std::cout << i << " " << pos[i] << " " << pt.pos[i] << " " << std::abs(pos[i] - pt.pos[i]);
+ // std::cout << i << " " << pos[i] << " " << pt.pos[i] << " " <<
+ // std::abs(pos[i] - pt.pos[i]);
if (std::abs(pos[i] - pt.pos[i]) > tol) {
// std::cout << " " << false << std::endl;
return false;
- } //else
- // std::cout << " " << true << std::endl;
+ } // else
+ // std::cout << " " << true << std::endl;
}
return true;
}
bool operator<(const Point & pt) const {
UInt i = 0, j = 0;
- for ( ; (i < dim) && (j < dim); i++, j++ ) {
- if (pos[i] < pt.pos[j]) return true;
- if (pt.pos[j] < pos[i]) return false;
+ for (; (i < dim) && (j < dim); i++, j++) {
+ if (pos[i] < pt.pos[j])
+ return true;
+ if (pt.pos[j] < pos[i])
+ return false;
}
return (i == dim) && (j != dim);
}
- bool operator!=(const Point & pt) const {
- return !(operator==(pt));
- }
+ bool operator!=(const Point & pt) const { return !(operator==(pt)); }
Real & operator()(UInt d) { return pos[d]; }
const Real & operator()(UInt d) const { return pos[d]; }
void read(const std::string & str) {
std::stringstream sstr(str);
- for (UInt i = 0; i < dim; ++i) sstr >> pos[i];
+ for (UInt i = 0; i < dim; ++i)
+ sstr >> pos[i];
}
void write(std::ostream & ostr) const {
for (UInt i = 0; i < dim; ++i) {
- if(i != 0) ostr << " ";
- // ostr << std::setprecision(std::numeric_limits<Real>::digits) << pos[i];
+ if (i != 0)
+ ostr << " ";
+ // ostr << std::setprecision(std::numeric_limits<Real>::digits) <<
+ // pos[i];
ostr << std::setprecision(9) << pos[i];
}
}
+
private:
UInt id;
Real pos[dim];
double tol;
};
-template<UInt dim>
-struct neighbors_map_t {
- typedef std::map<Point<dim>, std::vector< Point<dim> > > type;
+template <UInt dim> struct neighbors_map_t {
+ typedef std::map<Point<dim>, std::vector<Point<dim>>> type;
};
-template<UInt dim>
-inline std::ostream & operator <<(std::ostream & stream, const Point<dim> & _this)
-{
+template <UInt dim>
+inline std::ostream & operator<<(std::ostream & stream,
+ const Point<dim> & _this) {
_this.write(stream);
return stream;
}
diff --git a/test/test_synchronizer/test_node_synchronizer.cc b/test/test_synchronizer/test_node_synchronizer.cc
index 63324557f..d913dbf35 100644
--- a/test/test_synchronizer/test_node_synchronizer.cc
+++ b/test/test_synchronizer/test_node_synchronizer.cc
@@ -1,160 +1,160 @@
/**
* @file test_node_synchronizer.cc
*
* @author Nicolas Richart
*
* @date creation Tue Apr 04 2017
*
* @brief test the default node synchronizer present in the mesh
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test_synchronizers_fixture.hh"
/* -------------------------------------------------------------------------- */
#include "communicator.hh"
#include "data_accessor.hh"
#include "mesh.hh"
#include "node_synchronizer.hh"
/* -------------------------------------------------------------------------- */
-#include <random>
#include <chrono>
-#include <thread>
#include <limits>
+#include <random>
+#include <thread>
/* -------------------------------------------------------------------------- */
using namespace akantu;
class DataAccessorTest : public DataAccessor<UInt> {
public:
explicit DataAccessorTest(Array<int> & data) : data(data) {}
UInt getNbData(const Array<UInt> & nodes, const SynchronizationTag &) const {
return nodes.size() * sizeof(int);
}
void packData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
const SynchronizationTag &) const {
for (auto node : nodes) {
buffer << data(node);
}
}
void unpackData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
const SynchronizationTag &) {
for (auto node : nodes) {
buffer >> data(node);
}
}
protected:
Array<int> & data;
};
class TestNodeSynchronizerFixture : public TestSynchronizerFixture {
public:
static constexpr int max_int = std::numeric_limits<int>::max();
void SetUp() override {
TestSynchronizerFixture::SetUp();
this->distribute();
UInt nb_nodes = this->mesh->getNbNodes();
node_data = std::make_unique<Array<int>>(nb_nodes);
for (auto && data : enumerate(*node_data)) {
auto n = std::get<0>(data);
auto & d = std::get<1>(data);
UInt gn = this->mesh->getNodeGlobalId(n);
if (this->mesh->isMasterNode(n))
d = gn;
else if (this->mesh->isLocalNode(n))
d = -gn;
else if (this->mesh->isSlaveNode(n))
d = max_int;
else
d = -max_int;
}
data_accessor = std::make_unique<DataAccessorTest>(*node_data);
}
void TearDown() override {
data_accessor.reset(nullptr);
node_data.reset(nullptr);
}
void checkData() {
for (auto && data : enumerate(*this->node_data)) {
auto n = std::get<0>(data);
auto & d = std::get<1>(data);
UInt gn = this->mesh->getNodeGlobalId(n);
if (this->mesh->isMasterNode(n))
EXPECT_EQ(d, gn);
else if (this->mesh->isLocalNode(n))
EXPECT_EQ(d, -gn);
else if (this->mesh->isSlaveNode(n))
EXPECT_EQ(d, gn);
else
EXPECT_EQ(d, -max_int);
}
}
protected:
std::unique_ptr<Array<int>> node_data;
std::unique_ptr<DataAccessorTest> data_accessor;
};
/* -------------------------------------------------------------------------- */
TEST_F(TestNodeSynchronizerFixture, SynchroneOnce) {
auto & synchronizer = this->mesh->getNodeSynchronizer();
synchronizer.synchronizeOnce(*this->data_accessor, _gst_test);
this->checkData();
}
/* -------------------------------------------------------------------------- */
TEST_F(TestNodeSynchronizerFixture, Synchrone) {
auto & node_synchronizer = this->mesh->getNodeSynchronizer();
node_synchronizer.synchronize(*this->data_accessor, _gst_test);
this->checkData();
}
/* -------------------------------------------------------------------------- */
TEST_F(TestNodeSynchronizerFixture, Asynchrone) {
auto & synchronizer = this->mesh->getNodeSynchronizer();
synchronizer.asynchronousSynchronize(*this->data_accessor, _gst_test);
std::random_device r;
std::default_random_engine engine(r());
std::uniform_int_distribution<int> uniform_dist(10, 100);
std::chrono::microseconds delay(uniform_dist(engine));
std::this_thread::sleep_for(delay);
synchronizer.waitEndSynchronize(*this->data_accessor, _gst_test);
this->checkData();
}
diff --git a/test/test_synchronizer/test_synchronizer_communication.cc b/test/test_synchronizer/test_synchronizer_communication.cc
index afda377fa..2756302d2 100644
--- a/test/test_synchronizer/test_synchronizer_communication.cc
+++ b/test/test_synchronizer/test_synchronizer_communication.cc
@@ -1,92 +1,93 @@
/**
* @file test_synchronizer_communication.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 01 2010
* @date last modification: Sun Oct 19 2014
*
* @brief test to synchronize barycenters
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
-#include "test_synchronizers_fixture.hh"
#include "test_data_accessor.hh"
+#include "test_synchronizers_fixture.hh"
/* -------------------------------------------------------------------------- */
#include "element_synchronizer.hh"
/* -------------------------------------------------------------------------- */
-#include <random>
#include <chrono>
+#include <random>
#include <thread>
/* -------------------------------------------------------------------------- */
class TestElementSynchronizerFixture : public TestSynchronizerFixture {
public:
void SetUp() override {
TestSynchronizerFixture::SetUp();
this->distribute();
/// compute barycenter for each element
- barycenters = std::make_unique<ElementTypeMapArray<Real>>("barycenters", "", 0);
+ barycenters =
+ std::make_unique<ElementTypeMapArray<Real>>("barycenters", "", 0);
this->initBarycenters(*barycenters, *mesh);
- test_accessor = std::make_unique<TestAccessor>(*this->mesh, *this->barycenters);
+ test_accessor =
+ std::make_unique<TestAccessor>(*this->mesh, *this->barycenters);
}
void TearDown() override {
barycenters.reset(nullptr);
test_accessor.reset(nullptr);
}
protected:
std::unique_ptr<ElementTypeMapArray<Real>> barycenters;
std::unique_ptr<TestAccessor> test_accessor;
};
-
/* -------------------------------------------------------------------------- */
TEST_F(TestElementSynchronizerFixture, SynchroneOnce) {
auto & synchronizer = this->mesh->getElementSynchronizer();
synchronizer.synchronizeOnce(*this->test_accessor, _gst_test);
}
/* -------------------------------------------------------------------------- */
TEST_F(TestElementSynchronizerFixture, Synchrone) {
auto & synchronizer = this->mesh->getElementSynchronizer();
synchronizer.synchronize(*this->test_accessor, _gst_test);
}
/* -------------------------------------------------------------------------- */
TEST_F(TestElementSynchronizerFixture, Asynchrone) {
-auto & synchronizer = this->mesh->getElementSynchronizer();
-synchronizer.asynchronousSynchronize(*this->test_accessor, _gst_test);
+ auto & synchronizer = this->mesh->getElementSynchronizer();
+ synchronizer.asynchronousSynchronize(*this->test_accessor, _gst_test);
std::random_device r;
std::default_random_engine engine(r());
std::uniform_int_distribution<int> uniform_dist(10, 100);
std::chrono::microseconds delay(uniform_dist(engine));
std::this_thread::sleep_for(delay);
synchronizer.waitEndSynchronize(*this->test_accessor, _gst_test);
}

Event Timeline