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 
31  ParaviewWriter(std::unique_ptr<mfem::ParaViewDataCollection> pv_, const StateVecs& states_, const StateVecs& duals_)
32  : pv(std::move(pv_)), states(states_), dual_states(duals_)
33  {
34  }
35 
38  void write(size_t step, double time, const std::vector<const FiniteElementState*>& current_states)
39  {
41  SLIC_ERROR_ROOT_IF(current_states.size() != states.size(), "wrong number of output states to write");
42 
43  for (size_t n = 0; n < states.size(); ++n) {
44  auto& state = states[n];
45  *state = *current_states[n];
46  state->gridFunction();
47  }
48 
49  pv->SetCycle(static_cast<int>(step));
50  pv->SetTime(time);
51  pv->Save();
52  }
53 
56  void write(size_t step, double time, const std::vector<const FiniteElementDual*>& current_duals)
57  {
59  SLIC_ERROR_ROOT_IF(current_duals.size() != dual_states.size(), "wrong number of output states to write");
60 
61  for (size_t n = 0; n < dual_states.size(); ++n) {
62  auto& dual = dual_states[n];
63  current_duals[n]->linearForm().ParallelAssemble(*dual);
64  dual->gridFunction();
65  }
66 
67  pv->SetCycle(static_cast<int>(step));
68  pv->SetTime(time);
69  pv->Save();
70  }
71 
75  void write(int step, double time, const std::vector<FieldState>& current_fields)
76  {
78  SLIC_ERROR_ROOT_IF(current_fields.size() != states.size(), "wrong number of output states to write");
79 
80  for (size_t n = 0; n < states.size(); ++n) {
81  auto& state = states[n];
82  *state = *current_fields[n].get();
83  state->gridFunction();
84 
85  auto& dual = dual_states[n];
86  current_fields[n].get_dual()->linearForm().ParallelAssemble(*dual);
87  dual->gridFunction();
88  }
89 
90  pv->SetCycle(step);
91  pv->SetTime(time);
92  pv->Save();
93  }
94 
96  void write(size_t step, double time, const std::vector<FieldState>& current_fields)
97  {
98  write(static_cast<int>(step), time, current_fields);
99  }
100 
101  private:
102  std::unique_ptr<mfem::ParaViewDataCollection> pv;
103  StateVecs states;
104  StateVecs dual_states;
105 };
106 
109 inline auto createParaviewWriter(const smith::Mesh& mesh, const std::vector<FieldState>& states,
110  std::string output_name)
111 {
112  if (output_name == "") {
113  output_name = "default";
114  }
115 
116  ParaviewWriter::StateVecs output_states;
117  ParaviewWriter::StateVecs output_duals;
118 
119  auto non_const_mesh = const_cast<mfem::ParMesh*>(&mesh.mfemParMesh());
120  auto paraview_dc = std::make_unique<mfem::ParaViewDataCollection>(output_name, non_const_mesh);
121  // visualization order has to be at least 1 for paraview (because there is no zero order mesh)
122  int max_order_in_fields = 1;
123 
124  // Find the maximum polynomial order in the physics module's states
125  for (const auto& fstate : states) {
126  const auto& state = fstate.get();
127  output_states.push_back(std::make_shared<smith::FiniteElementState>(state->space(), state->name()));
128  paraview_dc->RegisterField(state->name(), &output_states.back()->gridFunction());
129  max_order_in_fields = std::max(max_order_in_fields, state->space().GetOrder(0));
130 
131  const auto& dual = fstate.get_dual();
132  output_duals.push_back(std::make_shared<smith::FiniteElementState>(dual->space(), dual->name()));
133  paraview_dc->RegisterField(dual->name(), &output_duals.back()->gridFunction());
134  max_order_in_fields = std::max(max_order_in_fields, dual->space().GetOrder(0));
135  }
136 
137  // Set the options for the paraview output files
138  paraview_dc->SetLevelsOfDetail(max_order_in_fields);
139  paraview_dc->SetHighOrderOutput(true);
140  paraview_dc->SetDataFormat(mfem::VTKFormat::BINARY);
141  paraview_dc->SetCompression(true);
142 
143  return ParaviewWriter(std::move(paraview_dc), output_states, output_duals);
144 }
145 
148 inline auto createParaviewWriter(const mfem::ParMesh& mesh, const std::vector<const FiniteElementState*>& states,
149  std::string output_name)
150 {
151  if (output_name == "") {
152  output_name = "default";
153  }
154 
155  ParaviewWriter::StateVecs output_states;
156  for (const auto& s : states) {
157  output_states.push_back(std::make_shared<smith::FiniteElementState>(s->space(), s->name()));
158  }
159 
160  auto non_const_mesh = const_cast<mfem::ParMesh*>(&mesh);
161  auto paraview_dc = std::make_unique<mfem::ParaViewDataCollection>(output_name, non_const_mesh);
162  // visualization order has to be at least 1 for paraview (because there is no zero order mesh)
163  int max_order_in_fields = 1;
164 
165  // Find the maximum polynomial order in the physics module's states
166  for (const auto& state : output_states) {
167  paraview_dc->RegisterField(state->name(), &state->gridFunction());
168  max_order_in_fields = std::max(max_order_in_fields, state->space().GetOrder(0));
169  }
170 
171  // Set the options for the paraview output files
172  paraview_dc->SetLevelsOfDetail(max_order_in_fields);
173  paraview_dc->SetHighOrderOutput(true);
174  paraview_dc->SetDataFormat(mfem::VTKFormat::BINARY);
175  paraview_dc->SetCompression(true);
176 
177  return ParaviewWriter(std::move(paraview_dc), output_states, {});
178 }
179 
180 } // 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 ...
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 &duals_)
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)
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
Dual number struct (value plus gradient)
Definition: dual.hpp:28