https://mooseframework.inl.gov
NavierStokesLHDGAssemblyHelper.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 #include "MooseVariableFE.h"
12 #include "MooseVariableScalar.h"
13 #include "SystemBase.h"
14 #include "MooseMesh.h"
15 #include "MooseObject.h"
16 #include "NS.h"
17 #include "TransientInterface.h"
18 
19 using namespace libMesh;
20 
23 {
25  params.addRequiredParam<NonlinearVariableName>(NS::pressure, "The pressure variable.");
26  params.addRequiredParam<NonlinearVariableName>("v", "The y-component of velocity");
27  params.addParam<NonlinearVariableName>("w", "The z-component of velocity");
28  params.renameParam("gradient_variable", "grad_u", "The gradient of the x-component of velocity");
29  params.addRequiredParam<NonlinearVariableName>("grad_v",
30  "The gradient of the y-component of velocity");
31  params.addParam<NonlinearVariableName>("grad_w", "The gradient of the z-component of velocity");
32  params.renameParam("face_variable", "face_u", "The x-component of the face velocity");
33  params.addRequiredParam<NonlinearVariableName>("face_v", "The y-component of the face velocity");
34  params.addParam<NonlinearVariableName>("face_w", "The z-component of the face velocity");
35  params.addParam<NonlinearVariableName>(
36  "enclosure_lm",
37  "For enclosed problems like the lid driven cavity this variable can be provided to remove "
38  "the pressure nullspace");
39  params.renameParam("diffusivity", NS::mu, "The dynamic viscosity");
40  params.addRequiredParam<Real>(NS::density, "The density");
41  return params;
42 }
43 
45  const MooseObject * const moose_obj,
46  MaterialPropertyInterface * const mpi,
48  const TransientInterface * const ti,
49  const FEProblemBase & fe_problem,
50  SystemBase & sys,
51  const MooseMesh & mesh,
52  const THREAD_ID tid)
53  : DiffusionLHDGAssemblyHelper(moose_obj, mpi, mvdi, ti, fe_problem, sys, tid),
54  // vars
55  _v_var(sys.getFieldVariable<Real>(tid, moose_obj->getParam<NonlinearVariableName>("v"))),
56  _w_var(mesh.dimension() > 2
57  ? &sys.getFieldVariable<Real>(tid, moose_obj->getParam<NonlinearVariableName>("w"))
58  : nullptr),
59  _grad_v_var(sys.getFieldVariable<RealVectorValue>(
60  tid, moose_obj->getParam<NonlinearVariableName>("grad_v"))),
61  _grad_w_var(mesh.dimension() > 2
62  ? &sys.getFieldVariable<RealVectorValue>(
63  tid, moose_obj->getParam<NonlinearVariableName>("grad_w"))
64  : nullptr),
65  _v_face_var(
66  sys.getFieldVariable<Real>(tid, moose_obj->getParam<NonlinearVariableName>("face_v"))),
67  _w_face_var(
68  mesh.dimension() > 2
69  ? &sys.getFieldVariable<Real>(tid, moose_obj->getParam<NonlinearVariableName>("face_w"))
70  : nullptr),
71  _pressure_var(
72  sys.getFieldVariable<Real>(tid, moose_obj->getParam<NonlinearVariableName>(NS::pressure))),
73  _enclosure_lm_var(moose_obj->isParamValid("enclosure_lm")
74  ? &sys.getScalarVariable(
75  tid, moose_obj->getParam<NonlinearVariableName>("enclosure_lm"))
76  : nullptr),
77  // dof indices
78  _qv_dof_indices(_grad_v_var.dofIndices()),
79  _v_dof_indices(_v_var.dofIndices()),
80  _lm_v_dof_indices(_v_face_var.dofIndices()),
81  _qw_dof_indices(_grad_w_var ? &_grad_w_var->dofIndices() : nullptr),
82  _w_dof_indices(_w_var ? &_w_var->dofIndices() : nullptr),
83  _lm_w_dof_indices(_w_face_var ? &_w_face_var->dofIndices() : nullptr),
84  _p_dof_indices(_pressure_var.dofIndices()),
85  _global_lm_dof_indices(_enclosure_lm_var ? &_enclosure_lm_var->dofIndices() : nullptr),
86  // solutions
87  _qv_sol(_grad_v_var.sln()),
88  _v_sol(_v_var.sln()),
89  _lm_v_sol(_v_face_var.sln()),
90  _qw_sol(_grad_w_var ? &_grad_w_var->sln() : nullptr),
91  _w_sol(_w_var ? &_w_var->sln() : nullptr),
92  _lm_w_sol(_w_face_var ? &_w_face_var->sln() : nullptr),
93  _p_sol(_pressure_var.sln()),
94  _global_lm_dof_value(_enclosure_lm_var ? &_enclosure_lm_var->sln() : nullptr),
95  _rho(moose_obj->getParam<Real>(NS::density))
96 {
97  if (mesh.dimension() > 2)
98  mooseError("3D not yet implemented");
99 
104 
105  const auto vel_type = _u_var.feType();
106  auto check_type = [&vel_type](const auto & var)
107  {
108  if (vel_type != var.feType())
109  mooseError(
110  var.name(),
111  "does not have the same finite element type as the x-component velocity. All scalar "
112  "field finite element types must be the same for the Navier-Stokes L-HDG implementation");
113  };
114  check_type(_v_var);
115  if (_w_var)
116  check_type(*_w_var);
117  check_type(_pressure_var);
118 
119  const auto grad_type = _grad_u_var.feType();
120  auto check_grad_type = [&grad_type](const auto & var)
121  {
122  if (grad_type != var.feType())
123  mooseError(
124  var.name(),
125  "does not have the same finite element type as the x-component velocity gradient. All "
126  "vector field finite element types must be the same for the Navier-Stokes L-HDG "
127  "implementation");
128  };
129  check_grad_type(_grad_v_var);
130  if (_grad_w_var)
131  check_grad_type(*_grad_w_var);
132 
133  const auto lm_type = _u_face_var.feType();
134  auto check_lm_type = [&lm_type](const auto & var)
135  {
136  if (lm_type != var.feType())
137  mooseError(var.name(),
138  "does not have the same finite element type as the x-component face variable. All "
139  "face variable finite element types must be the same for the Navier-Stokes L-HDG "
140  "implementation");
141  };
142  check_lm_type(_v_face_var);
143  if (_w_face_var)
144  check_lm_type(*_w_face_var);
145 }
146 
147 void
149  const unsigned int vel_component,
150  const Moose::Functor<Real> & body_force,
151  const MooseArray<Real> & JxW,
152  const QBase & qrule,
153  const Elem * const current_elem,
154  const MooseArray<Point> & q_point,
155  DenseVector<Number> & scalar_re)
156 {
158  vel_gradient, body_force, JxW, qrule, current_elem, q_point, scalar_re);
159 
160  for (const auto qp : make_range(qrule.n_points()))
161  {
162  const auto rho_vel_cross_vel = rhoVelCrossVelResidual(_u_sol, _v_sol, qp, vel_component);
163  Gradient qp_p;
164  qp_p(vel_component) = _p_sol[qp];
165 
166  for (const auto i : index_range(scalar_re))
167  {
168  // Scalar equation dependence on pressure dofs
169  scalar_re(i) -= JxW[qp] * (_grad_scalar_phi[i][qp] * qp_p);
170 
171  // Scalar equation dependence on scalar dofs
172  scalar_re(i) -= JxW[qp] * (_grad_scalar_phi[i][qp] * rho_vel_cross_vel);
173  }
174  }
175 }
176 
177 void
179  const MooseArray<Real> & JxW,
180  const QBase & qrule,
181  DenseMatrix<Number> & scalar_vector_jac,
182  DenseMatrix<Number> & scalar_u_vel_jac,
183  DenseMatrix<Number> & scalar_v_vel_jac,
184  DenseMatrix<Number> & scalar_p_jac)
185 {
186  DiffusionLHDGAssemblyHelper::scalarVolumeJacobian(JxW, qrule, scalar_vector_jac);
187 
188  for (const auto i : make_range(scalar_vector_jac.m()))
189  for (const auto qp : make_range(qrule.n_points()))
190  {
191  // Scalar equation dependence on pressure dofs
192  for (const auto j : make_range(scalar_p_jac.n()))
193  {
194  Gradient p_phi;
195  p_phi(vel_component) = _scalar_phi[j][qp];
196  scalar_p_jac(i, j) -= JxW[qp] * (_grad_scalar_phi[i][qp] * p_phi);
197  }
198 
199  // Scalar equation dependence on scalar dofs
200  mooseAssert(scalar_u_vel_jac.n() == scalar_v_vel_jac.n(), "These must be the same size");
201  for (const auto j : make_range(scalar_u_vel_jac.n()))
202  {
203  // derivatives wrt 0th component of velocity
204  {
205  const auto rho_vel_cross_vel =
206  rhoVelCrossVelJacobian(_u_sol, _v_sol, qp, vel_component, 0, _scalar_phi, j);
207  scalar_u_vel_jac(i, j) -= JxW[qp] * (_grad_scalar_phi[i][qp] * rho_vel_cross_vel);
208  }
209  // derivatives wrt 1th component of velocity
210  {
211  const auto rho_vel_cross_vel =
212  rhoVelCrossVelJacobian(_u_sol, _v_sol, qp, vel_component, 1, _scalar_phi, j);
213  scalar_v_vel_jac(i, j) -= JxW[qp] * (_grad_scalar_phi[i][qp] * rho_vel_cross_vel);
214  }
215  }
216  }
217 }
218 
219 void
221  const Moose::Functor<Real> & pressure_mms_forcing_function,
222  const MooseArray<Real> & JxW,
223  const QBase & qrule,
224  const Elem * const current_elem,
225  const MooseArray<Point> & q_point,
226  DenseVector<Number> & pressure_re,
227  DenseVector<Number> & global_lm_re)
228 {
229  for (const auto qp : make_range(qrule.n_points()))
230  {
231  // Prepare forcing function
232  const auto f = pressure_mms_forcing_function(
233  Moose::ElemQpArg{current_elem, qp, &qrule, q_point[qp]}, _ti.determineState());
234 
235  const Gradient vel(_u_sol[qp], _v_sol[qp]);
236  for (const auto i : make_range(pressure_re.size()))
237  {
238  pressure_re(i) -= JxW[qp] * (_grad_scalar_phi[i][qp] * vel);
239 
240  // Pressure equation forcing function RHS
241  pressure_re(i) -= JxW[qp] * _scalar_phi[i][qp] * f;
242 
243  if (_enclosure_lm_var)
244  {
245  mooseAssert(
246  _global_lm_dof_value->size() == 1,
247  "There should only be one degree of freedom for removing the pressure nullspace");
248  pressure_re(i) -= JxW[qp] * _scalar_phi[i][qp] * (*_global_lm_dof_value)[0];
249  }
250  }
251 
252  if (_enclosure_lm_var)
253  global_lm_re(0) -= JxW[qp] * _p_sol[qp];
254  }
255 }
256 
257 void
259  const QBase & qrule,
260  DenseMatrix<Number> & p_u_vel_jac,
261  DenseMatrix<Number> & p_v_vel_jac,
262  DenseMatrix<Number> & p_global_lm_jac,
263  DenseMatrix<Number> & global_lm_p_jac)
264 {
265  for (const auto qp : make_range(qrule.n_points()))
266  {
267  for (const auto i : make_range(p_u_vel_jac.m()))
268  {
269  for (const auto j : make_range(p_u_vel_jac.n()))
270  {
271  {
272  const Gradient phi(_scalar_phi[j][qp], 0);
273  p_u_vel_jac(i, j) -= JxW[qp] * (_grad_scalar_phi[i][qp] * phi);
274  }
275  {
276  const Gradient phi(0, _scalar_phi[j][qp]);
277  p_v_vel_jac(i, j) -= JxW[qp] * (_grad_scalar_phi[i][qp] * phi);
278  }
279  }
280  if (_enclosure_lm_var)
281  p_global_lm_jac(i, 0) -= JxW[qp] * _scalar_phi[i][qp];
282  }
283 
284  if (_enclosure_lm_var)
285  {
286  for (const auto j : make_range(global_lm_p_jac.n()))
287  global_lm_p_jac(0, j) -= JxW[qp] * _scalar_phi[j][qp];
288  }
289  }
290 }
291 
294  const MooseArray<Number> & v_sol,
295  const unsigned int qp,
296  const unsigned int vel_component)
297 {
298  const RealVectorValue U(u_sol[qp], v_sol[qp]);
299  return _rho * U * U(vel_component);
300 }
301 
304  const MooseArray<Number> & v_sol,
305  const unsigned int qp,
306  const unsigned int vel_component,
307  const unsigned int vel_j_component,
308  const MooseArray<std::vector<Real>> & phi,
309  const unsigned int j)
310 {
311  const RealVectorValue U(u_sol[qp], v_sol[qp]);
312  RealVectorValue vector_phi;
313  vector_phi(vel_j_component) = phi[j][qp];
314  auto ret = vector_phi * U(vel_component);
315  if (vel_component == vel_j_component)
316  ret += U * phi[j][qp];
317  ret *= _rho;
318  return ret;
319 }
320 
321 void
323  const QBase & qrule_face,
324  const MooseArray<Point> & normals,
325  DenseVector<Number> & pressure_re)
326 {
327  for (const auto qp : make_range(qrule_face.n_points()))
328  {
329  const Gradient vel(_lm_u_sol[qp], _lm_v_sol[qp]);
330  const auto vdotn = vel * normals[qp];
331  for (const auto i : make_range(pressure_re.size()))
332  pressure_re(i) += JxW_face[qp] * vdotn * _scalar_phi_face[i][qp];
333  }
334 }
335 
336 void
338  const QBase & qrule_face,
339  const MooseArray<Point> & normals,
340  DenseMatrix<Number> & p_lm_u_vel_jac,
341  DenseMatrix<Number> & p_lm_v_vel_jac)
342 {
343  mooseAssert((p_lm_u_vel_jac.m() == p_lm_v_vel_jac.m()) &&
344  (p_lm_u_vel_jac.n() == p_lm_v_vel_jac.n()),
345  "We already checked that lm finite element types are the same, so these matrices "
346  "should be the same size");
347  for (const auto i : make_range(p_lm_u_vel_jac.m()))
348  for (const auto j : make_range(p_lm_u_vel_jac.n()))
349  for (const auto qp : make_range(qrule_face.n_points()))
350  {
351  {
352  const Gradient phi(_lm_phi_face[j][qp], 0);
353  p_lm_u_vel_jac(i, j) += JxW_face[qp] * phi * normals[qp] * _scalar_phi_face[i][qp];
354  }
355  {
356  const Gradient phi(0, _lm_phi_face[j][qp]);
357  p_lm_v_vel_jac(i, j) += JxW_face[qp] * phi * normals[qp] * _scalar_phi_face[i][qp];
358  }
359  }
360 }
361 
362 void
364  const MooseArray<Number> & scalar_sol,
365  const MooseArray<Number> & lm_sol,
366  const unsigned int vel_component,
367  const MooseArray<Real> & JxW_face,
368  const QBase & qrule_face,
369  const MooseArray<Point> & normals,
370  DenseVector<Number> & scalar_re)
371 {
373  vector_sol, scalar_sol, lm_sol, JxW_face, qrule_face, normals, scalar_re);
374 
375  for (const auto qp : make_range(qrule_face.n_points()))
376  {
377  Gradient qp_p;
378  qp_p(vel_component) = _p_sol[qp];
379  const auto rho_vel_cross_vel = rhoVelCrossVelResidual(_lm_u_sol, _lm_v_sol, qp, vel_component);
380 
381  for (const auto i : make_range(scalar_re.size()))
382  {
383  // pressure
384  scalar_re(i) += JxW_face[qp] * _scalar_phi_face[i][qp] * (qp_p * normals[qp]);
385 
386  // lm from convection term
387  scalar_re(i) += JxW_face[qp] * _scalar_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
388  }
389  }
390 }
391 
392 void
393 NavierStokesLHDGAssemblyHelper::scalarFaceJacobian(const unsigned int vel_component,
394  const MooseArray<Real> & JxW_face,
395  const QBase & qrule_face,
396  const MooseArray<Point> & normals,
397  DenseMatrix<Number> & scalar_vector_jac,
398  DenseMatrix<Number> & scalar_scalar_jac,
399  DenseMatrix<Number> & scalar_lm_jac,
400  DenseMatrix<Number> & scalar_p_jac,
401  DenseMatrix<Number> & scalar_lm_u_vel_jac,
402  DenseMatrix<Number> & scalar_lm_v_vel_jac)
403 
404 {
406  JxW_face, qrule_face, normals, scalar_vector_jac, scalar_scalar_jac, scalar_lm_jac);
407 
408  for (const auto i : make_range(scalar_lm_u_vel_jac.m()))
409  for (const auto qp : make_range(qrule_face.n_points()))
410  {
411  for (const auto j : make_range(scalar_p_jac.n()))
412  {
413  Gradient p_phi;
414  p_phi(vel_component) = _scalar_phi_face[j][qp];
415  // pressure
416  scalar_p_jac(i, j) += JxW_face[qp] * _scalar_phi_face[i][qp] * (p_phi * normals[qp]);
417  }
418 
419  for (const auto j : make_range(scalar_lm_u_vel_jac.n()))
420  {
421  //
422  // from convection term
423  //
424 
425  // derivatives wrt 0th component of velocity
426  {
427  const auto rho_vel_cross_vel =
428  rhoVelCrossVelJacobian(_lm_u_sol, _lm_v_sol, qp, vel_component, 0, _lm_phi_face, j);
429  scalar_lm_u_vel_jac(i, j) +=
430  JxW_face[qp] * _scalar_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
431  }
432  // derivatives wrt 1th component of velocity
433  {
434  const auto rho_vel_cross_vel =
435  rhoVelCrossVelJacobian(_lm_u_sol, _lm_v_sol, qp, vel_component, 1, _lm_phi_face, j);
436  scalar_lm_v_vel_jac(i, j) +=
437  JxW_face[qp] * _scalar_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
438  }
439  }
440  }
441 }
442 
443 void
445  const MooseArray<Number> & scalar_sol,
446  const MooseArray<Number> & lm_sol,
447  const unsigned int vel_component,
448  const MooseArray<Real> & JxW_face,
449  const QBase & qrule_face,
450  const MooseArray<Point> & normals,
451  const Elem * const neigh,
452  DenseVector<Number> & lm_re)
453 {
455  vector_sol, scalar_sol, lm_sol, JxW_face, qrule_face, normals, lm_re);
456 
457  for (const auto qp : make_range(qrule_face.n_points()))
458  {
459  Gradient qp_p;
460  qp_p(vel_component) = _p_sol[qp];
461  const auto rho_vel_cross_vel = rhoVelCrossVelResidual(_lm_u_sol, _lm_v_sol, qp, vel_component);
462 
463  for (const auto i : make_range(lm_re.size()))
464  {
465  // pressure
466  lm_re(i) += JxW_face[qp] * _lm_phi_face[i][qp] * (qp_p * normals[qp]);
467 
468  // If we are an internal face we add the convective term. On the outflow boundary we do not
469  // zero out the convection term, e.g. we are going to set q + p + tau * (u - u_hat) to zero
470  if (neigh)
471  // lm from convection term
472  lm_re(i) += JxW_face[qp] * _lm_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
473  }
474  }
475 }
476 
477 void
478 NavierStokesLHDGAssemblyHelper::lmFaceJacobian(const unsigned int vel_component,
479  const MooseArray<Real> & JxW_face,
480  const QBase & qrule_face,
481  const MooseArray<Point> & normals,
482  const Elem * const neigh,
483  DenseMatrix<Number> & lm_vec_jac,
484  DenseMatrix<Number> & lm_scalar_jac,
485  DenseMatrix<Number> & lm_lm_jac,
486  DenseMatrix<Number> & lm_p_jac,
487  DenseMatrix<Number> & lm_lm_u_vel_jac,
488  DenseMatrix<Number> & lm_lm_v_vel_jac)
489 {
491  JxW_face, qrule_face, normals, lm_vec_jac, lm_scalar_jac, lm_lm_jac);
492 
493  for (const auto i : make_range(lm_p_jac.m()))
494  for (const auto qp : make_range(qrule_face.n_points()))
495  {
496  for (const auto j : make_range(lm_p_jac.n()))
497  {
498  Gradient p_phi;
499  p_phi(vel_component) = _scalar_phi_face[j][qp];
500  lm_p_jac(i, j) += JxW_face[qp] * _lm_phi_face[i][qp] * (p_phi * normals[qp]);
501  }
502 
503  for (const auto j : make_range(lm_lm_u_vel_jac.n()))
504  if (neigh)
505  {
506  // derivatives wrt 0th component of velocity
507  {
508  const auto rho_vel_cross_vel =
509  rhoVelCrossVelJacobian(_lm_u_sol, _lm_v_sol, qp, vel_component, 0, _lm_phi_face, j);
510  lm_lm_u_vel_jac(i, j) +=
511  JxW_face[qp] * _lm_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
512  }
513  // derivatives wrt 1th component of velocity
514  {
515  const auto rho_vel_cross_vel =
516  rhoVelCrossVelJacobian(_lm_u_sol, _lm_v_sol, qp, vel_component, 1, _lm_phi_face, j);
517  lm_lm_v_vel_jac(i, j) +=
518  JxW_face[qp] * _lm_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
519  }
520  }
521  }
522 }
523 
524 void
526  const std::array<const Moose::Functor<Real> *, 3> & dirichlet_vel,
527  const MooseArray<Real> & JxW_face,
528  const QBase & qrule_face,
529  const MooseArray<Point> & normals,
530  const Elem * const current_elem,
531  const unsigned int current_side,
532  const MooseArray<Point> & q_point_face,
533  DenseVector<Number> & pressure_re)
534 {
535  for (const auto qp : make_range(qrule_face.n_points()))
536  {
537  const Moose::ElemSideQpArg elem_side_qp_arg{
538  current_elem, current_side, qp, &qrule_face, q_point_face[qp]};
539  const auto time_arg = _ti.determineState();
540  const RealVectorValue dirichlet_velocity((*dirichlet_vel[0])(elem_side_qp_arg, time_arg),
541  (*dirichlet_vel[1])(elem_side_qp_arg, time_arg),
542  (*dirichlet_vel[2])(elem_side_qp_arg, time_arg));
543  const auto vdotn = dirichlet_velocity * normals[qp];
544  for (const auto i : make_range(pressure_re.size()))
545  pressure_re(i) += JxW_face[qp] * vdotn * _scalar_phi_face[i][qp];
546  }
547 }
548 
549 void
551  const MooseArray<Gradient> & vector_sol,
552  const MooseArray<Number> & scalar_sol,
553  const unsigned int vel_component,
554  const std::array<const Moose::Functor<Real> *, 3> & dirichlet_vel,
555  const MooseArray<Real> & JxW_face,
556  const QBase & qrule_face,
557  const MooseArray<Point> & normals,
558  const Elem * const current_elem,
559  const unsigned int current_side,
560  const MooseArray<Point> & q_point_face,
561  DenseVector<Number> & scalar_re)
562 {
564  scalar_sol,
565  *dirichlet_vel[vel_component],
566  JxW_face,
567  qrule_face,
568  normals,
569  current_elem,
570  current_side,
571  q_point_face,
572  scalar_re);
573 
574  for (const auto qp : make_range(qrule_face.n_points()))
575  {
576  Gradient qp_p;
577  qp_p(vel_component) = _p_sol[qp];
578 
579  const Moose::ElemSideQpArg elem_side_qp_arg{
580  current_elem, current_side, qp, &qrule_face, q_point_face[qp]};
581  const auto time_arg = _ti.determineState();
582  const RealVectorValue dirichlet_velocity((*dirichlet_vel[0])(elem_side_qp_arg, time_arg),
583  (*dirichlet_vel[1])(elem_side_qp_arg, time_arg),
584  (*dirichlet_vel[2])(elem_side_qp_arg, time_arg));
585  const auto scalar_value = dirichlet_velocity(vel_component);
586 
587  for (const auto i : make_range(scalar_re.size()))
588  {
589  // pressure
590  scalar_re(i) += JxW_face[qp] * _scalar_phi_face[i][qp] * (qp_p * normals[qp]);
591 
592  // dirichlet lm from advection term
593  scalar_re(i) += JxW_face[qp] * _scalar_phi_face[i][qp] *
594  (_rho * dirichlet_velocity * normals[qp]) * scalar_value;
595  }
596  }
597 }
598 
599 void
601  const MooseArray<Real> & JxW_face,
602  const QBase & qrule_face,
603  const MooseArray<Point> & normals,
604  DenseMatrix<Number> & scalar_vector_jac,
605  DenseMatrix<Number> & scalar_scalar_jac,
606  DenseMatrix<Number> & scalar_pressure_jac)
607 {
609  JxW_face, qrule_face, normals, scalar_vector_jac, scalar_scalar_jac);
610 
611  for (const auto i : make_range(scalar_pressure_jac.m()))
612  for (const auto j : make_range(scalar_pressure_jac.n()))
613  for (const auto qp : make_range(qrule_face.n_points()))
614  {
615  Gradient p_phi;
616  p_phi(vel_component) = _scalar_phi_face[j][qp];
617  // pressure
618  scalar_pressure_jac(i, j) += JxW_face[qp] * _scalar_phi_face[i][qp] * (p_phi * normals[qp]);
619  }
620 }
void pressureVolumeJacobian(const MooseArray< Real > &JxW, const libMesh::QBase &qrule, DenseMatrix< Number > &p_u_vel_jac, DenseMatrix< Number > &p_v_vel_jac, DenseMatrix< Number > &p_global_lm_jac, DenseMatrix< Number > &global_lm_p_jac)
Compute the volumetric contributions to the pressure Jacobian, e.g.
const MooseArray< std::vector< Real > > & _scalar_phi_face
const MooseArray< Number > & _u_sol
const MooseArray< std::vector< Real > > & _scalar_phi
void scalarDirichletResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const Moose::Functor< Real > &dirichlet_value, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const current_elem, const unsigned int current_side, const MooseArray< Point > &q_point_face, DenseVector< Number > &scalar_re)
const libMesh::FEType & feType() const
void lmFaceJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const neigh, DenseMatrix< Number > &lm_vec_jac, DenseMatrix< Number > &lm_scalar_jac, DenseMatrix< Number > &lm_lm_jac, DenseMatrix< Number > &lm_p_jac, DenseMatrix< Number > &lm_lm_u_vel_jac, DenseMatrix< Number > &lm_lm_v_vel_jac)
const MooseVariableFE< Real > & _v_var
RealVectorValue rhoVelCrossVelJacobian(const MooseArray< Number > &u_sol, const MooseArray< Number > &v_sol, const unsigned int qp, const unsigned int vel_component, const unsigned int vel_j_component, const MooseArray< std::vector< Real >> &phi, const unsigned int j)
void mooseError(Args &&... args)
void pressureVolumeResidual(const Moose::Functor< Real > &pressure_mms_forcing_function, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, const Elem *const current_elem, const MooseArray< Point > &q_point, DenseVector< Number > &pressure_re, DenseVector< Number > &global_lm_re)
Compute the volumetric contributions to the pressure residual, e.g.
const MooseArray< std::vector< Real > > & _lm_phi_face
const MooseVariableFE< Real > *const _w_var
Moose::StateArg determineState() const
const MooseVariableFE< Real > & _v_face_var
MeshBase & mesh
static const std::string density
Definition: NS.h:33
void pressureFaceJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &p_lm_u_vel_jac, DenseMatrix< Number > &p_lm_v_vel_jac)
const MooseArray< std::vector< RealVectorValue > > & _grad_scalar_phi
unsigned int m() const
void scalarFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &scalar_re)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
void scalarVolumeJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_u_vel_jac, DenseMatrix< Number > &scalar_v_vel_jac, DenseMatrix< Number > &scalar_p_jac)
Compute the volumetric contributions to a velocity Jacobian.
RealVectorValue rhoVelCrossVelResidual(const MooseArray< Number > &u_sol, const MooseArray< Number > &v_sol, const unsigned int qp, const unsigned int vel_component)
void scalarFaceJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac, DenseMatrix< Number > &scalar_lm_jac, DenseMatrix< Number > &scalar_p_jac, DenseMatrix< Number > &scalar_lm_u_vel_jac, DenseMatrix< Number > &scalar_lm_v_vel_jac)
void scalarDirichletJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac)
unsigned int size() const
void scalarDirichletResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const unsigned int vel_component, const std::array< const Moose::Functor< Real > *, 3 > &dirichlet_vel, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const current_elem, const unsigned int current_side, const MooseArray< Point > &q_point_face, DenseVector< Number > &scalar_re)
Real f(Real x)
Test function for Brents method.
static const std::string mu
Definition: NS.h:123
static InputParameters validParams()
void scalarFaceJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac, DenseMatrix< Number > &scalar_lm_jac)
const MooseVariableFE< RealVectorValue > & _grad_v_var
void lmFaceJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &lm_vec_jac, DenseMatrix< Number > &lm_scalar_jac, DenseMatrix< Number > &lm_lm_jac)
void lmFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &lm_re)
unsigned int n_points() const
const MooseVariableFE< RealVectorValue > *const _grad_w_var
void scalarVolumeResidual(const MooseArray< Gradient > &vector_field, const Moose::Functor< Real > &source, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, const Elem *const current_elem, const MooseArray< Point > &q_point, DenseVector< Number > &scalar_re)
const TransientInterface & _ti
const MooseVariableFE< Real > & _pressure_var
const MooseVariableFE< Real > & _u_face_var
void addMooseVariableDependency(MooseVariableFieldBase *var)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void pressureDirichletResidual(const std::array< const Moose::Functor< Real > *, 3 > &dirichlet_vel, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const current_elem, const unsigned int current_side, const MooseArray< Point > &q_point_face, DenseVector< Number > &pressure_re)
void pressureFaceResidual(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &pressure_re)
const MooseVariableFE< Real > & _u_var
static const std::string pressure
Definition: NS.h:56
const MooseArray< Number > & _lm_u_sol
IntRange< T > make_range(T beg, T end)
NavierStokesLHDGAssemblyHelper(const MooseObject *moose_obj, MaterialPropertyInterface *mpi, MooseVariableDependencyInterface *mvdi, const TransientInterface *const ti, const FEProblemBase &fe_problem, SystemBase &sys, const MooseMesh &mesh, const THREAD_ID tid)
virtual unsigned int size() const override final
void scalarVolumeJacobian(const MooseArray< Real > &JxW, const libMesh::QBase &qrule, DenseMatrix< Number > &scalar_vector_jac)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const MooseVariableFE< RealVectorValue > & _grad_u_var
const MooseVariableFE< Real > *const _w_face_var
void scalarFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &scalar_re)
unsigned int n() const
void lmFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const neigh, DenseVector< Number > &lm_re)
void scalarDirichletJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac, DenseMatrix< Number > &scalar_pressure_jac)
auto index_range(const T &sizable)
void scalarVolumeResidual(const MooseArray< Gradient > &vel_gradient, const unsigned int vel_component, const Moose::Functor< Real > &body_force, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, const Elem *const current_elem, const MooseArray< Point > &q_point, DenseVector< Number > &scalar_re)
Compute the volumetric contributions to a velocity residual for a provided velocity gradient and stre...
unsigned int THREAD_ID
const MooseVariableScalar *const _enclosure_lm_var
const MooseArray< Number > *const _global_lm_dof_value