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 : // MOOSE includes
11 : #include "ComputeMaterialsObjectThread.h"
12 : #include "NonlinearSystem.h"
13 : #include "Problem.h"
14 : #include "FEProblem.h"
15 : #include "MaterialPropertyStorage.h"
16 : #include "MaterialData.h"
17 : #include "Assembly.h"
18 : #include "AuxKernel.h"
19 : #include "Material.h"
20 :
21 : #include "libmesh/threads.h"
22 : #include "libmesh/quadrature.h"
23 :
24 10097 : ComputeMaterialsObjectThread::ComputeMaterialsObjectThread(
25 : FEProblemBase & fe_problem,
26 : MaterialPropertyStorage & material_props,
27 : MaterialPropertyStorage & bnd_material_props,
28 : MaterialPropertyStorage & neighbor_material_props,
29 10097 : std::vector<std::vector<std::unique_ptr<Assembly>>> & assembly)
30 : : ThreadedElementLoop<ConstElemRange>(fe_problem),
31 10097 : _fe_problem(fe_problem),
32 10097 : _material_props(material_props),
33 10097 : _bnd_material_props(bnd_material_props),
34 10097 : _neighbor_material_props(neighbor_material_props),
35 20194 : _materials(_fe_problem.getRegularMaterialsWarehouse()),
36 10097 : _interface_materials(_fe_problem.getInterfaceMaterialsWarehouse()),
37 10097 : _discrete_materials(_fe_problem.getDiscreteMaterialWarehouse()),
38 10097 : _assembly(assembly),
39 10097 : _need_internal_side_material(false),
40 10097 : _has_stateful_props(_material_props.hasStatefulProperties()),
41 10097 : _has_bnd_stateful_props(_bnd_material_props.hasStatefulProperties()),
42 20194 : _has_neighbor_stateful_props(_neighbor_material_props.hasStatefulProperties())
43 : {
44 10097 : }
45 :
46 : // Splitting Constructor
47 702 : ComputeMaterialsObjectThread::ComputeMaterialsObjectThread(ComputeMaterialsObjectThread & x,
48 702 : Threads::split split)
49 : : ThreadedElementLoop<ConstElemRange>(x, split),
50 702 : _fe_problem(x._fe_problem),
51 702 : _material_props(x._material_props),
52 702 : _bnd_material_props(x._bnd_material_props),
53 702 : _neighbor_material_props(x._neighbor_material_props),
54 702 : _materials(x._materials),
55 702 : _interface_materials(x._interface_materials),
56 702 : _discrete_materials(x._discrete_materials),
57 702 : _assembly(x._assembly),
58 702 : _need_internal_side_material(x._need_internal_side_material),
59 1404 : _has_stateful_props(_material_props.hasStatefulProperties()),
60 702 : _has_bnd_stateful_props(_bnd_material_props.hasStatefulProperties()),
61 1404 : _has_neighbor_stateful_props(_neighbor_material_props.hasStatefulProperties())
62 : {
63 702 : }
64 :
65 : void
66 50007 : ComputeMaterialsObjectThread::subdomainChanged()
67 : {
68 50007 : _need_internal_side_material = _fe_problem.needInternalNeighborSideMaterial(_subdomain, _tid);
69 50007 : _fe_problem.subdomainSetup(_subdomain, _tid);
70 :
71 50007 : std::set<MooseVariableFEBase *> needed_moose_vars;
72 50007 : _materials.updateVariableDependency(needed_moose_vars, _tid);
73 50007 : _discrete_materials.updateVariableDependency(needed_moose_vars, _tid);
74 50007 : _fe_problem.setActiveElementalMooseVariables(needed_moose_vars, _tid);
75 :
76 50007 : std::set<TagID> needed_fe_var_vector_tags;
77 50007 : _materials.updateBlockFEVariableCoupledVectorTagDependency(
78 50007 : _subdomain, needed_fe_var_vector_tags, _tid);
79 50007 : _discrete_materials.updateBlockFEVariableCoupledVectorTagDependency(
80 50007 : _subdomain, needed_fe_var_vector_tags, _tid);
81 50007 : _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_fe_var_vector_tags, _tid);
82 :
83 : // Note that we do not know here which materials will be active on this subdomain because we don't
84 : // have the various warehouses (kernels, ...) to gather the needed material properties like in
85 : // NonlinearThread
86 50007 : }
87 :
88 : void
89 1749920 : ComputeMaterialsObjectThread::onElement(const Elem * elem)
90 : {
91 1783412 : if (_materials.hasActiveBlockObjects(_subdomain, _tid) ||
92 33492 : _discrete_materials.hasActiveBlockObjects(_subdomain, _tid))
93 : {
94 1716828 : _fe_problem.prepare(elem, _tid);
95 1716828 : _fe_problem.reinitElem(elem, _tid);
96 :
97 1716828 : auto & material_data = _material_props.getMaterialData(_tid);
98 :
99 1716828 : unsigned int n_points = _assembly[_tid][0]->qRule()->n_points();
100 1716828 : material_data.resize(n_points);
101 :
102 1716828 : if (_has_stateful_props)
103 : {
104 267042 : if (_discrete_materials.hasActiveBlockObjects(_subdomain, _tid))
105 0 : _material_props.initStatefulProps(
106 0 : _tid, _discrete_materials.getActiveBlockObjects(_subdomain, _tid), n_points, *elem);
107 267042 : if (_materials.hasActiveBlockObjects(_subdomain, _tid))
108 267042 : _material_props.initStatefulProps(
109 267042 : _tid, _materials.getActiveBlockObjects(_subdomain, _tid), n_points, *elem);
110 : }
111 : }
112 1749920 : }
113 :
114 : void
115 371750 : ComputeMaterialsObjectThread::onBoundary(const Elem * elem,
116 : unsigned int side,
117 : BoundaryID bnd_id,
118 : const Elem * /*lower_d_elem = nullptr*/)
119 : {
120 371750 : if (_fe_problem.needBoundaryMaterialOnSide(bnd_id, _tid))
121 : {
122 107211 : _fe_problem.reinitElemFace(elem, side, _tid);
123 107211 : const auto face_n_points = _assembly[_tid][/*system_index*/ 0]->qRuleFace()->n_points();
124 :
125 107211 : _bnd_material_props.getMaterialData(_tid).resize(face_n_points);
126 :
127 107211 : if (_has_bnd_stateful_props)
128 : {
129 : // Face Materials
130 4198 : if (_discrete_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(_subdomain, _tid))
131 0 : _bnd_material_props.initStatefulProps(
132 : _tid,
133 0 : _discrete_materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(_subdomain, _tid),
134 : face_n_points,
135 : *elem,
136 : side);
137 4198 : if (_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(_subdomain, _tid))
138 4198 : _bnd_material_props.initStatefulProps(
139 : _tid,
140 4198 : _materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(_subdomain, _tid),
141 : face_n_points,
142 : *elem,
143 : side);
144 :
145 : // Boundary Materials
146 4198 : if (_discrete_materials.hasActiveBoundaryObjects(bnd_id, _tid))
147 0 : _bnd_material_props.initStatefulProps(
148 0 : _tid, _materials.getActiveBoundaryObjects(bnd_id, _tid), face_n_points, *elem, side);
149 4198 : if (_materials.hasActiveBoundaryObjects(bnd_id, _tid))
150 322 : _bnd_material_props.initStatefulProps(
151 322 : _tid, _materials.getActiveBoundaryObjects(bnd_id, _tid), face_n_points, *elem, side);
152 : }
153 : }
154 371750 : }
155 :
156 : void
157 3525577 : ComputeMaterialsObjectThread::onInternalSide(const Elem * elem, unsigned int side)
158 : {
159 3525577 : if (_need_internal_side_material)
160 : {
161 14255 : const Elem * neighbor = elem->neighbor_ptr(side);
162 :
163 14255 : _fe_problem.reinitElemNeighborAndLowerD(elem, side, _tid);
164 14255 : unsigned int face_n_points = _assembly[_tid][0]->qRuleFace()->n_points();
165 14255 : _bnd_material_props.getMaterialData(_tid).resize(face_n_points);
166 14255 : _neighbor_material_props.getMaterialData(_tid).resize(face_n_points);
167 :
168 14255 : if (_has_bnd_stateful_props)
169 : {
170 475 : if (_discrete_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(_subdomain, _tid))
171 0 : _bnd_material_props.initStatefulProps(
172 : _tid,
173 0 : _discrete_materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(_subdomain, _tid),
174 : face_n_points,
175 : *elem,
176 : side);
177 475 : if (_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(_subdomain, _tid))
178 475 : _bnd_material_props.initStatefulProps(
179 : _tid,
180 475 : _materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(_subdomain, _tid),
181 : face_n_points,
182 : *elem,
183 : side);
184 : }
185 :
186 14255 : unsigned int neighbor_side = neighbor->which_neighbor_am_i(_assembly[_tid][0]->elem());
187 :
188 14255 : if (_has_neighbor_stateful_props)
189 : {
190 : // Neighbor Materials
191 456 : if (_discrete_materials[Moose::NEIGHBOR_MATERIAL_DATA].hasActiveBlockObjects(
192 228 : neighbor->subdomain_id(), _tid))
193 0 : _neighbor_material_props.initStatefulProps(
194 : _tid,
195 0 : _discrete_materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveBlockObjects(
196 0 : neighbor->subdomain_id(), _tid),
197 : face_n_points,
198 : *elem,
199 : side);
200 228 : if (_materials[Moose::NEIGHBOR_MATERIAL_DATA].hasActiveBlockObjects(neighbor->subdomain_id(),
201 : _tid))
202 228 : _neighbor_material_props.initStatefulProps(
203 : _tid,
204 228 : _materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveBlockObjects(
205 228 : neighbor->subdomain_id(), _tid),
206 : face_n_points,
207 : *neighbor,
208 : neighbor_side);
209 : }
210 : }
211 3525577 : }
212 :
213 : void
214 11515 : ComputeMaterialsObjectThread::onInterface(const Elem * elem, unsigned int side, BoundaryID bnd_id)
215 : {
216 11515 : if (!_fe_problem.needInterfaceMaterialOnSide(bnd_id, _tid))
217 7851 : return;
218 :
219 3664 : _fe_problem.reinitElemFace(elem, side, _tid);
220 3664 : unsigned int face_n_points = _assembly[_tid][0]->qRuleFace()->n_points();
221 :
222 3664 : _bnd_material_props.getMaterialData(_tid).resize(face_n_points);
223 3664 : _neighbor_material_props.getMaterialData(_tid).resize(face_n_points);
224 :
225 3664 : if (_has_bnd_stateful_props)
226 : {
227 : // Face Materials
228 568 : if (_discrete_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(_subdomain, _tid))
229 0 : _bnd_material_props.initStatefulProps(
230 : _tid,
231 0 : _discrete_materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(_subdomain, _tid),
232 : face_n_points,
233 : *elem,
234 : side);
235 :
236 568 : if (_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(_subdomain, _tid))
237 568 : _bnd_material_props.initStatefulProps(
238 : _tid,
239 568 : _materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(_subdomain, _tid),
240 : face_n_points,
241 : *elem,
242 : side);
243 :
244 : // Boundary Materials
245 568 : if (_discrete_materials.hasActiveBoundaryObjects(bnd_id, _tid))
246 0 : _bnd_material_props.initStatefulProps(
247 0 : _tid, _materials.getActiveBoundaryObjects(bnd_id, _tid), face_n_points, *elem, side);
248 :
249 568 : if (_materials.hasActiveBoundaryObjects(bnd_id, _tid))
250 94 : _bnd_material_props.initStatefulProps(
251 94 : _tid, _materials.getActiveBoundaryObjects(bnd_id, _tid), face_n_points, *elem, side);
252 : }
253 :
254 3664 : const Elem * neighbor = elem->neighbor_ptr(side);
255 3664 : unsigned int neighbor_side = neighbor->which_neighbor_am_i(_assembly[_tid][0]->elem());
256 :
257 : // Do we have neighbor stateful properties or do we have stateful interface material properties?
258 : // If either then we need to reinit the neighbor, so at least at a minimum _neighbor_elem isn't
259 : // NULL!
260 7328 : if (neighbor->active() &&
261 3664 : (_has_neighbor_stateful_props ||
262 3190 : (_has_bnd_stateful_props && _interface_materials.hasActiveBoundaryObjects(bnd_id, _tid))))
263 493 : _fe_problem.reinitNeighbor(elem, side, _tid);
264 :
265 3664 : if (_has_neighbor_stateful_props && neighbor->active())
266 : {
267 : // Neighbor Materials
268 948 : if (_discrete_materials[Moose::NEIGHBOR_MATERIAL_DATA].hasActiveBlockObjects(
269 474 : neighbor->subdomain_id(), _tid))
270 0 : _neighbor_material_props.initStatefulProps(
271 : _tid,
272 0 : _discrete_materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveBlockObjects(
273 0 : neighbor->subdomain_id(), _tid),
274 : face_n_points,
275 : *elem,
276 : side);
277 :
278 474 : if (_materials[Moose::NEIGHBOR_MATERIAL_DATA].hasActiveBlockObjects(neighbor->subdomain_id(),
279 : _tid))
280 474 : _neighbor_material_props.initStatefulProps(
281 : _tid,
282 474 : _materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveBlockObjects(neighbor->subdomain_id(),
283 : _tid),
284 : face_n_points,
285 : *neighbor,
286 : neighbor_side);
287 : }
288 :
289 : // Interface Materials. Make sure we do these after neighbors
290 3664 : if (_has_bnd_stateful_props && _interface_materials.hasActiveBoundaryObjects(bnd_id, _tid))
291 151 : _bnd_material_props.initStatefulProps(
292 : _tid,
293 151 : _interface_materials.getActiveBoundaryObjects(bnd_id, _tid),
294 : face_n_points,
295 : *elem,
296 : side);
297 : }
298 :
299 : void
300 702 : ComputeMaterialsObjectThread::join(const ComputeMaterialsObjectThread & /*y*/)
301 : {
302 702 : }
303 :
304 : void
305 10799 : ComputeMaterialsObjectThread::post()
306 : {
307 10799 : _fe_problem.clearActiveElementalMooseVariables(_tid);
308 10799 : }
|