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 "ElementLoopUserObject.h"
11 :
12 : InputParameters
13 74 : ElementLoopUserObject::validParams()
14 : {
15 74 : InputParameters params = GeneralUserObject::validParams();
16 74 : params += BlockRestrictable::validParams();
17 74 : return params;
18 0 : }
19 :
20 37 : ElementLoopUserObject::ElementLoopUserObject(const InputParameters & parameters)
21 : : GeneralUserObject(parameters),
22 : BlockRestrictable(this),
23 : Coupleable(this, false),
24 : MooseVariableDependencyInterface(this),
25 74 : _mesh(_subproblem.mesh()),
26 37 : _current_elem(_assembly.elem()),
27 37 : _current_elem_volume(_assembly.elemVolume()),
28 37 : _q_point(_assembly.qPoints()),
29 37 : _qrule(_assembly.qRule()),
30 37 : _JxW(_assembly.JxW()),
31 37 : _coord(_assembly.coordTransformation()),
32 37 : _have_interface_elems(false)
33 : {
34 : // Keep track of which variables are coupled so we know what we depend on
35 : const std::vector<MooseVariableFEBase *> & coupled_vars = getCoupledMooseVars();
36 74 : for (unsigned int i = 0; i < coupled_vars.size(); i++)
37 74 : addMooseVariableDependency(coupled_vars[i]);
38 37 : }
39 :
40 0 : ElementLoopUserObject::ElementLoopUserObject(ElementLoopUserObject & x, Threads::split /*split*/)
41 : : GeneralUserObject(x.parameters()),
42 : BlockRestrictable(&x),
43 : Coupleable(this, false),
44 : MooseVariableDependencyInterface(this),
45 0 : _mesh(x._subproblem.mesh()),
46 0 : _current_elem(x._assembly.elem()),
47 0 : _current_elem_volume(x._assembly.elemVolume()),
48 0 : _q_point(x._assembly.qPoints()),
49 0 : _qrule(x._assembly.qRule()),
50 0 : _JxW(x._assembly.JxW()),
51 0 : _coord(x._assembly.coordTransformation()),
52 0 : _have_interface_elems(false)
53 : {
54 : // Keep track of which variables are coupled so we know what we depend on
55 : const std::vector<MooseVariableFEBase *> & coupled_vars = x.getCoupledMooseVars();
56 0 : for (unsigned int i = 0; i < coupled_vars.size(); i++)
57 0 : addMooseVariableDependency(coupled_vars[i]);
58 0 : }
59 :
60 37 : ElementLoopUserObject::~ElementLoopUserObject() {}
61 :
62 : void
63 564 : ElementLoopUserObject::initialize()
64 : {
65 564 : }
66 :
67 : void
68 38400 : ElementLoopUserObject::preElement(const Elem * elem)
69 : {
70 38400 : _fe_problem.setCurrentSubdomainID(elem, _tid);
71 38400 : }
72 :
73 : void
74 564 : ElementLoopUserObject::execute()
75 : {
76 564 : ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
77 :
78 : try
79 : {
80 564 : pre();
81 :
82 564 : _subdomain = std::numeric_limits<SubdomainID>::max();
83 : ConstElemRange::const_iterator el = elem_range.begin();
84 38964 : for (el = elem_range.begin(); el != elem_range.end(); ++el)
85 : {
86 38400 : if (!keepGoing())
87 : break;
88 :
89 38400 : const Elem * elem = *el;
90 : unsigned int cur_subdomain = elem->subdomain_id();
91 38400 : preElement(elem);
92 :
93 38400 : _old_subdomain = _subdomain;
94 38400 : _subdomain = cur_subdomain;
95 :
96 38400 : if (this->hasBlocks(_subdomain))
97 : {
98 36800 : if (_subdomain != _old_subdomain)
99 548 : subdomainChanged();
100 :
101 36800 : onElement(elem);
102 :
103 110400 : for (unsigned int side = 0; side < elem->n_sides(); side++)
104 : {
105 73600 : std::vector<BoundaryID> boundary_ids = _mesh.getBoundaryIDs(elem, side);
106 :
107 73600 : if (boundary_ids.size() > 0)
108 : for (std::vector<BoundaryID>::iterator it = boundary_ids.begin();
109 1536 : it != boundary_ids.end();
110 : ++it)
111 768 : onBoundary(elem, side, *it);
112 :
113 73600 : if (elem->neighbor_ptr(side) != NULL)
114 : {
115 72864 : if (this->hasBlocks(elem->neighbor_ptr(side)->subdomain_id()))
116 72832 : onInternalSide(elem, side);
117 72864 : if (boundary_ids.size() > 0)
118 : for (std::vector<BoundaryID>::iterator it = boundary_ids.begin();
119 64 : it != boundary_ids.end();
120 : ++it)
121 32 : onInterface(elem, side, *it);
122 : }
123 73600 : } // sides
124 : }
125 : } // range
126 :
127 564 : post();
128 : }
129 0 : catch (MooseException & e)
130 : {
131 0 : caughtMooseException(e);
132 0 : }
133 564 : }
134 :
135 : void
136 564 : ElementLoopUserObject::finalize()
137 : {
138 564 : _have_interface_elems = true;
139 564 : }
140 :
141 : void
142 564 : ElementLoopUserObject::pre()
143 : {
144 564 : }
145 :
146 : void
147 548 : ElementLoopUserObject::subdomainChanged()
148 : {
149 548 : }
150 :
151 : void
152 36800 : ElementLoopUserObject::onElement(const Elem * elem)
153 : {
154 36800 : _current_elem = elem;
155 36800 : computeElement();
156 36800 : }
157 :
158 : void
159 768 : ElementLoopUserObject::onBoundary(const Elem * /*elem*/, unsigned int side, BoundaryID /*bnd_id*/)
160 : {
161 768 : _current_side = side;
162 768 : computeBoundary();
163 768 : }
164 :
165 : void
166 72832 : ElementLoopUserObject::onInternalSide(const Elem * elem, unsigned int side)
167 : {
168 72832 : _current_elem = elem;
169 : // Pointer to the neighbor we are currently working on.
170 72832 : _current_neighbor = elem->neighbor_ptr(side);
171 :
172 : // Get the global id of the element and the neighbor
173 : const dof_id_type elem_id = elem->id();
174 : const dof_id_type neighbor_id = _current_neighbor->id();
175 :
176 : // TODO: add if-statement to check if this needs to be executed
177 72832 : if ((_current_neighbor->active() && (_current_neighbor->level() == elem->level()) &&
178 36416 : (elem_id < neighbor_id)) ||
179 36416 : (_current_neighbor->level() < elem->level()))
180 : {
181 36416 : computeInternalSide();
182 : }
183 :
184 72832 : if (!_have_interface_elems &&
185 4550 : (_current_elem->processor_id() != _current_neighbor->processor_id()))
186 : {
187 : // if my current neighbor is on another processor store the current element ID for later
188 : // communication
189 20 : _interface_elem_ids.insert(_current_elem->id());
190 : }
191 72832 : }
192 :
193 : void
194 32 : ElementLoopUserObject::onInterface(const Elem * elem, unsigned int side, BoundaryID /*bnd_id*/)
195 : {
196 32 : _current_elem = elem;
197 : // Pointer to the neighbor we are currently working on.
198 32 : _current_neighbor = elem->neighbor_ptr(side);
199 :
200 : // Get the global id of the element and the neighbor
201 : const dof_id_type elem_id = elem->id();
202 : const dof_id_type neighbor_id = _current_neighbor->id();
203 :
204 : // TODO: add if-statement to check if this needs to be executed
205 32 : if ((_current_neighbor->active() && (_current_neighbor->level() == elem->level()) &&
206 0 : (elem_id < neighbor_id)) ||
207 0 : (_current_neighbor->level() < elem->level()))
208 : {
209 32 : computeInterface();
210 : }
211 :
212 32 : if (!_have_interface_elems &&
213 4 : (_current_elem->processor_id() != _current_neighbor->processor_id()))
214 : {
215 : // if my current neighbor is on another processor store the current element
216 : // ID for later communication
217 2 : _interface_elem_ids.insert(_current_elem->id());
218 : }
219 32 : }
220 :
221 : void
222 564 : ElementLoopUserObject::post()
223 : {
224 564 : }
225 :
226 : void
227 0 : ElementLoopUserObject::join(const ElementLoopUserObject & /*y*/)
228 : {
229 0 : }
230 :
231 : void
232 0 : ElementLoopUserObject::computeElement()
233 : {
234 0 : }
235 :
236 : void
237 768 : ElementLoopUserObject::computeBoundary()
238 : {
239 768 : }
240 :
241 : void
242 36416 : ElementLoopUserObject::computeInternalSide()
243 : {
244 36416 : }
245 :
246 : void
247 32 : ElementLoopUserObject::computeInterface()
248 : {
249 32 : }
250 :
251 : void
252 0 : ElementLoopUserObject::meshChanged()
253 : {
254 : _interface_elem_ids.clear();
255 0 : _have_interface_elems = false;
256 0 : }
257 :
258 : void
259 0 : ElementLoopUserObject::caughtMooseException(MooseException & e)
260 : {
261 0 : std::string what(e.what());
262 0 : _fe_problem.setException(what);
263 0 : }
|