MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
fe_var_data.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_fe_var_data_h__
21 #define __mast_fe_var_data_h__
22 
23 // MAST includes
25 #include <mast/base/exceptions.hpp>
26 
27 
28 namespace MAST {
29 namespace FEBasis {
30 
31 template <typename BasisScalarType,
32  typename NodalScalarType,
33  typename SolScalarType,
34  uint_t NComponents,
35  uint_t Dim,
36  typename ContextType,
37  typename FEBasisDerivativeType>
38 class FEVarData {
39 
40 public:
41 
42  using fe_shape_deriv_t = FEBasisDerivativeType;
44  using sol_vec_view_t = Eigen::Map<const typename Eigen::Matrix<scalar_t, NComponents, 1>>;
45 
47  _compute_du_dx (false),
48  _fe (nullptr)
49  {}
50  virtual ~FEVarData() {}
51 
52  template <typename AccessorType>
53  inline void init(const ContextType& c,
54  const AccessorType& coeffs) {
55 
56  _init_coefficients(c, coeffs);
57  _init_variables(c);
58  }
59 
60  inline void clear_coeffs_and_vars() {
61 
62  _coeff_vec.setZero();
63 
64  _u.setZero();
65  _du_dx.setZero();
66  }
67 
68  inline void set_compute_du_dx(bool f) { _compute_du_dx = f;}
69 
70  inline void set_fe_shape_data(const FEBasisDerivativeType& fe) {
71 
72  Assert0(!_fe, "FE pointer already initialized.");
73  _fe = &fe;
74  }
75 
76  inline const FEBasisDerivativeType& get_fe_shape_data() const {
77 
78  Assert0(_fe, "FE pointer not initialized.");
79  return *_fe;
80  }
81 
82  inline uint_t n_components() const { return NComponents;}
83 
84  inline uint_t n_q_points() const {
85 
86  Assert0(_fe, "FE pointer not initialized");
87  return _fe->n_q_points();
88  }
89 
90  inline scalar_t u(uint_t qp, uint_t comp) const {
91 
92  Assert0(_coeff_vec.size(), "Object not initialized");
93  Assert2(comp <= NComponents,
94  comp, NComponents,
95  "Invalid component index");
96 
97  return _u(comp, qp);
98  }
99 
100  inline scalar_t du_dx(uint_t qp, uint_t comp, uint_t x_i) const
101  {
102  Assert0(_compute_du_dx, "Object not initialized with du/dx");
103  Assert0(_coeff_vec.size(), "Object not initialized");
104  Assert2(comp <= NComponents,
105  comp, NComponents,
106  "Invalid component index");
107 
108  return _du_dx(x_i*NComponents+comp, qp);
109  }
110 
111 protected:
112 
113  template <typename AccessorType>
114  inline void _init_coefficients(const ContextType& c,
115  const AccessorType& coeffs) {
116 
117  uint_t
118  n_coeffs = coeffs.size();
119 
120  Assert0(_fe, "FE pointer not initialized");
121  Assert2(n_coeffs == _fe->n_basis() * NComponents,
122  n_coeffs, _fe->n_basis() * NComponents,
123  "Incompatible dimensions of coefficient vector");
124 
125  _coeff_vec = Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>::Zero(n_coeffs);
126 
127  for (uint_t i=0; i<n_coeffs; i++)
128  _coeff_vec(i) = coeffs(i);
129  }
130 
131 
132  inline void _init_variables(const ContextType& c) {
133 
134  Assert0(_fe, "FE pointer not initialized");
135 
136  uint_t
137  n_qp = _fe->n_q_points(),
138  n_basis = _fe->n_basis();
139 
140  Assert2(_coeff_vec.size() == n_basis*NComponents,
141  _coeff_vec.size(), n_basis*NComponents,
142  "Coefficients not initialized");
143 
144  _u = Eigen::Matrix<scalar_t, NComponents, Eigen::Dynamic>::Zero(NComponents, n_qp);
145 
146  // now, initialize the solution value and derivatives.
147  for (uint_t i=0; i<n_qp; i++)
148  for (uint_t j=0; j<NComponents; j++)
149  for (uint_t k=0; k<n_basis; k++)
150  _u(j, i) += _fe->phi(i, k) * _coeff_vec(j*n_basis+k);
151 
152  if (_compute_du_dx) {
153 
154  _du_dx = Eigen::Matrix<scalar_t, NComponents*Dim, Eigen::Dynamic>::Zero(NComponents*Dim, n_qp);
155 
156  for (uint_t i=0; i<n_qp; i++)
157  for (uint_t j=0; j<NComponents; j++)
158  for (uint_t l=0; l<Dim; l++)
159  for (uint_t k=0; k<n_basis; k++)
160  _du_dx(NComponents*l+j, i) += _fe->dphi_dx(i, k, l) * _coeff_vec(j*n_basis+k);
161  }
162  else
163  _du_dx.setZero();
164  }
165 
166 
167  template <typename VecType, typename V=SolScalarType>
168  inline
171 
172  Assert2(i <= v.size(), i, v.size(), "Invalid vector index");
173 
174  v(i) += complex_t(0., ComplexStepDelta);
175  }
176 
178  const FEBasisDerivativeType *_fe;
179  Eigen::Matrix<scalar_t, NComponents, Eigen::Dynamic> _u;
180  Eigen::Matrix<scalar_t, NComponents*Dim, Eigen::Dynamic> _du_dx;
181  Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> _coeff_vec;
182 };
183 
184 
185 } // namespace FEBasis
186 } // namespace MAST
187 
188 #endif // __mast_fe_var_data_h__
const FEBasisDerivativeType * _fe
const FEBasisDerivativeType & get_fe_shape_data() const
Definition: fe_var_data.hpp:76
FEBasisDerivativeType fe_shape_deriv_t
Definition: fe_var_data.hpp:42
Eigen::Map< const typename Eigen::Matrix< scalar_t, NComponents, 1 > > sol_vec_view_t
Definition: fe_var_data.hpp:44
uint_t n_q_points() const
Definition: fe_var_data.hpp:84
void _init_variables(const ContextType &c)
Eigen::Matrix< scalar_t, NComponents *Dim, Eigen::Dynamic > _du_dx
std::enable_if< std::is_same< V, complex_t >::value, void >::type _add_complex_perturbation(VecType &v, uint_t i)
void _init_coefficients(const ContextType &c, const AccessorType &coeffs)
uint_t n_components() const
Definition: fe_var_data.hpp:82
std::complex< real_t > complex_t
std::enable_if< Dim< 3, ScalarType >::typesource_load_multiplier(const SourceLoadFieldType *f, const SectionAreaType *s, ContextType &c) { Assert0(f, "Invalid pointer");Assert0(s, "Invalid pointer");return f-> value(c) *s -> value(c)
void set_fe_shape_data(const FEBasisDerivativeType &fe)
Definition: fe_var_data.hpp:70
#define ComplexStepDelta
Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > _coeff_vec
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
unsigned int uint_t
#define Assert2(cond, v1, v2, msg)
Definition: exceptions.hpp:152
Eigen::Matrix< scalar_t, NComponents, Eigen::Dynamic > _u
scalar_t du_dx(uint_t qp, uint_t comp, uint_t x_i) const
scalar_t u(uint_t qp, uint_t comp) const
Definition: fe_var_data.hpp:90
void init(const ContextType &c, const AccessorType &coeffs)
Definition: fe_var_data.hpp:53
void set_compute_du_dx(bool f)
Definition: fe_var_data.hpp:68
typename MAST::DeducedScalarType< NodalScalarType, SolScalarType >::type scalar_t
Definition: fe_var_data.hpp:43