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