MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
mindlin_plate_strain_energy.hpp
Go to the documentation of this file.
1 /*
2 * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3 * Copyright (C) 2013-2020 Manav Bhatia and MAST authors
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
20 #ifndef __mast_linear_mindlin_plate_strain_energy_h__
21 #define __mast_linear_mindlin_plate_strain_energy_h__
22 
23 // MAST includes
25 
26 namespace MAST {
27 namespace Physics {
28 namespace Elasticity {
29 namespace MindlinPlate {
30 
31 
32 template <typename FEVarType,
33  typename SectionPropertyType,
34  typename ContextType>
35 class StrainEnergy {
36 
37 public:
38 
39  using scalar_t = typename FEVarType::scalar_t;
40  using basis_scalar_t = typename FEVarType::fe_shape_deriv_t::scalar_t;
41  using vector_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
42  using matrix_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
43  using fe_shape_deriv_t = typename FEVarType::fe_shape_deriv_t;
44 
46  _property (nullptr),
47  _bending_fe_var_data (nullptr),
48  _shear_fe_var_data (nullptr)
49  { }
50 
51  virtual ~StrainEnergy() { }
52 
53  inline void
54  set_section_property(const SectionPropertyType& p) {
55 
56  Assert0(!_property, "Property already initialized.");
57 
58  _property = &p;
59  }
60 
61  inline void set_fe_var_data(const FEVarType& bending_fe_data,
62  const FEVarType& shear_fe_data) {
63 
65  "FE data already initialized.");
66  Assert2(bending_fe_data.n_components() == shear_fe_data.n_components(),
67  bending_fe_data.n_components(), shear_fe_data.n_components(),
68  "Bending and shear FE data must have same number of components");
69 
70  _bending_fe_var_data = &bending_fe_data;
71  _shear_fe_var_data = &shear_fe_data;
72  }
73 
74  inline uint_t n_dofs() const {
75 
76  Assert0(_bending_fe_var_data, "FE data not initialized.");
77 
78  return 3*_bending_fe_var_data->get_fe_shape_data().n_basis();
79  }
80 
81  inline void compute(ContextType& c,
82  vector_t& res,
83  matrix_t* jac = nullptr) const {
84 
86  "FE data not initialized.");
87  Assert0(_property, "Section property not initialized");
88 
89  // process the inplane strain components
90  {
91  const typename FEVarType::fe_shape_deriv_t
92  &fe = _bending_fe_var_data->get_fe_shape_data();
93 
94  typename Eigen::Matrix<scalar_t, 3, 1>
95  epsilon,
96  stress;
97  vector_t
98  vec = vector_t::Zero(3*fe.n_basis());
99 
100  typename SectionPropertyType::inplane_value_t
101  mat;
102 
103  matrix_t
104  mat1 = matrix_t::Zero(3, 3*fe.n_basis()),
105  mat2 = matrix_t::Zero(3*fe.n_basis(), 3*fe.n_basis());
106 
108  Bxmat;
109  Bxmat.reinit(3, 3, fe.n_basis());
110 
111 
112  for (uint_t i=0; i<fe.n_q_points(); i++) {
113 
114  c.qp = i;
115 
116  _property->inplane_value(c, mat);
118  <scalar_t, scalar_t, FEVarType>
119  (*_bending_fe_var_data, i, 1., epsilon, Bxmat);
120  stress = mat * epsilon;
121  Bxmat.vector_mult_transpose(vec, stress);
122  res += fe.detJxW(i) * vec;
123 
124  if (jac) {
125 
126  Bxmat.left_multiply(mat1, mat);
127  Bxmat.right_multiply_transpose(mat2, mat1);
128  (*jac) += fe.detJxW(i) * mat2;
129  }
130  }
131  }
132 
133  // process the transverse shear strain components
134  {
135  const typename FEVarType::fe_shape_deriv_t
136  &fe = _shear_fe_var_data->get_fe_shape_data();
137 
138  typename Eigen::Matrix<scalar_t, 2, 1>
139  epsilon,
140  stress;
141  vector_t
142  vec = vector_t::Zero(3*fe.n_basis());
143 
144  typename SectionPropertyType::shear_value_t
145  mat;
146 
147  matrix_t
148  mat1 = matrix_t::Zero(2, 3*fe.n_basis()),
149  mat2 = matrix_t::Zero(3*fe.n_basis(), 3*fe.n_basis());
150 
152  Bxmat;
153  Bxmat.reinit(2, 3, fe.n_basis());
154 
155 
156  for (uint_t i=0; i<fe.n_q_points(); i++) {
157 
158  c.qp = i;
159 
160  _property->shear_value(c, mat);
162  <scalar_t, scalar_t, FEVarType>
163  (*_shear_fe_var_data, i, epsilon, Bxmat);
164  stress = mat * epsilon;
165  Bxmat.vector_mult_transpose(vec, stress);
166  res += fe.detJxW(i) * vec;
167 
168  if (jac) {
169 
170  Bxmat.left_multiply(mat1, mat);
171  Bxmat.right_multiply_transpose(mat2, mat1);
172  (*jac) += fe.detJxW(i) * mat2;
173  }
174  }
175  }
176  }
177 
178  template <typename ScalarFieldType>
179  inline void derivative(ContextType& c,
180  const ScalarFieldType& f,
181  vector_t& res,
182  matrix_t* jac = nullptr) const {
183 
185  "FE data not initialized.");
186  Assert0(_property, "Section property not initialized");
187 
188  // process the inplane strain components
189  {
190  const typename FEVarType::fe_shape_deriv_t
191  &fe = _bending_fe_var_data->get_fe_shape_data();
192 
193  typename Eigen::Matrix<scalar_t, 3, 1>
194  epsilon,
195  stress;
196  vector_t
197  vec = vector_t::Zero(3*fe.n_basis());
198 
199  typename SectionPropertyType::inplane_value_t
200  mat;
201 
202  matrix_t
203  mat1 = matrix_t::Zero(3, 3*fe.n_basis()),
204  mat2 = matrix_t::Zero(3*fe.n_basis(), 3*fe.n_basis());
205 
207  Bxmat;
208  Bxmat.reinit(3, 3, fe.n_basis());
209 
210 
211  for (uint_t i=0; i<fe.n_q_points(); i++) {
212 
213  c.qp = i;
214 
215  _property->inplane_derivative(c, f, mat);
217  <scalar_t, scalar_t, FEVarType>
218  (*_bending_fe_var_data, i, 1., epsilon, Bxmat);
219  stress = mat * epsilon;
220  Bxmat.vector_mult_transpose(vec, stress);
221  res += fe.detJxW(i) * vec;
222 
223  if (jac) {
224 
225  Bxmat.left_multiply(mat1, mat);
226  Bxmat.right_multiply_transpose(mat2, mat1);
227  (*jac) += fe.detJxW(i) * mat2;
228  }
229  }
230  }
231 
232  // process the transverse shear strain components
233  {
234  const typename FEVarType::fe_shape_deriv_t
235  &fe = _shear_fe_var_data->get_fe_shape_data();
236 
237  typename Eigen::Matrix<scalar_t, 2, 1>
238  epsilon,
239  stress;
240  vector_t
241  vec = vector_t::Zero(3*fe.n_basis());
242 
243  typename SectionPropertyType::shear_value_t
244  mat;
245 
246  matrix_t
247  mat1 = matrix_t::Zero(2, 3*fe.n_basis()),
248  mat2 = matrix_t::Zero(3*fe.n_basis(), 3*fe.n_basis());
249 
251  Bxmat;
252  Bxmat.reinit(2, 3, fe.n_basis());
253 
254 
255  for (uint_t i=0; i<fe.n_q_points(); i++) {
256 
257  c.qp = i;
258 
259  _property->shear_derivative(c, f, mat);
261  <scalar_t, scalar_t, FEVarType>
262  (*_shear_fe_var_data, i, epsilon, Bxmat);
263  stress = mat * epsilon;
264  Bxmat.vector_mult_transpose(vec, stress);
265  res += fe.detJxW(i) * vec;
266 
267  if (jac) {
268 
269  Bxmat.left_multiply(mat1, mat);
270  Bxmat.right_multiply_transpose(mat2, mat1);
271  (*jac) += fe.detJxW(i) * mat2;
272  }
273  }
274  }
275  }
276 
277 
278 private:
279 
280 
281 
282  const SectionPropertyType *_property;
283  const FEVarType *_bending_fe_var_data;
284  const FEVarType *_shear_fe_var_data;
285 };
286 
287 } // namespace MindlinPlate
288 } // namespace Elasticity
289 } // namespace Physics
290 } // namespace MAST
291 
292 #endif // __mast_linear_mindlin_plate_strain_energy_h__
void compute(ContextType &c, vector_t &res, matrix_t *jac=nullptr) const
typename FEVarType::fe_shape_deriv_t::scalar_t basis_scalar_t
void derivative(ContextType &c, const ScalarFieldType &f, vector_t &res, matrix_t *jac=nullptr) const
void set_fe_var_data(const FEVarType &bending_fe_data, const FEVarType &shear_fe_data)
void inplane_strain(const FEVarType &fe_var, const uint_t qp, const VarScalarType z, typename Eigen::Matrix< VarScalarType, 3, 1 > &epsilon, MAST::Numerics::FEMOperatorMatrix< NodalScalarType > &Bmat)
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
typename Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > vector_t
unsigned int uint_t
#define Assert2(cond, v1, v2, msg)
Definition: exceptions.hpp:152
void transverse_shear_strain(const FEVarType &fe_var, const uint_t qp, typename Eigen::Matrix< VarScalarType, 2, 1 > &epsilon, MAST::Numerics::FEMOperatorMatrix< NodalScalarType > &Bmat)
typename Eigen::Matrix< scalar_t, Eigen::Dynamic, Eigen::Dynamic > matrix_t
void reinit(uint_t n_interpolated_vars, uint_t n_discrete_vars, uint_t n_discrete_dofs_per_var)
this initializes the operator for number of rows and variables, assuming that all variables has the s...