OGS
TESLocalAssemblerInner-impl.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 
18 
20 #include "TESOGS5MaterialModels.h"
21 #include "TESReactionAdaptor.h"
22 
23 namespace ProcessLib
24 {
25 namespace TES
26 {
27 template <typename Traits>
29  const AssemblyParams& ap, const unsigned num_int_pts,
30  const unsigned dimension)
31  : _d{ap, num_int_pts, dimension}
32 {
33 }
34 
35 template <typename Traits>
37  const unsigned int_pt)
38 {
39  // TODO: Dalton's law property
41  _d.vapour_mass_fraction, _d.ap.M_react, _d.ap.M_inert);
43 
44  const double M_pp = _d.ap.poro / _d.p * _d.rho_GR;
45  const double M_pT = -_d.ap.poro / _d.T * _d.rho_GR;
46  const double M_px = (_d.ap.M_react - _d.ap.M_inert) * _d.p / (R * _d.T) *
47  dxn_dxm * _d.ap.poro;
48 
49  const double M_Tp = -_d.ap.poro;
50  const double M_TT =
51  _d.ap.poro * _d.rho_GR * _d.ap.cpG // TODO: vapour heat capacity
52  +
53  (1.0 - _d.ap.poro) * _d.solid_density[int_pt] *
54  _d.ap.cpS; // TODO: adsorbate heat capacity
55  const double M_Tx = 0.0;
56 
57  const double M_xp = 0.0;
58  const double M_xT = 0.0;
59  const double M_xx = _d.ap.poro * _d.rho_GR;
60 
61  Eigen::Matrix3d M;
62  M << M_pp, M_pT, M_px, M_Tp, M_TT, M_Tx, M_xp, M_xT, M_xx;
63 
64  return M;
65 }
66 
67 template <typename Traits>
68 typename Traits::LaplaceMatrix
70  const unsigned dim)
71 {
72  const double eta_GR = fluid_viscosity(_d.p, _d.T, _d.vapour_mass_fraction);
73 
74  const double lambda_F =
75  fluid_heat_conductivity(_d.p, _d.T, _d.vapour_mass_fraction);
76  const double lambda_S = _d.ap.solid_heat_cond;
77 
78  using Mat = typename Traits::MatrixDimDim;
79 
80  typename Traits::LaplaceMatrix L =
81  Traits::LaplaceMatrix::Zero(dim * NODAL_DOF, dim * NODAL_DOF);
82 
83  // TODO: k_rel
84  // L_pp
85  Traits::blockDimDim(L, 0, 0, dim, dim) =
86  Traits::blockDimDim(_d.ap.solid_perm_tensor, 0, 0, dim, dim) *
87  _d.rho_GR / eta_GR;
88 
89  // TODO: add zeolite part
90  // L_TT
91  Traits::blockDimDim(L, dim, dim, dim, dim) =
92  Mat::Identity(dim, dim) *
93  (_d.ap.poro * lambda_F + (1.0 - _d.ap.poro) * lambda_S);
94 
95  // L_xx
96  Traits::blockDimDim(L, 2 * dim, 2 * dim, dim, dim) =
97  Mat::Identity(dim, dim) * (_d.ap.tortuosity * _d.ap.poro * _d.rho_GR *
98  _d.ap.diffusion_coefficient_component);
99 
100  return L;
101 }
102 
103 template <typename Traits>
105  const unsigned /*int_pt*/)
106 {
107  const double A_pp = 0.0;
108  const double A_pT = 0.0;
109 
110  const double A_px = 0.0;
111 
112  const double A_Tp = 0.0;
113 
114  const double A_TT = _d.rho_GR * _d.ap.cpG; // porosity?
115  const double A_Tx = 0.0;
116 
117  const double A_xp = 0.0;
118  const double A_xT = 0.0;
119  const double A_xx = _d.rho_GR; // porosity?
120 
121  Eigen::Matrix3d A;
122  A << A_pp, A_pT, A_px, A_Tp, A_TT, A_Tx, A_xp, A_xT, A_xx;
123 
124  return A;
125 }
126 
127 template <typename Traits>
129  const unsigned /*int_pt*/)
130 {
131  const double C_pp = 0.0;
132  const double C_pT = 0.0;
133 
134  const double C_px = 0.0;
135 
136  const double C_Tp = 0.0;
137 
138  const double C_TT = 0.0;
139  const double C_Tx = 0.0;
140 
141  const double C_xp = 0.0;
142  const double C_xT = 0.0;
143  const double C_xx = (_d.ap.poro - 1.0) * _d.qR;
144 
145  Eigen::Matrix3d C;
146  C << C_pp, C_pT, C_px, C_Tp, C_TT, C_Tx, C_xp, C_xT, C_xx;
147 
148  return C;
149 }
150 
151 template <typename Traits>
153  const unsigned int_pt)
154 {
155  const double reaction_enthalpy =
156  _d.ap.react_sys->getEnthalpy(_d.p_V, _d.T, _d.ap.M_react);
157 
158  const double rhs_p =
159  (_d.ap.poro - 1.0) * _d.qR; // TODO [CL] body force term
160 
161  const double rhs_T =
162  _d.rho_GR * _d.ap.poro * _d.ap.fluid_specific_heat_source +
163  (1.0 - _d.ap.poro) * _d.qR * reaction_enthalpy +
164  _d.solid_density[int_pt] * (1.0 - _d.ap.poro) *
165  _d.ap.solid_specific_heat_source;
166  // TODO [CL] momentum production term
167 
168  const double rhs_x =
169  (_d.ap.poro - 1.0) * _d.qR; // TODO [CL] what if x < 0.0
170 
171  Eigen::Vector3d rhs;
172  rhs << rhs_p, rhs_T, rhs_x;
173 
174  return rhs;
175 }
176 
177 template <typename Traits>
179 {
180  auto const& rate = _d.reaction_adaptor->initReaction(int_pt);
181  _d.qR = rate.reaction_rate;
182  _d.reaction_rate[int_pt] = rate.reaction_rate;
183  _d.solid_density[int_pt] = rate.solid_density;
184 }
185 
186 template <typename Traits>
188  const unsigned int_pt,
189  const std::vector<double>& localX,
190  typename Traits::ShapeMatrices const& sm)
191 {
192 #ifndef NDEBUG
193  // fill local data with garbage to aid in debugging
194  _d.p = _d.T = _d.vapour_mass_fraction = _d.p_V = _d.rho_GR = _d.qR =
195  std::numeric_limits<double>::quiet_NaN();
196 #endif
197 
198  NumLib::shapeFunctionInterpolate(localX, sm.N, _d.p, _d.T,
199  _d.vapour_mass_fraction);
200 
201  // pre-compute certain properties
203  _d.vapour_mass_fraction, _d.ap.M_react, _d.ap.M_inert);
204 
205  initReaction(int_pt);
206 
207  assert(_d.p > 0.0);
208  assert(_d.T > 0.0);
209  assert(0.0 <= _d.vapour_mass_fraction && _d.vapour_mass_fraction <= 1.0);
210 
211  _d.rho_GR = fluid_density(_d.p, _d.T, _d.vapour_mass_fraction);
212 }
213 
214 template <typename Traits>
216  unsigned integration_point,
217  std::vector<double> const& localX,
218  typename Traits::ShapeMatrices const& sm,
219  const double weight,
220  Eigen::Map<typename Traits::LocalMatrix>& local_M,
221  Eigen::Map<typename Traits::LocalMatrix>& local_K,
222  Eigen::Map<typename Traits::LocalVector>& local_b)
223 {
224  preEachAssembleIntegrationPoint(integration_point, localX, sm);
225 
226  auto const N =
227  static_cast<unsigned>(sm.dNdx.cols()); // number of integration points
228  auto const D =
229  static_cast<unsigned>(sm.dNdx.rows()); // global dimension: 1, 2 or 3
230 
231  assert(N * NODAL_DOF == local_M.cols());
232 
233  auto const laplaceCoeffMat = getLaplaceCoeffMatrix(integration_point, D);
234  assert(laplaceCoeffMat.cols() == D * NODAL_DOF);
235  auto const massCoeffMat = getMassCoeffMatrix(integration_point);
236  auto const advCoeffMat = getAdvectionCoeffMatrix(integration_point);
237  auto const contentCoeffMat = getContentCoeffMatrix(integration_point);
238 
239  // calculate velocity
240  assert((unsigned)sm.dNdx.rows() == _d.velocity.size() &&
241  (unsigned)sm.dNdx.cols() == _d.velocity[0].size());
242 
243  auto const velocity =
244  (Traits::blockDimDim(laplaceCoeffMat, 0, 0, D, D) *
245  (sm.dNdx * Eigen::Map<const typename Traits::Vector1Comp>(localX.data(),
246  N) // grad_p
247  /
248  -_d.rho_GR))
249  .eval();
250  assert(velocity.size() == D);
251 
252  for (unsigned d = 0; d < D; ++d)
253  {
254  _d.velocity[d][integration_point] = velocity[d];
255  }
256 
257  auto const detJ_w_im_NT =
258  (sm.detJ * weight * sm.integralMeasure * sm.N.transpose()).eval();
259  auto const detJ_w_im_NT_N = (detJ_w_im_NT * sm.N).eval();
260  assert(detJ_w_im_NT_N.rows() == N && detJ_w_im_NT_N.cols() == N);
261 
262  auto const detJ_w_im_NT_vT_dNdx =
263  (detJ_w_im_NT * velocity.transpose() * sm.dNdx).eval();
264  assert(detJ_w_im_NT_vT_dNdx.rows() == N && detJ_w_im_NT_vT_dNdx.cols() == N);
265 
266  for (unsigned r = 0; r < NODAL_DOF; ++r)
267  {
268  for (unsigned c = 0; c < NODAL_DOF; ++c)
269  {
270  Traits::blockShpShp(local_K, N * r, N * c, N, N).noalias() +=
271  sm.detJ * weight * sm.integralMeasure * sm.dNdx.transpose() *
272  Traits::blockDimDim(laplaceCoeffMat, D * r, D * c, D, D) *
273  sm.dNdx // end Laplacian part
274  + detJ_w_im_NT_N * contentCoeffMat(r, c) +
275  detJ_w_im_NT_vT_dNdx * advCoeffMat(r, c);
276  Traits::blockShpShp(local_M, N * r, N * c, N, N).noalias() +=
277  detJ_w_im_NT_N * massCoeffMat(r, c);
278  }
279  }
280 
281  auto const rhsCoeffVector = getRHSCoeffVector(integration_point);
282 
283  for (unsigned r = 0; r < NODAL_DOF; ++r)
284  {
285  Traits::blockShp(local_b, N * r, N).noalias() +=
286  rhsCoeffVector(r) * sm.N.transpose() * sm.detJ * weight *
287  sm.integralMeasure;
288  }
289 }
290 
291 template <typename Traits>
293 {
294  if (_d.ap.iteration_in_current_timestep == 1)
295  {
296  if (_d.ap.number_of_try_of_iteration ==
297  1) // TODO has to hold if the above holds.
298  {
299  _d.solid_density_prev_ts = _d.solid_density;
300  _d.reaction_rate_prev_ts = _d.reaction_rate;
301 
302  _d.reaction_adaptor->preZerothTryAssemble();
303  }
304  else
305  {
306  _d.solid_density = _d.solid_density_prev_ts;
307  }
308  }
309 }
310 
311 } // namespace TES
312 
313 } // namespace ProcessLib
static double getMolarFraction(double xm, double M_this, double M_other)
Definition: Adsorption.cpp:96
static double dMolarFraction(double xm, double M_this, double M_other)
Definition: Adsorption.cpp:102
TESLocalAssemblerInner(AssemblyParams const &ap, const unsigned num_int_pts, const unsigned dimension)
static const double r
void shapeFunctionInterpolate(const NodalValues &nodal_values, const ShapeMatrix &shape_matrix_N, double &interpolated_value, ScalarTypes &... interpolated_values)
Definition: Interpolation.h:79
const unsigned NODAL_DOF
double fluid_heat_conductivity(const double p, const double T, const double x)
double fluid_viscosity(const double p, const double T, const double x)
double fluid_density(const double p, const double T, const double x)