46#include <unordered_map>
140class Default2DOutputPlugin final :
public IOutputPlugin {
146 explicit Default2DOutputPlugin(std::string h5_path);
147 ~Default2DOutputPlugin()
override;
150 Default2DOutputPlugin(
const Default2DOutputPlugin&) =
delete;
151 Default2DOutputPlugin& operator=(
const Default2DOutputPlugin&) =
delete;
173 int initialize(
const std::vector<std::string>& init_args,
174 const IPluginComponentInfo* info)
override;
183 int validate(
const SimulationContext& ctx)
override;
199 int prepare(
const SimulationContext& ctx)
override;
210 int update(
const SimulationSnapshot& snapshot)
override;
224 int finalize(
const SimulationContext& ctx)
override;
232 const char* last_error_message() const noexcept
override {
return last_error_.c_str(); }
251 void prepareMeshAndDatasets(
const MeshData& mesh);
269 void setMeshCoordinateScale(
double metres_per_model_unit);
291 std::string configureOutput(
const SolverOptions2D& opts,
double report_step_sec);
300 unsigned reportVariables() const noexcept {
return report_vars_; }
316 void enqueueSourceHistory(std::shared_ptr<const SourceResultHistory> history);
319 friend class openswmm::SWMMEngine;
321 bool checkpoint_fresh_ =
false;
322 bool checkpoint_write_failed_ =
false;
323 void checkpointWriteStatus(herr_t);
324 std::string checkpoint_header_;
325 struct PreparedCheckpoint;
326 std::string checkpointBytes(
const SimulationContext&,
double next_report_ms,
327 const SimulationSnapshot&);
328 std::shared_ptr<PreparedCheckpoint> prepareCheckpoint(
const SimulationContext&,
329 double next_report_ms,
330 const SimulationSnapshot&,
331 const SourceResultHistory*, std::string);
332 void installCheckpoint(PreparedCheckpoint&);
333 io::CheckpointOutputPublication::Output checkpointPublication(
const PreparedCheckpoint&)
const;
334 void adoptCheckpoint(PreparedCheckpoint&)
noexcept;
335 void validateCheckpoint(hid_t,
const SimulationContext&,
double,
const SimulationSnapshot&,
336 hsize_t,
double,
bool)
const;
337 std::vector<hid_t*> checkpointDatasets();
338 void closeDatasets() noexcept;
339 std::
string fileBytes() const;
340 std::
string captureFileCheckpoint(const SimulationContext&,
double, const SimulationSnapshot&,
341 const std::filesystem::path&,
342 std::shared_ptr<io::OwnedCheckpointFile>&);
343 std::shared_ptr<PreparedCheckpoint>
344 prepareFileCheckpoint(const SimulationContext&,
double, const SimulationSnapshot&, std::
string);
345 void resolveCheckpointDatasets(PreparedCheckpoint&, const SimulationSnapshot&);
346 std::mutex source_mutex_;
347 std::vector<std::shared_ptr<const SourceResultHistory>> source_pending_;
348 std::shared_ptr<const SourceResultHistory> source_written_;
349 int writePendingSourceHistory();
351 hid_t storage_type_ = H5T_NATIVE_DOUBLE;
352 int compression_ = 4;
353 unsigned report_vars_ = 0x7FFu;
354 std::vector<std::
string> species_filter_;
355 std::vector<
int> species_rows_;
356 double report_2d_step_days_ = 0.0;
357 double next_due_days_ = -1.0;
365 bool want(
unsigned bit) const noexcept {
return (report_vars_ & bit) != 0; }
378 void writeSpeciesRows(
const double* all, hsize_t n_species_in);
380 std::string h5_path_;
382 std::string last_error_;
384 std::unordered_map<std::string, std::string>
385 native_species_units_;
386 std::string model_crs_;
387 double metres_per_model_unit_ = 1.0;
389 hid_t file_id_ = H5I_INVALID_HID;
392 hid_t ds_time_ = H5I_INVALID_HID;
393 hid_t ds_face_depth_ = H5I_INVALID_HID;
394 hid_t ds_face_head_ = H5I_INVALID_HID;
395 hid_t ds_face_grad_hx_ = H5I_INVALID_HID;
396 hid_t ds_face_grad_hy_ = H5I_INVALID_HID;
397 hid_t ds_face_grad_hx_lim_ = H5I_INVALID_HID;
398 hid_t ds_face_grad_hy_lim_ = H5I_INVALID_HID;
399 hid_t ds_face_rainfall_ = H5I_INVALID_HID;
400 hid_t ds_face_coupling_flux_ = H5I_INVALID_HID;
401 hid_t ds_face_net_source_ = H5I_INVALID_HID;
402 hid_t ds_face_infil_rate_ = H5I_INVALID_HID;
403 hid_t ds_face_infil_cum_ = H5I_INVALID_HID;
404 hid_t ds_face_rain_cum_ = H5I_INVALID_HID;
407 ids.fill(H5I_INVALID_HID);
410 void createSnowDatasets(
const SimulationSnapshot&);
415 hid_t ds_face_species_conc_ = H5I_INVALID_HID;
416 hsize_t n_species_ = 0;
420 hid_t ds_face_buildup_ = H5I_INVALID_HID;
421 hsize_t n_buildup_ = 0;
428 static constexpr int kGwFaceFields = 27;
429 static constexpr hsize_t kGwLedgerTerms = 15;
430 hid_t ds_gw_face_[kGwFaceFields] = {
431 H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
432 H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
433 H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
434 H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
435 H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID, H5I_INVALID_HID,
436 H5I_INVALID_HID, H5I_INVALID_HID};
437 hid_t ds_gw_ledger_ = H5I_INVALID_HID;
440 static constexpr hsize_t kGwSpeciesLedgerTerms = 15;
441 hid_t ds_gw_sat_conc_ = H5I_INVALID_HID;
442 hid_t ds_gw_unsat_conc_ = H5I_INVALID_HID;
443 hid_t ds_gw_species_ledger_ = H5I_INVALID_HID;
444 hsize_t n_gw_species_ = 0;
445 hid_t ds_gw_bed_exchange_ = H5I_INVALID_HID;
446 hid_t ds_gw_theta_ = H5I_INVALID_HID;
447 hsize_t n_gw_beds_ = 0;
448 hsize_t n_gw_layers_ = 0;
449 hid_t ds_gw_layer_mass_ = H5I_INVALID_HID, ds_gw_layer_conc_ = H5I_INVALID_HID;
450 hid_t ds_gw_boundary_water_ = H5I_INVALID_HID, ds_gw_boundary_species_ = H5I_INVALID_HID;
451 hid_t ds_gw_transport_ledger_ = H5I_INVALID_HID;
452 hsize_t n_gw_transport_layers_ = 0, n_gw_boundaries_ = 0;
453 bool gw_created_ =
false;
454 void createGroundwaterDatasets(
const SimulationSnapshot& snap);
455 bool heat_created_ =
false;
456 hsize_t n_heat_layers_ = 0;
457 hsize_t n_heat_lid_layers_ = 0;
458 hid_t ds_heat_water_temp_ = H5I_INVALID_HID;
459 hid_t ds_heat_bed_temp_ = H5I_INVALID_HID;
460 hid_t ds_heat_bed_energy_ = H5I_INVALID_HID;
461 hid_t ds_heat_bed_initial_energy_ = H5I_INVALID_HID;
462 hid_t ds_heat_bed_capacity_ = H5I_INVALID_HID;
463 hid_t ds_heat_bed_pore_volume_ = H5I_INVALID_HID;
464 hid_t ds_heat_bed_species_conc_ = H5I_INVALID_HID;
465 hid_t ds_heat_bed_species_initial_amount_ = H5I_INVALID_HID;
466 hid_t ds_heat_bed_species_exchange_ = H5I_INVALID_HID;
467 hid_t ds_heat_bed_age_generation_ = H5I_INVALID_HID;
468 hsize_t n_heat_bed_species_ = 0;
469 hid_t ds_heat_surface_budget_ = H5I_INVALID_HID;
470 hid_t ds_heat_evaporation_ = H5I_INVALID_HID;
471 hid_t ds_heat_ground_temp_ = H5I_INVALID_HID;
472 hid_t ds_heat_ground_energy_ = H5I_INVALID_HID;
473 hid_t ds_heat_ground_capacity_ = H5I_INVALID_HID;
474 hid_t ds_heat_layer_temp_ = H5I_INVALID_HID;
475 hid_t ds_heat_layer_energy_ = H5I_INVALID_HID;
476 hid_t ds_heat_layer_capacity_ = H5I_INVALID_HID;
477 hid_t ds_heat_ground_budget_ = H5I_INVALID_HID;
478 hid_t ds_heat_lid_temp_ = H5I_INVALID_HID;
479 hid_t ds_heat_lid_energy_ = H5I_INVALID_HID;
480 hid_t ds_heat_lid_capacity_ = H5I_INVALID_HID;
481 hid_t ds_heat_lid_ground_contact_ = H5I_INVALID_HID;
482 void createThermalDatasets(
const SimulationSnapshot& snap);
483 const MeshData* mixing_mesh_ =
nullptr;
484 std::unique_ptr<InertialEdges> mixing_edges_;
485 std::unique_ptr<MomentumPhysics2D> mixing_diagnostics_;
486 bool mixing_enabled_ =
false, momentum_velocity_ =
false;
487 double mixing_cs_ = .1, mixing_background_ = 0, mixing_depth_coefficient_ = 0, mixing_dry_ = .001,
489 const char* turbulence_name_ =
"NONE";
490 hid_t ds_face_eddy_viscosity_ = H5I_INVALID_HID;
491 hid_t ds_face_strain_rate_ = H5I_INVALID_HID;
492 hid_t ds_face_vx_ = H5I_INVALID_HID;
493 hid_t ds_face_vy_ = H5I_INVALID_HID;
494 hid_t ds_face_continuity_err_ = H5I_INVALID_HID;
495 hid_t ds_edge_flux_ = H5I_INVALID_HID;
496 hid_t ds_node_head_ = H5I_INVALID_HID;
497 hid_t ds_node_depth_ = H5I_INVALID_HID;
500 hid_t ds_face_max_depth_ = H5I_INVALID_HID;
501 hid_t ds_face_max_velocity_ = H5I_INVALID_HID;
502 hid_t ds_face_max_continuity_err_ = H5I_INVALID_HID;
504 hsize_t n_faces_ = 0;
505 hsize_t n_nodes_ = 0;
506 hsize_t edge_stride_ = 3;
507 hsize_t n_steps_ = 0;
517 void writeMeshTopology(
const SimulationContext& ctx);
527 void writeCrsVariable();
549 hid_t createUnlimitedDataset(
const char* name,
int rank,
const hsize_t* dims,
550 const hsize_t* chunk_dims, hid_t type = -1);
564 void writeStringAttr(hid_t loc,
const char* name,
const char* value);
574 void writeDoubleAttr(hid_t loc,
const char* name,
double value);
589 void extendAndWrite2D(hid_t ds,
const double* data, hsize_t n_cols);
608 void extendAndWrite4D(hid_t ds,
const double* data, hsize_t a, hsize_t b, hsize_t c);
625 void extendAndWrite3D(hid_t ds,
const double* data, hsize_t dim1, hsize_t dim2);
639 hid_t createFaceEnvelopeDataset(
const char* name,
const char* long_name,
const char* units);
651 void writeFaceEnvelope(hid_t ds,
const double* data);
Versioned checkpoint file serialization and integrity checks.
Publication of outputs associated with restored checkpoint sessions.
Interface for output-writing plugins.
Definition MomentumPhysics2D.hpp:25
Definition SourceResultHistory.hpp:41
PluginState
Plugin lifecycle states.
Definition PluginState.hpp:86
State state(const FvClosure &table, const Jet &h, const Jet &velocity, uint8_t press)
Construct a differentiated wet face state from depth and velocity.
Definition ImplicitWetKernels.hpp:234
StmtPtr prepare(sqlite3 *db, const std::string &sql)
Prepare the first SQL statement without stepping it.
Definition GpkgUtils.hpp:171
void initialize(SimulationContext &ctx)
Build node-LID hydraulic cells and initial retained/mobile water state.
Definition LidNode.cpp:517
void validate(SimulationContext &ctx)
Validate node-LID model references, layers, supported physics and anchored geometry.
Definition LidNode.cpp:271
Definition ExchangeLaw.hpp:60
Definition ExchangeLaw.hpp:60
constexpr std::array< SnowResultField, 23 > meshSnowFields
Definition SnowResults.hpp:24
Canonical unique interior-edge layout + per-cell incidence for the local-inertial scheme.
Definition InertialEdges.hpp:60
SoA storage for 2D mixed triangle/quad mesh geometry and topology.
Definition MeshData.hpp:65
Definition SolverOptions2D.hpp:257