OGS
SmallDeformation/LocalAssemblerInterface.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/Eigenvalues>
7#include <vector>
8
12#include "MaterialForces.h"
21
22namespace ProcessLib
23{
24namespace SmallDeformation
25{
26template <int DisplacementDim>
31{
33 MeshLib::Element const& e,
34 NumLib::GenericIntegrationMethod const& integration_method,
35 bool const is_axially_symmetric,
37 : process_data_(process_data),
38 integration_method_(integration_method),
39 element_(e),
40 is_axially_symmetric_(is_axially_symmetric),
41 solid_material_(MaterialLib::Solids::selectSolidConstitutiveRelation(
42 process_data_.solid_materials, process_data_.material_ids,
43 element_.getID()))
44 {
45 unsigned const n_integration_points =
46 integration_method_.getNumberOfPoints();
47
48 current_states_.resize(n_integration_points);
49 prev_states_.resize(n_integration_points);
50 output_data_.resize(n_integration_points);
51
52 material_states_.reserve(n_integration_points);
53 for (unsigned ip = 0; ip < n_integration_points; ++ip)
54 {
55 material_states_.emplace_back(
56 solid_material_.createMaterialStateVariables());
57
58 // Set initial stress field to zero. Might be overwritten by
59 // integration point data or initial stress.
60 std::get<StressData<DisplacementDim>>(this->current_states_[ip])
62 DisplacementDim>::Zero();
63 }
64 }
65
66 std::size_t setIPDataInitialConditions(std::string_view name,
67 double const* values,
68 int const integration_order)
69 {
70 if (integration_order !=
71 static_cast<int>(integration_method_.getIntegrationOrder()))
72 {
74 "Setting integration point initial conditions; The integration "
75 "order of the local assembler for element {:d} is different "
76 "from the integration order in the initial condition.",
77 element_.getID());
78 }
79
80 if (name.starts_with("material_state_variable_"))
81 {
82 name.remove_prefix(24);
83
84 auto const& internal_variables =
85 solid_material_.getInternalVariables();
86 if (auto const iv = std::find_if(
87 begin(internal_variables), end(internal_variables),
88 [&name](auto const& iv) { return iv.name == name; });
89 iv != end(internal_variables))
90 {
91 DBUG("Setting material state variable '{:s}'", name);
92 return ProcessLib::
94 values, material_states_,
96 DisplacementDim>::material_state_variables,
97 iv->reference);
98 }
99
100 WARN(
101 "Could not find variable {:s} in solid material model's "
102 "internal variables.",
103 name);
104 return 0;
105 }
106
107 // TODO this logic could be pulled out of the local assembler into the
108 // process. That might lead to a slightly better performance due to less
109 // string comparisons.
111 name, values, current_states_);
112 }
113
115 double const /*t*/, double const /*dt*/, Eigen::VectorXd const& /*x*/,
116 Eigen::VectorXd const& /*x_prev*/) override
117 {
118 int const elem_id = element_.getID();
120 x_position.setElementID(elem_id);
121 unsigned const n_integration_points =
122 integration_method_.getNumberOfPoints();
123
125 Eigen::Matrix<double, 3, 3>::Zero());
126
127 for (unsigned ip = 0; ip < n_integration_points; ip++)
128 {
129 auto const& sigma =
130 std::get<StressData<DisplacementDim>>(current_states_[ip])
131 .sigma;
132 sigma_sum += sigma;
133 }
134
135 Eigen::Matrix<double, 3, 3, 0, 3, 3> const sigma_avg =
137 n_integration_points;
138
139 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 3, 3>> e_s(
140 sigma_avg);
141
142 Eigen::Map<Eigen::Vector3d>(
143 &(*process_data_.principal_stress_values)[elem_id * 3], 3) =
144 e_s.eigenvalues();
145
146 auto eigen_vectors = e_s.eigenvectors();
147
148 for (auto i = 0; i < 3; i++)
149 {
150 Eigen::Map<Eigen::Vector3d>(
151 &(*process_data_.principal_stress_vector[i])[elem_id * 3], 3) =
152 eigen_vectors.col(i);
153 }
154 }
155
156 // TODO move to NumLib::ExtrapolatableElement
158 {
159 return integration_method_.getNumberOfPoints();
160 }
161
162 int getMaterialID() const
163 {
164 return process_data_.material_ids == nullptr
165 ? 0
166 : (*process_data_.material_ids)[element_.getID()];
167 }
168
170 std::function<std::span<double>(
172 MaterialStateVariables&)> const& get_values_span,
173 int const& n_components) const
174 {
178 get_values_span, n_components);
179 }
180
182 DisplacementDim>::MaterialStateVariables const&
183 getMaterialStateVariablesAt(unsigned integration_point) const
184 {
185 return *material_states_[integration_point].material_state_variables;
186 }
187
189 {
191
193 &Self::current_states_, &Self::output_data_);
194 }
195
196protected:
198
199 // Material state is special, because it contains both the current and the
200 // old state.
201 std::vector<MaterialStateData<DisplacementDim>> material_states_;
202 std::vector<typename ConstitutiveRelations::StatefulData<DisplacementDim>>
203 current_states_; // TODO maybe do not store but rather re-evaluate for
204 // state update
205 std::vector<
208 std::vector<typename ConstitutiveRelations::OutputData<DisplacementDim>>
210
217};
218
219} // namespace SmallDeformation
220} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
void setElementID(std::size_t element_id)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Eigen::Matrix< double, 3, 3 > kelvinVectorToTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
KelvinVectorType< DisplacementDim > tensorToKelvin(Eigen::Matrix< double, 3, 3 > const &m)
std::size_t reflectSetIPData(std::string_view const name, double const *values, std::vector< IPData > &ip_data_vector)
auto reflectWithoutName(Accessors &&... accessors)
ProcessLib::ConstitutiveRelations::PrevStateOf< StatefulData< DisplacementDim > > StatefulDataPrev
std::size_t setIntegrationPointDataMaterialStateVariables(double const *values, IntegrationPointDataVector &ip_data_vector, MemberType member, std::function< std::span< double >(MaterialStateVariables &)> get_values_span)
std::vector< double > getIntegrationPointDataMaterialStateVariables(IntegrationPointDataVector const &ip_data_vector, MemberType member, std::function< std::span< double >(MaterialStateVariables &)> get_values_span, int const n_components)
std::vector< double > getMaterialStateVariableInternalState(std::function< std::span< double >(typename MaterialLib::Solids::MechanicsBase< DisplacementDim >::MaterialStateVariables &)> const &get_values_span, int const &n_components) const
ConstitutiveRelations::ConstitutiveSetting< DisplacementDim > constitutive_setting
std::vector< typename ConstitutiveRelations::StatefulDataPrev< DisplacementDim > > prev_states_
std::size_t setIPDataInitialConditions(std::string_view name, double const *values, int const integration_order)
Returns number of read integration points.
std::vector< typename ConstitutiveRelations::StatefulData< DisplacementDim > > current_states_
std::vector< typename ConstitutiveRelations::OutputData< DisplacementDim > > output_data_
SmallDeformationLocalAssemblerInterface(MeshLib::Element const &e, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, SmallDeformationProcessData< DisplacementDim > &process_data)
void computeSecondaryVariableConcrete(double const, double const, Eigen::VectorXd const &, Eigen::VectorXd const &) override
MaterialLib::Solids::MechanicsBase< DisplacementDim >::MaterialStateVariables const & getMaterialStateVariablesAt(unsigned integration_point) const
MaterialLib::Solids::MechanicsBase< DisplacementDim > const & solid_material_