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"];
61 *
this, sol, pressure, time, dt,
67 [step_name](
int i) {
return fmt::format(step_name +
"{:d}.vtm", i); },
68 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) {
…}
75 if (!out_path.empty())
77 std::ofstream out(out_path);
80 logger().error(
"Unable to save simulation JSON to {}", out_path);
92 logger().error(
"Load the mesh first!");
97 logger().error(
"Solve the problem first!");
101 logger().info(
"Saving json...");
103 using json = nlohmann::json;
109 out << j.dump(4) << std::endl;
112 void State::save_subsolve(
const int i,
const int t,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure)
114 if (!
args[
"output"][
"advanced"][
"save_solve_sequence_debug"].get<bool>())
121 if (!
args[
"time"].is_null())
122 dt =
args[
"time"][
"dt"];
126 *
this, sol, pressure, t, dt,
112 void State::save_subsolve(
const int i,
const int t,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure) {
…}
135 logger().error(
"Load the mesh first!");
140 logger().error(
"Build the bases first!");
150 logger().error(
"Solve the problem first!");
162 double tend =
args.value(
"tend", 1.0);
164 if (!
args[
"time"].is_null())
165 dt =
args[
"time"][
"dt"];
168 *
this, sol, pressure,
169 !
args[
"time"].is_null(),
179 if (
assembler->name() ==
"Electrostatics")
181 std::shared_ptr<assembler::Electrostatics> electrostatics_assembler = std::dynamic_pointer_cast<assembler::Electrostatics>(
assembler);
183 double capacitance = 2 * energy;
184 logger().info(
"Capacitance computation: {}", capacitance);
190 const std::string restart_json_path =
args[
"output"][
"restart_json"];
191 if (restart_json_path.empty())
197 restart_json[
"time"] = {{
"t0", t0 + dt * t}};
199 restart_json[
"space"] = R
"({
202 "abs_max_edge_length": -1,
203 "rel_max_edge_length": -1
207 restart_json["space"][
"remesh"][
"collapse"][
"abs_max_edge_length"] = std::min(
208 args[
"space"][
"remesh"][
"collapse"][
"abs_max_edge_length"].get<double>(),
210 restart_json[
"space"][
"remesh"][
"collapse"][
"rel_max_edge_length"] = std::numeric_limits<float>::max();
212 std::string rest_mesh_path =
args[
"output"][
"data"][
"rest_mesh"].get<std::string>();
213 if (!rest_mesh_path.empty())
217 std::vector<json> patch;
218 if (
args[
"geometry"].is_array())
220 const std::vector<json> in_geometry =
args[
"geometry"];
221 for (
int i = 0; i < in_geometry.size(); ++i)
223 if (!in_geometry[i][
"is_obstacle"].get<bool>())
227 {
"path", fmt::format(
"/geometry/{}", i)},
232 const int remaining_geometry = in_geometry.size() - patch.size();
233 assert(remaining_geometry >= 0);
237 {
"path", fmt::format(
"/geometry/{}", remaining_geometry > 0 ?
"0" :
"-")},
241 {
"mesh", rest_mesh_path},
247 assert(
args[
"geometry"].is_object());
250 {
"path",
"/geometry"},
254 {
"path",
"/geometry"},
258 {
"mesh", rest_mesh_path},
263 restart_json[
"patch"] = patch;
266 restart_json[
"input"] = {{
274 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.
std::vector< io::SolutionFrame > solution_frames
saves the frames in a vector instead of VTU
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 has contact
Eigen::VectorXi disc_orders
vector of discretization orders, used when not all elements have the same degree, one per element
bool solve_export_to_file
flag to decide if exporting the time dependent solution to files or save it in the solution_frames ar...
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 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, std::vector< SolutionFrame > &solution_frames) const
exports everytihng, txt, vtu, etc
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, std::vector< SolutionFrame > &solution_frames) const
saves the vtu file for time t
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.