MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
traction_load.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_traction_load_h__
21 #define __mast_traction_load_h__
22 
23 // MAST includes
25 #include <mast/base/exceptions.hpp>
26 
27 namespace MAST {
28 namespace Physics {
29 namespace Elasticity {
30 
31 template <typename TractionType, uint_t Dim, typename ContextType>
32 inline
33 typename std::enable_if<Dim == 1, void>::type
34 traction_value(ContextType &c,
35  const TractionType &t,
36  typename TractionType::value_t &v) {
37 
38  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
39 
40  v(0) = t.get_scalar_for_dim(0).value(c);
41 }
42 
43 
44 template <typename TractionType, uint_t Dim, typename ContextType>
45 inline
46 typename std::enable_if<Dim == 2, void>::type
47 traction_value(ContextType &c,
48  const TractionType &t,
49  typename TractionType::value_t &v) {
50 
51  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
52 
53  v(0) = t.get_scalar_for_dim(0).value(c);
54  v(1) = t.get_scalar_for_dim(1).value(c);
55 }
56 
57 
58 template <typename TractionType, uint_t Dim, typename ContextType>
59 inline
60 typename std::enable_if<Dim == 3, void>::type
61 traction_value(ContextType &c,
62  const TractionType &t,
63  typename TractionType::value_t &v) {
64 
65  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
66 
67  v(0) = t.get_scalar_for_dim(0).value(c);
68  v(1) = t.get_scalar_for_dim(1).value(c);
69  v(2) = t.get_scalar_for_dim(2).value(c);
70 }
71 
72 
73 template <typename TractionType,
74  uint_t Dim,
75  typename ContextType,
76  typename ScalarFieldType>
77 inline
78 typename std::enable_if<Dim == 1, void>::type
79 traction_derivative(const ScalarFieldType &f,
80  ContextType &c,
81  const TractionType &t,
82  typename TractionType::value_t &v) {
83 
84  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
85 
86  v(0) = t.get_scalar_for_dim(0).derivative(c, f);
87 }
88 
89 
90 template <typename TractionType,
91  uint_t Dim,
92  typename ContextType,
93  typename ScalarFieldType>
94 inline
95 typename std::enable_if<Dim == 2, void>::type
96 traction_derivative(const ScalarFieldType &f,
97  ContextType &c,
98  const TractionType &t,
99  typename TractionType::value_t &v) {
100 
101  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
102 
103  v(0) = t.get_scalar_for_dim(0).derivative(c, f);
104  v(1) = t.get_scalar_for_dim(1).derivative(c, f);
105 }
106 
107 
108 template <typename TractionType,
109  uint_t Dim,
110  typename ContextType,
111  typename ScalarFieldType>
112 inline
113 typename std::enable_if<Dim == 3, void>::type
114 traction_derivative(const ScalarFieldType &f,
115  ContextType &c,
116  const TractionType &t,
117  typename TractionType::value_t &v) {
118 
119  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
120 
121  v(0) = t.get_scalar_for_dim(0).derivative(c, f);
122  v(1) = t.get_scalar_for_dim(1).derivative(c, f);
123  v(2) = t.get_scalar_for_dim(2).derivative(c, f);
124 }
125 
126 
133 template <typename TractionScalarType, uint_t Dim, typename ContextType>
134 class Traction {
135 
136 public:
137 
138  using scalar_t = typename TractionScalarType::scalar_t;
139  using value_t = Eigen::Matrix<scalar_t, Dim, 1>;
141 
142  Traction(const TractionScalarType *t0,
143  const TractionScalarType *t1 = nullptr,
144  const TractionScalarType *t2 = nullptr):
145  _t ({t0, t1, t2}) {
146 
147  Assert1(Dim>1 || t1 == nullptr,
148  Dim, "t1 should be nullptr for 1D traction");
149  Assert1(Dim>2 || t2 == nullptr,
150  Dim, "t2 should be nullptr for 2D traction");
151  }
152 
153  inline const TractionScalarType& get_scalar_for_dim(uint_t i) const {
154 
155  Assert2(i < Dim, i, Dim, "Invalid dimension index");
156  return *_t[i];
157  }
158 
159 
160  inline void value(ContextType& c, value_t& v) const {
161 
162  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
163 
164  traction_value<traction_t, Dim, ContextType>(c, *this, v);
165  }
166 
167  template <typename ScalarFieldType>
168  inline void
169  derivative(const ScalarFieldType& f, ContextType& c, value_t& v) const {
170 
171  Assert2(v.size() == Dim, v.size(), Dim, "Incorrect size");
172 
173  traction_derivative<traction_t, Dim, ContextType, ScalarFieldType>
174  (f, c, *this, v);
175  }
176 
177 
178 protected:
179 
180  std::vector<const TractionScalarType*> _t;
181 };
182 
183 
199 template <typename FEVarType,
200  typename TractionFieldType,
201  typename SectionAreaType,
202  uint_t Dim,
203  typename ContextType>
205 
206 public:
207 
208  using scalar_t = typename FEVarType::scalar_t;
209  using basis_scalar_t = typename FEVarType::fe_shape_deriv_t::scalar_t;
210  using vector_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
211  using matrix_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
212 
214  _section (nullptr),
215  _traction (nullptr),
216  _fe_var_data (nullptr)
217  { }
218 
219  virtual ~SurfaceTractionLoad() { }
220 
221  inline void set_section_area(const SectionAreaType& s) { _section = &s;}
222 
223  inline void set_traction(const TractionFieldType& t) { _traction = &t;}
224 
225  inline void set_fe_var_data(const FEVarType& fe) { _fe_var_data = &fe;}
226 
227  inline uint_t n_dofs() const {
228 
229  Assert0(_fe_var_data, "FE data not initialized.");
230 
231  return Dim*_fe_var_data->get_fe_shape_data().n_basis();
232  }
233 
241  inline void compute(ContextType& c,
242  vector_t& res,
243  matrix_t* jac = nullptr) const {
244 
245  Assert0(_fe_var_data, "FE data not initialized.");
246  Assert0(_section, "Section property not initialized");
247  Assert0(_traction, "Traction not initialized");
248 
249  const typename FEVarType::fe_shape_deriv_t
250  &fe = _fe_var_data->get_fe_shape_data();
251 
252  typename TractionFieldType::value_t
253  trac;
254 
255  for (uint_t i=0; i<fe.n_q_points(); i++) {
256 
257  c.qp = i;
258 
259  _traction->value(c, trac);
260 
261  trac *= _section->value(c);
262 
263  for (uint_t j=0; j<Dim; j++) {
264 
265  // j-th component of normal vector at ith quadrature point
266  scalar_t nj = fe.normal(i, j);
267 
268  if (nj != 0.) {
269  for (uint_t k=0; k<fe.n_basis(); k++)
270  res(j*fe.n_basis() + k) -= fe.detJxW(i) * fe.phi(i, k) * trac(j) * nj;
271  }
272  }
273  }
274  }
275 
276 
285  template <typename ScalarFieldType>
286  inline void derivative(ContextType& c,
287  const ScalarFieldType& f,
288  vector_t& res,
289  matrix_t* jac = nullptr) const {
290 
291  Assert0(_fe_var_data, "FE data not initialized.");
292  Assert0(_section, "Section property not initialized");
293  Assert0(_traction, "Traction not initialized");
294 
295  const typename FEVarType::fe_shape_deriv_t
296  &fe = _fe_var_data->get_fe_shape_data();
297 
298  typename TractionFieldType::value_t
299  trac,
300  dtrac;
301 
302  for (uint_t i=0; i<fe.n_q_points(); i++) {
303 
304  c.qp = i;
305 
306  _traction->value(c, trac);
307  _traction->derivative(f, c, dtrac);
308 
309  dtrac *= _section->value(c);
310  trac *= _section->derivative(c, f);
311  trac += dtrac;
312 
313  for (uint_t j=0; j<Dim; j++) {
314 
315  // j-th component of normal vector at ith quadrature point
316  scalar_t nj = fe.normal(i, j);
317 
318  if (nj != 0.) {
319  for (uint_t k=0; k<fe.n_basis(); k++)
320  res(j*fe.n_basis() + k) -= fe.detJxW(i) * fe.phi(i, k) * trac(j) * nj;
321  }
322  }
323  }
324  }
325 
326 private:
327 
328  const SectionAreaType *_section;
329  const TractionFieldType *_traction;
330  const FEVarType *_fe_var_data;
331 };
332 
333 
334 } // namespace Elasticity
335 } // namespace Physics
336 } // namespace MAST
337 
338 
339 #endif // __mast_traction_load_h__
void value(ContextType &c, value_t &v) const
const TractionScalarType & get_scalar_for_dim(uint_t i) const
typename Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > vector_t
#define Assert1(cond, v1, msg)
Definition: exceptions.hpp:143
std::enable_if< Dim==1, void >::type traction_derivative(const ScalarFieldType &f, ContextType &c, const TractionType &t, typename TractionType::value_t &v)
Traction(const TractionScalarType *t0, const TractionScalarType *t1=nullptr, const TractionScalarType *t2=nullptr)
void set_section_area(const SectionAreaType &s)
void derivative(ContextType &c, const ScalarFieldType &f, vector_t &res, matrix_t *jac=nullptr) const
Computes the derivative of residual of variational term with respect to parameter and returns it in...
typename FEVarType::fe_shape_deriv_t::scalar_t basis_scalar_t
std::enable_if< Dim==1, void >::type traction_value(ContextType &c, const TractionType &t, typename TractionType::value_t &v)
void compute(ContextType &c, vector_t &res, matrix_t *jac=nullptr) const
Computes the residual of variational term and returns it in res.
Eigen::Matrix< scalar_t, Dim, 1 > value_t
typename TractionScalarType::scalar_t scalar_t
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
unsigned int uint_t
#define Assert2(cond, v1, v2, msg)
Definition: exceptions.hpp:152
void set_traction(const TractionFieldType &t)
typename Eigen::Matrix< scalar_t, Eigen::Dynamic, Eigen::Dynamic > matrix_t
This class implements the discrete evaluation of the surface traction kernel defined as where...
std::vector< const TractionScalarType * > _t
void derivative(const ScalarFieldType &f, ContextType &c, value_t &v) const
This class defines a data structure that can be used to define a parameterized surface traction vecto...