MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
surface_flux.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_conduction_surface_flux_load_h__
21 #define __mast_conduction_surface_flux_load_h__
22 
23 // MAST includes
25 #include <mast/base/exceptions.hpp>
26 
27 namespace MAST {
28 namespace Physics {
29 namespace Conduction {
30 
31 template <typename ScalarType,
32  typename SectionAreaType,
33  typename FluxFieldType,
34  typename ContextType,
35  uint_t Dim>
36 typename std::enable_if<Dim<3, ScalarType>::type
37 flux_multiplier(const FluxFieldType *f,
38  const SectionAreaType *s,
39  ContextType &c) {
40  Assert0(f, "Invalid pointer");
41  Assert0(s, "Invalid pointer");
42  return f->value(c) * s->value(c);
43 }
44 
45 template <typename ScalarType,
46  typename SectionAreaType,
47  typename FluxFieldType,
48  typename ContextType,
49  uint_t Dim>
50 typename std::enable_if<Dim==3, ScalarType>::type
51 flux_multiplier(const FluxFieldType *f,
52  const SectionAreaType *s,
53  ContextType &c) {
54  Assert0(f, "Invalid pointer");
55  Assert0(!s, "Pointer must be nullptr");
56  return f->value(c);
57 }
58 
59 template <typename ScalarType,
60  typename SectionAreaType,
61  typename FluxFieldType,
62  typename ContextType,
63  typename ScalarFieldType,
64  uint_t Dim>
65 typename std::enable_if<Dim<3, ScalarType>::type
66 flux_derivative_multiplier(const FluxFieldType *f,
67  const SectionAreaType *s,
68  ContextType &c,
69  const ScalarFieldType &p) {
70 
71  Assert0(f, "Invalid pointer");
72  Assert0(s, "Invalid pointer");
73  return (f->value(c) * s->derivative(c, p) +
74  s->value(c) * f->derivative(c, p));
75 }
76 
77 template <typename ScalarType,
78  typename SectionAreaType,
79  typename FluxFieldType,
80  typename ContextType,
81  typename ScalarFieldType,
82  uint_t Dim>
83 typename std::enable_if<Dim==3, ScalarType>::type
84 flux_derivative_multiplier(const FluxFieldType *f,
85  const SectionAreaType *s,
86  ContextType &c,
87  const ScalarFieldType &p) {
88 
89  Assert0(f, "Invalid pointer");
90  Assert0(!s, "Pointer must be nullptr");
91  return f->derivative(c, p);
92 }
93 
94 
111 template <typename FEVarType,
112  typename FluxFieldType,
113  typename SectionAreaType,
114  uint_t Dim,
115  typename ContextType>
117 
118 public:
119 
120  using scalar_t = typename FEVarType::scalar_t;
121  using basis_scalar_t = typename FEVarType::fe_shape_deriv_t::scalar_t;
122  using vector_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, 1>;
123  using matrix_t = typename Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic>;
124 
126  _section (nullptr),
127  _flux (nullptr),
128  _fe_var_data (nullptr)
129  { }
130 
131  virtual ~SurfaceFluxLoad() { }
132 
136  inline void set_section_area(const SectionAreaType& s) {
137 
138  Assert1(Dim < 3, Dim, "SectionAreaType only used for 1D and 2D elements");
139 
140  _section = &s;
141  }
142 
143  inline void set_flux(const FluxFieldType& f) { _flux = &f;}
144 
145  inline void set_fe_var_data(const FEVarType& fe) { _fe_var_data = &fe;}
146 
147  inline uint_t n_dofs() const {
148 
149  Assert0(_fe_var_data, "FE data not initialized.");
150 
151  return _fe_var_data->get_fe_shape_data().n_basis();
152  }
153 
161  inline void
162  compute(ContextType& c,
163  vector_t& res,
164  matrix_t* jac = nullptr) const {
165 
166  Assert0(_fe_var_data, "FE data not initialized.");
167  Assert0(Dim==3 || _section, "Section property not initialized");
168  Assert0(_flux, "Flux not initialized");
169 
170  const typename FEVarType::fe_shape_deriv_t
171  &fe = _fe_var_data->get_fe_shape_data();
172 
173  for (uint_t i=0; i<fe.n_q_points(); i++) {
174 
175  c.qp = i;
177  SectionAreaType,
178  FluxFieldType,
179  ContextType,
180  Dim>(_flux, _section, c);
181 
182  for (uint_t k=0; k<fe.n_basis(); k++)
183  res(k) -= fe.detJxW(i) * fe.phi(i, k) * p;
184  }
185  }
186 
187 
196  template <typename ScalarFieldType>
197  inline void derivative(ContextType& c,
198  const ScalarFieldType& f,
199  vector_t& res,
200  matrix_t* jac = nullptr) const {
201 
202  Assert0(_fe_var_data, "FE data not initialized.");
203  Assert0(Dim==3 || _section, "Section property not initialized");
204  Assert0(_flux, "Flux not initialized");
205 
206  const typename FEVarType::fe_shape_deriv_t
207  &fe = _fe_var_data->get_fe_shape_data();
208 
209  for (uint_t i=0; i<fe.n_q_points(); i++) {
210 
211  c.qp = i;
212  scalar_t p =
213  flux_derivative_multiplier<scalar_t,
214  SectionAreaType,
215  FluxFieldType,
216  ContextType,
217  ScalarFieldType,
218  Dim>(_flux, _section, c, f);
219 
220  for (uint_t k=0; k<fe.n_basis(); k++)
221  res(k) -= fe.detJxW(i) * fe.phi(i, k) * p;
222  }
223  }
224 
225 private:
226 
227  const SectionAreaType *_section;
228  const FluxFieldType *_flux;
229  const FEVarType *_fe_var_data;
230 };
231 
232 } // namespace Conduction
233 } // namespace Physics
234 } // namespace MAST
235 
236 
237 #endif // __mast_conduction_surface_flux_load_h__
This class implements the discrete evaluation of the surface heat flux kernel defined as where...
void set_fe_var_data(const FEVarType &fe)
typename FEVarType::scalar_t scalar_t
typename Eigen::Matrix< scalar_t, Eigen::Dynamic, Eigen::Dynamic > matrix_t
#define Assert1(cond, v1, msg)
Definition: exceptions.hpp:143
typename Eigen::Matrix< scalar_t, Eigen::Dynamic, 1 > vector_t
std::enable_if< Dim==3, ScalarType >::type flux_multiplier(const FluxFieldType *f, const SectionAreaType *s, ContextType &c)
void set_flux(const FluxFieldType &f)
void compute(ContextType &c, vector_t &res, matrix_t *jac=nullptr) const
Computes the residual of variational term and returns it in res.
void set_section_area(const SectionAreaType &s)
Provides the section area through the object 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...
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
unsigned int uint_t
typename FEVarType::fe_shape_deriv_t::scalar_t basis_scalar_t