www.mooseframework.org
ComputeResidualThread.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "ComputeResidualThread.h"
11 #include "NonlinearSystem.h"
12 #include "Problem.h"
13 #include "FEProblem.h"
14 #include "KernelBase.h"
15 #include "IntegratedBCBase.h"
16 #include "DGKernelBase.h"
17 #include "InterfaceKernel.h"
18 #include "Material.h"
19 #include "TimeKernel.h"
20 #include "SwapBackSentinel.h"
21 
22 #include "libmesh/threads.h"
23 
25  const std::set<TagID> & tags)
26  : ThreadedElementLoop<ConstElemRange>(fe_problem),
27  _nl(fe_problem.getNonlinearSystemBase()),
28  _tags(tags),
29  _num_cached(0),
30  _integrated_bcs(_nl.getIntegratedBCWarehouse()),
31  _dg_kernels(_nl.getDGKernelWarehouse()),
32  _interface_kernels(_nl.getInterfaceKernelWarehouse()),
33  _kernels(_nl.getKernelWarehouse())
34 {
35 }
36 
37 // Splitting Constructor
39  : ThreadedElementLoop<ConstElemRange>(x, split),
40  _nl(x._nl),
41  _tags(x._tags),
42  _num_cached(0),
43  _integrated_bcs(x._integrated_bcs),
44  _dg_kernels(x._dg_kernels),
45  _interface_kernels(x._interface_kernels),
46  _kernels(x._kernels),
47  _tag_kernels(x._tag_kernels)
48 {
49 }
50 
52 
53 void
55 {
57 
58  // Update variable Dependencies
59  std::set<MooseVariableFEBase *> needed_moose_vars;
64 
65  // Update material dependencies
66  std::set<unsigned int> needed_mat_props;
71 
73  _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid);
75 
76  // If users pass a empty vector or a full size of vector,
77  // we take all kernels
78  if (!_tags.size() || _tags.size() == _fe_problem.numVectorTags())
79  {
84  }
85  // If we have one tag only,
86  // We call tag based storage
87  else if (_tags.size() == 1)
88  {
93  }
94  // This one may be expensive
95  else
96  {
101  }
102 }
103 
104 void
106 {
107  _fe_problem.prepare(elem, _tid);
108  _fe_problem.reinitElem(elem, _tid);
109 
110  // Set up Sentinel class so that, even if reinitMaterials() throws, we
111  // still remember to swap back during stack unwinding.
113 
115 
117  {
118  const auto & kernels = _tag_kernels->getActiveBlockObjects(_subdomain, _tid);
119  for (const auto & kernel : kernels)
120  kernel->computeResidual();
121  }
122 }
123 
124 void
125 ComputeResidualThread::onBoundary(const Elem * elem, unsigned int side, BoundaryID bnd_id)
126 {
128  {
129  const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
130 
131  _fe_problem.reinitElemFace(elem, side, bnd_id, _tid);
132 
133  // Set up Sentinel class so that, even if reinitMaterialsFace() throws, we
134  // still remember to swap back during stack unwinding.
136 
137  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
139 
140  for (const auto & bc : bcs)
141  {
142  if (bc->shouldApply())
143  bc->computeResidual();
144  }
145  }
146 }
147 
148 void
149 ComputeResidualThread::onInterface(const Elem * elem, unsigned int side, BoundaryID bnd_id)
150 {
152  {
153 
154  // Pointer to the neighbor we are currently working on.
155  const Elem * neighbor = elem->neighbor_ptr(side);
156 
157  if (neighbor->active())
158  {
159  _fe_problem.reinitNeighbor(elem, side, _tid);
160 
161  // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
162  // still remember to swap back during stack unwinding.
164  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
166 
168  _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
169 
170  const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
171  for (const auto & interface_kernel : int_ks)
172  interface_kernel->computeResidual();
173 
174  {
175  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
177  }
178  }
179  }
180 }
181 
182 void
183 ComputeResidualThread::onInternalSide(const Elem * elem, unsigned int side)
184 {
186  {
187  // Pointer to the neighbor we are currently working on.
188  const Elem * neighbor = elem->neighbor_ptr(side);
189 
190  // Get the global id of the element and the neighbor
191  const dof_id_type elem_id = elem->id(), neighbor_id = neighbor->id();
192 
193  if ((neighbor->active() && (neighbor->level() == elem->level()) && (elem_id < neighbor_id)) ||
194  (neighbor->level() < elem->level()))
195  {
196  _fe_problem.reinitNeighbor(elem, side, _tid);
197 
198  // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
199  // still remember to swap back during stack unwinding.
201  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
202 
204  _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
205 
206  const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid);
207  for (const auto & dg_kernel : dgks)
208  if (dg_kernel->hasBlocks(neighbor->subdomain_id()))
209  dg_kernel->computeResidual();
210 
211  {
212  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
214  }
215  }
216  }
217 }
218 
219 void
221 {
223  _num_cached++;
224 
225  if (_num_cached % 20 == 0)
226  {
227  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
229  }
230 }
231 
232 void
234 {
237 }
238 
239 void
241 {
242 }
virtual void onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id) override
Called when doing boundary assembling.
void updateBoundaryVariableDependency(std::set< MooseVariableFEBase *> &needed_moose_vars, THREAD_ID tid=0) const
virtual void prepare(const Elem *elem, THREAD_ID tid) override
Base class for assembly-like calculations.
virtual void addResidualNeighbor(THREAD_ID tid) override
bool hasActiveBlockObjects(THREAD_ID tid=0) const
void updateBlockMatPropDependency(SubdomainID id, std::set< unsigned int > &needed_mat_props, THREAD_ID tid=0) const
virtual void prepareMaterials(SubdomainID blk_id, THREAD_ID tid)
Add the MooseVariables that the current materials depend on to the dependency list.
virtual void setActiveElementalMooseVariables(const std::set< MooseVariableFEBase *> &moose_vars, THREAD_ID tid) override
Set the MOOSE variables to be reinited on each element.
const std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
virtual void postElement(const Elem *) override
Called after the element assembly is done (including surface assembling)
MooseObjectTagWarehouse< KernelBase > & _kernels
virtual void reinitMaterialsNeighbor(SubdomainID blk_id, THREAD_ID tid, bool swap_stateful=true)
void updateBlockVariableDependency(SubdomainID id, std::set< MooseVariableFEBase *> &needed_moose_vars, THREAD_ID tid=0) const
virtual void subdomainChanged() override
Called every time the current subdomain changes (i.e.
MooseObjectWarehouse< T > & getVectorTagsObjectWarehouse(const std::set< TagID > &tags, THREAD_ID tid)
Retrieve a moose object warehouse in which every moose object at least has one of the given vector ta...
MooseObjectWarehouse< KernelBase > * _tag_kernels
void join(const ComputeResidualThread &)
static PetscErrorCode Vec x
virtual void reinitElem(const Elem *elem, THREAD_ID tid) override
virtual void reinitMaterials(SubdomainID blk_id, THREAD_ID tid, bool swap_stateful=true)
virtual void reinitMaterialsBoundary(BoundaryID boundary_id, THREAD_ID tid, bool swap_stateful=true)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual void setActiveMaterialProperties(const std::set< unsigned int > &mat_prop_ids, THREAD_ID tid) override
Record and set the material properties required by the current computing thread.
virtual void subdomainSetup(SubdomainID subdomain, THREAD_ID tid)
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
MooseObjectTagWarehouse< InterfaceKernel > & _interface_kernels
Reference to interface kernel storage structure.
std::vector< std::string > split(const std::string &str, const std::string &delimiter)
Python like split function for strings.
Definition: MooseUtils.C:784
MooseObjectTagWarehouse< DGKernelBase > & _dg_kernels
Reference to DGKernel storage structure.
boundary_id_type BoundaryID
virtual void addCachedResidual(THREAD_ID tid) override
virtual void clearActiveMaterialProperties(THREAD_ID tid) override
Clear the active material properties.
virtual void onElement(const Elem *elem) override
Assembly of the element (not including surface assembly)
virtual void swapBackMaterials(THREAD_ID tid)
virtual unsigned int numVectorTags() const
The total number of tags.
Definition: SubProblem.h:122
virtual void swapBackMaterialsNeighbor(THREAD_ID tid)
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
MooseObjectWarehouse< InterfaceKernel > * _ik_warehouse
virtual void reinitElemFace(const Elem *elem, unsigned int side, BoundaryID bnd_id, THREAD_ID tid) override
virtual void post() override
Called after the element range loop.
virtual void onInternalSide(const Elem *elem, unsigned int side) override
Called when doing internal edge assembling.
ComputeResidualThread(FEProblemBase &fe_problem, const std::set< TagID > &tags)
virtual void reinitMaterialsFace(SubdomainID blk_id, THREAD_ID tid, bool swap_stateful=true)
const std::set< TagID > & _tags
MooseObjectWarehouse< T > & getVectorTagObjectWarehouse(TagID tag_id, THREAD_ID tid)
Retrieve a moose object warehouse in which every moose object has the given vector tag...
virtual void reinitNeighbor(const Elem *elem, unsigned int side, THREAD_ID tid) override
virtual void onInterface(const Elem *elem, unsigned int side, BoundaryID bnd_id) override
Called when doing interface assembling.
MooseObjectTagWarehouse< IntegratedBCBase > & _integrated_bcs
Reference to BC storage structures.
SubdomainID _subdomain
The subdomain for the current element.
virtual void cacheResidual(THREAD_ID tid) override
virtual void swapBackMaterialsFace(THREAD_ID tid)
MooseObjectWarehouse< IntegratedBCBase > * _ibc_warehouse
virtual void clearActiveElementalMooseVariables(THREAD_ID tid) override
Clear the active elemental MooseVariableFEBase.
void updateBoundaryMatPropDependency(std::set< unsigned int > &needed_mat_props, THREAD_ID tid=0) const
The "SwapBackSentinel" class&#39;s destructor guarantees that FEProblemBase::swapBackMaterials{Face,Neighbor}() is called even when an exception is thrown from FEProblemBase::reinitMaterials{Face,Neighbor}.
MooseObjectWarehouse< DGKernelBase > * _dg_warehouse