NEML2 2.1.0
Loading...
Searching...
No Matches
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#include "neml2/base/OptionSet.h"
31#include "neml2/base/TensorName.h"
32
33namespace neml2
34{
40template <class Derived, std::size_t N>
41class ElasticityInterface : public Derived
42{
43public:
45
47
48protected:
51
53 std::array<ElasticConstant, N> _constant_types;
54
56 std::array<const Scalar *, N> _constants;
57
59 std::array<bool, N> _need_derivs;
60
61private:
63 std::vector<TensorName<Scalar>> _coefs;
64
66 const std::vector<ElasticConstant> _coef_types;
67
69 std::vector<bool> _coef_as_param;
70
72 std::size_t _counter = 0;
73};
74
75} // namespace neml2
76
78// Implementation
80
81namespace neml2
82{
83template <class Derived, std::size_t N>
84OptionSet
86{
87 OptionSet options = Derived::expected_options();
88
89 MultiEnumSelection type_selection({"LAME_LAMBDA",
90 "BULK_MODULUS",
91 "SHEAR_MODULUS",
92 "YOUNGS_MODULUS",
93 "POISSONS_RATIO",
94 "P_WAVE_MODULUS",
95 "INVALID"},
96 {static_cast<int>(ElasticConstant::LAME_LAMBDA),
97 static_cast<int>(ElasticConstant::BULK_MODULUS),
98 static_cast<int>(ElasticConstant::SHEAR_MODULUS),
99 static_cast<int>(ElasticConstant::YOUNGS_MODULUS),
100 static_cast<int>(ElasticConstant::POISSONS_RATIO),
101 static_cast<int>(ElasticConstant::P_WAVE_MODULUS),
102 static_cast<int>(ElasticConstant::INVALID)},
103 {"INVALID"});
104 options.add<MultiEnumSelection>("coefficient_types",
105 type_selection,
106 "Types for each parameter, options are: " +
107 type_selection.join());
108
109 options.add<std::vector<TensorName<Scalar>>, FType::PARAMETER>(
110 "coefficients", "Coefficients used to define the elasticity tensor");
111
112 options.add<std::vector<bool>>(
113 "coefficient_as_parameter",
114 {true},
115 "Whether to treat the coefficients as (trainable) parameters. Default is true. Setting this "
116 "option to false will treat the coefficients as buffers.");
117
118 return options;
119}
120
121template <class Derived, std::size_t N>
123 : Derived(options),
124 _coefs(options.get<std::vector<TensorName<Scalar>>>("coefficients")),
125 _coef_types(options.get<MultiEnumSelection>("coefficient_types").as<ElasticConstant>()),
126 _coef_as_param(options.get<std::vector<bool>>("coefficient_as_parameter"))
127{
128 if (_coefs.size() != N)
129 throw NEMLException("Expected " + std::to_string(N) + " coefficients, got " +
130 std::to_string(_coefs.size()) + ".");
131 if (_coef_types.size() != N)
132 throw NEMLException("Expected " + std::to_string(N) + " coefficient types, got " +
133 std::to_string(_coef_types.size()) + ".");
134 if (_coef_as_param.size() != 1 && _coef_as_param.size() != N)
135 throw NEMLException("Expected 1 or " + std::to_string(N) +
136 " entries in coefficient_as_parameter, got " +
137 std::to_string(_coef_as_param.size()) + ".");
138
139 if (_coef_as_param.size() == 1)
140 _coef_as_param.resize(N, _coef_as_param[0]);
141
142 // Fill out _constants, _constant_types, and _constant_names by sorting the coefficients according
143 // to the order defined by ElasticConstant
150
151 // Figure out which coefficients need derivatives
152 for (std::size_t i = 0; i < _constant_types.size(); i++)
153 _need_derivs[i] = (Derived::nl_param(neml2::name(_constant_types[i])) != nullptr);
154}
155
156template <class Derived, std::size_t N>
157void
159{
160 for (std::size_t i = 0; i < _coefs.size(); i++)
161 {
162 if (_coef_types[i] == ElasticConstant::INVALID)
163 throw NEMLException("Invalid coefficient type provided for coefficient " + std::to_string(i) +
164 ".");
165
166 if (_coef_types[i] != ptype)
167 continue;
168
169 if (std::find(_constant_types.begin(), std::next(_constant_types.begin(), _counter), ptype) !=
170 std::next(_constant_types.begin(), _counter))
171 throw NEMLException("Duplicate coefficient type provided for coefficient " +
172 std::to_string(i) + ".");
173
174 const auto pname = neml2::name(ptype);
175 const auto * pval = _coef_as_param[i]
176 ? &Derived::template declare_parameter<Scalar>(
177 pname, _coefs[i], /*allow_nonlinear*/ true)
178 : &Derived::template declare_buffer<Scalar>(pname, _coefs[i]);
179
180 if (_counter >= N)
181 throw NEMLException("Too many coefficients provided.");
182 _constant_types[_counter] = ptype;
183 _constants[_counter] = pval;
184 _counter++;
185
186 return;
187 }
188}
189} // namespace neml2
std::array< const Scalar *, N > _constants
Input elastic constants (ordered according to ElasticConstant).
Definition ElasticityInterface.h:56
ElasticityInterface(const OptionSet &options)
Definition ElasticityInterface.h:122
std::array< bool, N > _need_derivs
Whether we need to calculate the derivative of the constants.
Definition ElasticityInterface.h:59
static OptionSet expected_options()
Definition ElasticityInterface.h:85
void declare_elastic_constant(ElasticConstant)
Declare elastic constants (by resolving cross-references).
Definition ElasticityInterface.h:158
std::array< ElasticConstant, N > _constant_types
Input elastic constant types (ordered according to ElasticConstant).
Definition ElasticityInterface.h:53
std::string join(const std::string &separator=", ") const
Join the choices into a single string with the given separator.
Selection of multiple enum value from a list of choices.
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:54
void add(const std::string &name, const T &default_value, std::string doc)
Create an option with its default value and its docstring.
Definition OptionSet.h:422
Scalar.
Definition Scalar.h:38
Definition DiagnosticsInterface.h:31
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)
@ PARAMETER
Definition types.h:94
The name of a tensor object that can be referenced in the input files.
Definition TensorName.h:47