diff --git a/doc/dev-docs/source/MaterialLinearElasticGeneric.rst b/doc/dev-docs/source/MaterialLinearElasticGeneric.rst index d41db25..d07d2b5 100644 --- a/doc/dev-docs/source/MaterialLinearElasticGeneric.rst +++ b/doc/dev-docs/source/MaterialLinearElasticGeneric.rst @@ -1,31 +1,40 @@ Generic Linear Elastic Material ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The generic linear elastic material is implemented in the class :cpp:class:`muSpectre::MaterialLinearElasticGeneric`, and is defined solely by the elastic stiffness tensor :math:`\mathbb{C}`, which has to be specified in `Voigt notation `_. The constitutive relation between the Cauchy stress :math:`\boldsymbol{\sigma}` and the small strain tensor :math:`\boldsymbol{\varepsilon}` is given by +The generic linear elastic material is implemented in the classes :cpp:class:`muSpectre::MaterialLinearElasticGeneric1` and :cpp:class:`muSpectre::MaterialLinearElasticGeneric2`, and is defined solely by the elastic stiffness tensor :math:`\mathbb{C}`, which has to be specified in `Voigt notation `_. In the case of :cpp:class:`muSpectre::MaterialLinearElasticGeneric2`, additionally, a per-pixel eigenstrain :math:`\bar{\boldsymbol{\varepsilon}}` can be supplied. The constitutive relation between the Cauchy stress :math:`\boldsymbol{\sigma}` and the small strain tensor :math:`\boldsymbol{\varepsilon}` is given by .. math:: :nowrap: \begin{align} \boldsymbol{\sigma} &= \mathbb{C}:\boldsymbol{\varepsilon}\\ - \sigma_{ij} &= C_{ijkl}\,\varepsilon_{kl} + \sigma_{ij} &= C_{ijkl}\,\varepsilon_{kl}, \quad\mbox{for the simple version, and}\\ + \boldsymbol{\sigma} &= \mathbb{C}:\left(\boldsymbol{\varepsilon}-\bar{\boldsymbol{\varepsilon}}\right)\\ + \sigma_{ij} &= C_{ijkl}\,\left(\varepsilon_{kl} - \bar\varepsilon_{kl}\right) \quad\mbox{ for the version with eigenstrain} \end{align} This implementation is convenient, as it covers all possible linear elastic behaviours, but it is by far not as efficient as :cpp:class:`muSpectre::MaterialLinearElastic1` for isotropic linear elasticity. This law can be used in both small strain and finite strain calculations. The following snippet shows how to use this law in python to implement isotropic linear elasticity: .. code-block:: python C = np.array([[2 * mu + lam, lam, lam, 0, 0, 0], [ lam, 2 * mu + lam, lam, 0, 0, 0], [ lam, lam, 2 * mu + lam, 0, 0, 0], [ 0, 0, 0, mu, 0, 0], [ 0, 0, 0, 0, mu, 0], [ 0, 0, 0, 0, 0, mu]]) - mat = muSpectre.material.MaterialLinearElasticGeneric_3d.make( + eigenstrain = np.array([[ 0, .01], + [.01, 0]]) + + mat1 = muSpectre.material.MaterialLinearElasticGeneric1_3d.make( + cell, "material", C) + mat1.add_pixel(pixel) + mat2 = muSpectre.material.MaterialLinearElasticGeneric2_3d.make( cell, "material", C) + mat2.add_pixel(pixel, eigenstrain) diff --git a/language_bindings/python/bind_py_material.cc b/language_bindings/python/bind_py_material.cc index 4001d6e..767b7b9 100644 --- a/language_bindings/python/bind_py_material.cc +++ b/language_bindings/python/bind_py_material.cc @@ -1,188 +1,192 @@ /** * @file bind_py_material.cc * * @author Till Junge * * @date 09 Jan 2018 * * @brief python bindings for µSpectre's materials * * Copyright © 2018 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with µSpectre; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * * Boston, MA 02111-1307, USA. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with proprietary FFT implementations or numerical libraries, containing parts * covered by the terms of those libraries' licenses, the licensors of this * Program grant you additional permission to convey the resulting work. */ #include "common/common.hh" #include "materials/material_linear_elastic1.hh" #include "materials/material_linear_elastic2.hh" #include "materials/material_linear_elastic3.hh" #include "materials/material_linear_elastic4.hh" #include "cell/cell_base.hh" #include "common/field_collection.hh" #include #include #include #include #include using namespace muSpectre; // NOLINT // TODO(junge): figure this out namespace py = pybind11; using namespace pybind11::literals; // NOLINT: recommended usage /* ---------------------------------------------------------------------- */ template -void add_material_linear_elastic_generic_helper(py::module & mod); +void add_material_linear_elastic_generic1_helper(py::module & mod); +/* ---------------------------------------------------------------------- */ +template +void add_material_linear_elastic_generic2_helper(py::module & mod); /** * python binding for the optionally objective form of Hooke's law */ template void add_material_linear_elastic1_helper(py::module & mod) { std::stringstream name_stream{}; name_stream << "MaterialLinearElastic1_" << dim << 'd'; const auto name{name_stream.str()}; using Mat_t = MaterialLinearElastic1; using Sys_t = CellBase; py::class_>(mod, name.c_str()) .def_static("make", [](Sys_t & sys, std::string n, Real e, Real p) -> Mat_t & { return Mat_t::make(sys, n, e, p); }, "cell"_a, "name"_a, "Young"_a, "Poisson"_a, py::return_value_policy::reference, py::keep_alive<1, 0>()) .def("add_pixel", [](Mat_t & mat, Ccoord_t pix) { mat.add_pixel(pix); }, "pixel"_a) .def("size", &Mat_t::size); } template void add_material_linear_elastic2_helper(py::module & mod) { std::stringstream name_stream{}; name_stream << "MaterialLinearElastic2_" << dim << 'd'; const auto name{name_stream.str()}; using Mat_t = MaterialLinearElastic2; using Sys_t = CellBase; py::class_>(mod, name.c_str()) .def_static("make", [](Sys_t & sys, std::string n, Real e, Real p) -> Mat_t & { return Mat_t::make(sys, n, e, p); }, "cell"_a, "name"_a, "Young"_a, "Poisson"_a, py::return_value_policy::reference, py::keep_alive<1, 0>()) .def("add_pixel", [](Mat_t & mat, Ccoord_t pix, py::EigenDRef & eig) { Eigen::Matrix eig_strain{eig}; mat.add_pixel(pix, eig_strain); }, "pixel"_a, "eigenstrain"_a) .def("size", &Mat_t::size); } template void add_material_linear_elastic3_helper(py::module & mod) { std::stringstream name_stream{}; name_stream << "MaterialLinearElastic3_" << dim << 'd'; const auto name{name_stream.str()}; using Mat_t = MaterialLinearElastic3; using Sys_t = CellBase; py::class_>(mod, name.c_str()) .def(py::init(), "name"_a) .def_static("make", [](Sys_t & sys, std::string n) -> Mat_t & { return Mat_t::make(sys, n); }, "cell"_a, "name"_a, py::return_value_policy::reference, py::keep_alive<1, 0>()) .def("add_pixel", [](Mat_t & mat, Ccoord_t pix, Real Young, Real Poisson) { mat.add_pixel(pix, Young, Poisson); }, "pixel"_a, "Young"_a, "Poisson"_a) .def("size", &Mat_t::size); } template void add_material_linear_elastic4_helper(py::module & mod) { std::stringstream name_stream{}; name_stream << "MaterialLinearElastic4_" << dim << 'd'; const auto name{name_stream.str()}; using Mat_t = MaterialLinearElastic4; using Sys_t = CellBase; py::class_>(mod, name.c_str()) .def(py::init(), "name"_a) .def_static("make", [](Sys_t & sys, std::string n) -> Mat_t & { return Mat_t::make(sys, n); }, "cell"_a, "name"_a, py::return_value_policy::reference, py::keep_alive<1, 0>()) .def("add_pixel", [](Mat_t & mat, Ccoord_t pix, Real Young, Real Poisson) { mat.add_pixel(pix, Young, Poisson); }, "pixel"_a, "Young"_a, "Poisson"_a) .def("size", &Mat_t::size); } template void add_material_helper(py::module & mod) { std::stringstream name_stream{}; name_stream << "Material_" << dim << 'd'; const std::string name{name_stream.str()}; using Mat_t = MaterialBase; using FC_t = LocalFieldCollection; using FCBase_t = FieldCollectionBase; py::class_(mod, name.c_str()) .def_property_readonly("collection", [](Mat_t & material) -> FCBase_t & { return material.get_collection(); }, "returns the field collection containing internal " "fields of this material", py::return_value_policy::reference_internal); add_material_linear_elastic1_helper(mod); add_material_linear_elastic2_helper(mod); add_material_linear_elastic3_helper(mod); add_material_linear_elastic4_helper(mod); - add_material_linear_elastic_generic_helper(mod); + add_material_linear_elastic_generic1_helper(mod); + add_material_linear_elastic_generic2_helper(mod); } void add_material(py::module & mod) { auto material{mod.def_submodule("material")}; material.doc() = "bindings for constitutive laws"; add_material_helper(material); add_material_helper(material); } diff --git a/language_bindings/python/bind_py_material_linear_elastic_generic.cc b/language_bindings/python/bind_py_material_linear_elastic_generic.cc index 9c0cbe3..5a55bde 100644 --- a/language_bindings/python/bind_py_material_linear_elastic_generic.cc +++ b/language_bindings/python/bind_py_material_linear_elastic_generic.cc @@ -1,86 +1,134 @@ /** * @file bind_py_material_linear_elastic_generic.cc * * @author Till Junge * * @date 20 Dec 2018 * * @brief bindings for the generic linear elastic law defined by its stiffness * tensor * * Copyright © 2018 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with µSpectre; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with proprietary FFT implementations or numerical libraries, containing parts * covered by the terms of those libraries' licenses, the licensors of this * Program grant you additional permission to convey the resulting work. */ -#include "materials/material_linear_elastic_generic.hh" +#include "materials/material_linear_elastic_generic1.hh" +#include "materials/material_linear_elastic_generic2.hh" #include "cell/cell_base.hh" #include #include #include - #include #include using namespace muSpectre; // NOLINT // TODO(junge): figure this out namespace py = pybind11; using namespace pybind11::literals; // NOLINT: recommended usage /** * python binding for the generic linear elastic material */ template -void add_material_linear_elastic_generic_helper(py::module & mod) { -std::stringstream name_stream{}; -name_stream << "MaterialLinearElasticGeneric_" << Dim << "d"; -const auto name{name_stream.str()}; +void add_material_linear_elastic_generic1_helper(py::module & mod) { + std::stringstream name_stream{}; + name_stream << "MaterialLinearElasticGeneric1_" << Dim << "d"; + const auto name{name_stream.str()}; -using Mat_t = MaterialLinearElasticGeneric; -using Cell_t = CellBase; + using Mat_t = MaterialLinearElasticGeneric1; + using Cell_t = CellBase; -py::class_>(mod, name.c_str()) - .def_static("make", - [](Cell_t & cell, std::string name, - const py::EigenDRef< - Eigen::Matrix> & - elastic_tensor) -> Mat_t & { - return Mat_t::make(cell, name, elastic_tensor); - }, - "cell"_a, "name"_a, "elastic_tensor"_a, - py::return_value_policy::reference, py::keep_alive<1, 0>(), - "Factory function returning a MaterialLinearElastic instance. " - "The elastic tensor has to be specified in Voigt notation.") - .def("add_pixel", - [](Mat_t & mat, Ccoord_t pix) { mat.add_pixel(pix); }, "pixel"_a, - "Register a new pixel to this material. subsequent evaluations of the " - "stress and tangent in the cell will use this constitutive law for " - "this " - "particular pixel") - .def("size", &Mat_t::size); + py::class_>(mod, name.c_str()) + .def_static( + "make", + [](Cell_t & cell, std::string name, + const py::EigenDRef< + Eigen::Matrix> & + elastic_tensor) -> Mat_t & { + return Mat_t::make(cell, name, elastic_tensor); + }, + "cell"_a, "name"_a, "elastic_tensor"_a, + py::return_value_policy::reference, py::keep_alive<1, 0>(), + "Factory function returning a MaterialLinearElastic instance. " + "The elastic tensor has to be specified in Voigt notation.") + .def("add_pixel", + [](Mat_t & mat, Ccoord_t pix) { mat.add_pixel(pix); }, + "pixel"_a, + "Register a new pixel to this material. subsequent evaluations of " + "the " + "stress and tangent in the cell will use this constitutive law for " + "this " + "particular pixel") + .def("size", &Mat_t::size); } +/** + * python binding for the generic linear elastic material with eigenstcain + */ +template +void add_material_linear_elastic_generic2_helper(py::module & mod) { + std::stringstream name_stream{}; + name_stream << "MaterialLinearElasticGeneric2_" << Dim << "d"; + const auto name{name_stream.str()}; + + using Mat_t = MaterialLinearElasticGeneric2; + using Cell_t = CellBase; + + py::class_>(mod, name.c_str()) + .def_static( + "make", + [](Cell_t & cell, std::string name, + const py::EigenDRef< + Eigen::Matrix> & + elastic_tensor) -> Mat_t & { + return Mat_t::make(cell, name, elastic_tensor); + }, + "cell"_a, "name"_a, "elastic_tensor"_a, + py::return_value_policy::reference, py::keep_alive<1, 0>(), + "Factory function returning a MaterialLinearElastic instance. " + "The elastic tensor has to be specified in Voigt notation.") + .def("add_pixel", + [](Mat_t & mat, Ccoord_t pix) { mat.add_pixel(pix); }, + "pixel"_a, + "Register a new pixel to this material. Subsequent evaluations of " + "the stress and tangent in the cell will use this constitutive law " + "for this particular pixel") + .def("add_pixel", + [](Mat_t & mat, Ccoord_t pix, + py::EigenDRef & eig) { + Eigen::Matrix eig_strain{eig}; + mat.add_pixel(pix, eig_strain); + }, + "pixel"_a, "eigenstrain"_a, + "Register a new pixel to this material and assign the eigenstrain. " + "Subsequent Evaluations of the stress and tangent in the cell will " + "use this constitutive law for this particular pixel") + .def("size", &Mat_t::size); +} -template void add_material_linear_elastic_generic_helper(py::module &); -template void add_material_linear_elastic_generic_helper(py::module &); +template void add_material_linear_elastic_generic1_helper(py::module &); +template void add_material_linear_elastic_generic1_helper(py::module &); +template void add_material_linear_elastic_generic2_helper(py::module &); +template void add_material_linear_elastic_generic2_helper(py::module &); diff --git a/src/materials/CMakeLists.txt b/src/materials/CMakeLists.txt index ff1b225..cd4dbee 100644 --- a/src/materials/CMakeLists.txt +++ b/src/materials/CMakeLists.txt @@ -1,49 +1,50 @@ # ============================================================================= # file CMakeLists.txt # # @author Till Junge # # @date 08 Jan 2018 # # @brief configuration for material laws # # @section LICENSE # # Copyright © 2018 Till Junge # # µSpectre is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation, either version 3, or (at # your option) any later version. # # µSpectre is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with µSpectre; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Additional permission under GNU GPL version 3 section 7 # # If you modify this Program, or any covered work, by linking or combining it # with proprietary FFT implementations or numerical libraries, containing parts # covered by the terms of those libraries' licenses, the licensors of this # Program grant you additional permission to convey the resulting work. # ============================================================================= set (materials_SRC ${CMAKE_CURRENT_SOURCE_DIR}/material_base.cc ${CMAKE_CURRENT_SOURCE_DIR}/material_linear_elastic1.cc ${CMAKE_CURRENT_SOURCE_DIR}/material_linear_elastic2.cc ${CMAKE_CURRENT_SOURCE_DIR}/material_linear_elastic3.cc ${CMAKE_CURRENT_SOURCE_DIR}/material_linear_elastic4.cc - ${CMAKE_CURRENT_SOURCE_DIR}/material_linear_elastic_generic.cc + ${CMAKE_CURRENT_SOURCE_DIR}/material_linear_elastic_generic1.cc + ${CMAKE_CURRENT_SOURCE_DIR}/material_linear_elastic_generic2.cc ${CMAKE_CURRENT_SOURCE_DIR}/material_hyper_elasto_plastic1.cc ) target_sources(muSpectre PRIVATE ${materials_SRC}) diff --git a/src/materials/material_linear_elastic2.hh b/src/materials/material_linear_elastic2.hh index 319ce2d..873c33b 100644 --- a/src/materials/material_linear_elastic2.hh +++ b/src/materials/material_linear_elastic2.hh @@ -1,203 +1,201 @@ /** * @file material_linear_elastic2.hh * * @author Till Junge * * @date 03 Feb 2018 * * @brief linear elastic material with imposed eigenstrain and its * type traits. Uses the MaterialMuSpectre facilities to keep it * simple * * Copyright © 2018 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with µSpectre; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * * Boston, MA 02111-1307, USA. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with proprietary FFT implementations or numerical libraries, containing parts * covered by the terms of those libraries' licenses, the licensors of this * Program grant you additional permission to convey the resulting work. */ #ifndef SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC2_HH_ #define SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC2_HH_ #include "materials/material_linear_elastic1.hh" #include "common/field.hh" #include namespace muSpectre { template class MaterialLinearElastic2; /** * traits for objective linear elasticity with eigenstrain */ template struct MaterialMuSpectre_traits> { //! global field collection using GFieldCollection_t = typename MaterialBase::GFieldCollection_t; //! expected map type for strain fields using StrainMap_t = MatrixFieldMap; //! expected map type for stress fields using StressMap_t = MatrixFieldMap; //! expected map type for tangent stiffness fields using TangentMap_t = T4MatrixFieldMap; //! declare what type of strain measure your law takes as input constexpr static auto strain_measure{StrainMeasure::GreenLagrange}; //! declare what type of stress measure your law yields as output constexpr static auto stress_measure{StressMeasure::PK2}; //! local field_collections used for internals using LFieldColl_t = LocalFieldCollection; //! local strain type using LStrainMap_t = MatrixFieldMap; //! elasticity with eigenstrain using InternalVariables = std::tuple; }; /** * implements objective linear elasticity with an eigenstrain per pixel */ template class MaterialLinearElastic2 : public MaterialMuSpectre, DimS, DimM> { public: //! base class using Parent = MaterialMuSpectre; //! type for stiffness tensor construction using Stiffness_t = Eigen::TensorFixedSize>; //! traits of this material using traits = MaterialMuSpectre_traits; //! Type of container used for storing eigenstrain using InternalVariables = typename traits::InternalVariables; //! Hooke's law implementation using Hooke = typename MatTB::Hooke; //! reference to any type that casts to a matrix using StrainTensor = Eigen::Ref>; //! Default constructor MaterialLinearElastic2() = delete; //! Construct by name, Young's modulus and Poisson's ratio MaterialLinearElastic2(std::string name, Real young, Real poisson); //! Copy constructor MaterialLinearElastic2(const MaterialLinearElastic2 & other) = delete; //! Move constructor MaterialLinearElastic2(MaterialLinearElastic2 && other) = delete; //! Destructor virtual ~MaterialLinearElastic2() = default; //! Copy assignment operator MaterialLinearElastic2 & operator=(const MaterialLinearElastic2 & other) = delete; //! Move assignment operator MaterialLinearElastic2 & operator=(MaterialLinearElastic2 && other) = delete; /** * evaluates second Piola-Kirchhoff stress given the Green-Lagrange * strain (or Cauchy stress if called with a small strain tensor) */ template inline decltype(auto) evaluate_stress(s_t && E, eigen_s_t && E_eig); /** * evaluates both second Piola-Kirchhoff stress and stiffness given * the Green-Lagrange strain (or Cauchy stress and stiffness if * called with a small strain tensor) */ template inline decltype(auto) evaluate_stress_tangent(s_t && E, eigen_s_t && E_eig); /** * return the internals tuple */ InternalVariables & get_internals() { return this->internal_variables; } /** * overload add_pixel to write into eigenstrain */ void add_pixel(const Ccoord_t & pixel) final; /** * overload add_pixel to write into eigenstrain */ void add_pixel(const Ccoord_t & pixel, const StrainTensor & E_eig); protected: //! linear material without eigenstrain used to compute response MaterialLinearElastic1 material; //! storage for eigenstrain using Field_t = TensorField, Real, secondOrder, DimM>; Field_t & eigen_field; //!< field holding the eigen strain per pixel //! tuple for iterable eigen_field InternalVariables internal_variables; - - private: }; /* ---------------------------------------------------------------------- */ template template auto MaterialLinearElastic2::evaluate_stress(s_t && E, eigen_s_t && E_eig) -> decltype(auto) { return this->material.evaluate_stress(E - E_eig); } /* ---------------------------------------------------------------------- */ template template auto MaterialLinearElastic2::evaluate_stress_tangent( s_t && E, eigen_s_t && E_eig) -> decltype(auto) { // using mat = Eigen::Matrix; // mat ecopy{E}; // mat eig_copy{E_eig}; // mat ediff{ecopy-eig_copy}; // std::cout << "eidff - (E-E_eig)" << std::endl << ediff-(E-E_eig) << // std::endl; std::cout << "P1 " << std::endl << // mat{std::get<0>(this->material.evaluate_stress_tangent(E-E_eig))} << // "" << std::endl; std::cout << "P2" << std::endl << // mat{std::get<0>(this->material.evaluate_stress_tangent(std::move(ediff)))} // << std::endl; return this->material.evaluate_stress_tangent(E - E_eig); } } // namespace muSpectre #endif // SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC2_HH_ diff --git a/src/materials/material_linear_elastic_generic.cc b/src/materials/material_linear_elastic_generic1.cc similarity index 86% rename from src/materials/material_linear_elastic_generic.cc rename to src/materials/material_linear_elastic_generic1.cc index 54390f4..a82fdce 100644 --- a/src/materials/material_linear_elastic_generic.cc +++ b/src/materials/material_linear_elastic_generic1.cc @@ -1,71 +1,71 @@ /** - * @file material_linear_elastic_generic.cc + * @file material_linear_elastic_generic1.cc * * @author Till Junge * * @date 21 Sep 2018 * * @brief implementation for MaterialLinearElasticGeneric * * Copyright © 2018 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with µSpectre; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * * Boston, MA 02111-1307, USA. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with proprietary FFT implementations or numerical libraries, containing parts * covered by the terms of those libraries' licenses, the licensors of this * Program grant you additional permission to convey the resulting work. */ -#include "materials/material_linear_elastic_generic.hh" +#include "materials/material_linear_elastic_generic1.hh" #include "common/voigt_conversion.hh" namespace muSpectre { /* ---------------------------------------------------------------------- */ template - MaterialLinearElasticGeneric::MaterialLinearElasticGeneric( + MaterialLinearElasticGeneric1::MaterialLinearElasticGeneric1( const std::string & name, const CInput_t & C_voigt) : Parent{name} { using VC_t = VoigtConversion; constexpr Dim_t VSize{vsize(DimM)}; if (not(C_voigt.rows() == VSize) or not(C_voigt.cols() == VSize)) { std::stringstream err_str{}; err_str << "The stiffness tensor should be input as a " << VSize << " × " << VSize << " Matrix in Voigt notation. You supplied" << " a " << C_voigt.rows() << " × " << C_voigt.cols() << " matrix"; } for (int i{0}; i < DimM; ++i) { for (int j{0}; j < DimM; ++j) { for (int k{0}; k < DimM; ++k) { for (int l{0}; l < DimM; ++l) { get(this->C, i, j, k, l) = C_voigt(VC_t::sym_mat(i, j), VC_t::sym_mat(k, l)); } } } } } - template class MaterialLinearElasticGeneric; - template class MaterialLinearElasticGeneric; - template class MaterialLinearElasticGeneric; + template class MaterialLinearElasticGeneric1; + template class MaterialLinearElasticGeneric1; + template class MaterialLinearElasticGeneric1; } // namespace muSpectre diff --git a/src/materials/material_linear_elastic_generic.hh b/src/materials/material_linear_elastic_generic1.hh similarity index 73% rename from src/materials/material_linear_elastic_generic.hh rename to src/materials/material_linear_elastic_generic1.hh index 31b078a..0680233 100644 --- a/src/materials/material_linear_elastic_generic.hh +++ b/src/materials/material_linear_elastic_generic1.hh @@ -1,187 +1,185 @@ /** - * @file material_linear_elastic_generic.hh + * @file material_linear_elastic_generic1.hh * * @author Till Junge * * @date 21 Sep 2018 * * @brief Implementation fo a generic linear elastic material that * stores the full elastic stiffness tensor. Convenient but not the * most efficient * * Copyright © 2018 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with µSpectre; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * * Boston, MA 02111-1307, USA. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with proprietary FFT implementations or numerical libraries, containing parts * covered by the terms of those libraries' licenses, the licensors of this * Program grant you additional permission to convey the resulting work. */ -#ifndef SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC_HH_ -#define SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC_HH_ +#ifndef SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC1_HH_ +#define SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC1_HH_ #include "common/common.hh" #include "common/T4_map_proxy.hh" #include "materials/material_muSpectre_base.hh" #include "common/tensor_algebra.hh" namespace muSpectre { /** * forward declaration */ template - class MaterialLinearElasticGeneric; + class MaterialLinearElasticGeneric1; /** * traits for use by MaterialMuSpectre for crtp */ template - struct MaterialMuSpectre_traits> { + struct MaterialMuSpectre_traits> { //! global field collection using GFieldCollection_t = typename MaterialBase::GFieldCollection_t; //! expected map type for strain fields using StrainMap_t = MatrixFieldMap; //! expected map type for stress fields using StressMap_t = MatrixFieldMap; //! expected map type for tangent stiffness fields using TangentMap_t = T4MatrixFieldMap; //! declare what type of strain measure your law takes as input constexpr static auto strain_measure{StrainMeasure::GreenLagrange}; //! declare what type of stress measure your law yields as output constexpr static auto stress_measure{StressMeasure::PK2}; //! elasticity without internal variables using InternalVariables = std::tuple<>; }; /** * Linear elastic law defined by a full stiffness tensor. Very * generic, but not most efficient */ template - class MaterialLinearElasticGeneric - : public MaterialMuSpectre, DimS, - DimM> { + class MaterialLinearElasticGeneric1 + : public MaterialMuSpectre, + DimS, DimM> { public: //! parent type - using Parent = - MaterialMuSpectre, DimS, DimM>; + using Parent = MaterialMuSpectre, + DimS, DimM>; //! generic input tolerant to python input using CInput_t = Eigen::Ref, 0, Eigen::Stride>; //! Default constructor - MaterialLinearElasticGeneric() = delete; + MaterialLinearElasticGeneric1() = delete; /** * Constructor by name and stiffness tensor. * * @param name unique material name * @param C_voigt elastic tensor in Voigt notation */ - MaterialLinearElasticGeneric(const std::string & name, - const CInput_t & C_voigt); + MaterialLinearElasticGeneric1(const std::string & name, + const CInput_t & C_voigt); //! Copy constructor - MaterialLinearElasticGeneric(const MaterialLinearElasticGeneric & other) = + MaterialLinearElasticGeneric1(const MaterialLinearElasticGeneric1 & other) = delete; //! Move constructor - MaterialLinearElasticGeneric(MaterialLinearElasticGeneric && other) = + MaterialLinearElasticGeneric1(MaterialLinearElasticGeneric1 && other) = delete; //! Destructor - virtual ~MaterialLinearElasticGeneric() = default; + virtual ~MaterialLinearElasticGeneric1() = default; //! Copy assignment operator - MaterialLinearElasticGeneric & - operator=(const MaterialLinearElasticGeneric & other) = delete; + MaterialLinearElasticGeneric1 & + operator=(const MaterialLinearElasticGeneric1 & other) = delete; //! Move assignment operator - MaterialLinearElasticGeneric & - operator=(MaterialLinearElasticGeneric && other) = delete; + MaterialLinearElasticGeneric1 & + operator=(MaterialLinearElasticGeneric1 && other) = delete; //! see //! http://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html EIGEN_MAKE_ALIGNED_OPERATOR_NEW; /** * evaluates second Piola-Kirchhoff stress given the Green-Lagrange * strain (or Cauchy stress if called with a small strain tensor) */ template inline decltype(auto) evaluate_stress(const Eigen::MatrixBase & E); /** * evaluates both second Piola-Kirchhoff stress and stiffness given * the Green-Lagrange strain (or Cauchy stress and stiffness if * called with a small strain tensor) */ - template - inline decltype(auto) evaluate_stress_tangent(s_t && E); + template + inline decltype(auto) + evaluate_stress_tangent(const Eigen::MatrixBase & E); /** * return the empty internals tuple */ std::tuple<> & get_internals() { return this->internal_variables; } /** - * return a reference to teh stiffness tensor + * return a reference to the stiffness tensor */ const T4Mat & get_C() const { return this->C; } protected: - T4Mat C{}; + T4Mat C{}; //! stiffness tensor //! empty tuple std::tuple<> internal_variables{}; - - private: }; /* ---------------------------------------------------------------------- */ template template - auto MaterialLinearElasticGeneric::evaluate_stress( + auto MaterialLinearElasticGeneric1::evaluate_stress( const Eigen::MatrixBase & E) -> decltype(auto) { static_assert(Derived::ColsAtCompileTime == DimM, "wrong input size"); static_assert(Derived::RowsAtCompileTime == DimM, "wrong input size"); return Matrices::tensmult(this->C, E); } /* ---------------------------------------------------------------------- */ template - template - auto - MaterialLinearElasticGeneric::evaluate_stress_tangent(s_t && E) - -> decltype(auto) { - using Stress_t = decltype(this->evaluate_stress(std::forward(E))); + template + auto MaterialLinearElasticGeneric1::evaluate_stress_tangent( + const Eigen::MatrixBase & E) -> decltype(auto) { + using Stress_t = decltype(this->evaluate_stress(E)); using Stiffness_t = Eigen::Map>; using Ret_t = std::tuple; - return Ret_t{this->evaluate_stress(std::forward(E)), + return Ret_t{this->evaluate_stress(E), Stiffness_t(this->C.data())}; } } // namespace muSpectre -#endif // SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC_HH_ +#endif // SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC1_HH_ diff --git a/src/materials/material_linear_elastic_generic2.cc b/src/materials/material_linear_elastic_generic2.cc new file mode 100644 index 0000000..fe22fb0 --- /dev/null +++ b/src/materials/material_linear_elastic_generic2.cc @@ -0,0 +1,68 @@ +/** + * @file material_linear_elastic_generic2.cc + * + * @author Till Junge + * + * @date 20 Dec 2018 + * + * @brief Implementation for generic linear elastic law with eigenstrains + * + * Copyright © 2018 Till Junge + * + * µSpectre is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3, or (at + * your option) any later version. + * + * µSpectre is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with µSpectre; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining it + * with proprietary FFT implementations or numerical libraries, containing parts + * covered by the terms of those libraries' licenses, the licensors of this + * Program grant you additional permission to convey the resulting work. + */ + +#include "material_linear_elastic_generic2.hh" + +namespace muSpectre { + + /* ---------------------------------------------------------------------- */ + template + MaterialLinearElasticGeneric2::MaterialLinearElasticGeneric2( + const std::string & name, const CInput_t & C_voigt) + : Parent{name}, worker{name, C_voigt}, + eigen_field{make_field("Eigenstrain", this->internal_fields)}, + internal_variables(eigen_field.get_const_map()) {} + + /* ---------------------------------------------------------------------- */ + template + void MaterialLinearElasticGeneric2::add_pixel( + const Ccoord_t & /*pixel*/) { + throw std::runtime_error("this material needs pixels with and eigenstrain"); + } + + /* ---------------------------------------------------------------------- */ + template + void MaterialLinearElasticGeneric2::add_pixel( + const Ccoord_t & pixel, const StrainTensor & E_eig) { + this->internal_fields.add_pixel(pixel); + Eigen::Map> strain_array( + E_eig.data()); + this->eigen_field.push_back(strain_array); + } + + template class MaterialLinearElasticGeneric2; + template class MaterialLinearElasticGeneric2; + template class MaterialLinearElasticGeneric2; + +} // namespace muSpectre diff --git a/src/materials/material_linear_elastic2.hh b/src/materials/material_linear_elastic_generic2.hh similarity index 52% copy from src/materials/material_linear_elastic2.hh copy to src/materials/material_linear_elastic_generic2.hh index 319ce2d..74efca4 100644 --- a/src/materials/material_linear_elastic2.hh +++ b/src/materials/material_linear_elastic_generic2.hh @@ -1,203 +1,202 @@ /** - * @file material_linear_elastic2.hh + * @file material_linear_elastic_generic2.hh * - * @author Till Junge + * @author Till Junge * - * @date 03 Feb 2018 + * @date 20 Dec 2018 * - * @brief linear elastic material with imposed eigenstrain and its - * type traits. Uses the MaterialMuSpectre facilities to keep it - * simple + * @brief implementation of a generic linear elastic law with eigenstrains * * Copyright © 2018 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with µSpectre; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * * Boston, MA 02111-1307, USA. + * Boston, MA 02111-1307, USA. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with proprietary FFT implementations or numerical libraries, containing parts * covered by the terms of those libraries' licenses, the licensors of this * Program grant you additional permission to convey the resulting work. */ -#ifndef SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC2_HH_ -#define SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC2_HH_ +#ifndef SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC2_HH_ +#define SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC2_HH_ -#include "materials/material_linear_elastic1.hh" -#include "common/field.hh" - -#include +#include "material_linear_elastic_generic1.hh" namespace muSpectre { + /** + * forward declaration + */ template - class MaterialLinearElastic2; + class MaterialLinearElasticGeneric2; /** - * traits for objective linear elasticity with eigenstrain + * traits for use by MaterialMuSpectre for crtp */ + template - struct MaterialMuSpectre_traits> { + struct MaterialMuSpectre_traits> { //! global field collection using GFieldCollection_t = typename MaterialBase::GFieldCollection_t; //! expected map type for strain fields using StrainMap_t = MatrixFieldMap; //! expected map type for stress fields using StressMap_t = MatrixFieldMap; //! expected map type for tangent stiffness fields using TangentMap_t = T4MatrixFieldMap; //! declare what type of strain measure your law takes as input constexpr static auto strain_measure{StrainMeasure::GreenLagrange}; //! declare what type of stress measure your law yields as output constexpr static auto stress_measure{StressMeasure::PK2}; //! local field_collections used for internals using LFieldColl_t = LocalFieldCollection; //! local strain type using LStrainMap_t = MatrixFieldMap; //! elasticity with eigenstrain using InternalVariables = std::tuple; }; /** - * implements objective linear elasticity with an eigenstrain per pixel + * Implementation proper of the class */ template - class MaterialLinearElastic2 - : public MaterialMuSpectre, DimS, - DimM> { - public: - //! base class - using Parent = MaterialMuSpectre; + class MaterialLinearElasticGeneric2 + : public MaterialMuSpectre, + DimS, DimM> { + //! parent type + using Parent = MaterialMuSpectre, + DimS, DimM>; + //! underlying worker class + using Law_t = MaterialLinearElasticGeneric1; + + //! generic input tolerant to python input + using CInput_t = typename Law_t::CInput_t; - //! type for stiffness tensor construction - using Stiffness_t = - Eigen::TensorFixedSize>; + //! reference to any type that casts to a matrix + using StrainTensor = Eigen::Ref>; //! traits of this material - using traits = MaterialMuSpectre_traits; + using traits = MaterialMuSpectre_traits; //! Type of container used for storing eigenstrain - using InternalVariables = typename traits::InternalVariables; + using InternalVariables_t = typename traits::InternalVariables; - //! Hooke's law implementation - using Hooke = - typename MatTB::Hooke; - - //! reference to any type that casts to a matrix - using StrainTensor = Eigen::Ref>; + public: //! Default constructor - MaterialLinearElastic2() = delete; + MaterialLinearElasticGeneric2() = delete; - //! Construct by name, Young's modulus and Poisson's ratio - MaterialLinearElastic2(std::string name, Real young, Real poisson); + //! Construct by name and elastic stiffness tensor + MaterialLinearElasticGeneric2(const std::string & name, + const CInput_t & C_voigt); //! Copy constructor - MaterialLinearElastic2(const MaterialLinearElastic2 & other) = delete; + MaterialLinearElasticGeneric2(const MaterialLinearElasticGeneric2 & other) = + delete; //! Move constructor - MaterialLinearElastic2(MaterialLinearElastic2 && other) = delete; + MaterialLinearElasticGeneric2(MaterialLinearElasticGeneric2 && other) = + default; //! Destructor - virtual ~MaterialLinearElastic2() = default; + virtual ~MaterialLinearElasticGeneric2() = default; //! Copy assignment operator - MaterialLinearElastic2 & - operator=(const MaterialLinearElastic2 & other) = delete; + MaterialLinearElasticGeneric2 & + operator=(const MaterialLinearElasticGeneric2 & other) = delete; //! Move assignment operator - MaterialLinearElastic2 & - operator=(MaterialLinearElastic2 && other) = delete; + MaterialLinearElasticGeneric2 & + operator=(MaterialLinearElasticGeneric2 && other) = default; + + //! see + //! http://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html + EIGEN_MAKE_ALIGNED_OPERATOR_NEW; /** * evaluates second Piola-Kirchhoff stress given the Green-Lagrange * strain (or Cauchy stress if called with a small strain tensor) */ - template - inline decltype(auto) evaluate_stress(s_t && E, eigen_s_t && E_eig); - + template + inline decltype(auto) + evaluate_stress(const Eigen::MatrixBase & E, + const Eigen::MatrixBase & E_eig); /** * evaluates both second Piola-Kirchhoff stress and stiffness given * the Green-Lagrange strain (or Cauchy stress and stiffness if * called with a small strain tensor) */ - template - inline decltype(auto) evaluate_stress_tangent(s_t && E, eigen_s_t && E_eig); + template + inline decltype(auto) + evaluate_stress_tangent(const Eigen::MatrixBase & E, + const Eigen::MatrixBase & E_eig); /** - * return the internals tuple + * returns tuple with only the eigenstrain field */ - InternalVariables & get_internals() { return this->internal_variables; } + InternalVariables_t & get_internals() { return this->internal_variables; } + + /** + * return a reference to the stiffness tensor + */ + const T4Mat & get_C() const { return this->worker.get_C(); } /** * overload add_pixel to write into eigenstrain */ void add_pixel(const Ccoord_t & pixel) final; /** * overload add_pixel to write into eigenstrain */ void add_pixel(const Ccoord_t & pixel, const StrainTensor & E_eig); protected: - //! linear material without eigenstrain used to compute response - MaterialLinearElastic1 material; + Law_t worker; //! underlying law to be evaluated //! storage for eigenstrain using Field_t = TensorField, Real, secondOrder, DimM>; Field_t & eigen_field; //!< field holding the eigen strain per pixel - //! tuple for iterable eigen_field - InternalVariables internal_variables; - - private: + InternalVariables_t internal_variables; }; /* ---------------------------------------------------------------------- */ template - template - auto MaterialLinearElastic2::evaluate_stress(s_t && E, - eigen_s_t && E_eig) - -> decltype(auto) { - return this->material.evaluate_stress(E - E_eig); + template + auto MaterialLinearElasticGeneric2::evaluate_stress( + const Eigen::MatrixBase & E, + const Eigen::MatrixBase & E_eig) -> decltype(auto) { + return this->worker.evaluate_stress(E - E_eig); } /* ---------------------------------------------------------------------- */ template - template - auto MaterialLinearElastic2::evaluate_stress_tangent( - s_t && E, eigen_s_t && E_eig) -> decltype(auto) { - // using mat = Eigen::Matrix; - // mat ecopy{E}; - // mat eig_copy{E_eig}; - // mat ediff{ecopy-eig_copy}; - // std::cout << "eidff - (E-E_eig)" << std::endl << ediff-(E-E_eig) << - // std::endl; std::cout << "P1 " << std::endl << - // mat{std::get<0>(this->material.evaluate_stress_tangent(E-E_eig))} << - // "" << std::endl; std::cout << "P2" << std::endl << - // mat{std::get<0>(this->material.evaluate_stress_tangent(std::move(ediff)))} - // << std::endl; - return this->material.evaluate_stress_tangent(E - E_eig); + template + auto MaterialLinearElasticGeneric2::evaluate_stress_tangent( + const Eigen::MatrixBase & E, + const Eigen::MatrixBase & E_eig) -> decltype(auto) { + return this->worker.evaluate_stress_tangent(E - E_eig); } } // namespace muSpectre -#endif // SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC2_HH_ +#endif /* SRC_MATERIALS_MATERIAL_LINEAR_ELASTIC_GENERIC2_HH_ */ diff --git a/tests/python_binding_tests.py b/tests/python_binding_tests.py index d87a950..f78e012 100755 --- a/tests/python_binding_tests.py +++ b/tests/python_binding_tests.py @@ -1,202 +1,202 @@ #!/usr/bin/env python3 """ file python_binding_tests.py @author Till Junge @date 09 Jan 2018 @brief Unit tests for python bindings @section LICENCE Copyright © 2018 Till Junge µSpectre is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3, or (at your option) any later version. µSpectre is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with µSpectre; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with proprietary FFT implementations or numerical libraries, containing parts covered by the terms of those libraries' licenses, the licensors of this Program grant you additional permission to convey the resulting work. """ import unittest import numpy as np from python_test_imports import µ from python_fft_tests import FFT_Check from python_projection_tests import * from python_material_linear_elastic3_test import MaterialLinearElastic3_Check from python_material_linear_elastic4_test import MaterialLinearElastic4_Check -from python_material_linear_elastic_generic_test import MaterialLinearElasticGeneric_Check +from python_material_linear_elastic_generic1_test import MaterialLinearElasticGeneric1_Check from python_field_tests import FieldCollection_Check class CellCheck(unittest.TestCase): def test_Construction(self): """ Simple check for cell constructors """ resolution = [5,7] lengths = [5.2, 8.3] formulation = µ.Formulation.small_strain try: sys = µ.Cell(resolution, lengths, formulation) mat = µ.material.MaterialLinearElastic1_2d.make(sys, "material", 210e9, .33) except Exception as err: print(err) raise err class MaterialLinearElastic1_2dCheck(unittest.TestCase): def setUp(self): self.resolution = [5,7] self.lengths = [5.2, 8.3] self.formulation = µ.Formulation.small_strain self.sys = µ.Cell(self.resolution, self.lengths, self.formulation) self.mat = µ.material.MaterialLinearElastic1_2d.make( self.sys, "material", 210e9, .33) def test_add_material(self): self.mat.add_pixel([2,1]) class SolverCheck(unittest.TestCase): def setUp(self): self.resolution = [3, 3]#[5,7] self.lengths = [3., 3.]#[5.2, 8.3] self.formulation = µ.Formulation.finite_strain self.sys = µ.Cell(self.resolution, self.lengths, self.formulation) self.hard = µ.material.MaterialLinearElastic1_2d.make( self.sys, "hard", 210e9, .33) self.soft = µ.material.MaterialLinearElastic1_2d.make( self.sys, "soft", 70e9, .33) def test_solve(self): for i, pixel in enumerate(self.sys): if i < 3: self.hard.add_pixel(pixel) else: self.soft.add_pixel(pixel) self.sys.initialise() tol = 1e-6 Del0 = np.array([[0, .1], [0, 0]]) maxiter = 100 verbose = 0 solver=µ.solvers.SolverCG(self.sys, tol, maxiter, verbose) r = µ.solvers.de_geus(self.sys, Del0, solver,tol, verbose) #print(r) class EigenStrainCheck(unittest.TestCase): def setUp(self): self.resolution = [3, 3]#[5,7] self.lengths = [3., 3.]#[5.2, 8.3] self.formulation = µ.Formulation.small_strain self.cell1 = µ.Cell(self.resolution, self.lengths, self.formulation) self.cell2 = µ.Cell(self.resolution, self.lengths, self.formulation) self.mat1 = µ.material.MaterialLinearElastic1_2d.make( self.cell1, "simple", 210e9, .33) self.mat2 = µ.material.MaterialLinearElastic2_2d.make( self.cell2, "eigen", 210e9, .33) self.mat3 = µ.material.MaterialLinearElastic2_2d.make( self.cell2, "eigen2", 120e9, .33) def test_globalisation(self): for pixel in self.cell2: self.mat2.add_pixel(pixel, np.random.rand(2,2)) loc_eigenstrain = self.mat2.collection.get_real_field("Eigenstrain").array glo_eigenstrain = self.cell2.get_globalised_internal_real_array("Eigenstrain") error = np.linalg.norm(loc_eigenstrain-glo_eigenstrain) self.assertEqual(error, 0) def test_globalisation_constant(self): for i, pixel in enumerate(self.cell2): if i%2 == 0: self.mat2.add_pixel(pixel, np.ones((2,2))) else: self.mat3.add_pixel(pixel, np.ones((2,2))) glo_eigenstrain = self.cell2.get_globalised_internal_real_array("Eigenstrain") error = np.linalg.norm(glo_eigenstrain-1) self.assertEqual(error, 0) def test_solve(self): verbose_test = False if verbose_test: print("start test_solve") grad = np.array([[1.1, .2], [ .3, 1.5]]) gl_strain = -0.5*(grad.T.dot(grad) - np.eye(2)) gl_strain = -0.5*(grad.T + grad - 2*np.eye(2)) grad = -gl_strain if verbose_test: print("grad =\n{}\ngl_strain =\n{}".format(grad, gl_strain)) for i, pixel in enumerate(self.cell1): self.mat1.add_pixel(pixel) self.mat2.add_pixel(pixel, gl_strain) self.cell1.initialise() self.cell2.initialise() tol = 1e-6 Del0_1 = grad Del0_2 = np.zeros_like(grad) maxiter = 2 verbose = 0 def solve(cell, grad): solver=µ.solvers.SolverCG(cell, tol, maxiter, verbose) r = µ.solvers.newton_cg(cell, grad, solver, tol, tol, verbose) return r results = [solve(cell, del0) for (cell, del0) in zip((self.cell1, self.cell2), (Del0_1, Del0_2))] P1 = results[0].stress P2 = results[1].stress error = np.linalg.norm(P1-P2)/np.linalg.norm(.5*(P1+P2)) if verbose_test: print("cell 1, no eigenstrain") print("P1:\n{}".format(P1[:,0])) print("F1:\n{}".format(results[0].grad[:,0])) print("cell 2, with eigenstrain") print("P2:\n{}".format(P2[:,0])) print("F2:\n{}".format(results[1].grad[:,0])) print("end test_solve") self.assertLess(error, tol) if __name__ == '__main__': unittest.main() diff --git a/tests/python_material_linear_elastic_generic_test.py b/tests/python_material_linear_elastic_generic1_test.py similarity index 96% rename from tests/python_material_linear_elastic_generic_test.py rename to tests/python_material_linear_elastic_generic1_test.py index 7b8754c..34aed91 100644 --- a/tests/python_material_linear_elastic_generic_test.py +++ b/tests/python_material_linear_elastic_generic1_test.py @@ -1,108 +1,108 @@ #!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file python_material_linear_elastic_generic.py @author Till Junge @date 20 Dec 2018 @brief tests the python bindings of the generic linear elastic material Copyright © 2018 Till Junge µSpectre is free software; you can redistribute it and/or modify it under the terms of the GNU General Lesser Public License as published by the Free Software Foundation, either version 3, or (at your option) any later version. µSpectre is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with µSpectre; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with proprietary FFT implementations or numerical libraries, containing parts covered by the terms of those libraries' licenses, the licensors of this Program grant you additional permission to convey the resulting work. """ import unittest import numpy as np from python_test_imports import µ -class MaterialLinearElasticGeneric_Check(unittest.TestCase): +class MaterialLinearElasticGeneric1_Check(unittest.TestCase): def setUp(self): self.resolution = [5,7,5] self.dim = len(self.resolution) self.lengths = [5.2, 8.3, 2.7] self.formulation = µ.Formulation.small_strain self.cell1 = µ.Cell(self.resolution, self.lengths, self.formulation) self.Young = 210e9 self.Poisson = .33 self.mat1 = µ.material.MaterialLinearElastic1_3d.make( self.cell1, "material", self.Young, self.Poisson) self.matO1 = µ.material.MaterialLinearElastic1_3d.make( self.cell1, "material", 2* self.Young, self.Poisson) E, nu = self.Young, self.Poisson lam, mu = E*nu/((1+nu)*(1-2*nu)), E/(2*(1+nu)) C = np.array([[2 * mu + lam, lam, lam, 0, 0, 0], [ lam, 2 * mu + lam, lam, 0, 0, 0], [ lam, lam, 2 * mu + lam, 0, 0, 0], [ 0, 0, 0, mu, 0, 0], [ 0, 0, 0, 0, mu, 0], [ 0, 0, 0, 0, 0, mu]]) self.cell2 = µ.Cell(self.resolution, self.lengths, self.formulation) - self.mat2 = µ.material.MaterialLinearElasticGeneric_3d.make( + self.mat2 = µ.material.MaterialLinearElasticGeneric1_3d.make( self.cell2, "material", C) self.matO2 = µ.material.MaterialLinearElastic1_3d.make( self.cell2, "material", 2* self.Young, self.Poisson) def test_equivalence(self): sym = lambda x: .5*(x + x.T) Del0 = sym((np.random.random((self.dim, self.dim))-.5)/10) for pixel in self.cell1: if pixel[0] == 0: self.matO1.add_pixel(pixel) self.matO2.add_pixel(pixel) else: self.mat1.add_pixel(pixel) self.mat2.add_pixel(pixel) tol = 1e-6 equil_tol = tol maxiter = 100 verbose = 0 solver1 = µ.solvers.SolverCG(self.cell1, tol, maxiter, verbose) solver2 = µ.solvers.SolverCG(self.cell2, tol, maxiter, verbose) r1 = µ.solvers.de_geus(self.cell1, Del0, solver1, tol, equil_tol, verbose) r2 = µ.solvers.de_geus(self.cell2, Del0, solver2, tol, equil_tol, verbose) error = (np.linalg.norm(r1.stress - r2.stress) / np.linalg.norm(r1.stress + r2.stress)) self.assertLess(error, 1e-13) diff --git a/tests/test_material_linear_elastic_generic.cc b/tests/test_material_linear_elastic_generic.cc index b7d6014..315ab1f 100644 --- a/tests/test_material_linear_elastic_generic.cc +++ b/tests/test_material_linear_elastic_generic.cc @@ -1,93 +1,93 @@ /** * @file test_material_linear_elastic_generic.cc * * @author Till Junge * * @date 21 Sep 2018 * * @brief test for the generic linear elastic law * * Copyright © 2018 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with µSpectre; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * * Boston, MA 02111-1307, USA. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with proprietary FFT implementations or numerical libraries, containing parts * covered by the terms of those libraries' licenses, the licensors of this * Program grant you additional permission to convey the resulting work. */ #include "tests.hh" -#include "materials/material_linear_elastic_generic.cc" +#include "materials/material_linear_elastic_generic1.hh" #include "materials/materials_toolbox.hh" #include namespace muSpectre { BOOST_AUTO_TEST_SUITE(material_linear_elastic_generic); template struct MatFixture { - using Mat_t = MaterialLinearElasticGeneric; + using Mat_t = MaterialLinearElasticGeneric1; using T2_t = Eigen::Matrix; using T4_t = T4Mat; using V_t = Eigen::Matrix; constexpr static Real lambda{2}, mu{1.5}; constexpr static Real get_lambda() { return lambda; } constexpr static Real get_mu() { return mu; } constexpr static Real young{mu * (3 * lambda + 2 * mu) / (lambda + mu)}; constexpr static Real poisson{lambda / (2 * (lambda + mu))}; using Hooke = MatTB::Hooke; MatFixture() : C_voigt{get_C_voigt()}, mat("material", this->C_voigt) {} static V_t get_C_voigt() { V_t C{}; C.setZero(); C.template topLeftCorner().setConstant(get_lambda()); C.template topLeftCorner() += 2 * get_mu() * T2_t::Identity(); constexpr Dim_t Rest{vsize(Dim) - Dim}; using Rest_t = Eigen::Matrix; C.template bottomRightCorner() += get_mu() * Rest_t::Identity(); return C; } V_t C_voigt; Mat_t mat; }; using mats = boost::mpl::list, MatFixture>; BOOST_FIXTURE_TEST_CASE_TEMPLATE(C_test, Fix, mats, Fix) { const auto ref_C{ Fix::Hooke::compute_C_T4(Fix::get_lambda(), Fix::get_mu())}; Real error{(ref_C - Fix::mat.get_C()).norm()}; BOOST_CHECK_LT(error, tol); if (not(error < tol)) { std::cout << "ref:" << std::endl << ref_C << std::endl; std::cout << "new:" << std::endl << Fix::mat.get_C() << std::endl; } } BOOST_AUTO_TEST_SUITE_END(); } // namespace muSpectre