16 #include "libmesh/threads.h"
21 template <
typename T, ComputeStage compute_stage>
28 template <
typename T, ComputeStage compute_stage>
35 template <
typename T, ComputeStage compute_stage>
39 prepareVectorTag(_assembly, _var.number());
41 precalculateResidual();
42 const unsigned int n_test = _grad_test.size();
44 if (_use_displaced_mesh)
45 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
47 const auto value = precomputeQpStrongResidual() * _ad_JxW[_qp] * _ad_coord[_qp];
48 for (_i = 0; _i < n_test; _i++)
49 _local_re(_i) += _grad_test[_i][_qp] * computeQpStabilization() * value;
52 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
54 const auto value = precomputeQpStrongResidual() * _JxW[_qp] * _coord[_qp];
55 for (_i = 0; _i < n_test; _i++)
56 _local_re(_i) += _regular_grad_test[_i][_qp] * computeQpStabilization() * value;
59 accumulateTaggedLocalResidual();
63 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
64 for (
unsigned int i = 0; i < _save_in.size(); i++)
65 _save_in[i]->sys().solution().add_vector(_local_re, _save_in[i]->dofIndices());
81 template <
typename T, ComputeStage compute_stage>
85 prepareMatrixTag(_assembly, _var.number(), _var.number());
87 size_t ad_offset = _var.number() * _sys.getMaxVarNDofsPerElem();
89 precalculateResidual();
91 if (_use_displaced_mesh)
92 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
95 const auto value = precomputeQpStrongResidual() * _ad_JxW[_qp] * _ad_coord[_qp];
96 for (_i = 0; _i < _grad_test.size(); _i++)
98 const auto residual = _grad_test[_i][_qp] * computeQpStabilization() * value;
99 for (_j = 0; _j < _var.phiSize(); _j++)
100 _local_ke(_i, _j) += residual.derivatives()[ad_offset + _j];
104 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
107 const auto value = precomputeQpStrongResidual() * _JxW[_qp] * _coord[_qp];
108 for (_i = 0; _i < _grad_test.size(); _i++)
110 const auto residual = _regular_grad_test[_i][_qp] * computeQpStabilization() * value;
111 for (_j = 0; _j < _var.phiSize(); _j++)
112 _local_ke(_i, _j) += residual.derivatives()[ad_offset + _j];
116 accumulateTaggedLocalMatrix();
118 if (_has_diag_save_in)
120 unsigned int rows = _local_ke.m();
121 DenseVector<Number> diag(rows);
122 for (
unsigned int i = 0; i < rows; i++)
123 diag(i) = _local_ke(i, i);
125 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
126 for (
unsigned int i = 0; i < _diag_save_in.size(); i++)
127 _diag_save_in[i]->sys().solution().add_vector(diag, _diag_save_in[i]->dofIndices());
143 template <
typename T, ComputeStage compute_stage>
147 std::vector<DualReal> residuals(_grad_test.size(), 0);
149 precalculateResidual();
151 if (_use_displaced_mesh)
152 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
154 const auto value = precomputeQpStrongResidual() * _ad_JxW[_qp] * _ad_coord[_qp];
155 for (_i = 0; _i < _grad_test.size(); _i++)
156 residuals[_i] += _grad_test[_i][_qp] * computeQpStabilization() * value;
159 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
161 const auto value = precomputeQpStrongResidual() * _JxW[_qp] * _coord[_qp];
162 for (_i = 0; _i < _grad_test.size(); _i++)
163 residuals[_i] += _regular_grad_test[_i][_qp] * computeQpStabilization() * value;
166 auto & ce = _assembly.couplingEntries();
167 for (
const auto & it : ce)
172 unsigned int ivar = ivariable.
number();
173 unsigned int jvar = jvariable.
number();
175 if (ivar != _var.number())
178 size_t ad_offset = jvar * _sys.getMaxVarNDofsPerElem();
180 prepareMatrixTag(_assembly, ivar, jvar);
182 if (_local_ke.m() != _grad_test.size() || _local_ke.n() != jvariable.
phiSize())
185 precalculateResidual();
186 for (_i = 0; _i < _grad_test.size(); _i++)
187 for (_j = 0; _j < jvariable.
phiSize(); _j++)
188 _local_ke(_i, _j) += residuals[_i].derivatives()[ad_offset + _j];
190 accumulateTaggedLocalMatrix();
206 template <
typename T, ComputeStage compute_stage>
210 mooseError(
"Override precomputeQpStrongResidual() in your ADKernelStabilized derived class!");