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 "ProjectMaterialProperties.h"
12 : #include "Problem.h"
13 : #include "FEProblem.h"
14 : #include "MaterialPropertyStorage.h"
15 : #include "MaterialData.h"
16 : #include "Assembly.h"
17 : #include "AuxKernel.h"
18 :
19 : #include "libmesh/threads.h"
20 : #include "libmesh/elem.h"
21 :
22 424 : ProjectMaterialProperties::ProjectMaterialProperties(
23 : bool refine,
24 : FEProblemBase & fe_problem,
25 : MaterialPropertyStorage & material_props,
26 : MaterialPropertyStorage & bnd_material_props,
27 424 : std::vector<std::vector<std::unique_ptr<Assembly>>> & assembly)
28 : : ThreadedElementLoop<ConstElemPointerRange>(fe_problem),
29 424 : _refine(refine),
30 424 : _fe_problem(fe_problem),
31 424 : _material_props(material_props),
32 424 : _bnd_material_props(bnd_material_props),
33 424 : _assembly(assembly),
34 424 : _need_internal_side_material(false),
35 848 : _materials(_fe_problem.getRegularMaterialsWarehouse()),
36 424 : _discrete_materials(_fe_problem.getDiscreteMaterialWarehouse())
37 : {
38 424 : }
39 :
40 : // Splitting Constructor
41 13 : ProjectMaterialProperties::ProjectMaterialProperties(ProjectMaterialProperties & x,
42 13 : Threads::split split)
43 : : ThreadedElementLoop<ConstElemPointerRange>(x, split),
44 13 : _refine(x._refine),
45 13 : _fe_problem(x._fe_problem),
46 13 : _material_props(x._material_props),
47 13 : _bnd_material_props(x._bnd_material_props),
48 13 : _assembly(x._assembly),
49 13 : _need_internal_side_material(x._need_internal_side_material),
50 13 : _materials(x._materials),
51 13 : _discrete_materials(x._discrete_materials)
52 : {
53 13 : }
54 :
55 450 : ProjectMaterialProperties::~ProjectMaterialProperties() {}
56 :
57 : void
58 287 : ProjectMaterialProperties::subdomainChanged()
59 : {
60 287 : _need_internal_side_material = _fe_problem.needSubdomainMaterialOnSide(_subdomain, _tid);
61 287 : }
62 :
63 : void
64 5210 : ProjectMaterialProperties::onElement(const Elem * elem)
65 : {
66 : // This check mirrors the check in ComputeMaterialsObjectThread::onElement as it must because it
67 : // is possible that there are no materials on this element's subdomain, e.g. if we are doing
68 : // mortar, in which case the properties will not have been resized in
69 : // ComputeMaterialsObjectThread::onElement, and consequently if we were to proceed we would get
70 : // bad access errors
71 5455 : if (!_materials.hasActiveBlockObjects(elem->subdomain_id(), _tid) &&
72 245 : !_discrete_materials.hasActiveBlockObjects(elem->subdomain_id(), _tid))
73 245 : return;
74 :
75 4965 : _assembly[_tid][0]->reinit(elem);
76 :
77 4965 : if (_refine)
78 : {
79 3825 : if (_mesh.doingPRefinement())
80 : {
81 800 : const auto & p_refinement_map = _mesh.getPRefinementMap(*elem);
82 800 : _material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
83 : p_refinement_map,
84 800 : *_assembly[_tid][0]->qRule(),
85 800 : *_assembly[_tid][0]->qRuleFace(),
86 : _tid,
87 : *elem,
88 : -1);
89 : }
90 : else
91 : {
92 : const std::vector<std::vector<QpMap>> & refinement_map =
93 3025 : _mesh.getRefinementMap(*elem, -1, -1, -1);
94 :
95 3025 : _material_props.prolongStatefulProps(
96 3025 : _mesh.processor_id(),
97 : refinement_map,
98 3025 : *_assembly[_tid][0]->qRule(),
99 3025 : *_assembly[_tid][0]->qRuleFace(),
100 : _material_props, // Passing in the same properties to do volume to volume projection
101 : _tid,
102 : *elem,
103 : -1,
104 : -1,
105 : -1); // Gets us volume projection
106 : }
107 : }
108 : else
109 : {
110 1140 : if (_mesh.doingPRefinement())
111 : {
112 0 : const auto & p_coarsening_map = _mesh.getPCoarseningMap(*elem);
113 0 : _material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
114 : p_coarsening_map,
115 0 : *_assembly[_tid][0]->qRule(),
116 0 : *_assembly[_tid][0]->qRuleFace(),
117 : _tid,
118 : *elem,
119 : -1);
120 : }
121 : else
122 : {
123 : const std::vector<std::pair<unsigned int, QpMap>> & coarsening_map =
124 1140 : _mesh.getCoarseningMap(*elem, -1);
125 :
126 1140 : _material_props.restrictStatefulProps(coarsening_map,
127 1140 : _mesh.coarsenedElementChildren(elem),
128 1140 : *_assembly[_tid][0]->qRule(),
129 1140 : *_assembly[_tid][0]->qRuleFace(),
130 : _tid,
131 : *elem,
132 : -1);
133 : }
134 : }
135 : }
136 :
137 : void
138 2018 : ProjectMaterialProperties::onBoundary(const Elem * elem,
139 : unsigned int side,
140 : BoundaryID bnd_id,
141 : const Elem * /*lower_d_elem = nullptr*/)
142 : {
143 2471 : if (_fe_problem.needBoundaryMaterialOnSide(bnd_id, _tid) &&
144 453 : _bnd_material_props.hasStatefulProperties())
145 : {
146 453 : _assembly[_tid][0]->reinit(elem, side);
147 :
148 453 : if (_refine)
149 : {
150 327 : if (_mesh.doingPRefinement())
151 : {
152 0 : const auto & p_refinement_map = _mesh.getPRefinementSideMap(*elem);
153 0 : _bnd_material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
154 : p_refinement_map,
155 0 : *_assembly[_tid][0]->qRule(),
156 0 : *_assembly[_tid][0]->qRuleFace(),
157 : _tid,
158 : *elem,
159 : side);
160 : }
161 : else
162 : {
163 : const std::vector<std::vector<QpMap>> & refinement_map =
164 327 : _mesh.getRefinementMap(*elem, side, -1, side);
165 :
166 327 : _bnd_material_props.prolongStatefulProps(
167 327 : _mesh.processor_id(),
168 : refinement_map,
169 327 : *_assembly[_tid][0]->qRule(),
170 327 : *_assembly[_tid][0]->qRuleFace(),
171 : _bnd_material_props, // Passing in the same properties to do side_to_side projection
172 : _tid,
173 : *elem,
174 : side,
175 : -1,
176 : side); // Gets us side to side projection
177 : }
178 : }
179 : else
180 : {
181 126 : if (_mesh.doingPRefinement())
182 : {
183 0 : const auto & p_coarsening_map = _mesh.getPCoarseningSideMap(*elem);
184 0 : _bnd_material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
185 : p_coarsening_map,
186 0 : *_assembly[_tid][0]->qRule(),
187 0 : *_assembly[_tid][0]->qRuleFace(),
188 : _tid,
189 : *elem,
190 : side);
191 : }
192 : else
193 : {
194 : const std::vector<std::pair<unsigned int, QpMap>> & coarsening_map =
195 126 : _mesh.getCoarseningMap(*elem, side);
196 :
197 126 : _bnd_material_props.restrictStatefulProps(coarsening_map,
198 126 : _mesh.coarsenedElementChildren(elem),
199 126 : *_assembly[_tid][0]->qRule(),
200 126 : *_assembly[_tid][0]->qRuleFace(),
201 : _tid,
202 : *elem,
203 : side);
204 : }
205 : }
206 : }
207 2018 : }
208 :
209 : void
210 21860 : ProjectMaterialProperties::onInternalSide(const Elem * elem, unsigned int /*side*/)
211 : {
212 21860 : if (_need_internal_side_material &&
213 0 : _refine) // If we're refining then we need to also project "internal" child sides.
214 : {
215 0 : mooseError("I'm pretty sure we're not handling stateful material property prolongation or "
216 : "restriction correctly on internal sides");
217 : for (unsigned int child = 0; child < elem->n_children(); child++)
218 : {
219 : const Elem * child_elem = elem->child_ptr(child);
220 :
221 : for (unsigned int side = 0; side < child_elem->n_sides(); side++)
222 : {
223 : if (!elem->is_child_on_side(child, side)) // Otherwise we already projected it
224 : {
225 : const std::vector<std::vector<QpMap>> & refinement_map =
226 : _mesh.getRefinementMap(*elem, -1, child, side);
227 :
228 : _bnd_material_props.prolongStatefulProps(
229 : _mesh.processor_id(),
230 : refinement_map,
231 : *_assembly[_tid][0]->qRule(),
232 : *_assembly[_tid][0]->qRuleFace(),
233 : _material_props, // Passing in the same properties to do side_to_side projection
234 : _tid,
235 : *elem,
236 : -1,
237 : child,
238 : side); // Gets us volume to side projection
239 : }
240 : }
241 : }
242 : }
243 21860 : }
244 :
245 : void
246 13 : ProjectMaterialProperties::join(const ProjectMaterialProperties & /*y*/)
247 : {
248 13 : }
|