Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
paraview_writer.hpp
Go to the documentation of this file.
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
13 #pragma once
14 
15 #include <string>
16 #include "mfem.hpp"
18 #include "smith/physics/mesh.hpp"
19 #include <variant>
20 
21 namespace smith {
22 
26  public:
27  using StateVecs = std::vector<std::shared_ptr<FiniteElementState> >;
28 
30  struct Options {
32  bool write_duals{true};
33  };
34 
39  ParaviewWriter(std::unique_ptr<mfem::ParaViewDataCollection> pv_, const StateVecs& states_,
40  const StateVecs& tracked_reactions_)
41  : pv(std::move(pv_)), states(states_), dual_states(tracked_reactions_), opts({})
42  {
43  }
44 
50  ParaviewWriter(std::unique_ptr<mfem::ParaViewDataCollection> pv_, const StateVecs& states_,
51  const StateVecs& tracked_reactions_, Options opts_)
52  : pv(std::move(pv_)), states(states_), dual_states(tracked_reactions_), opts(opts_)
53  {
54  }
55 
58  void write(size_t step, double time, const std::vector<const FiniteElementState*>& current_states)
59  {
61  SLIC_ERROR_ROOT_IF(current_states.size() != states.size(), "wrong number of output states to write");
62 
63  for (size_t n = 0; n < states.size(); ++n) {
64  auto& state = states[n];
65  *state = *current_states[n];
66  state->gridFunction();
67  }
68 
69  pv->SetCycle(static_cast<int>(step));
70  pv->SetTime(time);
71  pv->Save();
72  }
73 
76  void write(size_t step, double time, const std::vector<const FiniteElementDual*>& current_duals)
77  {
79  SLIC_ERROR_ROOT_IF(current_duals.size() != dual_states.size(), "wrong number of output states to write");
80 
81  for (size_t n = 0; n < dual_states.size(); ++n) {
82  auto& dual = dual_states[n];
83  current_duals[n]->linearForm().ParallelAssemble(*dual);
84  dual->gridFunction();
85  }
86 
87  pv->SetCycle(static_cast<int>(step));
88  pv->SetTime(time);
89  pv->Save();
90  }
91 
95  void write(int step, double time, const std::vector<FieldState>& current_fields)
96  {
98  SLIC_ERROR_ROOT_IF(current_fields.size() != states.size(), "wrong number of output states to write");
99 
100  for (size_t n = 0; n < states.size(); ++n) {
101  auto& state = states[n];
102  *state = *current_fields[n].get();
103  state->gridFunction();
104 
105  if (opts.write_duals) {
106  SLIC_ERROR_ROOT_IF(dual_states.size() != states.size(), "wrong number of output dual states to write");
107  auto& dual = dual_states[n];
108  current_fields[n].get_dual()->linearForm().ParallelAssemble(*dual);
109  dual->gridFunction();
110  }
111  }
112 
113  pv->SetCycle(step);
114  pv->SetTime(time);
115  pv->Save();
116  }
117 
119  void write(size_t step, double time, const std::vector<FieldState>& current_fields)
120  {
121  write(static_cast<int>(step), time, current_fields);
122  }
123 
124  private:
125  std::unique_ptr<mfem::ParaViewDataCollection> pv;
126  StateVecs states;
127  StateVecs dual_states;
128  Options opts;
129 };
130 
133 inline auto createParaviewWriter(const smith::Mesh& mesh, const std::vector<FieldState>& states,
134  std::string output_name, ParaviewWriter::Options opts)
135 {
136  if (output_name == "") {
137  output_name = "default";
138  }
139 
140  ParaviewWriter::StateVecs output_states;
141  ParaviewWriter::StateVecs output_duals;
142 
143  auto non_const_mesh = const_cast<mfem::ParMesh*>(&mesh.mfemParMesh());
144  auto paraview_dc = std::make_unique<mfem::ParaViewDataCollection>(output_name, non_const_mesh);
145  // visualization order has to be at least 1 for paraview (because there is no zero order mesh)
146  int max_order_in_fields = 1;
147 
148  // Find the maximum polynomial order in the physics module's states
149  for (const auto& fstate : states) {
150  const auto& state = fstate.get();
151  output_states.push_back(std::make_shared<smith::FiniteElementState>(state->space(), state->name()));
152  paraview_dc->RegisterField(state->name(), &output_states.back()->gridFunction());
153  max_order_in_fields = std::max(max_order_in_fields, state->space().GetOrder(0));
154 
155  if (opts.write_duals) {
156  const auto& dual = fstate.get_dual();
157  output_duals.push_back(std::make_shared<smith::FiniteElementState>(dual->space(), dual->name()));
158  paraview_dc->RegisterField(dual->name(), &output_duals.back()->gridFunction());
159  max_order_in_fields = std::max(max_order_in_fields, dual->space().GetOrder(0));
160  }
161  }
162 
163  // Set the options for the paraview output files
164  paraview_dc->SetLevelsOfDetail(max_order_in_fields);
165  paraview_dc->SetHighOrderOutput(true);
166  paraview_dc->SetDataFormat(mfem::VTKFormat::BINARY);
167  paraview_dc->SetCompression(true);
168 
169  return ParaviewWriter(std::move(paraview_dc), output_states, output_duals, opts);
170 }
171 
176 inline auto createParaviewWriter(const smith::Mesh& mesh, const std::vector<FieldState>& states,
177  std::string output_name)
178 {
179  return createParaviewWriter(mesh, states, std::move(output_name), ParaviewWriter::Options{});
180 }
181 
184 inline auto createParaviewWriter(const mfem::ParMesh& mesh, const std::vector<const FiniteElementState*>& states,
185  std::string output_name)
186 {
187  if (output_name == "") {
188  output_name = "default";
189  }
190 
191  ParaviewWriter::StateVecs output_states;
192  for (const auto& s : states) {
193  output_states.push_back(std::make_shared<smith::FiniteElementState>(s->space(), s->name()));
194  }
195 
196  auto non_const_mesh = const_cast<mfem::ParMesh*>(&mesh);
197  auto paraview_dc = std::make_unique<mfem::ParaViewDataCollection>(output_name, non_const_mesh);
198  // visualization order has to be at least 1 for paraview (because there is no zero order mesh)
199  int max_order_in_fields = 1;
200 
201  // Find the maximum polynomial order in the physics module's states
202  for (const auto& state : output_states) {
203  paraview_dc->RegisterField(state->name(), &state->gridFunction());
204  max_order_in_fields = std::max(max_order_in_fields, state->space().GetOrder(0));
205  }
206 
207  // Set the options for the paraview output files
208  paraview_dc->SetLevelsOfDetail(max_order_in_fields);
209  paraview_dc->SetHighOrderOutput(true);
210  paraview_dc->SetDataFormat(mfem::VTKFormat::BINARY);
211  paraview_dc->SetCompression(true);
212 
213  return ParaviewWriter(std::move(paraview_dc), output_states, {});
214 }
215 
216 } // namespace smith
Helper class for constructing a mesh consistent with Smith.
Definition: mesh.hpp:37
const mfem::ParMesh & mfemParMesh() const
Returns const parallel mfem mesh.
Definition: mesh.hpp:66
Class which interactions with ParaViewDataCollection to write arbitrary field results to disk....
void write(size_t step, double time, const std::vector< FieldState > &current_fields)
overload
std::vector< std::shared_ptr< FiniteElementState > > StateVecs
using
void write(size_t step, double time, const std::vector< const FiniteElementState * > &current_states)
write paraview output from vector of finite element states. states must be passed in with a consisten...
void write(size_t step, double time, const std::vector< const FiniteElementDual * > &current_duals)
write paraview output from vector of finite element duals. duals must be passed in with a consistent ...
ParaviewWriter(std::unique_ptr< mfem::ParaViewDataCollection > pv_, const StateVecs &states_, const StateVecs &tracked_reactions_)
Construct a writer backed by an existing ParaView data collection.
void write(int step, double time, const std::vector< FieldState > &current_fields)
write paraview output from vector of FieldState. These must be passed in with a consistent order as h...
ParaviewWriter(std::unique_ptr< mfem::ParaViewDataCollection > pv_, const StateVecs &states_, const StateVecs &tracked_reactions_, Options opts_)
Construct a writer backed by an existing ParaView data collection with explicit output options.
Smith mesh class which assists in constructing the appropriate parallel mfem meshes and registering a...
Accelerator functionality.
Definition: smith.cpp:36
auto createParaviewWriter(const smith::Mesh &mesh, const std::vector< FieldState > &states, std::string output_name, ParaviewWriter::Options opts)
Creates a ParaviewWriter from a mesh, vector of FieldState, and the name of the output paraview file....
SMITH_HOST_DEVICE auto max(dual< gradient_type > a, double b)
Implementation of max for dual numbers.
Definition: dual.hpp:229
#define SMITH_MARK_FUNCTION
Definition: profiling.hpp:90
Options that control which fields are written to ParaView output.
bool write_duals
When true, write dual/reaction fields alongside the primary states.
Dual number struct (value plus gradient)
Definition: dual.hpp:28