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 5128 : ComputeIndicatorThread::ComputeIndicatorThread(FEProblemBase & fe_problem, bool finalize)
27 : : ThreadedElementLoop<ConstElemRange>(fe_problem),
28 5128 : _fe_problem(fe_problem),
29 10256 : _aux_sys(fe_problem.getAuxiliarySystem()),
30 5128 : _indicator_whs(_fe_problem.getIndicatorWarehouse()),
31 5128 : _internal_side_indicators(_fe_problem.getInternalSideIndicatorWarehouse()),
32 5128 : _finalize(finalize)
33 : {
34 5128 : }
35 :
36 : // Splitting Constructor
37 480 : ComputeIndicatorThread::ComputeIndicatorThread(ComputeIndicatorThread & x, Threads::split split)
38 : : ThreadedElementLoop<ConstElemRange>(x, split),
39 480 : _fe_problem(x._fe_problem),
40 480 : _aux_sys(x._aux_sys),
41 480 : _indicator_whs(x._indicator_whs),
42 480 : _internal_side_indicators(x._internal_side_indicators),
43 480 : _finalize(x._finalize)
44 : {
45 480 : }
46 :
47 6088 : ComputeIndicatorThread::~ComputeIndicatorThread() {}
48 :
49 : void
50 29210 : ComputeIndicatorThread::subdomainChanged()
51 : {
52 29210 : _fe_problem.subdomainSetup(_subdomain, _tid);
53 :
54 29210 : _indicator_whs.subdomainSetup(_tid);
55 29210 : _internal_side_indicators.subdomainSetup(_tid);
56 :
57 29210 : std::set<MooseVariableFEBase *> needed_moose_vars;
58 29210 : _indicator_whs.updateVariableDependency(needed_moose_vars, _tid);
59 29210 : _internal_side_indicators.updateVariableDependency(needed_moose_vars, _tid);
60 29210 : _fe_problem.setActiveElementalMooseVariables(needed_moose_vars, _tid);
61 :
62 : // Update variable coupleable vector tags
63 29210 : std::set<TagID> needed_var_vector_tags;
64 29210 : _indicator_whs.updateBlockFEVariableCoupledVectorTagDependency(
65 29210 : _subdomain, needed_var_vector_tags, _tid);
66 29210 : _internal_side_indicators.updateBlockFEVariableCoupledVectorTagDependency(
67 29210 : _subdomain, needed_var_vector_tags, _tid);
68 29210 : _fe_problem.getMaterialWarehouse().updateBlockFEVariableCoupledVectorTagDependency(
69 29210 : _subdomain, needed_var_vector_tags, _tid);
70 29210 : _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_var_vector_tags, _tid);
71 :
72 29210 : std::unordered_set<unsigned int> needed_mat_props;
73 29210 : _indicator_whs.updateMatPropDependency(needed_mat_props, _tid);
74 29210 : _internal_side_indicators.updateMatPropDependency(needed_mat_props, _tid);
75 :
76 29210 : _fe_problem.prepareMaterials(needed_mat_props, _subdomain, _tid);
77 29210 : }
78 :
79 : void
80 1731406 : ComputeIndicatorThread::onElement(const Elem * elem)
81 : {
82 6167466 : for (auto * var : _aux_sys._elem_vars[_tid])
83 4436060 : var->prepareAux();
84 :
85 1731406 : _fe_problem.prepare(elem, _tid);
86 1731406 : _fe_problem.reinitElem(elem, _tid);
87 :
88 : // Set up Sentinel class so that, even if reinitMaterials() throws, we
89 : // still remember to swap back during stack unwinding.
90 1731406 : SwapBackSentinel sentinel(_fe_problem, &FEProblemBase::swapBackMaterials, _tid);
91 :
92 1731406 : _fe_problem.reinitMaterials(_subdomain, _tid);
93 :
94 : // Compute
95 1731406 : if (!_finalize)
96 : {
97 865703 : if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
98 : {
99 : const std::vector<std::shared_ptr<Indicator>> & indicators =
100 38338 : _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
101 76676 : for (const auto & indicator : indicators)
102 38338 : indicator->computeIndicator();
103 : }
104 : }
105 :
106 : // Finalize
107 : else
108 : {
109 865703 : if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
110 : {
111 : const std::vector<std::shared_ptr<Indicator>> & indicators =
112 38338 : _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
113 76676 : for (const auto & indicator : indicators)
114 38338 : indicator->finalize();
115 : }
116 :
117 865703 : if (_internal_side_indicators.hasActiveBlockObjects(_subdomain, _tid))
118 : {
119 : const std::vector<std::shared_ptr<InternalSideIndicatorBase>> & internal_indicators =
120 851519 : _internal_side_indicators.getActiveBlockObjects(_subdomain, _tid);
121 1704838 : for (const auto & internal_indicator : internal_indicators)
122 853319 : internal_indicator->finalize();
123 : }
124 : }
125 :
126 1731406 : if (!_finalize) // During finalize the Indicators should be setting values in the vectors manually
127 : {
128 865703 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
129 3083733 : for (auto * var : _aux_sys._elem_vars[_tid])
130 2218030 : var->add(_aux_sys.solution());
131 865703 : }
132 1731406 : }
133 :
134 : void
135 279562 : ComputeIndicatorThread::onBoundary(const Elem * /*elem*/,
136 : unsigned int /*side*/,
137 : BoundaryID /*bnd_id*/,
138 : const Elem * /*lower_d_elem = nullptr*/)
139 : {
140 279562 : }
141 :
142 : void
143 3470464 : ComputeIndicatorThread::onInternalSide(const Elem * elem, unsigned int side)
144 : {
145 3470464 : if (_finalize) // If finalizing we only do something on the elements
146 1735232 : return;
147 :
148 : // Pointer to the neighbor we are currently working on.
149 1735232 : const Elem * neighbor = elem->neighbor_ptr(side);
150 :
151 6201400 : for (auto * var : _aux_sys._elem_vars[_tid])
152 4466168 : var->prepareAux();
153 :
154 1735232 : SubdomainID block_id = elem->subdomain_id();
155 1735232 : if (_internal_side_indicators.hasActiveBlockObjects(block_id, _tid))
156 : {
157 1709263 : _fe_problem.reinitNeighbor(elem, side, _tid);
158 :
159 : // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
160 : // still remember to swap back during stack unwinding.
161 1709263 : SwapBackSentinel face_sentinel(_fe_problem, &FEProblemBase::swapBackMaterialsFace, _tid);
162 1709263 : _fe_problem.reinitMaterialsFace(block_id, _tid);
163 :
164 : SwapBackSentinel neighbor_sentinel(
165 1709263 : _fe_problem, &FEProblemBase::swapBackMaterialsNeighbor, _tid);
166 1709263 : _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
167 :
168 : const std::vector<std::shared_ptr<InternalSideIndicatorBase>> & indicators =
169 1709263 : _internal_side_indicators.getActiveBlockObjects(block_id, _tid);
170 3421766 : for (const auto & indicator : indicators)
171 1712503 : indicator->computeIndicator();
172 1709263 : }
173 : }
174 :
175 : void
176 1731406 : ComputeIndicatorThread::postElement(const Elem * /*elem*/)
177 : {
178 1731406 : }
179 :
180 : void
181 5608 : ComputeIndicatorThread::post()
182 : {
183 5608 : _fe_problem.clearActiveElementalMooseVariables(_tid);
184 5608 : _fe_problem.clearActiveMaterialProperties(_tid);
185 5608 : }
186 :
187 : void
188 480 : ComputeIndicatorThread::join(const ComputeIndicatorThread & /*y*/)
189 : {
190 480 : }
191 :
192 : void
193 5608 : ComputeIndicatorThread::printGeneralExecutionInformation() const
194 : {
195 5608 : if (!_fe_problem.shouldPrintExecution(_tid))
196 5468 : return;
197 :
198 140 : const auto & console = _fe_problem.console();
199 140 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag();
200 140 : if (!_finalize)
201 70 : console << "[DBG] Executing indicators on elements then on internal sides on " << execute_on
202 70 : << std::endl;
203 : else
204 70 : console << "[DBG] Finalizing indicator loop" << std::endl;
205 : }
206 :
207 : void
208 29210 : ComputeIndicatorThread::printBlockExecutionInformation() const
209 : {
210 29210 : if (!_fe_problem.shouldPrintExecution(_tid) || _blocks_exec_printed.count(_subdomain))
211 29070 : return;
212 :
213 140 : const auto & console = _fe_problem.console();
214 140 : if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
215 : {
216 80 : const auto & indicators = _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
217 80 : console << "[DBG] Ordering of element indicators on block " << _subdomain << std::endl;
218 80 : printExecutionOrdering<Indicator>(indicators, false);
219 : }
220 140 : if (_internal_side_indicators.hasActiveBlockObjects(_subdomain, _tid))
221 : {
222 140 : const auto & indicators = _internal_side_indicators.getActiveBlockObjects(_subdomain, _tid);
223 140 : console << "[DBG] Ordering of element internal sides indicators on block " << _subdomain
224 140 : << std::endl;
225 140 : printExecutionOrdering<InternalSideIndicatorBase>(indicators, false);
226 : }
227 140 : _blocks_exec_printed.insert(_subdomain);
228 : }
|