https://mooseframework.inl.gov
MeshOnlyAction.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 "MeshOnlyAction.h"
11 
12 #include "MooseApp.h"
13 #include "MooseMesh.h"
14 #include "Exodus.h"
15 #include "AddOutputAction.h"
16 #include "RestartableDataWriter.h"
17 
18 #include <filesystem>
19 
20 #include "libmesh/exodusII_io.h"
21 #include "libmesh/exodusII_io_helper.h"
22 #include "libmesh/checkpoint_io.h"
23 
24 using namespace libMesh;
25 
26 registerMooseAction("MooseApp", MeshOnlyAction, "mesh_only");
27 
30 {
31  return Action::validParams();
32 }
33 
35 
36 void
38 {
39  // Run error checking on input file first before trying to generate a mesh
40  bool warn = _app.unusedFlagIsWarning();
41  bool err = _app.unusedFlagIsError();
42  _app.builder().errorCheck(comm(), warn, err);
43 
44  std::string mesh_file = _app.parameters().get<std::string>("mesh_only");
45  auto & mesh_ptr = _app.actionWarehouse().mesh();
46 
47  // Print information about the mesh
48  _console << mesh_ptr->getMesh().get_info(/* verbosity = */ 2) << std::endl;
49 
50  if (mesh_file.empty())
51  {
52  mesh_file = _app.builder().getPrimaryFileName();
53  size_t pos = mesh_file.find_last_of('.');
54 
55  // Default to writing out an ExodusII mesh base on the input filename.
56  mesh_file = mesh_file.substr(0, pos) + "_in.e";
57  }
58 
64  if (mesh_file.find(".e") + 2 == mesh_file.size())
65  {
66  TIME_SECTION("act", 1, "Writing Exodus");
67 
68  auto & output_mesh = mesh_ptr->getMesh();
69  ExodusII_IO exio(output_mesh);
70 
71  // Default to the maximum name length allowed by libMesh ExodusII
72  exio.set_max_name_length(80);
73 
74  // Extract the Output action to look for a non-default name
75  // length, e.g. truncation to 32 to match gold files
76  const auto & output_actions = _app.actionWarehouse().getActionListByName("add_output");
77  for (const auto & act : output_actions)
78  {
79  AddOutputAction * action = dynamic_cast<AddOutputAction *>(act);
80  if (!action)
81  continue;
82 
83  InputParameters & params = action->getObjectParams();
84  if (params.isParamSetByUser("max_output_name_length"))
85  {
86  const int max_output_name_length =
87  action->getObjectParams().get<unsigned int>("max_output_name_length");
88 
89  exio.set_max_name_length(max_output_name_length);
90 
91  break;
92  }
93  }
94 
96 
97  // Default to non-HDF5 output for wider compatibility
98  exio.set_hdf5_writing(false);
99 
100  exio.write(mesh_file);
101 
102  // Check if extra element integers should be outputted to Exodus file
103  unsigned int n_eeid = output_mesh.n_elem_integers();
104 
105  // Iterate through all actions and see if `Outputs/output_extra_element_ids = true` in input
106  // file
107 
108  // Truth of whether to output extra element ids is initially determined by whether
109  // there are extra element ids defined on the mesh
110  bool output_extra_ids = (n_eeid > 0);
111  bool restrict_element_id_names = false;
112  std::vector<std::string> element_id_names;
113  for (const auto & act : output_actions)
114  {
115  // Extract the Output action
116  AddOutputAction * action = dynamic_cast<AddOutputAction *>(act);
117  if (!action)
118  continue;
119 
120  InputParameters & params = action->getObjectParams();
121  if (params.isParamSetByUser("output_extra_element_ids"))
122  {
123  // User has set output_extra_element_ids, truth of output_extra_ids determined by value of
124  // parameter
125  output_extra_ids = params.get<bool>("output_extra_element_ids");
126  if (output_extra_ids)
127  {
128  // `Outputs/extra_element_ids_to_output` sets a subset of extra element ids that should
129  // be outputted to Exodus
130  restrict_element_id_names = params.isParamValid("extra_element_ids_to_output");
131  if (restrict_element_id_names)
132  {
133  element_id_names = params.get<std::vector<std::string>>("extra_element_ids_to_output");
134  // Check which element id names actually are defined on the mesh, remove from
135  // element_id_names if they don't belong
136  for (auto it = element_id_names.begin(); it != element_id_names.end();)
137  {
138  // Erase contents of iterator and return iterator if element integer does not exist
139  if (!output_mesh.has_elem_integer(*it))
140  {
141  it = element_id_names.erase(it);
142  mooseWarning("Extra element id ",
143  *it,
144  " defined in Outputs/extra_element_ids_to_output "
145  "is not defined on the mesh and will be ignored.");
146  }
147  // Increment iterator if element integer exists
148  else
149  ++it;
150  }
151  }
152  }
153  break;
154  }
155  }
156 
157  if (output_extra_ids)
158  {
159  // Retrieve extra element id names and associated data
160  const auto n_elem = output_mesh.n_elem();
161  std::vector<std::string> eeid_vars;
162  const auto n_eeid_to_output = restrict_element_id_names ? element_id_names.size() : n_eeid;
163  std::vector<Number> eeid_soln(n_elem * n_eeid_to_output);
164  unsigned int soln_index = 0;
165  for (unsigned int i = 0; i < n_eeid; i++)
166  {
167  const auto eeid_name = output_mesh.get_elem_integer_name(i);
168  // If `Outputs/extra_element_ids_to_output` is not set, output all ids to Exodus
169  // Otherwise only output if the extra id name is contained within
170  // `Outputs/extra_element_ids_to_output`
171  if (!restrict_element_id_names ||
172  (std::find(element_id_names.begin(), element_id_names.end(), eeid_name) !=
173  element_id_names.end()))
174  {
175  eeid_vars.push_back(output_mesh.get_elem_integer_name(i));
176  for (const auto & elem : output_mesh.element_ptr_range())
177  {
178  eeid_soln[soln_index] = (int)elem->get_extra_integer(i);
179  ++soln_index;
180  }
181  }
182  }
183 
184  // Check size of output variables just in case none of the variables in
185  // `Outpus/extra_element_ids_to_output` are specified on the actual mesh
186  if (eeid_vars.size() > 0)
187  {
188  // Invoke ExodusII_IO_Helper to output extra element ids to Exodus file
189  auto & exio_helper = exio.get_exio_helper();
190 
191  // Output empty timestep to Exodus file
192  int empty_timestep = 1;
193  Real default_time = 1.0;
194  exio_helper.write_timestep(empty_timestep, default_time);
195 
196  // Write extra element id data to Exodus file
197  std::vector<std::set<subdomain_id_type>> vars_active_subdomains;
198  vars_active_subdomains.resize(n_eeid_to_output);
199  exio_helper.initialize_element_variables(eeid_vars, vars_active_subdomains);
200  exio_helper.write_element_values(
201  output_mesh, eeid_soln, empty_timestep, vars_active_subdomains);
202  }
203  else
204  mooseWarning(
205  "Outputs/output_extra_element_ids is set to true but no extra element ids are being "
206  "outputted. Please check extra element ids are properly defined on the mesh and any "
207  "variables specified in Outputs/extra_element_ids_to_output are spelled correctly.");
208  }
209  }
210 
211  else if (mesh_file.find(".cpa.gz") + 7 == mesh_file.size())
212  {
213  TIME_SECTION("act", 1, "Writing Checkpoint");
214 
215  CheckpointIO io(mesh_ptr->getMesh(), false);
216  io.write(mesh_file);
217 
218  // Write mesh metadata
219  if (processor_id() == 0)
220  {
221  const auto filenames = _app.writeRestartableMetaData(MooseApp::MESH_META_DATA, mesh_file);
222  Moose::out << "Mesh meta data written into "
223  << std::filesystem::absolute(filenames[0].parent_path()) << "." << std::endl;
224  }
225  }
226  else
227  {
228  // Just write the file using the name requested by the user.
229  mesh_ptr->getMesh().write(mesh_file);
230  }
231 }
OStreamProxy err
virtual void write(const std::string &name) override
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:40
static InputParameters validParams()
ExodusII_IO_Helper & get_exio_helper()
dof_id_type n_elem(const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
static const RestartableDataMapName MESH_META_DATA
Definition: MooseApp.h:135
void set_max_name_length(unsigned int max_length)
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
std::vector< std::filesystem::path > writeRestartableMetaData(const RestartableDataMapName &name, const std::filesystem::path &folder_base)
Writes the restartable meta data for name with a folder base of folder_base.
Definition: MooseApp.C:2279
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const std::list< Action * > & getActionListByName(const std::string &task) const
Retrieve a constant list of Action pointers associated with the passed in task.
Base class for actions.
Definition: Action.h:34
std::shared_ptr< MooseMesh > & mesh()
void mooseWarning(Args &&... args) const
Action for creating output objects.
static InputParameters validParams()
Definition: Action.C:26
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
Moose::Builder & builder()
Returns a writable reference to the builder.
Definition: MooseApp.h:225
bool unusedFlagIsError() const
Returns whether the flag for unused parameters is set to throw an error.
Definition: MooseApp.h:1094
ActionWarehouse & actionWarehouse()
Return a writable reference to the ActionWarehouse associated with this app.
Definition: MooseApp.h:216
void errorCheck(const libMesh::Parallel::Communicator &comm, bool warn_unused, bool err_unused)
Definition: Builder.C:358
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:385
std::string getPrimaryFileName(bool stripLeadingPath=true) const
Return the primary (first) filename that was parsed.
Definition: Builder.C:179
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
virtual void write(const std::string &fname) override
static void setOutputDimensionInExodusWriter(libMesh::ExodusII_IO &exodus_io, const MooseMesh &mesh, OutputDimension output_dim=OutputDimension::DEFAULT)
Helper method to change the output dimension in the passed in Exodus writer depending on the dimensio...
Definition: Exodus.C:296
bool unusedFlagIsWarning() const
Returns whether the flag for unused parameters is set to throw a warning only.
Definition: MooseApp.h:1091
MeshOnlyAction(const InputParameters &params)
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
processor_id_type processor_id() const
void set_hdf5_writing(bool write_hdf5)
void ErrorVector unsigned int
registerMooseAction("MooseApp", MeshOnlyAction, "mesh_only")
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.