14 if (!
args[
"output"][
"advanced"][
"compute_error"])
19 if (!
args[
"time"].is_null())
21 tend =
args[
"time"][
"tend"];
30 return args[
"root_path"].get<std::string>();
41 if (
output_dir.empty() || path.empty() || std::filesystem::path(path).is_absolute())
45 return std::filesystem::weakly_canonical(std::filesystem::path(
output_dir) / path).string();
48 void State::save_timestep(
const double time,
const int t,
const double t0,
const double dt,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure)
50 if (
args[
"output"][
"advanced"][
"save_time_sequence"] && !(t %
args[
"output"][
"paraview"][
"skip_frame"].get<int>()))
52 logger().trace(
"Saving VTU...");
54 const std::string step_name =
args[
"output"][
"advanced"][
"timestep_prefix"];
58 *
this, sol, pressure, time, dt,
63 [step_name](
int i) {
return fmt::format(step_name +
"{:d}.vtm", i); },
64 t, t0, dt,
args[
"output"][
"paraview"][
"skip_frame"].get<
int>());
48 void State::save_timestep(
const double time,
const int t,
const double t0,
const double dt,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure) {
…}
71 if (!out_path.empty())
73 std::ofstream out(out_path);
76 logger().error(
"Unable to save simulation JSON to {}", out_path);
88 logger().error(
"Load the mesh first!");
93 logger().error(
"Solve the problem first!");
97 logger().info(
"Saving json...");
99 using json = nlohmann::json;
105 out << j.dump(4) << std::endl;
108 void State::save_subsolve(
const int i,
const int t,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure)
110 if (!
args[
"output"][
"advanced"][
"save_solve_sequence_debug"].get<bool>())
114 if (!
args[
"time"].is_null())
115 dt =
args[
"time"][
"dt"];
119 *
this, sol, pressure, t, dt,
108 void State::save_subsolve(
const int i,
const int t,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure) {
…}
127 logger().error(
"Load the mesh first!");
132 logger().error(
"Build the bases first!");
142 logger().error(
"Solve the problem first!");
154 double tend =
args.value(
"tend", 1.0);
156 if (!
args[
"time"].is_null())
157 dt =
args[
"time"][
"dt"];
160 *
this, sol, pressure,
161 !
args[
"time"].is_null(),
171 if (
assembler->name() ==
"Electrostatics")
173 std::shared_ptr<assembler::Electrostatics> electrostatics_assembler = std::dynamic_pointer_cast<assembler::Electrostatics>(
assembler);
175 double capacitance = 2 * energy;
176 logger().info(
"Capacitance computation: {}", capacitance);
182 const std::string restart_json_path =
args[
"output"][
"restart_json"];
183 if (restart_json_path.empty())
189 restart_json[
"time"] = {{
"t0", t0 + dt * t}};
191 restart_json[
"space"] = R
"({
194 "abs_max_edge_length": -1,
195 "rel_max_edge_length": -1
199 restart_json["space"][
"remesh"][
"collapse"][
"abs_max_edge_length"] = std::min(
200 args[
"space"][
"remesh"][
"collapse"][
"abs_max_edge_length"].get<double>(),
202 restart_json[
"space"][
"remesh"][
"collapse"][
"rel_max_edge_length"] = std::numeric_limits<float>::max();
204 std::string rest_mesh_path =
args[
"output"][
"data"][
"rest_mesh"].get<std::string>();
205 if (!rest_mesh_path.empty())
209 std::vector<json> patch;
210 if (
args[
"geometry"].is_array())
212 const std::vector<json> in_geometry =
args[
"geometry"];
213 for (
int i = 0; i < in_geometry.size(); ++i)
215 if (!in_geometry[i][
"is_obstacle"].get<bool>())
219 {
"path", fmt::format(
"/geometry/{}", i)},
224 const int remaining_geometry = in_geometry.size() - patch.size();
225 assert(remaining_geometry >= 0);
229 {
"path", fmt::format(
"/geometry/{}", remaining_geometry > 0 ?
"0" :
"-")},
233 {
"mesh", rest_mesh_path},
239 assert(
args[
"geometry"].is_object());
242 {
"path",
"/geometry"},
246 {
"path",
"/geometry"},
250 {
"mesh", rest_mesh_path},
255 restart_json[
"patch"] = patch;
258 restart_json[
"input"] = {{
266 file << restart_json;
#define POLYFEM_SCOPED_TIMER(...)
io::OutRuntimeData timings
runtime statistics
int n_bases
number of bases
int n_pressure_bases
number of pressure bases
assembler::AssemblyValsCache ass_vals_cache
used to store assembly values for small problems
const std::vector< basis::ElementBases > & geom_bases() const
Get a constant reference to the geometry mapping bases.
std::string root_path() const
Get the root path for the state (e.g., args["root_path"] or ".")
std::shared_ptr< assembler::Assembler > assembler
assemblers
void compute_errors(const Eigen::MatrixXd &sol)
computes all errors
void save_subsolve(const int i, const int t, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &pressure)
saves a subsolve when save_solve_sequence_debug is true
io::OutGeometryData out_geom
visualization stuff
std::string resolve_output_path(const std::string &path) const
Resolve output path relative to output_dir if the path is not absolute.
std::string output_dir
Directory for output files.
void save_timestep(const double time, const int t, const double t0, const double dt, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &pressure)
saves a timestep
void save_json(const Eigen::MatrixXd &sol, std::ostream &out)
saves the output statistic to a stream
double starting_min_edge_length
std::unique_ptr< mesh::Mesh > mesh
current mesh, it can be a Mesh2D or Mesh3D
std::shared_ptr< assembler::Problem > problem
current problem, it contains rhs and bc
json args
main input arguments containing all defaults
void save_restart_json(const double t0, const double dt, const int t) const
Save a JSON sim file for restarting the simulation at time t.
io::OutStatsData stats
Other statistics.
std::vector< basis::ElementBases > bases
FE bases, the size is #elements.
bool iso_parametric() const
check if using iso parametric bases
void export_data(const Eigen::MatrixXd &sol, const Eigen::MatrixXd &pressure)
saves all data on the disk according to the input params
std::string resolve_input_path(const std::string &path, const bool only_if_exists=false) const
Resolve input path relative to root_path() if the path is not absolute.
bool is_contact_enabled() const
does the simulation have contact
Eigen::VectorXi disc_orders
vector of discretization orders, used when not all elements have the same degree, one per element
void save_pvd(const std::string &name, const std::function< std::string(int)> &vtu_names, int time_steps, double t0, double dt, int skip_frame=1) const
save a PVD of a time dependent simulation
void save_vtu(const std::string &path, const State &state, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &pressure, const double t, const double dt, const ExportOptions &opts, const bool is_contact_enabled) const
saves the vtu file for time t
void export_data(const State &state, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &pressure, const bool is_time_dependent, const double tend_in, const double dt, const ExportOptions &opts, const std::string &vis_mesh_path, const std::string &nodes_path, const std::string &solution_path, const std::string &stress_path, const std::string &mises_path, const bool is_contact_enabled) const
exports everytihng, txt, vtu, etc
void save_json(const nlohmann::json &args, const int n_bases, const int n_pressure_bases, const Eigen::MatrixXd &sol, const mesh::Mesh &mesh, const Eigen::VectorXi &disc_orders, const assembler::Problem &problem, const OutRuntimeData &runtime, const std::string &formulation, const bool isoparametric, const int sol_at_node_id, nlohmann::json &j)
saves the output statistic to a json object
void compute_errors(const int n_bases, const std::vector< polyfem::basis::ElementBases > &bases, const std::vector< polyfem::basis::ElementBases > &gbases, const polyfem::mesh::Mesh &mesh, const assembler::Problem &problem, const double tend, const Eigen::MatrixXd &sol)
compute errors
std::string resolve_path(const std::string &path, const std::string &input_file_path, const bool only_if_exists=false)
bool is_param_valid(const json ¶ms, const std::string &key)
Determine if a key exists and is non-null in a json object.
spdlog::logger & logger()
Retrieves the current logger.