www.mooseframework.org
OversampleOutput.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 // MOOSE includes
11 #include "OversampleOutput.h"
12 #include "FEProblem.h"
13 #include "DisplacedProblem.h"
14 #include "MooseApp.h"
15 
16 #include "libmesh/distributed_mesh.h"
17 #include "libmesh/equation_systems.h"
18 #include "libmesh/mesh_function.h"
19 #include "libmesh/explicit_system.h"
20 
23 {
24 
25  // Get the parameters from the parent object
27  params.addParam<unsigned int>("refinements",
28  0,
29  "Number of uniform refinements for oversampling "
30  "(refinement levels beyond any uniform "
31  "refinements)");
32  params.addParam<Point>("position",
33  "Set a positional offset, this vector will get added to the "
34  "nodal coordinates to move the domain.");
35  params.addParam<MeshFileName>("file", "The name of the mesh file to read, for oversampling");
36 
37  // **** DEPRECATED AND REMOVED PARAMETERS ****
38  params.addDeprecatedParam<bool>("oversample",
39  false,
40  "Set to true to enable oversampling",
41  "This parameter is no longer active, simply set 'refinements' to "
42  "a value greater than zero to evoke oversampling");
43  params.addDeprecatedParam<bool>("append_oversample",
44  false,
45  "Append '_oversample' to the output file base",
46  "This parameter is no longer operational, to append "
47  "'_oversample' utilize the output block name or 'file_base'");
48 
49  // 'Oversampling' Group
50  params.addParamNamesToGroup("refinements position file", "Oversampling");
51 
52  return params;
53 }
54 
56  : AdvancedOutput(parameters),
57  _refinements(getParam<unsigned int>("refinements")),
58  _oversample(_refinements > 0 || isParamValid("file")),
59  _change_position(isParamValid("position")),
60  _position(_change_position ? getParam<Point>("position") : Point()),
61  _oversample_mesh_changed(true)
62 {
63 }
64 
65 void
67 {
69 
70  // Creates and initializes the oversampled mesh
72 }
73 
74 void
76 {
77  // Output is not allowed
78  if (!_allow_output && type != EXEC_FORCED)
79  return;
80 
81  // If recovering disable output of initial condition, it was already output
82  if (type == EXEC_INITIAL && _app.isRecovering())
83  return;
84 
85  // Return if the current output is not on the desired interval
86  if (type != EXEC_FINAL && !onInterval())
87  return;
88 
89  // store current simulation time
91 
92  // set current type
94 
95  // Call the output method
96  if (shouldOutput())
97  {
98  TIME_SECTION("outputStep", 2, "Outputting Step");
100  output();
101  }
102 
104 }
105 
107 {
108  // TODO: Remove once libmesh Issue #1184 is fixed
109  _oversample_es.reset();
110  _cloned_mesh_ptr.reset();
111 }
112 
113 void
115 {
117 }
118 
119 void
121 {
122  // Perform the mesh cloning, if needed
124  cloneMesh();
125  else
126  return;
127 
128  // Re-position the oversampled mesh
129  if (_change_position)
130  for (auto & node : _mesh_ptr->getMesh().node_ptr_range())
131  *node += _position;
132 
133  // Perform the mesh refinement
134  if (_oversample)
135  {
136  MeshRefinement mesh_refinement(_mesh_ptr->getMesh());
137 
138  // We want original and refined partitioning to match so we can
139  // query from one to the other safely on distributed meshes.
140  _mesh_ptr->getMesh().skip_partitioning(true);
141  mesh_refinement.uniformly_refine(_refinements);
142  }
143 
144  // We can't allow renumbering if we want to output multiple time
145  // steps to the same Exodus file
146  _mesh_ptr->getMesh().allow_renumbering(false);
147 
148  // Create the new EquationSystems
149  _oversample_es = std::make_unique<EquationSystems>(_mesh_ptr->getMesh());
150  _es_ptr = _oversample_es.get();
151 
152  // Reference the system from which we are copying
153  EquationSystems & source_es = _problem_ptr->es();
154 
155  // If we're going to be copying from that system later, we need to keep its
156  // original elements as ghost elements even if it gets grossly
157  // repartitioned, since we can't repartition the oversample mesh to
158  // match.
159  DistributedMesh * dist_mesh = dynamic_cast<DistributedMesh *>(&source_es.get_mesh());
160  if (dist_mesh)
161  {
162  for (auto & elem : dist_mesh->active_local_element_ptr_range())
163  dist_mesh->add_extra_ghost_elem(elem);
164  }
165 
166  // Initialize the _mesh_functions vector
167  unsigned int num_systems = source_es.n_systems();
168  _mesh_functions.resize(num_systems);
169 
170  // Loop over the number of systems
171  for (unsigned int sys_num = 0; sys_num < num_systems; sys_num++)
172  {
173  // Reference to the current system
174  System & source_sys = source_es.get_system(sys_num);
175 
176  // Add the system to the new EquationsSystems
177  ExplicitSystem & dest_sys = _oversample_es->add_system<ExplicitSystem>(source_sys.name());
178 
179  // Loop through the variables in the System
180  unsigned int num_vars = source_sys.n_vars();
181  if (num_vars > 0)
182  {
183  _mesh_functions[sys_num].resize(num_vars);
185  _serialized_solution->init(source_sys.n_dofs(), false, SERIAL);
186 
187  // Need to pull down a full copy of this vector on every processor so we can get values in
188  // parallel
189  source_sys.solution->localize(*_serialized_solution);
190 
191  // Add the variables to the system... simultaneously creating MeshFunctions for them.
192  for (unsigned int var_num = 0; var_num < num_vars; var_num++)
193  {
194  // Add the variable, allow for first and second lagrange
195  const FEType & fe_type = source_sys.variable_type(var_num);
196  FEType second(SECOND, LAGRANGE);
197  if (fe_type == second)
198  dest_sys.add_variable(source_sys.variable_name(var_num), second);
199  else
200  dest_sys.add_variable(source_sys.variable_name(var_num), FEType());
201  }
202  }
203  }
204 
205  // Initialize the newly created EquationSystem
206  _oversample_es->init();
207 }
208 
209 void
211 {
212  // Do nothing if oversampling and changing position are not enabled
213  if (!_oversample && !_change_position)
214  return;
215 
216  // Get a reference to actual equation system
217  EquationSystems & source_es = _problem_ptr->es();
218 
219  // Loop throuch each system
220  for (unsigned int sys_num = 0; sys_num < source_es.n_systems(); ++sys_num)
221  {
222  if (!_mesh_functions[sys_num].empty())
223  {
224  // Get references to the source and destination systems
225  System & source_sys = source_es.get_system(sys_num);
226  System & dest_sys = _oversample_es->get_system(sys_num);
227 
228  // Update the solution for the oversampled mesh
229  _serialized_solution->clear();
230  _serialized_solution->init(source_sys.n_dofs(), false, SERIAL);
231  source_sys.solution->localize(*_serialized_solution);
232 
233  // Update the mesh functions
234  for (unsigned int var_num = 0; var_num < _mesh_functions[sys_num].size(); ++var_num)
235  {
236 
237  // If the mesh has change the MeshFunctions need to be re-built, otherwise simply clear it
238  // for re-initialization
239  if (!_mesh_functions[sys_num][var_num] || _oversample_mesh_changed)
240  _mesh_functions[sys_num][var_num] = std::make_unique<MeshFunction>(
241  source_es, *_serialized_solution, source_sys.get_dof_map(), var_num);
242  else
243  _mesh_functions[sys_num][var_num]->clear();
244 
245  // Initialize the MeshFunctions for application to the oversampled solution
246  _mesh_functions[sys_num][var_num]->init();
247  }
248 
249  // Now loop over the nodes of the oversampled mesh setting values for each variable.
250  for (const auto & node : as_range(_mesh_ptr->localNodesBegin(), _mesh_ptr->localNodesEnd()))
251  for (unsigned int var_num = 0; var_num < _mesh_functions[sys_num].size(); ++var_num)
252  if (node->n_dofs(sys_num, var_num))
253  dest_sys.solution->set(node->dof_number(sys_num, var_num, 0),
254  (*_mesh_functions[sys_num][var_num])(
255  *node - _position)); // 0 value is for component
256 
257  dest_sys.solution->close();
258  }
259  }
260 
261  // Set this to false so that new output files are not created, since the oversampled mesh doesn't
262  // actually change
263  _oversample_mesh_changed = false;
264 }
265 
266 void
268 {
269  // Create the new mesh from a file
270  if (isParamValid("file"))
271  {
272  InputParameters mesh_params = _app.getFactory().getValidParams("FileMesh");
273  mesh_params.applyParameters(parameters(), {}, true);
274  mesh_params.set<bool>("nemesis") = false;
276  _app.getFactory().createUnique<MooseMesh>("FileMesh", "output_problem_mesh", mesh_params);
277  _cloned_mesh_ptr->allowRecovery(false); // We actually want to reread the initial mesh
278  _cloned_mesh_ptr->init();
279  _cloned_mesh_ptr->prepare(/*mesh_to_clone=*/nullptr);
280  _cloned_mesh_ptr->meshChanged();
281  }
282 
283  // Clone the existing mesh
284  else
285  {
286  if (_app.isRecovering())
287  mooseWarning("Recovering or Restarting with Oversampling may not work (especially with "
288  "adapted meshes)!! Refs #2295");
289 
291  }
292 
293  // Make sure that the mesh pointer points to the newly cloned mesh
294  _mesh_ptr = _cloned_mesh_ptr.get();
295 }
296 
297 void
298 OversampleOutput::setFileBaseInternal(const std::string & file_base)
299 {
301  // ** DEPRECATED SUPPORT **
302  if (getParam<bool>("append_oversample"))
303  _file_base += "_oversample";
304 }
bool _oversample_mesh_changed
A flag indicating that the mesh has changed and the oversampled mesh needs to be re-initialized.
virtual void meshChanged() override
Called on this object when the mesh changes.
LAGRANGE
virtual void setFileBaseInternal(const std::string &file_base)
Internal function that sets the file_base.
Definition: FileOutput.C:125
virtual void updateOversample()
Performs the update of the solution vector for the oversample/re-positioned mesh. ...
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
const ExecFlagType EXEC_FORCED
Definition: Moose.C:39
OversampleOutput(const InputParameters &parameters)
virtual bool onInterval()
Returns true if the output interval is satisfied.
Definition: Output.C:286
std::vector< std::vector< std::unique_ptr< MeshFunction > > > _mesh_functions
A vector of pointers to the mesh functions This is only populated when the oversample() function is c...
Point _position
When oversampling, the output is shift by this amount.
const ExecFlagType EXEC_NONE
Definition: Moose.C:27
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition: Factory.C:67
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void applyParameters(const InputParameters &common, const std::vector< std::string > &exclude={}, const bool allow_private=false)
Method for applying common parameters.
std::string _file_base
The base filename from the input paramaters.
Definition: FileOutput.h:89
virtual bool shouldOutput()
Handles logic for determining if a step should be output.
virtual void output()
A single call to this function should output all the necessary data for a single timestep.
const Parallel::Communicator & _communicator
std::unique_ptr< EquationSystems > _oversample_es
SECOND
void initOversample()
Setups the output object to produce re-positioned and/or oversampled results.
std::unique_ptr< NumericVector< Number > > _serialized_solution
Oversample solution vector.
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition: MooseApp.h:396
virtual EquationSystems & es() override
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
virtual void setFileBaseInternal(const std::string &file_base) override
Appends the base class&#39;s file base string.
Real & _last_output_simulation_time
last simulation time an output has occured
Definition: Output.h:277
SERIAL
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3199
EquationSystems * _es_ptr
Reference the the libMesh::EquationSystems object that contains the data.
Definition: Output.h:188
bool _oversample
Flag indicating that oversampling is enabled.
ExecFlagType _current_execute_flag
Current execute on flag.
Definition: Output.h:205
virtual void initialSetup() override
Call init() method on setup.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
void cloneMesh()
Clone mesh in preperation for re-positioning or oversampling.
FEProblemBase * _problem_ptr
Pointer the the FEProblemBase object for output object (use this)
Definition: Output.h:179
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:88
bool _allow_output
Flag for disabling output.
Definition: Output.h:265
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:51
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
static std::unique_ptr< NumericVector< Number > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Based class for output objects.
virtual ~OversampleOutput()
virtual void initialSetup()
Call init() method on setup.
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
virtual std::unique_ptr< MooseMesh > safeClone() const =0
A safer version of the clone() method that hands back an allocated object wrapped in a smart pointer...
MooseMesh * _mesh_ptr
A convenience pointer to the current mesh (reference or displaced depending on "use_displaced") ...
Definition: Output.h:191
const InputParameters & parameters() const
Get the parameters of the object.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
const unsigned int _refinements
The number of oversampling refinements.
MeshBase::node_iterator localNodesEnd()
Definition: MooseMesh.C:2784
static InputParameters validParams()
MeshBase::node_iterator localNodesBegin()
Calls local_nodes_begin/end() on the underlying libMesh mesh object.
Definition: MooseMesh.C:2778
std::unique_ptr< MooseObject > createUnique(const std::string &obj_name, const std::string &name, const 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:86
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition: MooseApp.C:1168
std::unique_ptr< MooseMesh > _cloned_mesh_ptr
bool _change_position
Flag for re-positioning.
static InputParameters validParams()
const ExecFlagType EXEC_FINAL
Definition: Moose.C:38
Real & _time
The current time for output purposes.
Definition: Output.h:208
void ErrorVector unsigned int
virtual void outputStep(const ExecFlagType &type) override
A single call to this function should output all the necessary data for a single timestep.
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:28