Line data Source code
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 :
10 : #include "TaggingInterface.h"
11 : #include "Conversion.h"
12 : #include "FEProblem.h"
13 : #include "Assembly.h"
14 : #include "ReferenceResidualConvergence.h"
15 : #include "ReferenceResidualProblem.h"
16 :
17 : #include "libmesh/dense_vector.h"
18 :
19 : InputParameters
20 6576877 : TaggingInterface::validParams()
21 : {
22 :
23 6576877 : InputParameters params = emptyInputParameters();
24 :
25 : // These are the default names for tags, but users will be able to add their own
26 13153754 : MultiMooseEnum vtags("nontime time", "nontime", true);
27 13153754 : MultiMooseEnum mtags("nontime system", "system", true);
28 :
29 19730631 : params.addParam<bool>(
30 13153754 : "matrix_only", false, "Whether this object is only doing assembly to matrices (no vectors)");
31 :
32 26307508 : params.addParam<MultiMooseEnum>(
33 : "vector_tags", vtags, "The tag for the vectors this Kernel should fill");
34 :
35 26307508 : params.addParam<MultiMooseEnum>(
36 : "matrix_tags", mtags, "The tag for the matrices this Kernel should fill");
37 :
38 26307508 : params.addParam<std::vector<TagName>>("extra_vector_tags",
39 : "The extra tags for the vectors this Kernel should fill");
40 :
41 26307508 : params.addParam<std::vector<TagName>>(
42 : "absolute_value_vector_tags",
43 : "The tags for the vectors this residual object should fill with the "
44 : "absolute value of the residual contribution");
45 :
46 26307508 : params.addParam<std::vector<TagName>>("extra_matrix_tags",
47 : "The extra tags for the matrices this Kernel should fill");
48 :
49 19730631 : params.addParamNamesToGroup(
50 : "vector_tags matrix_tags extra_vector_tags extra_matrix_tags absolute_value_vector_tags",
51 : "Contribution to tagged field data");
52 :
53 13153754 : return params;
54 6576877 : }
55 :
56 209890 : TaggingInterface::TaggingInterface(const MooseObject * moose_object)
57 629670 : : _subproblem(*moose_object->parameters().getCheckedPointerParam<SubProblem *>("_subproblem")),
58 209890 : _moose_object(*moose_object),
59 419780 : _tag_params(_moose_object.parameters())
60 : {
61 209890 : auto & vector_tag_names = _tag_params.get<MultiMooseEnum>("vector_tags");
62 :
63 209890 : if (!vector_tag_names.isValid())
64 : {
65 74 : if (!_tag_params.get<bool>("matrix_only"))
66 4 : mooseError("MUST provide at least one vector_tag for Kernel: ", _moose_object.name());
67 : }
68 : else
69 : {
70 419663 : for (auto & vector_tag_name : vector_tag_names)
71 : {
72 209855 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name.name());
73 209847 : if (_subproblem.vectorTagType(vector_tag_id) != Moose::VECTOR_TAG_RESIDUAL)
74 0 : mooseError("Vector tag '",
75 0 : vector_tag_name.name(),
76 : "' for Kernel '",
77 0 : _moose_object.name(),
78 : "' is not a residual vector tag");
79 209847 : _vector_tags.insert(vector_tag_id);
80 : }
81 : }
82 :
83 : // Add extra vector tags. These tags should be created in the System already, otherwise
84 : // we can not add the extra tags
85 209878 : auto & extra_vector_tags = _tag_params.get<std::vector<TagName>>("extra_vector_tags");
86 :
87 212356 : for (auto & vector_tag_name : extra_vector_tags)
88 : {
89 2478 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name);
90 2478 : if (_subproblem.vectorTagType(vector_tag_id) != Moose::VECTOR_TAG_RESIDUAL)
91 0 : mooseError("Extra vector tag '",
92 : vector_tag_name,
93 : "' for Kernel '",
94 0 : _moose_object.name(),
95 : "' is not a residual vector tag");
96 2478 : _vector_tags.insert(vector_tag_id);
97 : }
98 :
99 : // Add absolue value vector tags. These tags should be created in the System already, otherwise
100 : // we can not add the extra tags
101 209878 : auto & abs_vector_tags = _tag_params.get<std::vector<TagName>>("absolute_value_vector_tags");
102 :
103 210724 : for (auto & vector_tag_name : abs_vector_tags)
104 : {
105 862 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name);
106 862 : if (_subproblem.vectorTagType(vector_tag_id) != Moose::VECTOR_TAG_RESIDUAL)
107 16 : mooseError("Absolute value vector tag '",
108 : vector_tag_name,
109 : "' for Kernel '",
110 16 : _moose_object.name(),
111 : "' is not a residual vector tag");
112 846 : _abs_vector_tags.insert(vector_tag_id);
113 : }
114 :
115 209862 : auto & matrix_tag_names = _tag_params.get<MultiMooseEnum>("matrix_tags");
116 :
117 209862 : if (matrix_tag_names.isValid())
118 511289 : for (auto & matrix_tag_name : matrix_tag_names)
119 301431 : _matrix_tags.insert(_subproblem.getMatrixTagID(matrix_tag_name.name()));
120 :
121 209858 : auto & extra_matrix_tags = _tag_params.get<std::vector<TagName>>("extra_matrix_tags");
122 :
123 211326 : for (auto & matrix_tag_name : extra_matrix_tags)
124 1468 : _matrix_tags.insert(_subproblem.getMatrixTagID(matrix_tag_name));
125 :
126 209858 : _re_blocks.resize(_vector_tags.size());
127 209858 : _absre_blocks.resize(_abs_vector_tags.size());
128 209858 : _ke_blocks.resize(_matrix_tags.size());
129 :
130 : const auto * const fe_problem =
131 839432 : moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base");
132 :
133 731094 : for (const auto & conv : fe_problem->getConvergenceObjects())
134 : {
135 521236 : const auto * const ref_conv = dynamic_cast<const ReferenceResidualConvergence *>(conv.get());
136 521236 : if (ref_conv)
137 : {
138 2477 : const auto reference_tag = ref_conv->referenceVectorTagID({});
139 : auto create_tags_split =
140 4954 : [reference_tag](const auto & tags, auto & non_ref_tags, auto & ref_tags)
141 : {
142 8640 : for (const auto tag : tags)
143 3686 : if (tag == reference_tag)
144 1209 : ref_tags.insert(tag);
145 : else
146 2477 : non_ref_tags.insert(tag);
147 4954 : };
148 2477 : create_tags_split(_vector_tags, _non_ref_vector_tags, _ref_vector_tags);
149 2477 : create_tags_split(_abs_vector_tags, _non_ref_abs_vector_tags, _ref_abs_vector_tags);
150 : }
151 : else
152 : {
153 518759 : _non_ref_vector_tags = _vector_tags;
154 518759 : _non_ref_abs_vector_tags = _abs_vector_tags;
155 : }
156 : }
157 209858 : }
158 :
159 : #ifdef MOOSE_KOKKOS_ENABLED
160 162146 : TaggingInterface::TaggingInterface(const TaggingInterface & object,
161 162146 : const Moose::Kokkos::FunctorCopy &)
162 162146 : : _subproblem(object._subproblem),
163 162146 : _moose_object(object._moose_object),
164 162146 : _tag_params(object._tag_params)
165 : {
166 162146 : }
167 : #endif
168 :
169 : void
170 0 : TaggingInterface::useVectorTag(const TagName & tag_name, VectorTagsKey)
171 : {
172 0 : if (!_subproblem.vectorTagExists(tag_name))
173 0 : mooseError("Vector tag ", tag_name, " does not exist in system");
174 :
175 0 : _vector_tags.insert(_subproblem.getVectorTagID(tag_name));
176 0 : }
177 :
178 : void
179 0 : TaggingInterface::useMatrixTag(const TagName & tag_name, MatrixTagsKey)
180 : {
181 0 : if (!_subproblem.matrixTagExists(tag_name))
182 0 : mooseError("Matrix tag ", tag_name, " does not exist in system");
183 :
184 0 : _matrix_tags.insert(_subproblem.getMatrixTagID(tag_name));
185 0 : }
186 :
187 : void
188 3333 : TaggingInterface::useVectorTag(TagID tag_id, VectorTagsKey)
189 : {
190 3333 : if (!_subproblem.vectorTagExists(tag_id))
191 0 : mooseError("Vector tag ", tag_id, " does not exist in system");
192 :
193 3333 : _vector_tags.insert(tag_id);
194 3333 : }
195 :
196 : void
197 5393 : TaggingInterface::useMatrixTag(TagID tag_id, MatrixTagsKey)
198 : {
199 5393 : if (!_subproblem.matrixTagExists(tag_id))
200 0 : mooseError("Matrix tag ", tag_id, " does not exist in system");
201 :
202 5393 : _matrix_tags.insert(tag_id);
203 5393 : }
204 :
205 : void
206 766142678 : TaggingInterface::prepareVectorTag(Assembly & assembly, const unsigned int ivar)
207 : {
208 766142678 : prepareVectorTagInternal(assembly, ivar, _vector_tags, _abs_vector_tags);
209 766142678 : }
210 :
211 : void
212 0 : TaggingInterface::prepareVectorTag(Assembly & assembly,
213 : const unsigned int ivar,
214 : const ResidualTagType tag_type)
215 : {
216 0 : if (tag_type == ResidualTagType::NonReference)
217 0 : prepareVectorTagInternal(assembly, ivar, _non_ref_vector_tags, _non_ref_abs_vector_tags);
218 : else
219 0 : prepareVectorTagInternal(assembly, ivar, _ref_vector_tags, _ref_abs_vector_tags);
220 0 : }
221 :
222 : void
223 766142678 : TaggingInterface::prepareVectorTagInternal(Assembly & assembly,
224 : const unsigned int ivar,
225 : const std::set<TagID> & vector_tags,
226 : const std::set<TagID> & absolute_value_vector_tags)
227 : {
228 1532285356 : auto prepare = [this, ivar, &assembly](auto & re_blocks, const auto & tags)
229 : {
230 1532285356 : re_blocks.clear();
231 1532285356 : re_blocks.reserve(tags.size());
232 2303160865 : for (const auto tag_id : tags)
233 : {
234 770875509 : const auto & tag = _subproblem.getVectorTag(tag_id);
235 770875509 : re_blocks.push_back(&assembly.residualBlock(ivar, Assembly::LocalDataKey{}, tag._type_id));
236 : }
237 1532285356 : };
238 :
239 766142678 : prepare(_re_blocks, vector_tags);
240 766142678 : prepare(_absre_blocks, absolute_value_vector_tags);
241 :
242 1532285356 : _local_re.resize(_re_blocks.empty()
243 0 : ? (_absre_blocks.empty() ? std::size_t(0) : _absre_blocks[0]->size())
244 766142678 : : _re_blocks[0]->size());
245 766142678 : }
246 :
247 : void
248 25994610 : TaggingInterface::prepareVectorTagNeighbor(Assembly & assembly, unsigned int ivar)
249 : {
250 25994610 : _re_blocks.resize(_vector_tags.size());
251 : mooseAssert(_vector_tags.size() >= 1, "we need at least one active tag");
252 25994610 : auto vector_tag = _vector_tags.begin();
253 51990678 : for (MooseIndex(_vector_tags) i = 0; i < _vector_tags.size(); i++, ++vector_tag)
254 : {
255 25996068 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
256 25996068 : _re_blocks[i] = &assembly.residualBlockNeighbor(ivar, Assembly::LocalDataKey{}, tag._type_id);
257 : }
258 25994610 : _local_re.resize(_re_blocks[0]->size());
259 :
260 25994610 : _absre_blocks.resize(_abs_vector_tags.size());
261 25994610 : vector_tag = _abs_vector_tags.begin();
262 25994754 : for (MooseIndex(_abs_vector_tags) i = 0; i < _abs_vector_tags.size(); i++, ++vector_tag)
263 : {
264 144 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
265 144 : _absre_blocks[i] =
266 288 : &assembly.residualBlockNeighbor(ivar, Assembly::LocalDataKey{}, tag._type_id);
267 : }
268 25994610 : }
269 :
270 : void
271 110448 : TaggingInterface::prepareVectorTagLower(Assembly & assembly, unsigned int ivar)
272 : {
273 110448 : _re_blocks.resize(_vector_tags.size());
274 : mooseAssert(_vector_tags.size() >= 1, "we need at least one active tag");
275 110448 : auto vector_tag = _vector_tags.begin();
276 220896 : for (MooseIndex(_vector_tags) i = 0; i < _vector_tags.size(); i++, ++vector_tag)
277 : {
278 110448 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
279 110448 : _re_blocks[i] = &assembly.residualBlockLower(ivar, Assembly::LocalDataKey{}, tag._type_id);
280 : }
281 110448 : _local_re.resize(_re_blocks[0]->size());
282 :
283 110448 : _absre_blocks.resize(_abs_vector_tags.size());
284 110448 : vector_tag = _abs_vector_tags.begin();
285 110592 : for (MooseIndex(_abs_vector_tags) i = 0; i < _abs_vector_tags.size(); i++, ++vector_tag)
286 : {
287 144 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
288 144 : _absre_blocks[i] = &assembly.residualBlockLower(ivar, Assembly::LocalDataKey{}, tag._type_id);
289 : }
290 110448 : }
291 :
292 : void
293 143195725 : TaggingInterface::prepareMatrixTag(Assembly & assembly, unsigned int ivar, unsigned int jvar)
294 : {
295 143195725 : _ke_blocks.resize(_matrix_tags.size());
296 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
297 143195725 : auto mat_vector = _matrix_tags.begin();
298 333801006 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
299 190605281 : _ke_blocks[i] = &assembly.jacobianBlock(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
300 :
301 143195725 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
302 143195725 : }
303 :
304 : void
305 0 : TaggingInterface::prepareMatrixTag(Assembly & assembly,
306 : unsigned int ivar,
307 : unsigned int jvar,
308 : DenseMatrix<Number> & k) const
309 : {
310 : mooseAssert(!_matrix_tags.empty(), "No matrix tags exist");
311 : const auto & ij_mat =
312 0 : assembly.jacobianBlock(ivar, jvar, Assembly::LocalDataKey{}, *_matrix_tags.begin());
313 0 : k.resize(ij_mat.m(), ij_mat.n());
314 0 : }
315 :
316 : void
317 854 : TaggingInterface::prepareMatrixTagNonlocal(Assembly & assembly,
318 : unsigned int ivar,
319 : unsigned int jvar)
320 : {
321 854 : _ke_blocks.resize(_matrix_tags.size());
322 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
323 854 : auto mat_vector = _matrix_tags.begin();
324 1708 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
325 1708 : _ke_blocks[i] =
326 854 : &assembly.jacobianBlockNonlocal(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
327 :
328 854 : _nonlocal_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
329 854 : }
330 :
331 : void
332 424997 : TaggingInterface::prepareMatrixTagNeighbor(Assembly & assembly,
333 : unsigned int ivar,
334 : unsigned int jvar,
335 : Moose::DGJacobianType type)
336 : {
337 424997 : _ke_blocks.resize(_matrix_tags.size());
338 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
339 424997 : auto mat_vector = _matrix_tags.begin();
340 863878 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
341 877762 : _ke_blocks[i] =
342 438881 : &assembly.jacobianBlockNeighbor(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
343 :
344 424997 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
345 424997 : }
346 :
347 : void
348 4256 : TaggingInterface::prepareMatrixTagNeighbor(Assembly & assembly,
349 : unsigned int ivar,
350 : unsigned int jvar,
351 : Moose::DGJacobianType type,
352 : DenseMatrix<Number> & k) const
353 : {
354 : mooseAssert(!_matrix_tags.empty(), "No matrix tags exist");
355 4256 : const auto & ij_mat = assembly.jacobianBlockNeighbor(
356 4256 : type, ivar, jvar, Assembly::LocalDataKey{}, *_matrix_tags.begin());
357 4256 : k.resize(ij_mat.m(), ij_mat.n());
358 4256 : }
359 :
360 : void
361 301808 : TaggingInterface::prepareMatrixTagLower(Assembly & assembly,
362 : unsigned int ivar,
363 : unsigned int jvar,
364 : Moose::ConstraintJacobianType type)
365 : {
366 301808 : _ke_blocks.resize(_matrix_tags.size());
367 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
368 301808 : auto mat_vector = _matrix_tags.begin();
369 603616 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
370 603616 : _ke_blocks[i] =
371 301808 : &assembly.jacobianBlockMortar(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
372 :
373 301808 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
374 301808 : }
375 :
376 : void
377 786013437 : TaggingInterface::accumulateTaggedLocalResidual()
378 : {
379 1576243681 : for (auto & re : _re_blocks)
380 790230244 : *re += _local_re;
381 786531189 : for (auto & absre : _absre_blocks)
382 1553832 : for (const auto i : index_range(_local_re))
383 1036080 : (*absre)(i) += std::abs(_local_re(i));
384 786013437 : }
385 :
386 : void
387 44252 : TaggingInterface::assignTaggedLocalResidual()
388 : {
389 88504 : for (auto & re : _re_blocks)
390 44252 : *re = _local_re;
391 44270 : for (auto & absre : _absre_blocks)
392 36 : for (const auto i : index_range(_local_re))
393 18 : (*absre)(i) = std::abs(_local_re(i));
394 44252 : }
395 :
396 : void
397 143902740 : TaggingInterface::accumulateTaggedLocalMatrix()
398 : {
399 335228920 : for (auto & ke : _ke_blocks)
400 191326180 : *ke += _local_ke;
401 143902740 : }
402 :
403 : void
404 0 : TaggingInterface::accumulateTaggedLocalMatrix(Assembly & assembly,
405 : const unsigned int ivar,
406 : const unsigned int jvar,
407 : const DenseMatrix<Number> & k)
408 : {
409 0 : _ke_blocks.resize(_matrix_tags.size());
410 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
411 0 : auto mat_vector = _matrix_tags.begin();
412 0 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
413 0 : _ke_blocks[i] = &assembly.jacobianBlock(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
414 : mooseAssert(_ke_blocks[0]->m() == k.m() && _ke_blocks[0]->n() == k.n(),
415 : "Passed-in k must match the blocks we are about to sum into");
416 0 : for (auto & ke : _ke_blocks)
417 0 : *ke += k;
418 0 : }
419 :
420 : void
421 0 : TaggingInterface::accumulateTaggedLocalMatrix(Assembly & assembly,
422 : const unsigned int ivar,
423 : const unsigned int jvar,
424 : const Moose::DGJacobianType type,
425 : const DenseMatrix<Number> & k)
426 : {
427 0 : _ke_blocks.resize(_matrix_tags.size());
428 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
429 0 : auto mat_vector = _matrix_tags.begin();
430 0 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
431 0 : _ke_blocks[i] =
432 0 : &assembly.jacobianBlockNeighbor(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
433 : mooseAssert(_ke_blocks[0]->m() == k.m() && _ke_blocks[0]->n() == k.n(),
434 : "Passed-in k must match the blocks we are about to sum into");
435 0 : for (auto & ke : _ke_blocks)
436 0 : *ke += k;
437 0 : }
438 :
439 : void
440 854 : TaggingInterface::accumulateTaggedNonlocalMatrix()
441 : {
442 1708 : for (auto & ke : _ke_blocks)
443 854 : *ke += _nonlocal_ke;
444 854 : }
445 :
446 : void
447 18 : TaggingInterface::assignTaggedLocalMatrix()
448 : {
449 36 : for (auto & ke : _ke_blocks)
450 18 : *ke = _local_ke;
451 18 : }
452 :
453 364110 : TaggingInterface::~TaggingInterface() {}
|