12 if (!
args[
"output"][
"advanced"][
"compute_error"])
17 if (!
args[
"time"].is_null())
19 tend =
args[
"time"][
"tend"];
28 return args[
"root_path"].get<std::string>();
39 if (
output_dir.empty() || path.empty() || std::filesystem::path(path).is_absolute())
43 return std::filesystem::weakly_canonical(std::filesystem::path(
output_dir) / path).string();
46 void State::save_timestep(
const double time,
const int t,
const double t0,
const double dt,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure)
48 if (
args[
"output"][
"advanced"][
"save_time_sequence"] && !(t %
args[
"output"][
"paraview"][
"skip_frame"].get<int>()))
50 logger().trace(
"Saving VTU...");
52 const std::string step_name =
args[
"output"][
"advanced"][
"timestep_prefix"];
59 *
this, sol, pressure, time, dt,
65 [step_name](
int i) {
return fmt::format(step_name +
"{:d}.vtm", i); },
66 t, t0, dt,
args[
"output"][
"paraview"][
"skip_frame"].get<
int>());
73 if (!out_path.empty())
75 std::ofstream out(out_path);
78 logger().error(
"Unable to save simulation JSON to {}", out_path);
90 logger().error(
"Load the mesh first!");
95 logger().error(
"Solve the problem first!");
99 logger().info(
"Saving json...");
101 using json = nlohmann::json;
107 out << j.dump(4) << std::endl;
110 void State::save_subsolve(
const int i,
const int t,
const Eigen::MatrixXd &sol,
const Eigen::MatrixXd &pressure)
112 if (!
args[
"output"][
"advanced"][
"save_solve_sequence_debug"].get<bool>())
119 if (!
args[
"time"].is_null())
120 dt =
args[
"time"][
"dt"];
124 *
this, sol, pressure, t, dt,
133 logger().error(
"Load the mesh first!");
138 logger().error(
"Build the bases first!");
148 logger().error(
"Solve the problem first!");
160 double tend =
args.value(
"tend", 1.0);
162 if (!
args[
"time"].is_null())
163 dt =
args[
"time"][
"dt"];
166 *
this, sol, pressure,
167 !
args[
"time"].is_null(),
180 const std::string restart_json_path =
args[
"output"][
"restart_json"];
181 if (restart_json_path.empty())
187 restart_json[
"time"] = {{
"t0", t0 + dt * t}};
189 restart_json[
"space"] = R
"({
192 "abs_max_edge_length": -1,
193 "rel_max_edge_length": -1
197 restart_json["space"][
"remesh"][
"collapse"][
"abs_max_edge_length"] = std::min(
198 args[
"space"][
"remesh"][
"collapse"][
"abs_max_edge_length"].get<double>(),
200 restart_json[
"space"][
"remesh"][
"collapse"][
"rel_max_edge_length"] = std::numeric_limits<float>::max();
202 std::string rest_mesh_path =
args[
"output"][
"data"][
"rest_mesh"].get<std::string>();
203 if (!rest_mesh_path.empty())
207 std::vector<json> patch;
208 if (
args[
"geometry"].is_array())
210 const std::vector<json> in_geometry =
args[
"geometry"];
211 for (
int i = 0; i < in_geometry.size(); ++i)
213 if (!in_geometry[i][
"is_obstacle"].get<bool>())
217 {
"path", fmt::format(
"/geometry/{}", i)},
222 const int remaining_geometry = in_geometry.size() - patch.size();
223 assert(remaining_geometry >= 0);
227 {
"path", fmt::format(
"/geometry/{}", remaining_geometry > 0 ?
"0" :
"-")},
231 {
"mesh", rest_mesh_path},
237 assert(
args[
"geometry"].is_object());
240 {
"path",
"/geometry"},
244 {
"path",
"/geometry"},
248 {
"mesh", rest_mesh_path},
253 restart_json[
"patch"] = patch;
256 restart_json[
"input"] = {{
264 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
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.