NEML2 2.0.0
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
ElasticityInterface.h
1// Copyright 2024, UChicago Argonne, LLC
2// All Rights Reserved
3// Software Name: NEML2 -- the New Engineering material Model Library, version 2
4// By: Argonne National Laboratory
5// OPEN SOURCE LICENSE (MIT)
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23// THE SOFTWARE.
24
25#pragma once
26
27#include "neml2/models/solid_mechanics/elasticity/ElasticityConverter.h"
28#include "neml2/base/MultiEnumSelection.h"
29#include "neml2/tensors/Scalar.h"
30
31namespace neml2
32{
38template <class Derived, std::size_t N>
39class ElasticityInterface : public Derived
40{
41public:
43
45
46protected:
49
51 std::array<ElasticConstant, N> _constant_types;
52
54 std::array<const Scalar *, N> _constants;
55
57 std::array<bool, N> _need_derivs;
58
59private:
61 std::vector<TensorName<Scalar>> _coefs;
62
64 const std::vector<ElasticConstant> _coef_types;
65
67 std::vector<bool> _coef_as_param;
68
70 std::size_t _counter = 0;
71};
72
73} // namespace neml2
74
76// Implementation
78
79namespace neml2
80{
81template <class Derived, std::size_t N>
82OptionSet
84{
85 OptionSet options = Derived::expected_options();
86
87 MultiEnumSelection type_selection({"LAME_LAMBDA",
88 "BULK_MODULUS",
89 "SHEAR_MODULUS",
90 "YOUNGS_MODULUS",
91 "POISSONS_RATIO",
92 "P_WAVE_MODULUS",
93 "INVALID"},
94 {static_cast<int>(ElasticConstant::LAME_LAMBDA),
95 static_cast<int>(ElasticConstant::BULK_MODULUS),
96 static_cast<int>(ElasticConstant::SHEAR_MODULUS),
97 static_cast<int>(ElasticConstant::YOUNGS_MODULUS),
98 static_cast<int>(ElasticConstant::POISSONS_RATIO),
99 static_cast<int>(ElasticConstant::P_WAVE_MODULUS),
100 static_cast<int>(ElasticConstant::INVALID)},
101 {"INVALID"});
102 options.set<MultiEnumSelection>("coefficient_types") = type_selection;
103 options.set("coefficient_types").doc() =
104 "Types for each parameter, options are: " + type_selection.candidates_str();
105
106 options.set_parameter<std::vector<TensorName<Scalar>>>("coefficients");
107 options.set("coefficients").doc() = "Coefficients used to define the elasticity tensor";
108
109 options.set<std::vector<bool>>("coefficient_as_parameter") = {true};
110 options.set("coefficient_as_parameter").doc() =
111 "Whether to treat the coefficients as (trainable) parameters. Default is true. Setting this "
112 "option to false will treat the coefficients as buffers.";
113
114 return options;
115}
116
117template <class Derived, std::size_t N>
119 : Derived(options),
120 _coefs(options.get<std::vector<TensorName<Scalar>>>("coefficients")),
121 _coef_types(options.get<MultiEnumSelection>("coefficient_types").as<ElasticConstant>()),
122 _coef_as_param(options.get<std::vector<bool>>("coefficient_as_parameter"))
123{
124 if (_coefs.size() != N)
125 throw NEMLException("Expected " + std::to_string(N) + " coefficients, got " +
126 std::to_string(_coefs.size()) + ".");
127 if (_coef_types.size() != N)
128 throw NEMLException("Expected " + std::to_string(N) + " coefficient types, got " +
129 std::to_string(_coef_types.size()) + ".");
130 if (_coef_as_param.size() != 1 && _coef_as_param.size() != N)
131 throw NEMLException("Expected 1 or " + std::to_string(N) +
132 " entries in coefficient_as_parameter, got " +
133 std::to_string(_coef_as_param.size()) + ".");
134
135 if (_coef_as_param.size() == 1)
136 _coef_as_param.resize(N, _coef_as_param[0]);
137
138 // Fill out _constants, _constant_types, and _constant_names by sorting the coefficients according
139 // to the order defined by ElasticConstant
146
147 // Figure out which coefficients need derivatives
148 for (std::size_t i = 0; i < _constant_types.size(); i++)
149 _need_derivs[i] = (Derived::nl_param(neml2::name(_constant_types[i])) != nullptr);
150}
151
152template <class Derived, std::size_t N>
153void
155{
156 for (std::size_t i = 0; i < _coefs.size(); i++)
157 {
158 if (_coef_types[i] == ElasticConstant::INVALID)
159 throw NEMLException("Invalid coefficient type provided for coefficient " + std::to_string(i) +
160 ".");
161
162 if (_coef_types[i] != ptype)
163 continue;
164
165 if (std::find(_constant_types.begin(), std::next(_constant_types.begin(), _counter), ptype) !=
166 std::next(_constant_types.begin(), _counter))
167 throw NEMLException("Duplicate coefficient type provided for coefficient " +
168 std::to_string(i) + ".");
169
170 const auto pname = neml2::name(ptype);
171 const auto * pval = _coef_as_param[i]
172 ? &Derived::template declare_parameter<Scalar>(
173 pname, _coefs[i], /*allow_nonlinear*/ true)
174 : &Derived::template declare_buffer<Scalar>(pname, _coefs[i]);
175
176 if (_counter >= N)
177 throw NEMLException("Too many coefficients provided.");
178 _constant_types[_counter] = ptype;
179 _constants[_counter] = pval;
180 _counter++;
181
182 return;
183 }
184}
185} // namespace neml2
std::array< const Scalar *, N > _constants
Input elastic constants (ordered according to ElasticConstant)
Definition ElasticityInterface.h:54
ElasticityInterface(const OptionSet &options)
Definition ElasticityInterface.h:118
std::array< bool, N > _need_derivs
Whether we need to calculate the derivative of the constants.
Definition ElasticityInterface.h:57
static OptionSet expected_options()
Definition ElasticityInterface.h:83
void declare_elastic_constant(ElasticConstant)
Declare elastic constants (by resolving cross-references)
Definition ElasticityInterface.h:154
std::array< ElasticConstant, N > _constant_types
Input elastic constant types (ordered according to ElasticConstant)
Definition ElasticityInterface.h:51
Selection of multiple enum value from a list of candidates.
Definition MultiEnumSelection.h:41
Definition errors.h:34
A custom map-like data structure. The keys are strings, and the values can be nonhomogeneously typed.
Definition OptionSet.h:52
T & set_parameter(const std::string &)
Convenient method to request a parameter.
Definition OptionSet.h:284
T & set(const std::string &)
Definition OptionSet.h:273
Scalar.
Definition Scalar.h:38
Definition DiagnosticsInterface.cxx:30
ElasticConstant
Definition ElasticityConverter.h:38
@ P_WAVE_MODULUS
Definition ElasticityConverter.h:46
@ SHEAR_MODULUS
Definition ElasticityConverter.h:43
@ POISSONS_RATIO
Definition ElasticityConverter.h:45
@ BULK_MODULUS
Definition ElasticityConverter.h:42
@ YOUNGS_MODULUS
Definition ElasticityConverter.h:44
@ LAME_LAMBDA
Definition ElasticityConverter.h:41
@ INVALID
Definition ElasticityConverter.h:39
std::string name(ElasticConstant p)
Definition ElasticityConverter.cxx:30
The name of a tensor object that can be referenced in the input files.
Definition TensorName.h:46