Page MenuHomec4science

structural_mechanics_model.cc
No OneTemporary

File Metadata

Created
Thu, May 23, 07:04

structural_mechanics_model.cc

/**
* @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 "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
#include "dumper_elemental_field.hh"
#include "dumper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
namespace akantu {
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::StructuralMechanicsModel(Mesh & mesh, UInt dim,
const ID & id,
const MemoryID & memory_id)
: Model(mesh, 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_DEBUG_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);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::~StructuralMechanicsModel() = default;
/* -------------------------------------------------------------------------- */
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_momentum, nb_degree_of_freedom,
"external_force");
this->allocNodalField(internal_force_momentum, nb_degree_of_freedom,
"internal_force");
this->allocNodalField(blocked_dofs, spatial_dimension, "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(spatial_dimension, _not_ghost, _ek_structural)) {
computeRotationMatrix(type);
}
getFEEngine().initShapeFunctions(_not_ghost);
getFEEngine().initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize(
const ElementType & type) {
UInt size;
#define GET_TANGENT_STIFFNESS_VOIGT_SIZE(type) \
size = getTangentStiffnessVoigtSize<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_TANGENT_STIFFNESS_VOIGT_SIZE);
#undef GET_TANGENT_STIFFNESS_VOIGT_SIZE
return size;
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
getDOFManager().getMatrix("K").clear();
for (auto & type : mesh.elementTypes(_spatial_dimension = spatial_dimension,
_element_kind = _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 = spatial_dimension,
_element_kind = _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::updateResidual() {
AKANTU_DEBUG_IN();
auto & K = getDOFManager().getMatrix("K");
internal_force_momentum->clear();
K.matVecMul(*displacement_rotation, *internal_force_momentum);
*internal_force_momentum *= -1.;
getDOFManager().assembleToResidual("displacement", *external_force_momentum,
1.);
getDOFManager().assembleToResidual("displacement", *internal_force_momentum,
1.);
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;
T.clear();
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_momentum, group_name, n,
0, padding_flag);
}
if (field_name == "momentum") {
return mesh.createStridedNodalField(external_force_momentum, group_name,
nb_degree_of_freedom - n, n,
padding_flag);
}
if (field_name == "internal_force") {
return mesh.createStridedNodalField(internal_force_momentum, group_name, n,
0, padding_flag);
}
if (field_name == "internal_momentum") {
return mesh.createStridedNodalField(internal_force_momentum, 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;
}
/* -------------------------------------------------------------------------- */
} // namespace akantu

Event Timeline