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 6008789 : TaggingInterface::validParams()
21 : {
22 :
23 6008789 : InputParameters params = emptyInputParameters();
24 :
25 : // These are the default names for tags, but users will be able to add their own
26 6008789 : MultiMooseEnum vtags("nontime time", "nontime", true);
27 6008789 : MultiMooseEnum mtags("nontime system", "system", true);
28 :
29 18026367 : params.addParam<bool>(
30 12017578 : "matrix_only", false, "Whether this object is only doing assembly to matrices (no vectors)");
31 :
32 6008789 : params.addParam<MultiMooseEnum>(
33 : "vector_tags", vtags, "The tag for the vectors this Kernel should fill");
34 :
35 6008789 : params.addParam<MultiMooseEnum>(
36 : "matrix_tags", mtags, "The tag for the matrices this Kernel should fill");
37 :
38 6008789 : params.addParam<std::vector<TagName>>("extra_vector_tags",
39 : "The extra tags for the vectors this Kernel should fill");
40 :
41 6008789 : 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 6008789 : params.addParam<std::vector<TagName>>("extra_matrix_tags",
47 : "The extra tags for the matrices this Kernel should fill");
48 :
49 6008789 : 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 12017578 : return params;
54 6008789 : }
55 :
56 189729 : TaggingInterface::TaggingInterface(const MooseObject * moose_object)
57 189729 : : _subproblem(*moose_object->parameters().getCheckedPointerParam<SubProblem *>("_subproblem")),
58 189729 : _moose_object(*moose_object),
59 379458 : _tag_params(_moose_object.parameters())
60 : {
61 189729 : auto & vector_tag_names = _tag_params.get<MultiMooseEnum>("vector_tags");
62 :
63 189729 : if (!vector_tag_names.isValid())
64 : {
65 30 : 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 379427 : for (auto & vector_tag_name : vector_tag_names)
71 : {
72 189736 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name.name());
73 189728 : 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 189728 : _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 189717 : auto & extra_vector_tags = _tag_params.get<std::vector<TagName>>("extra_vector_tags");
86 :
87 191771 : for (auto & vector_tag_name : extra_vector_tags)
88 : {
89 2054 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name);
90 2054 : 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 2054 : _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 189717 : auto & abs_vector_tags = _tag_params.get<std::vector<TagName>>("absolute_value_vector_tags");
102 :
103 190510 : for (auto & vector_tag_name : abs_vector_tags)
104 : {
105 809 : const TagID vector_tag_id = _subproblem.getVectorTagID(vector_tag_name);
106 809 : 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 793 : _abs_vector_tags.insert(vector_tag_id);
113 : }
114 :
115 189701 : auto & matrix_tag_names = _tag_params.get<MultiMooseEnum>("matrix_tags");
116 :
117 189701 : if (matrix_tag_names.isValid())
118 463010 : for (auto & matrix_tag_name : matrix_tag_names)
119 273313 : _matrix_tags.insert(_subproblem.getMatrixTagID(matrix_tag_name.name()));
120 :
121 189697 : auto & extra_matrix_tags = _tag_params.get<std::vector<TagName>>("extra_matrix_tags");
122 :
123 190778 : for (auto & matrix_tag_name : extra_matrix_tags)
124 1081 : _matrix_tags.insert(_subproblem.getMatrixTagID(matrix_tag_name));
125 :
126 189697 : _re_blocks.resize(_vector_tags.size());
127 189697 : _absre_blocks.resize(_abs_vector_tags.size());
128 189697 : _ke_blocks.resize(_matrix_tags.size());
129 :
130 : const auto * const fe_problem =
131 189697 : moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base");
132 :
133 570761 : for (const auto & conv : fe_problem->getConvergenceObjects())
134 : {
135 381064 : const auto * const ref_conv = dynamic_cast<const ReferenceResidualConvergence *>(conv.get());
136 381064 : if (ref_conv)
137 : {
138 2372 : const auto reference_tag = ref_conv->referenceVectorTagID({});
139 : auto create_tags_split =
140 8266 : [reference_tag](const auto & tags, auto & non_ref_tags, auto & ref_tags)
141 : {
142 8266 : for (const auto tag : tags)
143 3522 : if (tag == reference_tag)
144 1150 : ref_tags.insert(tag);
145 : else
146 2372 : non_ref_tags.insert(tag);
147 4744 : };
148 2372 : create_tags_split(_vector_tags, _non_ref_vector_tags, _ref_vector_tags);
149 2372 : create_tags_split(_abs_vector_tags, _non_ref_abs_vector_tags, _ref_abs_vector_tags);
150 : }
151 : else
152 : {
153 378692 : _non_ref_vector_tags = _vector_tags;
154 378692 : _non_ref_abs_vector_tags = _abs_vector_tags;
155 : }
156 : }
157 189697 : }
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 3197 : TaggingInterface::useVectorTag(TagID tag_id, VectorTagsKey)
179 : {
180 3197 : if (!_subproblem.vectorTagExists(tag_id))
181 0 : mooseError("Vector tag ", tag_id, " does not exist in system");
182 :
183 3197 : _vector_tags.insert(tag_id);
184 3197 : }
185 :
186 : void
187 5176 : TaggingInterface::useMatrixTag(TagID tag_id, MatrixTagsKey)
188 : {
189 5176 : if (!_subproblem.matrixTagExists(tag_id))
190 0 : mooseError("Matrix tag ", tag_id, " does not exist in system");
191 :
192 5176 : _matrix_tags.insert(tag_id);
193 5176 : }
194 :
195 : void
196 688669486 : TaggingInterface::prepareVectorTag(Assembly & assembly, const unsigned int ivar)
197 : {
198 688669486 : prepareVectorTagInternal(assembly, ivar, _vector_tags, _abs_vector_tags);
199 688669486 : }
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 688669486 : 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 3456444647 : auto prepare = [this, ivar, &assembly](auto & re_blocks, const auto & tags)
219 : {
220 1377338972 : re_blocks.clear();
221 1377338972 : re_blocks.reserve(tags.size());
222 2070374197 : for (const auto tag_id : tags)
223 : {
224 693035225 : const auto & tag = _subproblem.getVectorTag(tag_id);
225 693035225 : re_blocks.push_back(&assembly.residualBlock(ivar, Assembly::LocalDataKey{}, tag._type_id));
226 : }
227 1377338972 : };
228 :
229 688669486 : prepare(_re_blocks, vector_tags);
230 688669486 : prepare(_absre_blocks, absolute_value_vector_tags);
231 :
232 1377338972 : _local_re.resize(_re_blocks.empty()
233 0 : ? (_absre_blocks.empty() ? std::size_t(0) : _absre_blocks[0]->size())
234 688669486 : : _re_blocks[0]->size());
235 688669486 : }
236 :
237 : void
238 24017343 : TaggingInterface::prepareVectorTagNeighbor(Assembly & assembly, unsigned int ivar)
239 : {
240 24017343 : _re_blocks.resize(_vector_tags.size());
241 : mooseAssert(_vector_tags.size() >= 1, "we need at least one active tag");
242 24017343 : auto vector_tag = _vector_tags.begin();
243 48035982 : for (MooseIndex(_vector_tags) i = 0; i < _vector_tags.size(); i++, ++vector_tag)
244 : {
245 24018639 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
246 24018639 : _re_blocks[i] = &assembly.residualBlockNeighbor(ivar, Assembly::LocalDataKey{}, tag._type_id);
247 : }
248 24017343 : _local_re.resize(_re_blocks[0]->size());
249 :
250 24017343 : _absre_blocks.resize(_abs_vector_tags.size());
251 24017343 : vector_tag = _abs_vector_tags.begin();
252 24017471 : for (MooseIndex(_abs_vector_tags) i = 0; i < _abs_vector_tags.size(); i++, ++vector_tag)
253 : {
254 128 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
255 128 : _absre_blocks[i] =
256 256 : &assembly.residualBlockNeighbor(ivar, Assembly::LocalDataKey{}, tag._type_id);
257 : }
258 24017343 : }
259 :
260 : void
261 103486 : TaggingInterface::prepareVectorTagLower(Assembly & assembly, unsigned int ivar)
262 : {
263 103486 : _re_blocks.resize(_vector_tags.size());
264 : mooseAssert(_vector_tags.size() >= 1, "we need at least one active tag");
265 103486 : auto vector_tag = _vector_tags.begin();
266 206972 : for (MooseIndex(_vector_tags) i = 0; i < _vector_tags.size(); i++, ++vector_tag)
267 : {
268 103486 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
269 103486 : _re_blocks[i] = &assembly.residualBlockLower(ivar, Assembly::LocalDataKey{}, tag._type_id);
270 : }
271 103486 : _local_re.resize(_re_blocks[0]->size());
272 :
273 103486 : _absre_blocks.resize(_abs_vector_tags.size());
274 103486 : vector_tag = _abs_vector_tags.begin();
275 103614 : for (MooseIndex(_abs_vector_tags) i = 0; i < _abs_vector_tags.size(); i++, ++vector_tag)
276 : {
277 128 : const VectorTag & tag = _subproblem.getVectorTag(*vector_tag);
278 128 : _absre_blocks[i] = &assembly.residualBlockLower(ivar, Assembly::LocalDataKey{}, tag._type_id);
279 : }
280 103486 : }
281 :
282 : void
283 127898776 : TaggingInterface::prepareMatrixTag(Assembly & assembly, unsigned int ivar, unsigned int jvar)
284 : {
285 127898776 : _ke_blocks.resize(_matrix_tags.size());
286 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
287 127898776 : auto mat_vector = _matrix_tags.begin();
288 298076740 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
289 170177964 : _ke_blocks[i] = &assembly.jacobianBlock(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
290 :
291 127898776 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
292 127898776 : }
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 770 : TaggingInterface::prepareMatrixTagNonlocal(Assembly & assembly,
308 : unsigned int ivar,
309 : unsigned int jvar)
310 : {
311 770 : _ke_blocks.resize(_matrix_tags.size());
312 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
313 770 : auto mat_vector = _matrix_tags.begin();
314 1540 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
315 1540 : _ke_blocks[i] =
316 770 : &assembly.jacobianBlockNonlocal(ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
317 :
318 770 : _nonlocal_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
319 770 : }
320 :
321 : void
322 395986 : TaggingInterface::prepareMatrixTagNeighbor(Assembly & assembly,
323 : unsigned int ivar,
324 : unsigned int jvar,
325 : Moose::DGJacobianType type)
326 : {
327 395986 : _ke_blocks.resize(_matrix_tags.size());
328 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
329 395986 : auto mat_vector = _matrix_tags.begin();
330 804314 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
331 816656 : _ke_blocks[i] =
332 408328 : &assembly.jacobianBlockNeighbor(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
333 :
334 395986 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
335 395986 : }
336 :
337 : void
338 3760 : 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 3760 : const auto & ij_mat = assembly.jacobianBlockNeighbor(
346 3760 : type, ivar, jvar, Assembly::LocalDataKey{}, *_matrix_tags.begin());
347 3760 : k.resize(ij_mat.m(), ij_mat.n());
348 3760 : }
349 :
350 : void
351 276164 : TaggingInterface::prepareMatrixTagLower(Assembly & assembly,
352 : unsigned int ivar,
353 : unsigned int jvar,
354 : Moose::ConstraintJacobianType type)
355 : {
356 276164 : _ke_blocks.resize(_matrix_tags.size());
357 : mooseAssert(_matrix_tags.size() >= 1, "we need at least one active tag");
358 276164 : auto mat_vector = _matrix_tags.begin();
359 552328 : for (MooseIndex(_matrix_tags) i = 0; i < _matrix_tags.size(); i++, ++mat_vector)
360 552328 : _ke_blocks[i] =
361 276164 : &assembly.jacobianBlockMortar(type, ivar, jvar, Assembly::LocalDataKey{}, *mat_vector);
362 :
363 276164 : _local_ke.resize(_ke_blocks[0]->m(), _ke_blocks[0]->n());
364 276164 : }
365 :
366 : void
367 707061147 : TaggingInterface::accumulateTaggedLocalResidual()
368 : {
369 1418029585 : for (auto & re : _re_blocks)
370 710968438 : *re += _local_re;
371 707521131 : for (auto & absre : _absre_blocks)
372 1380464 : for (const auto i : index_range(_local_re))
373 920480 : (*absre)(i) += std::abs(_local_re(i));
374 707061147 : }
375 :
376 : void
377 39292 : TaggingInterface::assignTaggedLocalResidual()
378 : {
379 78584 : for (auto & re : _re_blocks)
380 39292 : *re = _local_re;
381 39308 : for (auto & absre : _absre_blocks)
382 32 : for (const auto i : index_range(_local_re))
383 16 : (*absre)(i) = std::abs(_local_re(i));
384 39292 : }
385 :
386 : void
387 128553323 : TaggingInterface::accumulateTaggedLocalMatrix()
388 : {
389 299398176 : for (auto & ke : _ke_blocks)
390 170844853 : *ke += _local_ke;
391 128553323 : }
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 770 : TaggingInterface::accumulateTaggedNonlocalMatrix()
431 : {
432 1540 : for (auto & ke : _ke_blocks)
433 770 : *ke += _nonlocal_ke;
434 770 : }
435 :
436 : void
437 16 : TaggingInterface::assignTaggedLocalMatrix()
438 : {
439 32 : for (auto & ke : _ke_blocks)
440 16 : *ke = _local_ke;
441 16 : }
442 :
443 182228 : TaggingInterface::~TaggingInterface() {}
|