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 98 : ElementLoopUserObject::validParams()
14 : {
15 98 : InputParameters params = GeneralUserObject::validParams();
16 98 : params += BlockRestrictable::validParams();
17 98 : return params;
18 0 : }
19 :
20 49 : ElementLoopUserObject::ElementLoopUserObject(const InputParameters & parameters)
21 : : GeneralUserObject(parameters),
22 : BlockRestrictable(this),
23 : Coupleable(this, false),
24 : MooseVariableDependencyInterface(this),
25 98 : _mesh(_subproblem.mesh()),
26 49 : _current_elem(_assembly.elem()),
27 49 : _current_elem_volume(_assembly.elemVolume()),
28 49 : _q_point(_assembly.qPoints()),
29 49 : _qrule(_assembly.qRule()),
30 49 : _JxW(_assembly.JxW()),
31 49 : _coord(_assembly.coordTransformation()),
32 49 : _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 98 : for (unsigned int i = 0; i < coupled_vars.size(); i++)
37 98 : addMooseVariableDependency(coupled_vars[i]);
38 49 : }
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 49 : ElementLoopUserObject::~ElementLoopUserObject() {}
61 :
62 : void
63 744 : ElementLoopUserObject::initialize()
64 : {
65 744 : }
66 :
67 : void
68 47400 : ElementLoopUserObject::preElement(const Elem * elem)
69 : {
70 47400 : _fe_problem.setCurrentSubdomainID(elem, _tid);
71 47400 : }
72 :
73 : void
74 744 : ElementLoopUserObject::execute()
75 : {
76 744 : ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
77 :
78 : try
79 : {
80 744 : pre();
81 :
82 744 : _subdomain = std::numeric_limits<SubdomainID>::max();
83 : ConstElemRange::const_iterator el = elem_range.begin();
84 48144 : for (el = elem_range.begin(); el != elem_range.end(); ++el)
85 : {
86 47400 : if (!keepGoing())
87 : break;
88 :
89 47400 : const Elem * elem = *el;
90 : unsigned int cur_subdomain = elem->subdomain_id();
91 47400 : preElement(elem);
92 :
93 47400 : _old_subdomain = _subdomain;
94 47400 : _subdomain = cur_subdomain;
95 :
96 47400 : if (this->hasBlocks(_subdomain))
97 : {
98 45400 : if (_subdomain != _old_subdomain)
99 720 : subdomainChanged();
100 :
101 45400 : onElement(elem);
102 :
103 136200 : for (unsigned int side = 0; side < elem->n_sides(); side++)
104 : {
105 90800 : std::vector<BoundaryID> boundary_ids = _mesh.getBoundaryIDs(elem, side);
106 :
107 90800 : if (boundary_ids.size() > 0)
108 : for (std::vector<BoundaryID>::iterator it = boundary_ids.begin();
109 1896 : it != boundary_ids.end();
110 : ++it)
111 948 : onBoundary(elem, side, *it);
112 :
113 90800 : if (elem->neighbor_ptr(side) != NULL)
114 : {
115 89892 : if (this->hasBlocks(elem->neighbor_ptr(side)->subdomain_id()))
116 89852 : onInternalSide(elem, side);
117 89892 : if (boundary_ids.size() > 0)
118 : for (std::vector<BoundaryID>::iterator it = boundary_ids.begin();
119 80 : it != boundary_ids.end();
120 : ++it)
121 40 : onInterface(elem, side, *it);
122 : }
123 90800 : } // sides
124 : }
125 : } // range
126 :
127 744 : post();
128 : }
129 0 : catch (MooseException & e)
130 : {
131 0 : caughtMooseException(e);
132 0 : }
133 744 : }
134 :
135 : void
136 744 : ElementLoopUserObject::finalize()
137 : {
138 744 : _have_interface_elems = true;
139 744 : }
140 :
141 : void
142 744 : ElementLoopUserObject::pre()
143 : {
144 744 : }
145 :
146 : void
147 720 : ElementLoopUserObject::subdomainChanged()
148 : {
149 720 : }
150 :
151 : void
152 45400 : ElementLoopUserObject::onElement(const Elem * elem)
153 : {
154 45400 : _current_elem = elem;
155 45400 : computeElement();
156 45400 : }
157 :
158 : void
159 948 : ElementLoopUserObject::onBoundary(const Elem * /*elem*/, unsigned int side, BoundaryID /*bnd_id*/)
160 : {
161 948 : _current_side = side;
162 948 : computeBoundary();
163 948 : }
164 :
165 : void
166 89852 : ElementLoopUserObject::onInternalSide(const Elem * elem, unsigned int side)
167 : {
168 89852 : _current_elem = elem;
169 : // Pointer to the neighbor we are currently working on.
170 89852 : _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 89852 : if ((_current_neighbor->active() && (_current_neighbor->level() == elem->level()) &&
178 44926 : (elem_id < neighbor_id)) ||
179 44926 : (_current_neighbor->level() < elem->level()))
180 : {
181 44926 : computeInternalSide();
182 : }
183 :
184 89852 : if (!_have_interface_elems &&
185 5638 : (_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 30 : _interface_elem_ids.insert(_current_elem->id());
190 : }
191 89852 : }
192 :
193 : void
194 40 : ElementLoopUserObject::onInterface(const Elem * elem, unsigned int side, BoundaryID /*bnd_id*/)
195 : {
196 40 : _current_elem = elem;
197 : // Pointer to the neighbor we are currently working on.
198 40 : _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 40 : if ((_current_neighbor->active() && (_current_neighbor->level() == elem->level()) &&
206 0 : (elem_id < neighbor_id)) ||
207 0 : (_current_neighbor->level() < elem->level()))
208 : {
209 40 : computeInterface();
210 : }
211 :
212 40 : if (!_have_interface_elems &&
213 5 : (_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 3 : _interface_elem_ids.insert(_current_elem->id());
218 : }
219 40 : }
220 :
221 : void
222 744 : ElementLoopUserObject::post()
223 : {
224 744 : }
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 948 : ElementLoopUserObject::computeBoundary()
238 : {
239 948 : }
240 :
241 : void
242 44926 : ElementLoopUserObject::computeInternalSide()
243 : {
244 44926 : }
245 :
246 : void
247 40 : ElementLoopUserObject::computeInterface()
248 : {
249 40 : }
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 : }
|