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