diff --git a/examples/static/static.cc b/examples/static/static.cc index a1bddacf2..ff3dfa20f 100644 --- a/examples/static/static.cc +++ b/examples/static/static.cc @@ -1,81 +1,81 @@ /** * @file static.cc * * @author Nicolas Richart * @author Oumaima Sabir * * @date creation: Mon Aug 09 2010 * @date last modification: Sun Dec 30 2018 * * @brief This code refers to the implicit static example from the user manual * * * @section LICENSE * * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #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"); + model.addDumpField("stress"); /// 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", SolveConvergenceCriteria::_solution); model.solveStep(); - model.dump(); finalize(); return EXIT_SUCCESS; } diff --git a/src/model/solid_mechanics/solid_mechanics_model_io.cc b/src/model/solid_mechanics/solid_mechanics_model_io.cc index cbc91d01f..b67dff6e4 100644 --- a/src/model/solid_mechanics/solid_mechanics_model_io.cc +++ b/src/model/solid_mechanics/solid_mechanics_model_io.cc @@ -1,323 +1,323 @@ /** * @file solid_mechanics_model_io.cc * * @author Guillaume Anciaux * @author David Simon Kammer * @author Nicolas Richart * * @date creation: Sun Jul 09 2017 * @date last modification: Fri Apr 09 2021 * * @brief Dumpable part of the SolidMechnicsModel * * * @section LICENSE * * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #include "solid_mechanics_model.hh" #include "group_manager_inline_impl.hh" #include "dumpable_inline_impl.hh" /* -------------------------------------------------------------------------- */ #include "dumper_element_partition.hh" #include "dumper_elemental_field.hh" #include "dumper_field.hh" #include "dumper_homogenizing_field.hh" #include "dumper_internal_material_field.hh" #include "dumper_iohelper.hh" #include "dumper_material_padders.hh" #include "dumper_paraview.hh" /* -------------------------------------------------------------------------- */ namespace akantu { /* -------------------------------------------------------------------------- */ bool SolidMechanicsModel::isInternal(const std::string & field_name, ElementKind element_kind) { /// check if at least one material contains field_id as an internal for (auto & material : materials) { bool is_internal = material->isInternal(field_name, element_kind); if (is_internal) { return true; } } return false; } /* -------------------------------------------------------------------------- */ ElementTypeMap SolidMechanicsModel::getInternalDataPerElem(const std::string & field_name, ElementKind element_kind) { if (!(this->isInternal(field_name, element_kind))) { AKANTU_EXCEPTION("unknown internal " << field_name); } for (auto & material : materials) { if (material->isInternal(field_name, element_kind)) { return material->getInternalDataPerElem(field_name, element_kind); } } return ElementTypeMap(); } /* -------------------------------------------------------------------------- */ ElementTypeMapArray & SolidMechanicsModel::flattenInternal(const std::string & field_name, ElementKind kind, const GhostType ghost_type) { auto key = std::make_pair(field_name, kind); ElementTypeMapArray * internal_flat; auto it = this->registered_internals.find(key); if (it == this->registered_internals.end()) { auto internal = std::make_unique>(field_name, this->id); internal_flat = internal.get(); this->registered_internals[key] = std::move(internal); } else { internal_flat = it->second.get(); } for (auto type : mesh.elementTypes(Model::spatial_dimension, ghost_type, kind)) { if (internal_flat->exists(type, ghost_type)) { auto & internal = (*internal_flat)(type, ghost_type); internal.resize(0); } } for (auto & material : materials) { if (material->isInternal(field_name, kind)) { material->flattenInternal(field_name, *internal_flat, ghost_type, kind); } } return *internal_flat; } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::flattenAllRegisteredInternals(ElementKind kind) { ElementKind _kind; ID _id; for (auto & internal : this->registered_internals) { std::tie(_id, _kind) = internal.first; if (kind == _kind) { this->flattenInternal(_id, kind); } } } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::inflateInternal( const std::string & field_name, const ElementTypeMapArray & field, ElementKind kind, GhostType ghost_type) { for (auto & material : materials) { if (material->isInternal(field_name, kind)) { material->inflateInternal(field_name, field, ghost_type, kind); } } } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::onDump() { this->flattenAllRegisteredInternals(_ek_regular); } /* -------------------------------------------------------------------------- */ std::shared_ptr SolidMechanicsModel::createElementalField( const std::string & field_name, const std::string & group_name, bool padding_flag, UInt spatial_dimension, ElementKind kind) { std::shared_ptr field; if (field_name == "partitions") { field = mesh.createElementalField( mesh.getConnectivities(), group_name, spatial_dimension, kind); } else if (field_name == "material_index") { field = mesh.createElementalField( 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"; } else if (field_name == "Von Mises stress") { field_name_copy = "stress"; } bool is_internal = this->isInternal(field_name_copy, kind); if (is_internal) { auto nb_data_per_elem = this->getInternalDataPerElem(field_name_copy, kind); auto & internal_flat = this->flattenInternal(field_name_copy, kind); field = mesh.createElementalField( internal_flat, group_name, spatial_dimension, kind, nb_data_per_elem); std::unique_ptr func; if (field_name == "strain") { func = std::make_unique>(*this); } else if (field_name == "Von Mises stress") { func = std::make_unique(*this); } else if (field_name == "Green strain") { func = std::make_unique>(*this); } else if (field_name == "principal strain") { func = std::make_unique>(*this); } else if (field_name == "principal Green strain") { func = std::make_unique>(*this); } if (func) { field = dumpers::FieldComputeProxy::createFieldCompute(field, std::move(func)); } // treat the paddings if (padding_flag) { if (field_name == "stress") { if (spatial_dimension == 2) { auto foo = std::make_unique>(*this); field = dumpers::FieldComputeProxy::createFieldCompute( field, std::move(foo)); } } else if (field_name == "strain" || field_name == "Green strain") { if (spatial_dimension == 2) { auto foo = std::make_unique>(*this); field = dumpers::FieldComputeProxy::createFieldCompute( field, std::move(foo)); } } } // homogenize the field auto foo = dumpers::HomogenizerProxy::createHomogenizer(*field); field = dumpers::FieldComputeProxy::createFieldCompute(field, std::move(foo)); } } return field; } /* -------------------------------------------------------------------------- */ std::shared_ptr SolidMechanicsModel::createNodalFieldReal(const std::string & field_name, const std::string & group_name, bool padding_flag) { std::map *> real_nodal_fields; real_nodal_fields["displacement"] = this->displacement.get(); real_nodal_fields["mass"] = this->mass.get(); real_nodal_fields["velocity"] = this->velocity.get(); real_nodal_fields["acceleration"] = this->acceleration.get(); real_nodal_fields["external_force"] = this->external_force.get(); real_nodal_fields["internal_force"] = this->internal_force.get(); real_nodal_fields["increment"] = this->displacement_increment.get(); if (field_name == "force") { AKANTU_EXCEPTION("The 'force' field has been renamed in 'external_force'"); } else if (field_name == "residual") { AKANTU_EXCEPTION( "The 'residual' field has been replaced by 'internal_force'"); } std::shared_ptr field; if (padding_flag) { field = this->mesh.createNodalField(real_nodal_fields[field_name], group_name, 3); } else { field = this->mesh.createNodalField(real_nodal_fields[field_name], group_name); } return field; } /* -------------------------------------------------------------------------- */ std::shared_ptr SolidMechanicsModel::createNodalFieldBool( const std::string & field_name, const std::string & group_name, __attribute__((unused)) bool padding_flag) { std::map *> uint_nodal_fields; uint_nodal_fields["blocked_dofs"] = blocked_dofs.get(); std::shared_ptr field; field = mesh.createNodalField(uint_nodal_fields[field_name], group_name); return field; } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::dump(const std::string & dumper_name) { - this->onDump(); EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent()); + this->onDump(); mesh.dump(dumper_name); } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::dump(const std::string & dumper_name, UInt step) { - this->onDump(); EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent()); + this->onDump(); mesh.dump(dumper_name, step); } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::dump(const std::string & dumper_name, Real time, UInt step) { - this->onDump(); EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent()); + this->onDump(); mesh.dump(dumper_name, time, step); } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::dump() { - this->onDump(); EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent()); + this->onDump(); mesh.dump(); } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::dump(UInt step) { - this->onDump(); EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent()); + this->onDump(); mesh.dump(step); } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::dump(Real time, UInt step) { - this->onDump(); EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent()); + this->onDump(); mesh.dump(time, step); } } // namespace akantu