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 "ComputeIndicatorThread.h"
11 :
12 : // MOOSE includes
13 : #include "AuxiliarySystem.h"
14 : #include "FEProblem.h"
15 : #include "Indicator.h"
16 : #include "InternalSideIndicatorBase.h"
17 : #include "MooseVariableFE.h"
18 : #include "Problem.h"
19 : #include "SwapBackSentinel.h"
20 : // For dynamic casting to Coupleable
21 : #include "Material.h"
22 : #include "InterfaceMaterial.h"
23 :
24 : #include "libmesh/threads.h"
25 :
26 4750 : ComputeIndicatorThread::ComputeIndicatorThread(FEProblemBase & fe_problem, bool finalize)
27 : : ThreadedElementLoop<ConstElemRange>(fe_problem),
28 4750 : _fe_problem(fe_problem),
29 9500 : _aux_sys(fe_problem.getAuxiliarySystem()),
30 4750 : _indicator_whs(_fe_problem.getIndicatorWarehouse()),
31 4750 : _internal_side_indicators(_fe_problem.getInternalSideIndicatorWarehouse()),
32 4750 : _finalize(finalize)
33 : {
34 4750 : }
35 :
36 : // Splitting Constructor
37 14 : ComputeIndicatorThread::ComputeIndicatorThread(ComputeIndicatorThread & x, Threads::split split)
38 : : ThreadedElementLoop<ConstElemRange>(x, split),
39 14 : _fe_problem(x._fe_problem),
40 14 : _aux_sys(x._aux_sys),
41 14 : _indicator_whs(x._indicator_whs),
42 14 : _internal_side_indicators(x._internal_side_indicators),
43 14 : _finalize(x._finalize)
44 : {
45 14 : }
46 :
47 4778 : ComputeIndicatorThread::~ComputeIndicatorThread() {}
48 :
49 : void
50 25062 : ComputeIndicatorThread::subdomainChanged()
51 : {
52 25062 : _fe_problem.subdomainSetup(_subdomain, _tid);
53 :
54 25062 : _indicator_whs.subdomainSetup(_tid);
55 25062 : _internal_side_indicators.subdomainSetup(_tid);
56 :
57 25062 : std::set<MooseVariableFEBase *> needed_moose_vars;
58 25062 : _indicator_whs.updateVariableDependency(needed_moose_vars, _tid);
59 25062 : _internal_side_indicators.updateVariableDependency(needed_moose_vars, _tid);
60 25062 : _fe_problem.setActiveElementalMooseVariables(needed_moose_vars, _tid);
61 :
62 : // Update variable coupleable vector tags
63 25062 : std::set<TagID> needed_var_vector_tags;
64 25062 : _indicator_whs.updateBlockFEVariableCoupledVectorTagDependency(
65 25062 : _subdomain, needed_var_vector_tags, _tid);
66 25062 : _internal_side_indicators.updateBlockFEVariableCoupledVectorTagDependency(
67 25062 : _subdomain, needed_var_vector_tags, _tid);
68 25062 : _fe_problem.getMaterialWarehouse().updateBlockFEVariableCoupledVectorTagDependency(
69 25062 : _subdomain, needed_var_vector_tags, _tid);
70 25062 : _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_var_vector_tags, _tid);
71 :
72 25062 : std::unordered_set<unsigned int> needed_mat_props;
73 25062 : _indicator_whs.updateMatPropDependency(needed_mat_props, _tid);
74 25062 : _internal_side_indicators.updateMatPropDependency(needed_mat_props, _tid);
75 :
76 : // Only prepare (and therefore reinit) materials if an indicator actually consumes a material
77 : // property. Otherwise skip the material system entirely to avoid recomputing the whole stack.
78 25062 : if (!needed_mat_props.empty())
79 0 : _fe_problem.prepareMaterials(needed_mat_props, _subdomain, _tid);
80 : else
81 25062 : _fe_problem.clearActiveMaterialProperties(_tid);
82 25062 : }
83 :
84 : void
85 1523446 : ComputeIndicatorThread::onElement(const Elem * elem)
86 : {
87 5442852 : for (auto * var : _aux_sys._elem_vars[_tid])
88 3919406 : var->prepareAux();
89 :
90 1523446 : _fe_problem.prepare(elem, _tid);
91 1523446 : _fe_problem.reinitElem(elem, _tid);
92 :
93 : // Set up Sentinel class so that, even if reinitMaterials() throws, we
94 : // still remember to swap back during stack unwinding.
95 1523446 : SwapBackSentinel sentinel(_fe_problem, &FEProblemBase::swapBackMaterials, _tid);
96 :
97 1523446 : _fe_problem.reinitMaterials(_subdomain, _tid);
98 :
99 : // Compute
100 1523446 : if (!_finalize)
101 : {
102 761723 : if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
103 : {
104 : const std::vector<std::shared_ptr<Indicator>> & indicators =
105 33256 : _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
106 66512 : for (const auto & indicator : indicators)
107 33256 : indicator->computeIndicator();
108 : }
109 : }
110 :
111 : // Finalize
112 : else
113 : {
114 761723 : if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
115 : {
116 : const std::vector<std::shared_ptr<Indicator>> & indicators =
117 33256 : _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
118 66512 : for (const auto & indicator : indicators)
119 33256 : indicator->finalize();
120 : }
121 :
122 761723 : if (_internal_side_indicators.hasActiveBlockObjects(_subdomain, _tid))
123 : {
124 : const std::vector<std::shared_ptr<InternalSideIndicatorBase>> & internal_indicators =
125 749115 : _internal_side_indicators.getActiveBlockObjects(_subdomain, _tid);
126 1503222 : for (const auto & internal_indicator : internal_indicators)
127 754107 : internal_indicator->finalize();
128 : }
129 : }
130 :
131 1523446 : if (!_finalize) // During finalize the Indicators should be setting values in the vectors manually
132 2721426 : for (auto * var : _aux_sys._elem_vars[_tid])
133 1959703 : var->add(_aux_sys.solution());
134 1523446 : }
135 :
136 : void
137 248646 : ComputeIndicatorThread::onBoundary(const Elem * /*elem*/,
138 : unsigned int /*side*/,
139 : BoundaryID /*bnd_id*/,
140 : const Elem * /*lower_d_elem = nullptr*/)
141 : {
142 248646 : }
143 :
144 : void
145 3051382 : ComputeIndicatorThread::onInternalSide(const Elem * elem, unsigned int side)
146 : {
147 3051382 : if (_finalize) // If finalizing we only do something on the elements
148 1525691 : return;
149 :
150 : // Pointer to the neighbor we are currently working on.
151 1525691 : const Elem * neighbor = elem->neighbor_ptr(side);
152 :
153 5467115 : for (auto * var : _aux_sys._elem_vars[_tid])
154 3941424 : var->prepareAux();
155 :
156 1525691 : SubdomainID block_id = elem->subdomain_id();
157 1525691 : if (_internal_side_indicators.hasActiveBlockObjects(block_id, _tid))
158 : {
159 1502606 : _fe_problem.reinitNeighbor(elem, side, _tid);
160 :
161 : // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
162 : // still remember to swap back during stack unwinding.
163 1502606 : SwapBackSentinel face_sentinel(_fe_problem, &FEProblemBase::swapBackMaterialsFace, _tid);
164 1502606 : _fe_problem.reinitMaterialsFace(block_id, _tid);
165 :
166 : SwapBackSentinel neighbor_sentinel(
167 1502606 : _fe_problem, &FEProblemBase::swapBackMaterialsNeighbor, _tid);
168 1502606 : _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
169 :
170 : const std::vector<std::shared_ptr<InternalSideIndicatorBase>> & indicators =
171 1502606 : _internal_side_indicators.getActiveBlockObjects(block_id, _tid);
172 3014492 : for (const auto & indicator : indicators)
173 1511886 : indicator->computeIndicator();
174 1502606 : }
175 : }
176 :
177 : void
178 1523446 : ComputeIndicatorThread::postElement(const Elem * /*elem*/)
179 : {
180 1523446 : }
181 :
182 : void
183 4764 : ComputeIndicatorThread::post()
184 : {
185 4764 : _fe_problem.clearActiveElementalMooseVariables(_tid);
186 4764 : _fe_problem.clearActiveMaterialProperties(_tid);
187 4764 : }
188 :
189 : void
190 14 : ComputeIndicatorThread::join(const ComputeIndicatorThread & /*y*/)
191 : {
192 14 : }
193 :
194 : void
195 4764 : ComputeIndicatorThread::printGeneralExecutionInformation() const
196 : {
197 4764 : if (!_fe_problem.shouldPrintExecution(_tid))
198 4638 : return;
199 :
200 126 : const auto & console = _fe_problem.console();
201 126 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag();
202 126 : if (!_finalize)
203 63 : console << "[DBG] Executing indicators on elements then on internal sides on " << execute_on
204 63 : << std::endl;
205 : else
206 63 : console << "[DBG] Finalizing indicator loop" << std::endl;
207 : }
208 :
209 : void
210 25062 : ComputeIndicatorThread::printBlockExecutionInformation() const
211 : {
212 25062 : if (!_fe_problem.shouldPrintExecution(_tid) || _blocks_exec_printed.count(_subdomain))
213 24936 : return;
214 :
215 126 : const auto & console = _fe_problem.console();
216 126 : if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
217 : {
218 72 : const auto & indicators = _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
219 72 : console << "[DBG] Ordering of element indicators on block " << _subdomain << std::endl;
220 216 : printExecutionOrdering<Indicator>(indicators, false);
221 : }
222 126 : if (_internal_side_indicators.hasActiveBlockObjects(_subdomain, _tid))
223 : {
224 126 : const auto & indicators = _internal_side_indicators.getActiveBlockObjects(_subdomain, _tid);
225 126 : console << "[DBG] Ordering of element internal sides indicators on block " << _subdomain
226 126 : << std::endl;
227 378 : printExecutionOrdering<InternalSideIndicatorBase>(indicators, false);
228 : }
229 126 : _blocks_exec_printed.insert(_subdomain);
230 : }
|