www.mooseframework.org
AuxiliarySystem.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 #include "AuxiliarySystem.h"
16 #include "FEProblem.h"
17 #include "Factory.h"
18 #include "AuxKernel.h"
19 #include "AuxScalarKernel.h"
20 #include "MaterialData.h"
21 #include "Assembly.h"
22 #include "GeometricSearchData.h"
27 #include "Parser.h"
28 #include "TimeIntegrator.h"
29 #include "Conversion.h"
30 
31 #include "libmesh/quadrature_gauss.h"
32 #include "libmesh/node_range.h"
33 #include "libmesh/numeric_vector.h"
34 
35 // AuxiliarySystem ////////
36 
37 AuxiliarySystem::AuxiliarySystem(FEProblemBase & subproblem, const std::string & name)
38  : SystemBase(subproblem, name, Moose::VAR_AUXILIARY),
39  _fe_problem(subproblem),
40  _sys(subproblem.es().add_system<TransientExplicitSystem>(name)),
41  _current_solution(NULL),
42  _serialized_solution(*NumericVector<Number>::build(_fe_problem.comm()).release()),
43  _solution_previous_nl(NULL),
44  _u_dot(addVector("u_dot", true, GHOSTED)),
45  _need_serialized_solution(false)
46 {
47  _nodal_vars.resize(libMesh::n_threads());
48  _elem_vars.resize(libMesh::n_threads());
49 }
50 
52 
53 void
55 {
56 }
57 
58 void
60 {
62  _solution_previous_nl = &addVector("u_previous_newton", true, GHOSTED);
63 }
64 
65 void
67 {
68  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
69  {
72 
75 
78  }
79 }
80 
81 void
83 {
84  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
85  {
89  }
90 }
91 
92 void
94 {
95  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
96  {
100  }
101 }
102 
103 void
105 {
106  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
107  {
111  }
112 }
113 
114 void
116 {
117  for (unsigned int tid = 0; tid < libMesh::n_threads(); tid++)
118  {
122  }
123 }
124 
125 void
127 {
131 }
132 
133 void
134 AuxiliarySystem::addVariable(const std::string & var_name,
135  const FEType & type,
136  Real scale_factor,
137  const std::set<SubdomainID> * const active_subdomains /* = NULL*/)
138 {
139  SystemBase::addVariable(var_name, type, scale_factor, active_subdomains);
140  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
141  {
142  MooseVariable * var = dynamic_cast<MooseVariable *>(_vars[tid].getVariable(var_name));
143  if (var != NULL)
144  {
145  if (var->feType().family == LAGRANGE)
146  _nodal_vars[tid][var_name] = var;
147  else
148  _elem_vars[tid][var_name] = var;
149  }
150  }
151 }
152 
153 void
155  const std::string & name,
156  InputParameters parameters)
157 {
158  parameters.set<SystemBase *>("_sys") = this;
160 }
161 
162 void
163 AuxiliarySystem::addKernel(const std::string & kernel_name,
164  const std::string & name,
165  InputParameters parameters)
166 {
167  parameters.set<AuxiliarySystem *>("_aux_sys") = this;
168 
169  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
170  {
171  std::shared_ptr<AuxKernel> kernel =
172  _factory.create<AuxKernel>(kernel_name, name, parameters, tid);
173  if (kernel->isNodal())
174  _nodal_aux_storage.addObject(kernel, tid);
175  else
176  _elemental_aux_storage.addObject(kernel, tid);
177  }
178 }
179 
180 void
181 AuxiliarySystem::addScalarKernel(const std::string & kernel_name,
182  const std::string & name,
183  InputParameters parameters)
184 {
185  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
186  {
187  std::shared_ptr<AuxScalarKernel> kernel =
188  _factory.create<AuxScalarKernel>(kernel_name, name, parameters, tid);
189  _aux_scalar_storage.addObject(kernel, tid);
190  }
191 }
192 
193 void
194 AuxiliarySystem::reinitElem(const Elem * /*elem*/, THREAD_ID tid)
195 {
196  for (const auto & it : _nodal_vars[tid])
197  {
198  MooseVariable * var = it.second;
199  var->computeElemValues();
200  }
201 
202  for (const auto & it : _elem_vars[tid])
203  {
204  MooseVariable * var = it.second;
205  var->reinitAux();
206  var->computeElemValues();
207  }
208 }
209 
210 void
211 AuxiliarySystem::reinitElemFace(const Elem * /*elem*/,
212  unsigned int /*side*/,
213  BoundaryID /*bnd_id*/,
214  THREAD_ID tid)
215 {
216  for (const auto & it : _nodal_vars[tid])
217  {
218  MooseVariable * var = it.second;
219  var->computeElemValuesFace();
220  }
221 
222  for (const auto & it : _elem_vars[tid])
223  {
224  MooseVariable * var = it.second;
225  var->reinitAux();
226  var->reinitAuxNeighbor();
227  var->computeElemValuesFace();
228  }
229 }
230 
231 NumericVector<Number> &
233 {
234  return _u_dot;
235 }
236 
237 NumericVector<Number> &
239 {
241  return _serialized_solution;
242 }
243 
244 void
246 {
248  _sys.n_dofs() > 0) // libMesh does not like serializing of empty vectors
249  {
250  if (!_serialized_solution.initialized() || _serialized_solution.size() != _sys.n_dofs())
251  {
252  _serialized_solution.clear();
253  _serialized_solution.init(_sys.n_dofs(), false, SERIAL);
254  }
255 
256  solution().localize(_serialized_solution);
257  }
258 }
259 
260 void
262 {
263  // avoid division by dt which might be zero.
264  if (_fe_problem.dt() > 0. && _time_integrator)
265  _time_integrator->preStep();
266 
267  // We need to compute time derivatives every time each kind of the variables is finished, because:
268  //
269  // a) the user might want to use the aux variable value somewhere, thus we need to provide the
270  // up-to-date value
271  // b) time integration system works with the whole vectors of solutions, thus we cannot update
272  // only a part of the vector
273  //
274 
275  if (_vars[0].scalars().size() > 0)
276  {
277  computeScalarVars(type);
278  // compute time derivatives of scalar aux variables _after_ the values were updated
279  if (_fe_problem.dt() > 0. && _time_integrator)
280  _time_integrator->computeTimeDerivatives();
281  }
282 
283  if (_vars[0].variables().size() > 0)
284  {
285  computeNodalVars(type);
286  // compute time derivatives of nodal aux variables _after_ the values were updated
287  if (_fe_problem.dt() > 0. && _time_integrator)
288  _time_integrator->computeTimeDerivatives();
289  }
290 
291  if (_vars[0].variables().size() > 0)
292  {
293  computeElementalVars(type);
294  // compute time derivatives of elemental aux variables _after_ the values were updated
295  if (_fe_problem.dt() > 0. && _time_integrator)
296  _time_integrator->computeTimeDerivatives();
297  }
298 
301 }
302 
303 std::set<std::string>
305 {
306  std::set<std::string> depend_objects;
307 
308  // Elemental AuxKernels
309  {
310  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
312  for (const auto & aux : auxs)
313  {
314  const std::set<std::string> & uo = aux->getDependObjects();
315  depend_objects.insert(uo.begin(), uo.end());
316  }
317  }
318 
319  // Nodal AuxKernels
320  {
321  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
323  for (const auto & aux : auxs)
324  {
325  const std::set<std::string> & uo = aux->getDependObjects();
326  depend_objects.insert(uo.begin(), uo.end());
327  }
328  }
329 
330  return depend_objects;
331 }
332 
333 std::set<std::string>
335 {
336  std::set<std::string> depend_objects;
337 
338  // Elemental AuxKernels
339  {
340  const std::vector<std::shared_ptr<AuxKernel>> & auxs =
342  for (const auto & aux : auxs)
343  {
344  const std::set<std::string> & uo = aux->getDependObjects();
345  depend_objects.insert(uo.begin(), uo.end());
346  }
347  }
348 
349  // Nodal AuxKernels
350  {
351  const std::vector<std::shared_ptr<AuxKernel>> & auxs = _nodal_aux_storage.getActiveObjects();
352  for (const auto & aux : auxs)
353  {
354  const std::set<std::string> & uo = aux->getDependObjects();
355  depend_objects.insert(uo.begin(), uo.end());
356  }
357  }
358 
359  return depend_objects;
360 }
361 
362 NumericVector<Number> &
363 AuxiliarySystem::addVector(const std::string & vector_name,
364  const bool project,
365  const ParallelType type)
366 {
367  if (hasVector(vector_name))
368  return getVector(vector_name);
369 
370  NumericVector<Number> * vec = &_sys.add_vector(vector_name, project, type);
371 
372  return *vec;
373 }
374 
375 void
377 {
378  // Reference to the current storage container
380 
381  if (storage.hasActiveObjects())
382  {
383  std::string compute_aux_tag = "computeScalarAux(" + Moose::stringify(type) + ")";
384  Moose::perf_log.push(compute_aux_tag, "Execution");
385 
386  PARALLEL_TRY
387  {
388  // FIXME: run multi-threaded
389  THREAD_ID tid = 0;
390  if (storage.hasActiveObjects())
391  {
393 
394  // Call compute() method on all active AuxScalarKernel objects
395  const std::vector<std::shared_ptr<AuxScalarKernel>> & objects =
396  storage.getActiveObjects(tid);
397  for (const auto & obj : objects)
398  obj->compute();
399 
400  const std::vector<MooseVariableScalar *> & scalar_vars = getScalarVariables(tid);
401  for (const auto & var : scalar_vars)
402  var->insert(solution());
403  }
404  }
405  PARALLEL_CATCH;
406 
407  Moose::perf_log.pop(compute_aux_tag, "Execution");
408 
409  solution().close();
410  _sys.update();
411  }
412 }
413 
414 void
416 {
417  // Reference to the Nodal AuxKernel storage
419 
420  if (nodal.hasActiveBlockObjects())
421  {
422  std::string compute_aux_tag = "computeNodalAux(" + Moose::stringify(type) + ")";
423  Moose::perf_log.push(compute_aux_tag, "Execution");
424 
425  // Block Nodal AuxKernels
426  PARALLEL_TRY
427  {
428  ConstNodeRange & range = *_mesh.getLocalNodeRange();
430  Threads::parallel_reduce(range, navt);
431 
432  solution().close();
433  _sys.update();
434  }
435  PARALLEL_CATCH;
436  Moose::perf_log.pop(compute_aux_tag, "Execution");
437  }
438 
439  if (nodal.hasActiveBoundaryObjects())
440  {
441  std::string compute_aux_tag = "computeNodalAuxBCs(" + Moose::stringify(type) + ")";
442  Moose::perf_log.push(compute_aux_tag, "Execution");
443 
444  // Boundary Nodal AuxKernels
445  PARALLEL_TRY
446  {
449  Threads::parallel_reduce(bnd_nodes, nabt);
450 
451  solution().close();
452  _sys.update();
453  }
454  PARALLEL_CATCH;
455  Moose::perf_log.pop(compute_aux_tag, "Execution");
456  }
457 }
458 
459 void
461 {
462  // Reference to the Nodal AuxKernel storage
464 
465  if (elemental.hasActiveBlockObjects())
466  {
467  std::string compute_aux_tag = "computeElemAux(" + Moose::stringify(type) + ")";
468  Moose::perf_log.push(compute_aux_tag, "Execution");
469 
470  // Block Elemental AuxKernels
471  PARALLEL_TRY
472  {
473  ConstElemRange & range = *_mesh.getActiveLocalElementRange();
474  ComputeElemAuxVarsThread eavt(_fe_problem, elemental, true);
475  Threads::parallel_reduce(range, eavt);
476 
477  solution().close();
478  _sys.update();
479  }
480  PARALLEL_CATCH;
481  Moose::perf_log.pop(compute_aux_tag, "Execution");
482  }
483 
484  // Boundary Elemental AuxKernels
485  if (elemental.hasActiveBoundaryObjects())
486  {
487  std::string compute_aux_tag = "computeElemAuxBCs(" + Moose::stringify(type) + ")";
488  Moose::perf_log.push(compute_aux_tag, "Execution");
489 
490  PARALLEL_TRY
491  {
493  ComputeElemAuxBcsThread eabt(_fe_problem, elemental, true);
494  Threads::parallel_reduce(bnd_elems, eabt);
495 
496  solution().close();
497  _sys.update();
498  }
499  PARALLEL_CATCH;
500  Moose::perf_log.pop(compute_aux_tag, "Execution");
501  }
502 }
503 
504 void
505 AuxiliarySystem::augmentSparsity(SparsityPattern::Graph & /*sparsity*/,
506  std::vector<dof_id_type> & /*n_nz*/,
507  std::vector<dof_id_type> & /*n_oz*/)
508 {
509 }
510 
511 Order
513 {
514  Order order = CONSTANT;
515  std::vector<MooseVariable *> vars = _vars[0].variables();
516  for (const auto & var : vars)
517  {
518  if (!var->isNodal()) // nodal aux variables do not need quadrature
519  {
520  FEType fe_type = var->feType();
521  if (fe_type.default_quadrature_order() > order)
522  order = fe_type.default_quadrature_order();
523  }
524  }
525 
526  return order;
527 }
528 
529 bool
531 {
533 }
534 
535 void
537 {
538  // Evaluate aux variables to get the solution vector
540 }
Object is evaluated in every residual computation.
Definition: MooseTypes.h:96
ExecuteMooseObjectWarehouse< AuxKernel > _nodal_aux_storage
ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems...
Definition: MooseMesh.C:685
std::shared_ptr< MooseObject > create(const std::string &obj_name, const std::string &name, InputParameters parameters, THREAD_ID tid=0, bool print_deprecated=true)
Build an object (must be registered) - THIS METHOD IS DEPRECATED (Use create<T>()) ...
Definition: Factory.C:46
NumericVector< Number > & _serialized_solution
Serialized version of the solution vector.
const std::vector< MooseVariableScalar * > & getScalarVariables(THREAD_ID tid)
Definition: SystemBase.h:422
void computeScalarVars(ExecFlagType type)
void sort(THREAD_ID tid=0)
Performs a sort using the DependencyResolver.
const FEType & feType() const
Get the type of finite element object.
Class for stuff related to variables.
Definition: MooseVariable.h:43
virtual void augmentSparsity(SparsityPattern::Graph &, std::vector< dof_id_type > &, std::vector< dof_id_type > &) override
Will modify the sparsity pattern to add logical geometric connections.
std::vector< std::map< std::string, MooseVariable * > > _nodal_vars
void jacobianSetup(THREAD_ID tid=0) const
Convenience methods for calling object setup methods.
virtual void addVariable(const std::string &var_name, const FEType &type, Real scale_factor, const std::set< SubdomainID > *const active_subdomains=NULL)
Adds a variable to the system.
Definition: SystemBase.C:500
virtual NumericVector< Number > & solutionUDot() override
virtual const std::string & name()
Definition: SystemBase.h:453
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > ConstBndElemRange
Definition: MooseMesh.h:1185
virtual void subdomainSetup(THREAD_ID tid=0) const
virtual void computeElemValuesFace()
Compute values at facial quadrature points.
AuxiliarySystem(FEProblemBase &subproblem, const std::string &name)
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
virtual void updateActive(THREAD_ID tid)
Factory & _factory
Definition: SystemBase.h:481
NumericVector< Number > & _u_dot
solution vector for u^dot
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Base class for a system (of equations)
Definition: SystemBase.h:91
ExecuteMooseObjectWarehouse< AuxScalarKernel > _aux_scalar_storage
virtual void addExtraVectors() override
Method called during initialSetup to add extra system vector if they are required by the simulation...
bool needMaterialOnSide(BoundaryID bnd_id)
Indicated whether this system needs material properties on boundaries.
virtual void reinitElem(const Elem *elem, THREAD_ID tid) override
Reinit an element assembly info.
ConstNodeRange * getLocalNodeRange()
Definition: MooseMesh.C:714
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual void residualSetup()
void reinitAuxNeighbor()
virtual void timestepSetup()
virtual void addObject(std::shared_ptr< T > object, THREAD_ID tid=0)
Adds an object to the storage structure.
std::set< std::string > getDependObjects()
virtual bool hasVector(const std::string &name)
Check if the named vector exists in the system.
Definition: SystemBase.C:589
void computeElementalVars(ExecFlagType type)
virtual void setPreviousNewtonSolution()
std::vector< std::map< std::string, MooseVariable * > > _elem_vars
NumericVector< Number > & addVector(const std::string &vector_name, const bool project, const ParallelType type) override
Adds a solution length vector to the system.
Base class for making kernels that work on auxiliary scalar variables.
virtual void timestepSetup(THREAD_ID tid=0) const
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
virtual void jacobianSetup()
FEProblemBase & _fe_problem
virtual Order getMinQuadratureOrder() override
Get the minimum quadrature order for evaluating elemental auxiliary variables.
virtual void initialSetup(THREAD_ID tid=0) const
Convenience methods for calling object setup methods.
PerfLog perf_log
Perflog to be used by applications.
void needsPreviousNewtonIteration(bool state)
Set a flag that indicated that user required values for the previous Newton iterate.
bool hasActiveObjects(THREAD_ID tid=0) const
Convenience functions for determining if objects exist.
virtual Real & dt() const
Base class for creating new auxiliary kernels and auxiliary boundary conditions.
Definition: AuxKernel.h:51
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:66
TransientExplicitSystem & _sys
void residualSetup(THREAD_ID tid=0) const
bool _need_serialized_solution
Whether or not a copy of the residual needs to be made.
virtual void compute(ExecFlagType type)
Compute auxiliary variables.
virtual NumericVector< Number > & solution() override
std::vector< VariableWarehouse > _vars
Variable warehouses (one for each thread)
Definition: SystemBase.h:488
MatType type
virtual void computeElemValues()
Compute values at interior quadrature points.
virtual void reinitScalars(THREAD_ID tid) override
Base class for time integrators.
MooseMesh & _mesh
Definition: SystemBase.h:483
MPI_Comm comm
void computeNodalVars(ExecFlagType type)
void addScalarKernel(const std::string &kernel_name, const std::string &name, InputParameters parameters)
Adds a scalar kernel.
virtual void reinitElemFace(const Elem *elem, unsigned int side, BoundaryID bnd_id, THREAD_ID tid) override
Reinit assembly info for a side of an element.
bool hasActiveBlockObjects(THREAD_ID tid=0) const
ExecuteMooseObjectWarehouse< AuxKernel > _elemental_aux_storage
virtual NumericVector< Number > & serializedSolution() override
Returns a reference to a serialized version of the solution vector for this subproblem.
ExecFlagType
Execution flags - when is the object executed/evaluated.
Definition: MooseTypes.h:90
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
Definition: MooseMesh.C:734
Definition: Moose.h:84
virtual void serializeSolution()
virtual void initialSetup()
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > ConstBndNodeRange
Some useful StoredRange typedefs.
Definition: MooseMesh.h:1184
virtual void updateActive(THREAD_ID tid=0)
Updates the active objects storage.
virtual void addVariable(const std::string &var_name, const FEType &type, Real scale_factor, const std::set< SubdomainID > *const active_subdomains=NULL) override
Adds a variable to the system.
const std::vector< std::shared_ptr< T > > & getActiveObjects(THREAD_ID tid=0) const
Retrieve complete vector to the active all/block/boundary restricted objects for a given thread...
void addTimeIntegrator(const std::string &type, const std::string &name, InputParameters parameters)
Add a time integrator.
virtual void init() override
Initialize the system.
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector.
Definition: SystemBase.C:598
NumericVector< Number > * _solution_previous_nl
Solution vector of the previous nonlinear iterate.
virtual ~AuxiliarySystem()
A system that holds auxiliary variables.
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
Definition: MooseMesh.C:724
std::shared_ptr< TimeIntegrator > _time_integrator
Time integrator.
boundary_id_type BoundaryID
Definition: MooseTypes.h:75
unsigned int THREAD_ID
Definition: MooseTypes.h:79
void addKernel(const std::string &kernel_name, const std::string &name, InputParameters parameters)
Adds an auxiliary kernel.
virtual void subdomainSetup()