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 6050367 : TaggingInterface::validParams()
21 : {
22 :
23 6050367 : InputParameters params = emptyInputParameters();
24 :
25 : // These are the default names for tags, but users will be able to add their own
26 6050367 : MultiMooseEnum vtags("nontime time", "nontime", true);
27 6050367 : MultiMooseEnum mtags("nontime system", "system", true);
28 :
29 18151101 : params.addParam<bool>(
30 12100734 : "matrix_only", false, "Whether this object is only doing assembly to matrices (no vectors)");
31 :
32 6050367 : params.addParam<MultiMooseEnum>(
33 : "vector_tags", vtags, "The tag for the vectors this Kernel should fill");
34 :
35 6050367 : params.addParam<MultiMooseEnum>(
36 : "matrix_tags", mtags, "The tag for the matrices this Kernel should fill");
37 :
38 6050367 : params.addParam<std::vector<TagName>>("extra_vector_tags",
39 : "The extra tags for the vectors this Kernel should fill");
40 :
41 6050367 : 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 6050367 : params.addParam<std::vector<TagName>>("extra_matrix_tags",
47 : "The extra tags for the matrices this Kernel should fill");
48 :
49 6050367 : 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 12100734 : return params;
54 6050367 : }
55 :
56 203412 : TaggingInterface::TaggingInterface(const MooseObject * moose_object)
57 203412 : : _subproblem(*moose_object->parameters().getCheckedPointerParam<SubProblem *>("_subproblem")),
58 203412 : _moose_object(*moose_object),
59 406824 : _tag_params(_moose_object.parameters())
60 : {
61 203412 : auto & vector_tag_names = _tag_params.get<MultiMooseEnum>("vector_tags");
62 :
63 203412 : if (!vector_tag_names.isValid())
64 : {
65 32 : 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 406791 : for (auto & vector_tag_name : vector_tag_names)
71 : {
72 203419 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name.name());
73 203411 : 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 203411 : _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 203400 : auto & extra_vector_tags = _tag_params.get<std::vector<TagName>>("extra_vector_tags");
86 :
87 205566 : for (auto & vector_tag_name : extra_vector_tags)
88 : {
89 2166 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name);
90 2166 : 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 2166 : _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 203400 : auto & abs_vector_tags = _tag_params.get<std::vector<TagName>>("absolute_value_vector_tags");
102 :
103 204246 : 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 32 : 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 203384 : auto & matrix_tag_names = _tag_params.get<MultiMooseEnum>("matrix_tags");
116 :
117 203384 : if (matrix_tag_names.isValid())
118 496665 : for (auto & matrix_tag_name : matrix_tag_names)
119 293285 : _matrix_tags.insert(_subproblem.getMatrixTagID(matrix_tag_name.name()));
120 :
121 203380 : auto & extra_matrix_tags = _tag_params.get<std::vector<TagName>>("extra_matrix_tags");
122 :
123 204548 : for (auto & matrix_tag_name : extra_matrix_tags)
124 1168 : _matrix_tags.insert(_subproblem.getMatrixTagID(matrix_tag_name));
125 :
126 203380 : _re_blocks.resize(_vector_tags.size());
127 203380 : _absre_blocks.resize(_abs_vector_tags.size());
128 203380 : _ke_blocks.resize(_matrix_tags.size());
129 :
130 : const auto * const fe_problem =
131 203380 : moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base");
132 :
133 707385 : for (const auto & conv : fe_problem->getConvergenceObjects())
134 : {
135 504005 : const auto * const ref_conv = dynamic_cast<const ReferenceResidualConvergence *>(conv.get());
136 504005 : if (ref_conv)
137 : {
138 2477 : const auto reference_tag = ref_conv->referenceVectorTagID({});
139 : auto create_tags_split =
140 8640 : [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 501528 : _non_ref_vector_tags = _vector_tags;
154 501528 : _non_ref_abs_vector_tags = _abs_vector_tags;
155 : }
156 : }
157 203380 : }
158 :
159 : void
160 0 : TaggingInterface::useVectorTag(const TagName & tag_name, VectorTagsKey)
161 : {
162 0 : if (!_subproblem.vectorTagExists(tag_name))
163 0 : mooseError("Vector tag ", tag_name, " does not exist in system");
164 :
165 0 : _vector_tags.insert(_subproblem.getVectorTagID(tag_name));
166 0 : }
167 :
168 : void
169 0 : TaggingInterface::useMatrixTag(const TagName & tag_name, MatrixTagsKey)
170 : {
171 0 : if (!_subproblem.matrixTagExists(tag_name))
172 0 : mooseError("Matrix tag ", tag_name, " does not exist in system");
173 :
174 0 : _matrix_tags.insert(_subproblem.getMatrixTagID(tag_name));
175 0 : }
176 :
177 : void
178 3333 : TaggingInterface::useVectorTag(TagID tag_id, VectorTagsKey)
179 : {
180 3333 : if (!_subproblem.vectorTagExists(tag_id))
181 0 : mooseError("Vector tag ", tag_id, " does not exist in system");
182 :
183 3333 : _vector_tags.insert(tag_id);
184 3333 : }
185 :
186 : void
187 5393 : TaggingInterface::useMatrixTag(TagID tag_id, MatrixTagsKey)
188 : {
189 5393 : if (!_subproblem.matrixTagExists(tag_id))
190 0 : mooseError("Matrix tag ", tag_id, " does not exist in system");
191 :
192 5393 : _matrix_tags.insert(tag_id);
193 5393 : }
194 :
195 : void
196 763440022 : TaggingInterface::prepareVectorTag(Assembly & assembly, const unsigned int ivar)
197 : {
198 763440022 : prepareVectorTagInternal(assembly, ivar, _vector_tags, _abs_vector_tags);
199 763440022 : }
200 :
201 : void
202 0 : TaggingInterface::prepareVectorTag(Assembly & assembly,
203 : const unsigned int ivar,
204 : const ResidualTagType tag_type)
205 : {
206 0 : if (tag_type == ResidualTagType::NonReference)
207 0 : prepareVectorTagInternal(assembly, ivar, _non_ref_vector_tags, _non_ref_abs_vector_tags);
208 : else
209 0 : prepareVectorTagInternal(assembly, ivar, _ref_vector_tags, _ref_abs_vector_tags);
210 0 : }
211 :
212 : void
213 763440022 : TaggingInterface::prepareVectorTagInternal(Assembly & assembly,
214 : const unsigned int ivar,
215 : const std::set<TagID> & vector_tags,
216 : const std::set<TagID> & absolute_value_vector_tags)
217 : {
218 3831398603 : auto prepare = [this, ivar, &assembly](auto & re_blocks, const auto & tags)
219 : {
220 1526880044 : re_blocks.clear();
221 1526880044 : re_blocks.reserve(tags.size());
222 2295052897 : for (const auto tag_id : tags)
223 : {
224 768172853 : const auto & tag = _subproblem.getVectorTag(tag_id);
225 768172853 : re_blocks.push_back(&assembly.residualBlock(ivar, Assembly::LocalDataKey{}, tag._type_id));
226 : }
227 1526880044 : };
228 :
229 763440022 : prepare(_re_blocks, vector_tags);
230 763440022 : prepare(_absre_blocks, absolute_value_vector_tags);
231 :
232 1526880044 : _local_re.resize(_re_blocks.empty()
233 0 : ? (_absre_blocks.empty() ? std::size_t(0) : _absre_blocks[0]->size())
234 763440022 : : _re_blocks[0]->size());
235 763440022 : }
236 :
237 : void
238 25505359 : TaggingInterface::prepareVectorTagNeighbor(Assembly & assembly, unsigned int ivar)
239 : {
240 25505359 : _re_blocks.resize(_vector_tags.size());
241 : mooseAssert(_vector_tags.size() >= 1, "we need at least one active tag");
242 25505359 : auto vector_tag = _vector_tags.begin();
243 51012176 : for (MooseIndex(_vector_tags) i = 0; i < _vector_tags.size(); i++, ++vector_tag)
244 : {
245 25506817 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
246 25506817 : _re_blocks[i] = &assembly.residualBlockNeighbor(ivar, Assembly::LocalDataKey{}, tag._type_id);
247 : }
248 25505359 : _local_re.resize(_re_blocks[0]->size());
249 :
250 25505359 : _absre_blocks.resize(_abs_vector_tags.size());
251 25505359 : vector_tag = _abs_vector_tags.begin();
252 25505503 : for (MooseIndex(_abs_vector_tags) i = 0; i < _abs_vector_tags.size(); i++, ++vector_tag)
253 : {
254 144 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
255 144 : _absre_blocks[i] =
256 288 : &assembly.residualBlockNeighbor(ivar, Assembly::LocalDataKey{}, tag._type_id);
257 : }
258 25505359 : }
259 :
260 : void
261 110242 : TaggingInterface::prepareVectorTagLower(Assembly & assembly, unsigned int ivar)
262 : {
263 110242 : _re_blocks.resize(_vector_tags.size());
264 : mooseAssert(_vector_tags.size() >= 1, "we need at least one active tag");
265 110242 : auto vector_tag = _vector_tags.begin();
266 220484 : for (MooseIndex(_vector_tags) i = 0; i < _vector_tags.size(); i++, ++vector_tag)
267 : {
268 110242 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
269 110242 : _re_blocks[i] = &assembly.residualBlockLower(ivar, Assembly::LocalDataKey{}, tag._type_id);
270 : }
271 110242 : _local_re.resize(_re_blocks[0]->size());
272 :
273 110242 : _absre_blocks.resize(_abs_vector_tags.size());
274 110242 : vector_tag = _abs_vector_tags.begin();
275 110386 : for (MooseIndex(_abs_vector_tags) i = 0; i < _abs_vector_tags.size(); i++, ++vector_tag)
276 : {
277 144 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
278 144 : _absre_blocks[i] = &assembly.residualBlockLower(ivar, Assembly::LocalDataKey{}, tag._type_id);
279 : }
280 110242 : }
281 :
282 : void
283 142818410 : TaggingInterface::prepareMatrixTag(Assembly & assembly, unsigned int ivar, unsigned int jvar)
284 : {
285 142818410 : _ke_blocks.resize(_matrix_tags.size());
286 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
287 142818410 : auto mat_vector = _matrix_tags.begin();
288 332802315 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
289 189983905 : _ke_blocks[i] = &assembly.jacobianBlock(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
290 :
291 142818410 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
292 142818410 : }
293 :
294 : void
295 0 : TaggingInterface::prepareMatrixTag(Assembly & assembly,
296 : unsigned int ivar,
297 : unsigned int jvar,
298 : DenseMatrix<Number> & k) const
299 : {
300 : mooseAssert(!_matrix_tags.empty(), "No matrix tags exist");
301 : const auto & ij_mat =
302 0 : assembly.jacobianBlock(ivar, jvar, Assembly::LocalDataKey{}, *_matrix_tags.begin());
303 0 : k.resize(ij_mat.m(), ij_mat.n());
304 0 : }
305 :
306 : void
307 854 : TaggingInterface::prepareMatrixTagNonlocal(Assembly & assembly,
308 : unsigned int ivar,
309 : unsigned int jvar)
310 : {
311 854 : _ke_blocks.resize(_matrix_tags.size());
312 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
313 854 : auto mat_vector = _matrix_tags.begin();
314 1708 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
315 1708 : _ke_blocks[i] =
316 854 : &assembly.jacobianBlockNonlocal(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
317 :
318 854 : _nonlocal_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
319 854 : }
320 :
321 : void
322 424925 : TaggingInterface::prepareMatrixTagNeighbor(Assembly & assembly,
323 : unsigned int ivar,
324 : unsigned int jvar,
325 : Moose::DGJacobianType type)
326 : {
327 424925 : _ke_blocks.resize(_matrix_tags.size());
328 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
329 424925 : auto mat_vector = _matrix_tags.begin();
330 863734 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
331 877618 : _ke_blocks[i] =
332 438809 : &assembly.jacobianBlockNeighbor(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
333 :
334 424925 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
335 424925 : }
336 :
337 : void
338 4256 : TaggingInterface::prepareMatrixTagNeighbor(Assembly & assembly,
339 : unsigned int ivar,
340 : unsigned int jvar,
341 : Moose::DGJacobianType type,
342 : DenseMatrix<Number> & k) const
343 : {
344 : mooseAssert(!_matrix_tags.empty(), "No matrix tags exist");
345 4256 : const auto & ij_mat = assembly.jacobianBlockNeighbor(
346 4256 : type, ivar, jvar, Assembly::LocalDataKey{}, *_matrix_tags.begin());
347 4256 : k.resize(ij_mat.m(), ij_mat.n());
348 4256 : }
349 :
350 : void
351 301808 : TaggingInterface::prepareMatrixTagLower(Assembly & assembly,
352 : unsigned int ivar,
353 : unsigned int jvar,
354 : Moose::ConstraintJacobianType type)
355 : {
356 301808 : _ke_blocks.resize(_matrix_tags.size());
357 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
358 301808 : auto mat_vector = _matrix_tags.begin();
359 603616 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
360 603616 : _ke_blocks[i] =
361 301808 : &assembly.jacobianBlockMortar(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
362 :
363 301808 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
364 301808 : }
365 :
366 : void
367 783015444 : TaggingInterface::accumulateTaggedLocalResidual()
368 : {
369 1570247695 : for (auto & re : _re_blocks)
370 787232251 : *re += _local_re;
371 783533196 : for (auto & absre : _absre_blocks)
372 1553832 : for (const auto i : index_range(_local_re))
373 1036080 : (*absre)(i) += std::abs(_local_re(i));
374 783015444 : }
375 :
376 : void
377 44252 : TaggingInterface::assignTaggedLocalResidual()
378 : {
379 88504 : for (auto & re : _re_blocks)
380 44252 : *re = _local_re;
381 44270 : for (auto & absre : _absre_blocks)
382 36 : for (const auto i : index_range(_local_re))
383 18 : (*absre)(i) = std::abs(_local_re(i));
384 44252 : }
385 :
386 : void
387 143525354 : TaggingInterface::accumulateTaggedLocalMatrix()
388 : {
389 334230087 : for (auto & ke : _ke_blocks)
390 190704733 : *ke += _local_ke;
391 143525354 : }
392 :
393 : void
394 0 : TaggingInterface::accumulateTaggedLocalMatrix(Assembly & assembly,
395 : const unsigned int ivar,
396 : const unsigned int jvar,
397 : const DenseMatrix<Number> & k)
398 : {
399 0 : _ke_blocks.resize(_matrix_tags.size());
400 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
401 0 : auto mat_vector = _matrix_tags.begin();
402 0 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
403 0 : _ke_blocks[i] = &assembly.jacobianBlock(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
404 : mooseAssert(_ke_blocks[0]->m() == k.m() && _ke_blocks[0]->n() == k.n(),
405 : "Passed-in k must match the blocks we are about to sum into");
406 0 : for (auto & ke : _ke_blocks)
407 0 : *ke += k;
408 0 : }
409 :
410 : void
411 0 : TaggingInterface::accumulateTaggedLocalMatrix(Assembly & assembly,
412 : const unsigned int ivar,
413 : const unsigned int jvar,
414 : const Moose::DGJacobianType type,
415 : const DenseMatrix<Number> & k)
416 : {
417 0 : _ke_blocks.resize(_matrix_tags.size());
418 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
419 0 : auto mat_vector = _matrix_tags.begin();
420 0 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
421 0 : _ke_blocks[i] =
422 0 : &assembly.jacobianBlockNeighbor(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
423 : mooseAssert(_ke_blocks[0]->m() == k.m() && _ke_blocks[0]->n() == k.n(),
424 : "Passed-in k must match the blocks we are about to sum into");
425 0 : for (auto & ke : _ke_blocks)
426 0 : *ke += k;
427 0 : }
428 :
429 : void
430 854 : TaggingInterface::accumulateTaggedNonlocalMatrix()
431 : {
432 1708 : for (auto & ke : _ke_blocks)
433 854 : *ke += _nonlocal_ke;
434 854 : }
435 :
436 : void
437 18 : TaggingInterface::assignTaggedLocalMatrix()
438 : {
439 36 : for (auto & ke : _ke_blocks)
440 18 : *ke = _local_ke;
441 18 : }
442 :
443 195800 : TaggingInterface::~TaggingInterface() {}
|