MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
linear_thermoelastic_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_linear_thermoelasticity_load_h__
21 #define __mast_linear_thermoelasticity_load_h__
22 
23 // MAST includes
25 
26 namespace MAST {
27 namespace Physics {
28 namespace Elasticity {
29 namespace LinearContinuum {
30 
31 
32 template <typename FEVarType,
33  typename TemperatureFieldType,
34  typename ExpansionCoeffType,
35  typename SectionPropertyType,
36  uint_t Dim,
37  typename ContextType>
39 
40 public:
41 
42  using scalar_t = typename FEVarType::scalar_t;
43  using basis_scalar_t = typename FEVarType::fe_shape_deriv_t::scalar_t;
44  using vector_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
45  using matrix_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
46  using fe_shape_deriv_t = typename FEVarType::fe_shape_deriv_t;
47  static const uint_t
49 
51  _property (nullptr),
52  _temperature (nullptr),
53  _alpha (nullptr),
54  _fe_var_data (nullptr)
55  { }
56 
57  virtual ~ThermoelasticLoad() { }
58 
59  inline void
60  set_section_property(const SectionPropertyType& p) {
61 
62  Assert0(!_property, "Property already initialized.");
63 
64  _property = &p;
65  }
66 
67  inline void set_temperature(const TemperatureFieldType& dt) { _temperature = &dt;}
68 
69  inline void set_coeff_thermal_expansion(const ExpansionCoeffType& a) { _alpha = &a;}
70 
71  inline void set_fe_var_data(const FEVarType& fe_data)
72  {
73  Assert0(!_fe_var_data, "FE data already initialized.");
74  _fe_var_data = &fe_data;
75  }
76 
77  inline uint_t n_dofs() const {
78 
79  Assert0(_fe_var_data, "FE data not initialized.");
80 
81  return Dim*_fe_var_data->get_fe_shape_data().n_basis();
82  }
83 
84  inline void compute(ContextType& c,
85  vector_t& res,
86  matrix_t* jac = nullptr) const {
87 
88  Assert0(_fe_var_data, "FE data not initialized.");
89  Assert0(_property, "Section property not initialized");
90  Assert0(_alpha, "Coefficient of thermal expansion");
91  Assert0(_temperature, "Temperature not initialized");
92 
93  const typename FEVarType::fe_shape_deriv_t
94  &fe = _fe_var_data->get_fe_shape_data();
95 
96  typename Eigen::Matrix<scalar_t, n_strain, 1>
97  dt_vec = Eigen::Matrix<scalar_t, n_strain, 1>::Zero(),
98  epsilon,
99  stress;
100  vector_t
101  vec = vector_t::Zero(Dim*fe.n_basis());
102 
103  for (uint_t i=0; i<Dim; i++) dt_vec(i) = 1.;
104 
105  typename SectionPropertyType::value_t
106  mat;
107 
109  Bxmat;
110  Bxmat.reinit(n_strain, Dim, fe.n_basis());
111 
112 
113  for (uint_t i=0; i<fe.n_q_points(); i++) {
114 
115  c.qp = i;
116  scalar_t
117  dt = _temperature->value(c),
118  alpha = _alpha->value(c);
119 
120  _property->value(c, mat);
122  <scalar_t, scalar_t, FEVarType, Dim>(*_fe_var_data, i, epsilon, Bxmat);
123  stress = mat * dt_vec;
124  Bxmat.vector_mult_transpose(vec, stress);
125  res -= (fe.detJxW(i) * dt * alpha) * vec;
126 
127  // nothing to be done for Jacobian due to linear term
128  // if (jac) { }
129  }
130  }
131 
132  template <typename ScalarFieldType>
133  inline void derivative(ContextType& c,
134  const ScalarFieldType& f,
135  vector_t& res,
136  matrix_t* jac = nullptr) const {
137 
138  Assert0(_fe_var_data, "FE data not initialized.");
139  Assert0(_property, "Section property not initialized");
140  Assert0(_temperature, "Temperature not initialized");
141 
142  const typename FEVarType::fe_shape_deriv_t
143  &fe = _fe_var_data->get_fe_shape_data();
144 
145  typename Eigen::Matrix<scalar_t, n_strain, 1>
146  dt_vec = Eigen::Matrix<scalar_t, n_strain, 1>::Zero(),
147  epsilon,
148  stress;
149  vector_t
150  vec = vector_t::Zero(Dim*fe.n_basis());
151 
152  for (uint_t i=0; i<Dim; i++) dt_vec(i) = 1.;
153 
154  typename SectionPropertyType::value_t
155  mat,
156  dmat;
157 
159  Bxmat;
160  Bxmat.reinit(n_strain, Dim, fe.n_basis());
161 
162  for (uint_t i=0; i<fe.n_q_points(); i++) {
163 
164  c.qp = i;
165 
167  <scalar_t, scalar_t, FEVarType, Dim>(*_fe_var_data, i, epsilon, Bxmat);
168 
169  // dC/dp dT
170  scalar_t
171  dt = _temperature->value(c),
172  dtdp = _temperature->derivative(c, f),
173  alpha = _alpha->value(c),
174  dalphadp = _alpha->derivative(c, f);
175 
176  _property->value(c, mat);
177  _property->derivative(c, f, dmat);
178 
179  stress = mat*dt_vec * (dalphadp*dt + alpha*dtdp) + dmat*dt_vec * alpha*dt;
180  Bxmat.vector_mult_transpose(vec, stress);
181  res -= fe.detJxW(i) * vec;
182 
183  // nothing to be done for Jacobian due to linear term
184  // if (jac) { }
185  }
186  }
187 
188 
189 private:
190 
191 
192  const SectionPropertyType *_property;
193  const TemperatureFieldType *_temperature;
194  const ExpansionCoeffType *_alpha;
195  const FEVarType *_fe_var_data;
196 };
197 
198 } // namespace LinearContinuum
199 } // namespace Elasticity
200 } // namespace Physics
201 } // namespace MAST
202 
203 #endif // __mast_linear_thermoelasticity_load_h__
void derivative(ContextType &c, const ScalarFieldType &f, vector_t &res, matrix_t *jac=nullptr) const
void vector_mult_transpose(T1 &res, const T2 &v) const
res = v^T * [this]
void compute(ContextType &c, vector_t &res, matrix_t *jac=nullptr) const
typename FEVarType::fe_shape_deriv_t::scalar_t basis_scalar_t
std::enable_if< Dim==2, void >::type strain(const FEVarType &fe_var, const uint_t qp, typename Eigen::Matrix< VarScalarType, 3, 1 > &epsilon, MAST::Numerics::FEMOperatorMatrix< NodalScalarType > &Bmat)
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
unsigned int uint_t
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...
typename Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > vector_t