https://mooseframework.inl.gov
Nemesis.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
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 "Nemesis.h"
11 
12 // MOOSE includes
13 #include "FEProblem.h"
14 #include "MooseApp.h"
15 #include "MooseMesh.h"
16 #include "MooseVariableScalar.h"
17 #include "SystemBase.h"
18 
19 #include "libmesh/dof_map.h"
20 #include "libmesh/nemesis_io.h"
21 
22 using namespace libMesh;
23 
24 registerMooseObject("MooseApp", Nemesis);
25 
28 {
30  params += AdvancedOutput::enableOutputTypes("scalar postprocessor input");
31  params.addParam<bool>("write_hdf5", false, "Enables HDF5 output format for Nemesis files.");
32  params.addClassDescription("Object for output data in the Nemesis (parallel ExodusII) format.");
33  return params;
34 }
35 
36 Nemesis::Nemesis(const InputParameters & parameters)
37  : AdvancedOutput(parameters),
38  _nemesis_io_ptr(nullptr),
39  _file_num(declareRestartableData<unsigned int>("nemesis_file_num", 0)),
40  _nemesis_num(declareRestartableData<unsigned int>("nemesis_num", 0)),
41  _nemesis_initialized(false),
42  _recovering(_app.isRecovering()),
43  _nemesis_mesh_changed(declareRestartableData<bool>("nemesis_mesh_changed", true)),
44  _write_hdf5(getParam<bool>("write_hdf5"))
45 {
46 }
47 
48 void
50 {
52 }
53 
54 void
56 {
57  // Do not delete the Nemesis_IO object if it has not been used; also there is no need to setup
58  // the object in this case, so just return
59  if (_nemesis_io_ptr != nullptr && !_nemesis_initialized)
60  return;
61 
62  // Indicate to the Nemesis object that the mesh has changed
63  _nemesis_mesh_changed = true;
64 }
65 
66 void
68 {
69  if (_nemesis_io_ptr)
70  {
71  // Do nothing if the Nemesis_IO objects exists, but has not been initialized
73  return;
74 
75  // Do nothing if the mesh has not changed
77  return;
78  }
79 
80  // Create the new NemesisIO object
81  _nemesis_io_ptr = std::make_unique<Nemesis_IO>(_problem_ptr->mesh().getMesh());
82  _nemesis_initialized = false;
83 
84  if (_write_hdf5)
85  {
86 #ifndef LIBMESH_HAVE_HDF5
87  mooseError("Moose input requested HDF Nemesis output, but libMesh was built without HDF5.");
88 #endif
89 
90  // This is redundant unless the libMesh default changes
91  _nemesis_io_ptr->set_hdf5_writing(true);
92  }
93  else
94  {
95  _nemesis_io_ptr->set_hdf5_writing(false);
96  }
97 
99  {
100  // Set the recovering flag to false so that this special case is not triggered again
101  _recovering = false;
102 
103  // Set the append flag to true b/c on recover the file is being appended
104  _nemesis_io_ptr->append(true);
105  }
106  else
107  {
108  // Increment file counter
110  _file_num++;
111 
112  // Disable file appending and reset nemesis file number count
113  _nemesis_io_ptr->append(false);
114  _nemesis_num = 1;
115  }
116 }
117 
118 void
120 {
121  // List of desired postprocessor outputs
122  const std::set<std::string> & pps = getPostprocessorOutput();
123 
124  // Append the postprocessor data to the global name value parameters; scalar outputs
125  // also append these member variables
126  for (const auto & name : pps)
127  {
128  _global_names.push_back(name);
130  }
131 }
132 
133 void
135 {
136  // List of desired scalar outputs
137  const std::set<std::string> & out = getScalarOutput();
138 
139  // Append the scalar to the global output lists
140  for (const auto & out_name : out)
141  {
142  // Make sure scalar values are in sync with the solution vector
143  // and are visible on this processor. See TableOutput.C for
144  // TableOutput::outputScalarVariables() explanatory comments
145 
146  MooseVariableScalar & scalar_var = _problem_ptr->getScalarVariable(0, out_name);
147  scalar_var.reinit();
148  VariableValue value(scalar_var.sln());
149 
150  const std::vector<dof_id_type> & dof_indices = scalar_var.dofIndices();
151  const unsigned int n = dof_indices.size();
152  value.resize(n);
153 
154  const DofMap & dof_map = scalar_var.sys().dofMap();
155  for (unsigned int i = 0; i != n; ++i)
156  {
157  const processor_id_type pid = dof_map.dof_owner(dof_indices[i]);
158  this->comm().broadcast(value[i], pid);
159  }
160 
161  // If the scalar has a single component, output the name directly
162  if (n == 1)
163  {
164  _global_names.push_back(out_name);
165  _global_values.push_back(value[0]);
166  }
167 
168  // If the scalar as many components add indices to the end of the name
169  else
170  {
171  for (unsigned int i = 0; i < n; ++i)
172  {
173  std::ostringstream os;
174  os << out_name << "_" << i;
175  _global_names.push_back(os.str());
176  _global_values.push_back(value[i]);
177  }
178  }
179  }
180 }
181 
182 void
184 {
185  outputSetup();
186 
187  // Clear the global variables (postprocessors and scalars)
188  _global_names.clear();
189  _global_values.clear();
190 
191  // Call the output methods
193 
194  // Set up the whitelist of nodal variable names to write.
195  _nemesis_io_ptr->set_output_variables(
196  std::vector<std::string>(getNodalVariableOutput().begin(), getNodalVariableOutput().end()));
197 
198  // Write nodal data
199  _nemesis_io_ptr->write_timestep(
201  _nemesis_initialized = true;
202 
203  // Write elemental data
204  std::vector<std::string> elemental(getElementalVariableOutput().begin(),
206  _nemesis_io_ptr->set_output_variables(elemental);
207  _nemesis_io_ptr->write_element_data(*_es_ptr);
208 
209  // Increment output call counter for the current file
210  _nemesis_num++;
211 
212  // Write the global variables (populated by the output methods)
213  if (!_global_values.empty())
214  _nemesis_io_ptr->write_global_data(_global_values, _global_names);
215 
216  // Reset the mesh changed flag
217  _nemesis_mesh_changed = false;
218 }
219 
220 std::string
222 {
223  // Append the .e extension on the base file name
224  std::ostringstream output;
225  output << _file_base << ".e";
226 
227  // Add the _000x extension to the file
228  if (_file_num > 1)
229  output << "-s" << std::setw(_padding) << std::setprecision(0) << std::setfill('0') << std::right
230  << _file_num;
231 
232  // Return the filename
233  return output.str();
234 }
const std::set< std::string > & getPostprocessorOutput()
The list of postprocessor names that are set for output.
virtual void outputScalarVariables() override
Writes scalar AuxVariables to global output parameters.
virtual void meshChanged() override
Creates a new NemesisII_IO output object for outputting a new mesh.
std::vector< Real > _global_values
Storage for scalar values (postprocessors and scalar AuxVariables)
Definition: Nemesis.h:84
processor_id_type dof_owner(const dof_id_type dof) const
bool _recovering
Flag indicating MOOSE is recovering via –recover command-line option.
Definition: Nemesis.h:100
void reinit(bool reinit_for_derivative_reordering=false)
Fill out the VariableValue arrays from the system solution vector.
std::unique_ptr< libMesh::Nemesis_IO > _nemesis_io_ptr
Pointer to the libMesh::NemesisII_IO object that performs the actual data output. ...
Definition: Nemesis.h:81
std::vector< std::string > _global_names
Storage for names of the above scalar values.
Definition: Nemesis.h:87
bool _write_hdf5
Flag to output HDF5 format (when available) in Nemesis.
Definition: Nemesis.h:109
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
unsigned int & _nemesis_num
Count of outputs per exodus file.
Definition: Nemesis.h:94
const Parallel::Communicator & comm() const
std::string _file_base
The base filename from the input paramaters.
Definition: FileOutput.h:89
virtual void output()
A single call to this function should output all the necessary data for a single timestep.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
std::basic_ostream< charT, traits > * os
Definition: InfixIterator.h:33
virtual void outputPostprocessors() override
Writes postprocessor values to global output parameters.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
virtual void outputSetup()
Performs the necessary deletion and re-creating of NemesisII_IO object.
bool & _nemesis_mesh_changed
A flag indicating to the Nemesis object that the mesh has changed.
Definition: Nemesis.h:103
unsigned int _padding
Number of digits to pad the extensions.
Definition: FileOutput.h:83
uint8_t processor_id_type
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
Definition: SystemBase.C:1165
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const std::set< std::string > & getScalarOutput()
The list of scalar variables names that are set for output.
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3443
FEProblemBase * _problem_ptr
Pointer the the FEProblemBase object for output object (use this)
Definition: Output.h:185
virtual void output() override
Overload the Output::output method, this is required for Nemesis output due to the method utilized fo...
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the scalar variable reference from whichever system contains it.
virtual const std::vector< dof_id_type > & dofIndices() const
Get local DoF indices.
static InputParameters validParams()
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
static InputParameters enableOutputTypes(const std::string &names=std::string())
A method for enabling individual output type control.
const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name, std::size_t t_index=0) const
Get a read-only reference to the value associated with a Postprocessor that exists.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
Based class for output objects.
OutputTools< Real >::VariableValue VariableValue
Definition: MooseTypes.h:314
virtual void initialSetup()
Call init() method on setup.
bool _nemesis_initialized
Flag if the output has been initialized.
Definition: Nemesis.h:97
virtual void initialSetup() override
Sets up the libMesh::NemesisII_IO object used for outputting to the Nemesis format.
OStreamProxy out
libMesh::EquationSystems * _es_ptr
Reference the the libMesh::EquationSystems object that contains the data.
Definition: Output.h:194
Class for scalar variables (they are different).
virtual std::string filename() override
Returns the current filename, this method handles the -s000 suffix common to NemesisII files...
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
const std::set< std::string > & getElementalVariableOutput()
The list of elemental nonlinear variables names that are set for output.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
const std::set< std::string > & getNodalVariableOutput()
The list of nodal nonlinear variables names that are set for output.
registerMooseObject("MooseApp", Nemesis)
static InputParameters validParams()
SystemBase & sys()
Get the system this variable is part of.
Nemesis(const InputParameters &parameters)
Class constructor.
Real getGlobalTimeOffset() const
Each App has it&#39;s own local time.
Definition: MooseApp.h:341
const VariableValue & sln() const
virtual Real getOutputTime()
Get the time that will be used for stream/file outputting.
Definition: PetscOutput.C:273
void ErrorVector unsigned int
Class for output data to the Nemesis format.
Definition: Nemesis.h:24
unsigned int & _file_num
Current output filename; utilized by filename() to create the proper suffix.
Definition: Nemesis.h:90