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