OGS
SmallDeformationLocalAssemblerMatrix-impl.h
Go to the documentation of this file.
1 
11 #pragma once
12 
13 #include <Eigen/Eigen>
14 #include <valarray>
15 #include <vector>
16 
26 #include "SecondaryData.h"
29 
30 namespace ProcessLib
31 {
32 namespace LIE
33 {
34 namespace SmallDeformation
35 {
36 template <typename ShapeFunction, typename IntegrationMethod,
37  int DisplacementDim>
38 SmallDeformationLocalAssemblerMatrix<ShapeFunction, IntegrationMethod,
39  DisplacementDim>::
40  SmallDeformationLocalAssemblerMatrix(
41  MeshLib::Element const& e,
42  std::size_t const /*local_matrix_size*/,
43  bool const is_axially_symmetric,
44  unsigned const integration_order,
46  : _process_data(process_data),
47  _integration_method(integration_order),
48  _element(e),
49  _is_axially_symmetric(is_axially_symmetric)
50 {
51  unsigned const n_integration_points =
52  _integration_method.getNumberOfPoints();
53 
54  _ip_data.reserve(n_integration_points);
55  _secondary_data.N.resize(n_integration_points);
56 
57  auto const shape_matrices =
59  DisplacementDim>(e, is_axially_symmetric,
61 
63  _process_data.solid_materials, _process_data.material_ids, e.getID());
64 
65  for (unsigned ip = 0; ip < n_integration_points; ip++)
66  {
67  _ip_data.emplace_back(solid_material);
68  auto& ip_data = _ip_data[ip];
69  auto const& sm = shape_matrices[ip];
70  ip_data.N = sm.N;
71  ip_data.dNdx = sm.dNdx;
72  ip_data.integration_weight =
73  _integration_method.getWeightedPoint(ip).getWeight() *
74  sm.integralMeasure * sm.detJ;
75 
76  // Initialize current time step values
77  static const int kelvin_vector_size =
79  ip_data._sigma.setZero(kelvin_vector_size);
80  ip_data._eps.setZero(kelvin_vector_size);
81 
82  // Previous time step values are not initialized and are set later.
83  ip_data._sigma_prev.resize(kelvin_vector_size);
84  ip_data._eps_prev.resize(kelvin_vector_size);
85 
86  ip_data._C.resize(kelvin_vector_size, kelvin_vector_size);
87 
88  _secondary_data.N[ip] = sm.N;
89  }
90 }
91 
92 template <typename ShapeFunction, typename IntegrationMethod,
93  int DisplacementDim>
94 void SmallDeformationLocalAssemblerMatrix<ShapeFunction, IntegrationMethod,
95  DisplacementDim>::
96  assembleWithJacobian(double const t, double const dt,
97  std::vector<double> const& local_x,
98  std::vector<double> const& /*local_xdot*/,
99  const double /*dxdot_dx*/, const double /*dx_dx*/,
100  std::vector<double>& /*local_M_data*/,
101  std::vector<double>& /*local_K_data*/,
102  std::vector<double>& local_b_data,
103  std::vector<double>& local_Jac_data)
104 {
105  assert(_element.getDimension() == DisplacementDim);
106 
107  auto const local_matrix_size = local_x.size();
108 
109  auto local_Jac = MathLib::createZeroedMatrix<StiffnessMatrixType>(
110  local_Jac_data, local_matrix_size, local_matrix_size);
111 
112  auto local_b = MathLib::createZeroedVector<NodalDisplacementVectorType>(
113  local_b_data, local_matrix_size);
114 
115  unsigned const n_integration_points =
116  _integration_method.getNumberOfPoints();
117 
118  MPL::VariableArray variables;
119  MPL::VariableArray variables_prev;
121  x_position.setElementID(_element.getID());
122 
123  for (unsigned ip = 0; ip < n_integration_points; ip++)
124  {
125  x_position.setIntegrationPoint(ip);
126  auto const& w = _ip_data[ip].integration_weight;
127 
128  auto const& N = _ip_data[ip].N;
129  auto const& dNdx = _ip_data[ip].dNdx;
130  auto const x_coord =
131  NumLib::interpolateXCoordinate<ShapeFunction, ShapeMatricesType>(
132  _element, N);
133  auto const B =
134  LinearBMatrix::computeBMatrix<DisplacementDim,
135  ShapeFunction::NPOINTS,
136  typename BMatricesType::BMatrixType>(
137  dNdx, N, x_coord, _is_axially_symmetric);
138 
139  auto const& eps_prev = _ip_data[ip]._eps_prev;
140  auto const& sigma_prev = _ip_data[ip]._sigma_prev;
141 
142  auto& eps = _ip_data[ip]._eps;
143  auto& sigma = _ip_data[ip]._sigma;
144  auto& state = _ip_data[ip]._material_state_variables;
145 
146  eps.noalias() =
147  B * Eigen::Map<typename BMatricesType::NodalForceVectorType const>(
148  local_x.data(), ShapeFunction::NPOINTS * DisplacementDim);
149 
150  variables[static_cast<int>(
153  eps);
154 
155  variables_prev[static_cast<int>(MaterialPropertyLib::Variable::stress)]
157  sigma_prev);
158  variables_prev[static_cast<int>(
161  eps_prev);
162  variables_prev[static_cast<int>(
164  .emplace<double>(_process_data._reference_temperature);
165 
166  auto&& solution = _ip_data[ip]._solid_material.integrateStress(
167  variables_prev, variables, t, x_position, dt, *state);
168 
169  if (!solution)
170  {
171  OGS_FATAL("Computation of local constitutive relation failed.");
172  }
173 
175  std::tie(sigma, state, C) = std::move(*solution);
176 
177  local_b.noalias() -= B.transpose() * sigma * w;
178  local_Jac.noalias() += B.transpose() * C * B * w;
179  }
180 }
181 
182 template <typename ShapeFunction, typename IntegrationMethod,
183  int DisplacementDim>
184 void SmallDeformationLocalAssemblerMatrix<ShapeFunction, IntegrationMethod,
185  DisplacementDim>::
186  computeSecondaryVariableConcreteWithVector(
187  double const /*t*/, Eigen::VectorXd const& /*local_x*/)
188 {
189  // Compute average value per element
190  const int n = DisplacementDim == 2 ? 4 : 6;
191  Eigen::VectorXd ele_stress = Eigen::VectorXd::Zero(n);
192  Eigen::VectorXd ele_strain = Eigen::VectorXd::Zero(n);
193 
194  unsigned const n_integration_points =
195  _integration_method.getNumberOfPoints();
196  for (unsigned ip = 0; ip < n_integration_points; ip++)
197  {
198  auto& ip_data = _ip_data[ip];
199 
200  ele_stress += ip_data._sigma;
201  ele_strain += ip_data._eps;
202  }
203  ele_stress /= n_integration_points;
204  ele_strain /= n_integration_points;
205 
206  (*_process_data._mesh_prop_stress_xx)[_element.getID()] = ele_stress[0];
207  (*_process_data._mesh_prop_stress_yy)[_element.getID()] = ele_stress[1];
208  (*_process_data._mesh_prop_stress_zz)[_element.getID()] = ele_stress[2];
209  (*_process_data._mesh_prop_stress_xy)[_element.getID()] = ele_stress[3];
210  if (DisplacementDim == 3)
211  {
212  (*_process_data._mesh_prop_stress_yz)[_element.getID()] = ele_stress[4];
213  (*_process_data._mesh_prop_stress_xz)[_element.getID()] = ele_stress[5];
214  }
215 
216  (*_process_data._mesh_prop_strain_xx)[_element.getID()] = ele_strain[0];
217  (*_process_data._mesh_prop_strain_yy)[_element.getID()] = ele_strain[1];
218  (*_process_data._mesh_prop_strain_zz)[_element.getID()] = ele_strain[2];
219  (*_process_data._mesh_prop_strain_xy)[_element.getID()] = ele_strain[3];
220  if (DisplacementDim == 3)
221  {
222  (*_process_data._mesh_prop_strain_yz)[_element.getID()] = ele_strain[4];
223  (*_process_data._mesh_prop_strain_xz)[_element.getID()] = ele_strain[5];
224  }
225 }
226 
227 } // namespace SmallDeformation
228 } // namespace LIE
229 } // namespace ProcessLib
#define OGS_FATAL(...)
Definition: Error.h:26
virtual std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:82
void setElementID(std::size_t element_id)
void setIntegrationPoint(unsigned integration_point)
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
Definition: BMatrixPolicy.h:55
std::vector< IntegrationPointDataMatrix< ShapeMatricesType, BMatricesType, DisplacementDim >, Eigen::aligned_allocator< IntegrationPointDataMatrix< ShapeMatricesType, BMatricesType, DisplacementDim > > > _ip_data
MechanicsBase< DisplacementDim > & selectSolidConstitutiveRelation(std::map< int, std::unique_ptr< MechanicsBase< DisplacementDim >>> const &constitutive_relations, MeshLib::PropertyVector< int > const *const material_ids, std::size_t const element_id)
std::array< VariableType, static_cast< int >(Variable::number_of_variables)> VariableArray
Definition: VariableType.h:108
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Definition: KelvinVector.h:48
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Definition: KelvinVector.h:23
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType
Definition: KelvinVector.h:56
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
BMatrixType computeBMatrix(DNDX_Type const &dNdx, N_Type const &N, const double radius, const bool is_axially_symmetric)
Fills a B-matrix based on given shape function dN/dx values.
Definition: LinearBMatrix.h:42
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N
Definition: SecondaryData.h:28