diff --git a/src/model/solid_mechanics/materials/material_thermal.cc b/src/model/solid_mechanics/materials/material_thermal.cc index 171a5aee3..44b341e13 100644 --- a/src/model/solid_mechanics/materials/material_thermal.cc +++ b/src/model/solid_mechanics/materials/material_thermal.cc @@ -1,123 +1,111 @@ /** * @file material_thermal.cc * * @author Lucas Frerot * * @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 . * */ /* -------------------------------------------------------------------------- */ #include "material_thermal.hh" namespace akantu { /* -------------------------------------------------------------------------- */ template MaterialThermal::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 MaterialThermal::MaterialThermal(SolidMechanicsModel & model, 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) { AKANTU_DEBUG_IN(); this->initialize(); AKANTU_DEBUG_OUT(); } template void MaterialThermal::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"); delta_T.initialize(1); } /* -------------------------------------------------------------------------- */ template void MaterialThermal::initMaterial() { AKANTU_DEBUG_IN(); sigma_th.initialize(1); if(use_previous_stress_thermal) { sigma_th.initializeHistory(); } Material::initMaterial(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void MaterialThermal::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); - Array::iterator<> delta_t_it = this->delta_T(el_type, ghost_type).begin(); - Array::iterator<> sigma_th_it = this->sigma_th(el_type, ghost_type).begin(); - - MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type); - - /// TODO : implement with the matrix alpha - if (dim == 1) { - *sigma_th_it = - this->E * this->alpha * *delta_t_it; + 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)); } - else { - *sigma_th_it = - this->E/(1.-2.*this->nu) * this->alpha * *delta_t_it; - } - - ++delta_t_it; - ++sigma_th_it; - MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; 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 25b829db5..a1ed866e5 100644 --- a/src/model/solid_mechanics/materials/material_thermal.hh +++ b/src/model/solid_mechanics/materials/material_thermal.hh @@ -1,106 +1,113 @@ /** * @file material_thermal.hh * * @author Lucas Frerot * * @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 . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_THERMAL_HH__ #define __AKANTU_MATERIAL_THERMAL_HH__ namespace akantu { template 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 = ""); + 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; - /* ------------------------------------------------------------------------ */ - /* DataAccessor inherited members */ - /* ------------------------------------------------------------------------ */ -public: - - /* ------------------------------------------------------------------------ */ - /* Accessors */ - /* ------------------------------------------------------------------------ */ -public: - + /// 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 delta_T; /// Current thermal stress InternalField sigma_th; /// Tell if we need to use the previous thermal stress bool use_previous_stress_thermal; }; +/* ------------------------------------------------------------------------ */ +/* Inline impl */ +/* ------------------------------------------------------------------------ */ +template +inline void MaterialThermal::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/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt index 4a61fd5aa..0cee8012c 100644 --- a/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt +++ b/test/test_model/test_solid_mechanics_model/test_materials/CMakeLists.txt @@ -1,102 +1,96 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux # # @date creation: Fri Oct 22 2010 # @date last modification: Wed Jan 20 2016 # # @brief configuration for materials tests # # @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 . # # @section DESCRIPTION # #=============================================================================== #add_mesh(test_local_material_barre_trou_mesh barre_trou.geo 2 2) add_mesh(test_local_material_barre_trou_mesh mesh_section_gap.geo 2 2) register_test(test_local_material SOURCES test_local_material.cc local_material_damage.cc EXTRA_FILES local_material_damage.hh local_material_damage_inline_impl.cc DEPENDS test_local_material_barre_trou_mesh FILES_TO_COPY material.dat DIRECTORIES_TO_CREATE paraview PACKAGE core ) -add_mesh(test_material_thermal_mesh square.geo 2 1) -register_test(test_material_thermal - SOURCES test_material_thermal.cc - DEPENDS test_material_thermal_mesh - FILES_TO_COPY material_thermal.dat - PACKAGE core - ) # ============================================================================== add_mesh(test_interpolate_stress_mesh interpolation.geo 3 2) register_test(test_interpolate_stress test_interpolate_stress.cc FILES_TO_COPY material.dat DEPENDS test_interpolate_stress_mesh DIRECTORIES_TO_CREATE paraview PACKAGE lapack core ) #=============================================================================== add_mesh(test_material_orthotropic_square_mesh square.geo 2 1) register_test(test_material_orthotropic SOURCES test_material_orthotropic.cc DEPENDS test_material_orthotropic_square_mesh FILES_TO_COPY orthotropic.dat DIRECTORIES_TO_CREATE paraview PACKAGE core lapack ) #=============================================================================== register_test(test_material_mazars SOURCES test_material_mazars.cc FILES_TO_COPY material_mazars.dat DIRECTORIES_TO_CREATE paraview PACKAGE core lapack ) # ============================================================================== add_akantu_test(test_material_viscoelastic "test the visco elastic materials") add_akantu_test(test_material_non_local "test the non-local materials") add_akantu_test(test_material_elasto_plastic_linear_isotropic_hardening "test the elasto plastic with linear isotropic hardening materials") # ============================================================================== add_mesh(test_multi_material_elastic_mesh test_multi_material_elastic.geo 2 1) register_test(test_multi_material_elastic SOURCES test_multi_material_elastic.cc FILES_TO_COPY test_multi_material_elastic.dat DEPENDS test_multi_material_elastic_mesh PACKAGE implicit) # ============================================================================== # Material unit tests # ============================================================================== register_gtest_sources(SOURCES test_elastic_materials.cc PACKAGE core) register_gtest_sources(SOURCES test_finite_def_materials.cc PACKAGE core) register_gtest_sources(SOURCES test_damage_materials.cc PACKAGE core) register_gtest_sources(SOURCES test_plastic_materials.cc PACKAGE core) +register_gtest_sources(SOURCES test_material_thermal.cc PACKAGE core) register_gtest_test(test_material) 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 9eeeaa40c..5f1aa6d5e 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,100 +1,76 @@ -/** - * @file test_material_thermal.cc - * - * @author Lucas Frerot - * - * @date creation: Wed Aug 04 2010 - * @date last modification: Sun Oct 19 2014 - * - * @brief test of the class akantu::MaterialThermal - * - * @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 . - * - */ - -/* -------------------------------------------------------------------------- */ -#include - /* -------------------------------------------------------------------------- */ -#include "non_linear_solver.hh" +#include "material_thermal.hh" #include "solid_mechanics_model.hh" +#include "test_material_fixtures.hh" +/* -------------------------------------------------------------------------- */ +#include +#include /* -------------------------------------------------------------------------- */ using namespace akantu; -int main(int argc, char * argv[]) { - debug::setDebugLevel(dblWarning); - initialize("material_thermal.dat", argc, argv); - - Math::setTolerance(1.e-13); - - Mesh mesh(2); - mesh.read("square.msh"); - - SolidMechanicsModel model(mesh); - model.initFull(_analysis_method = _static); - - const Vector & min = mesh.getLowerBounds(); - const Vector & max = mesh.getUpperBounds(); +using types = ::testing::Types< + Traits, Traits, + Traits>; - Array & pos = mesh.getNodes(); - Array & boundary = model.getBlockedDOFs(); - Array & disp = model.getDisplacement(); - - for (UInt i = 0; i < mesh.getNbNodes(); ++i) { - if (Math::are_float_equal(pos(i, 0), min(0))) { - boundary(i, 0) = true; - } - - if (Math::are_float_equal(pos(i, 1), min(1))) { - boundary(i, 1) = true; - } - } +/* -------------------------------------------------------------------------- */ +template <> void FriendMaterial>::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; + auto error = std::abs(sigma - solution); + ASSERT_NEAR(error, 0, 1e-14); +} - model.setBaseName("test_material_thermal"); - model.addDumpField("displacement"); - model.addDumpField("strain"); - model.addDumpField("stress"); - model.addDumpField("delta_T"); +template <> void FriendMaterial>::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; + auto error = std::abs(sigma - solution); + ASSERT_NEAR(error, 0, 1e-14); +} - auto & solver = model.getNonLinearSolver("static"); - solver.set("max_iterations", 2); - solver.set("threshold", 1e-10); +template <> void FriendMaterial>::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); +} - model.solveStep(); +namespace { - for (UInt i = 0; i < mesh.getNbNodes(); ++i) { - if (Math::are_float_equal(pos(i, 0), max(0)) && - Math::are_float_equal(pos(i, 1), max(1))) { - if (!Math::are_float_equal(disp(i, 0), 1.0) || - !Math::are_float_equal(disp(i, 1), 1.0)) { - AKANTU_DEBUG_ERROR("Test not passed"); - return EXIT_FAILURE; - } - } - } +template +class TestMaterialThermalFixture : public ::TestMaterialFixture {}; - model.dump(); +TYPED_TEST_CASE(TestMaterialThermalFixture, types); - finalize(); +TYPED_TEST(TestMaterialThermalFixture, ThermalComputeStress) { + this->material->testComputeStress(); +} - std::cout << "Test passed" << std::endl; - return EXIT_SUCCESS; }