11---
2- title : " Workflow Eisenstadt 2005 (neuer Rechenkern 2026-01-22 )"
2+ title : " Workflow Eisenstadt 2005 (neuer Rechenkern 2026-02-24 )"
33output : rmarkdown::html_vignette
44vignette : >
55 %\VignetteIndexEntry{Workflow Eisenstadt 2005 (neuer Rechenkern 2026-01-22)}
@@ -25,15 +25,19 @@ is_ghactions <- TRUE
2525library(kwb.raindrop)
2626
2727path_list <- list(
28- root_path = "D :/raindrop/2025-12-19_Raindrop_Daten ",
28+ root_path = "C :/raindrop/2026-01-22_Raindrop_Daten ",
2929 dir_base = "<root_path>/Optimierungsfall",
30+ dir_data = "<dir_base>/data",
3031 dir_exe = "<root_path>/Berechnungskern",
31- dir_input = "<root_path>/Optimierungsfall/models/eisenstadt-optim/input",
32- dir_output = "<root_path>/Optimierungsfall/models/eisenstadt-optim/output",
32+ modelname = "Eisenstadt_2005",
33+ dir_input = "<root_path>/Optimierungsfall/models/<modelname>/input",
34+ dir_output = "<root_path>/Optimierungsfall/models/<modelname>/output",
3335 dir_target_output = "<dir_output>/<dir_target>",
34- file_base = "Eisenstadt_2005 .h5",
36+ file_base = "<modelname> .h5",
3537 file_errors_hdf5 = "Fehlerprotokoll.h5",
36- file_exe = "Regenwasserbewirtschaftung.exe",
38+ file_exe = "Regenwasserbewirtschaftung_2026-02-24.exe", #"Regenwasserbewirtschaftung_2025-12-10.exe",
39+ file_et = "<modelname>_ET0_2011-2025.csv",
40+ file_rain = "<modelname>_Zehnminutendaten_Niederschlag_v2_Datensatz_2011-2025.csv",
3741 file_results_hdf5_element = "Mulde_Rigole.h5",
3842 file_results_hdf5_flaeche = "Dach.h5",
3943 file_results_hdf5_verschaltungen = "<dir_target>_Verschaltungen.h5",
@@ -42,6 +46,8 @@ path_list <- list(
4246 file_target = "<dir_target>.h5",
4347 path_base = "<dir_base>/<file_base>",
4448 path_exe = "<dir_exe>/<file_exe>",
49+ path_et = "<dir_data>/<file_et>",
50+ path_rain = "<dir_data>/<file_rain>",
4551 path_errors_hdf5 = "<dir_target_output>/<file_errors_hdf5>",
4652 path_results_hdf5_element = "<dir_target_output>/<file_results_hdf5_element>",
4753 path_results_hdf5_flaeche = "<dir_target_output>/<file_results_hdf5_flaeche>",
@@ -148,117 +154,116 @@ htmlwidgets::saveWidget(DT::datatable(param_grid,
148154
149155
150156psi_s_mm <- function(kf_mmh) (3.237 * (kf_mmh/25.4)^(-0.328)) * 25.4
157+
158+ paths <- kwb.utils::resolve(path_list)
151159```
152160
153161### Run Model
154162
155163``` {r run_model, eval = !is_ghactions}
156- debug <- TRUE
157- #Number of cores for parallel processing (or: automatic)
158- future::plan(future::multisession, workers = parallel::detectCores())
164+ run_one <- function(i,
165+ timestep_hours,
166+ debug = FALSE,
167+ ...) {
159168
160- system.time(
161- future.apply::future_lapply(seq_len(nrow(param_grid)), function(i) {
162-
163169 param_grid_tmp <- param_grid[i, ]
164-
165- paths <- kwb.utils::resolve(path_list, dir_target = param_grid_tmp$scenario_name)
166-
167- fs::dir_create(paths$dir_input, recurse = TRUE)
168- fs::dir_create(paths$dir_output, recurse = TRUE)
169- fs::dir_create(paths$dir_target_output, recurse = TRUE)
170-
171- fs::file_copy(path = paths$path_base,
172- new_path = paths$path_target_input,
173- overwrite = TRUE)
174-
175- # "a" = read/write (legt an, falls nicht da); alternativ "r+" = read/write, aber nicht neu anlegen
176- h5 <- hdf5r::H5File$new(paths$path_target_input, mode = "a")
177-
178-
179- new_path <- stringr::str_c(normalizePath(fs::path_abs(paths$dir_target_output)),
180- "\\")
181-
182- # 2) Alle Werte lesen (als named list, Keys = absolute Pfade)
183- vals <- kwb.raindrop::h5_read_values(h5)
184-
185- vals$`//Berechnungsparameter/Ergebnispfad` <- new_path
186- vals$`//Berechnungsparameter/R-Plots` <- 0
187- vals$`//Berechnungsparameter/Ausgabemodus` <- "Optimierung" # "komplett" "Optimierung"
188- vals$`//Berechnungsparameter/Evapotranspiration_aktiv` <- 1
189- vals$`//Massnahmenelemente/Dach/Berechnungsparameter/Evapotranspiration_aktiv` <- 1
190- vals$`//Massnahmenelemente/Mulde_Rigole/Berechnungsparameter/Evapotranspiration_aktiv` <- 1
191- vals$`//Massnahmenelemente/Dach/Allgemein/Flaeche` <- param_grid_tmp$connected_area
192- vals$`//Massnahmenelemente/Mulde_Rigole/Allgemein/Flaeche` <- param_grid_tmp$mulde_area
193- vals$`//Massnahmenelemente/Mulde_Rigole/Eigenschaften_Oberflaeche/Ueberlaufhoehe` <- param_grid_tmp$mulde_height
194- vals$`//Bodenarten/Bodenfilter/Ks_HydraulicConductivity` <- param_grid_tmp$filter_hydraulicconductivity
195- vals$`//Bodenarten/Bodenfilter/Psi_Saugspannung_CapillarySuction` <- psi_s_mm(param_grid_tmp$filter_hydraulicconductivity)
196- #vals$`//Massnahmenelemente/Mulde_Rigole/Bodenschichtung/Startwerte_theta_ActualSoilMoisture` <- c(0.3, 0)
197- vals$`//Massnahmenelemente/Mulde_Rigole/Bodenschichtung/Schichtdicken` <- c(param_grid_tmp$filter_height,
198- param_grid_tmp$storage_height)
199- vals$`//Massnahmenelemente/Mulde_Rigole/Allgemein/Endversickerungsrate` <- param_grid_tmp$bottom_hydraulicconductivity
200-
201- # Timeseries (2×N) als tibble?
202- if (is.data.frame(vals[["//Kurven/Regen"]])) {
203- vals[["//Kurven/Regen"]]$value <- vals[["//Kurven/Regen"]]$value * param_grid_tmp$rain_factor
204- }
205170
171+ paths <- kwb.utils::resolve(path_list,
172+ dir_target = param_grid_tmp$scenario_name)
173+
174+ fs::dir_create(paths$dir_input, recurse = TRUE)
175+ fs::dir_create(paths$dir_output, recurse = TRUE)
176+ fs::dir_create(paths$dir_target_output, recurse = TRUE)
177+
178+ fs::file_copy(path = paths$path_base,
179+ new_path = paths$path_target_input,
180+ overwrite = TRUE)
181+
182+ h5 <- hdf5r::H5File$new(paths$path_target_input, mode = "a")
183+
184+ new_path <- stringr::str_c(normalizePath(fs::path_abs(paths$dir_target_output)),
185+ "\\")
186+
187+ vals <- kwb.raindrop::h5_read_values(h5)
188+
189+ vals$`//Berechnungsparameter/Ergebnispfad` <- new_path
190+ vals$`//Berechnungsparameter/Zeitschritt_Infiltration` <- timestep_hours
191+ vals$`//Berechnungsparameter/Zeitschritt_ET` <- timestep_hours
192+ #vals$`//Berechnungsparameter/Zeitschritt_Verschaltungen` <- timestep_hours
193+ vals$`//Berechnungsparameter/R-Plots` <- 0
194+ vals$`//Berechnungsparameter/Ausgabemodus` <- "Optimierung"
195+ vals$`//Berechnungsparameter/Evapotranspiration_aktiv` <- 1
196+
197+ vals$`//Massnahmenelemente/Dach/Berechnungsparameter/Evapotranspiration_aktiv` <- 1
198+ vals$`//Massnahmenelemente/Dach/Allgemein/Flaeche` <- param_grid_tmp$connected_area
199+
200+ vals$`//Massnahmenelemente/Mulde_Rigole/Berechnungsparameter/Evapotranspiration_aktiv` <- 1
201+ vals$`//Massnahmenelemente/Mulde_Rigole/Allgemein/Regen-Skalierungsfaktor` <- 1
202+ vals$`//Massnahmenelemente/Mulde_Rigole/Allgemein/Flaeche` <- param_grid_tmp$mulde_area
203+ vals$`//Massnahmenelemente/Mulde_Rigole/Eigenschaften_Oberflaeche/Ueberlaufhoehe` <- param_grid_tmp$mulde_height
204+ vals$`//Massnahmenelemente/Mulde_Rigole/Bodenschichtung/Startwerte_theta_ActualSoilMoisture` <- c(0.3, 0)
205+ vals$`//Massnahmenelemente/Mulde_Rigole/Bodenschichtung/Schichtdicken` <- c(param_grid_tmp$filter_height,
206+ param_grid_tmp$storage_height)
207+ vals$`//Massnahmenelemente/Mulde_Rigole/Allgemein/Endversickerungsrate` <- param_grid_tmp$bottom_hydraulicconductivity
208+
209+ vals$`//Bodenarten/Bodenfilter/Ks_HydraulicConductivity` <- param_grid_tmp$filter_hydraulicconductivity
210+ vals$`//Bodenarten/Bodenfilter/Psi_Saugspannung_CapillarySuction` <- psi_s_mm(param_grid_tmp$filter_hydraulicconductivity)
211+
212+ kwb.raindrop::h5_write_values(h5, vals, resize = TRUE,
213+ scalar_strategy = "error",
214+ verbose = FALSE)
215+ h5$close_all()
216+
217+ kwb.raindrop::run_model(path_exe = paths$path_exe,
218+ path_input = paths$path_target_input,
219+ debug = debug)
220+
221+ invisible(NULL)
222+ }
206223
207- kwb.raindrop::h5_write_values(h5, vals, resize = TRUE, scalar_strategy = "error", verbose = FALSE)
208- h5$close_all()
209-
210- kwb.raindrop::run_model(path_exe = paths$path_exe,
211- path_input = paths$path_target_input)
212- })
224+ n_cores <- parallel::detectCores()
225+
226+ system.time(expr = {
227+ kwb.raindrop::run_scenarios(indices = seq_len(nrow(param_grid)),
228+ run_one_scenario = run_one,
229+ timestep_hours = 0.1,
230+ debug = FALSE,
231+ parallel = TRUE,
232+ workers = n_cores,
233+ show_progress = TRUE
234+ )
235+ }
213236)
214237
215-
216238### Read results for first run
217-
218- paths <- kwb.utils::resolve(path_list, dir_target = sprintf("s%05d", i = 1))
239+ if(FALSE) {
240+ paths <- kwb.utils::resolve(path_list,
241+ dir_target = sprintf("s%05d", i = 1))
219242
220243#simulation_names <- basename(fs::dir_ls(paths$dir_output))
221244simulation_names <- scenarios_with_single_parameter_variation
222- simulation_names <- param_grid$scenario_name
223-
224- debug <- TRUE
225- errors_df <- lapply(simulation_names, function(s_name) {
226-
227- s_id <- s_name %>% stringr::str_remove("s") %>% as.integer()
228- paths <- kwb.utils::resolve(path_list, dir_target = s_name)
229-
230- if(fs::file_exists(paths$path_errors_hdf5)) {
231- kwb.utils::catAndRun(messageText = sprintf("Reading error file '%s'",
232- paths$path_errors_hdf5),
233- expr = {
234- error_hdf <- hdf5r::H5File$new(paths$path_errors_hdf5, mode = "r")
235-
236- tibble::tibble(id = s_id,
237- path = paths$path_errors_hdf5,
238- number_of_errors = error_hdf[["AnzahlFehler"]]$read()
239- )
240- },
241- dbg = debug)
242- }
243- }) %>%
244- dplyr::bind_rows()
245+ simulation_names <- param_grid$scenario_nam
246+ simulation_names <- simulation_names[1:8]
247+
248+ debug <- TRUEn_cores
249+ errors_df <- kwb.raindrop::read_raindrop_errors(simulation_names, path_list)
250+ x <- tidyr::unnest(errors_df, errors)
251+ x$Fehlerbeschreibung
252+ }
253+
245254```
246255
247256### Analyse Results
248257
249258``` {r analyse_results, eval = !is_ghactions}
250- paths <- kwb.utils::resolve(path_list, dir_target = sprintf("s%05d", i = 1))
251-
252- #simulation_names <- basename(fs::dir_ls(paths$dir_output))
253- simulation_names <- param_grid$scenario_name
254-
255259system.time(
256- simulation_results <- kwb.raindrop::get_simulation_results_optim(paths = paths,
257- path_list = path_list,
258- simulation_names = simulation_names)
260+ simulation_results <- kwb.raindrop::get_simulation_results_optim_parallel(
261+ paths = paths,
262+ path_list = path_list,
263+ simulation_names = param_grid$scenario_name,
264+ debug = FALSE)
259265)
260266
261-
262267system.time(
263268simulation_results_optimisation <- kwb.raindrop::add_overflow_events_and_waterbalance(
264269 simulation_results = simulation_results,
@@ -271,13 +276,17 @@ simulation_results_optimisation <- param_grid %>%
271276 by = c("scenario_name" = "s_name")) %>%
272277 dplyr::relocate(scenario_name, .before = connected_area)
273278
274- readr::write_csv(simulation_results_optimisation, file = "simulation_results_optimisation.csv")
279+ readr::write_csv(simulation_results_optimisation,
280+ file = sprintf("simulation_results_optimisation_%s.csv",
281+ paths$modelname)
282+ )
275283
276284htmlwidgets::saveWidget(DT::datatable(simulation_results_optimisation,
277285 filter = "top",
278286 options = list(pageLength = 25,
279287 autoWidth = TRUE)),
280- "simulation_results_optimisation.html",
288+ file = sprintf("simulation_results_optimisation_%s.html",
289+ paths$modelname),
281290 title = "RAINDROP - Solution Space")
282291
283292### Plot results
@@ -294,7 +303,8 @@ params <- c(
294303 #"rain_factor"
295304)
296305
297- pdff <- "simulation_results_optimisation_main-effects.pdf"
306+ pdff <- sprintf("simulation_results_optimisation_%s_main-effects.pdf",
307+ paths$modelname)
298308
299309gg <- kwb.raindrop::plot_main_effects(
300310 df = simulation_results_optimisation,
@@ -313,14 +323,16 @@ plotly_gg <- plotly::ggplotly(gg)
313323
314324htmlwidgets::saveWidget(
315325 widget = plotly_gg,
316- file = "simulation_results_optimisation_main-effects.html",
326+ file = sprintf("simulation_results_optimisation_%s_main-effects.html",
327+ paths$modelname),
317328 selfcontained = TRUE,
318329 title = "RAINDROP - Main Effects"
319330)
320331
321332
322333
323- pdff <- "simulation_results_optimisation_design-space_mulde-area_vs_parameters.pdf"
334+ pdff <- sprintf("simulation_results_optimisation_%s_design-space_mulde-area_vs_parameters.pdf",
335+ paths$modelname)
324336kwb.utils::preparePdf(pdfFile = pdff)
325337
326338for (y in c("mulde_height", "filter_hydraulicconductivity", "storage_height")) {
@@ -343,7 +355,9 @@ for (y in c("mulde_height", "filter_hydraulicconductivity", "storage_height")) {
343355 plotly_p <- suppressWarnings(plotly::ggplotly(p, tooltip = "text"))
344356 htmlwidgets::saveWidget(
345357 widget = plotly_p,
346- file = sprintf("simulation_results_optimisation_design-space_mulde-area_vs_%s.html", y),
358+ file = sprintf("simulation_results_optimisation_%s_design-space_mulde-area_vs_%s.html",
359+ paths$modelname,
360+ y),
347361 selfcontained = TRUE,
348362 title = sprintf("Design Space: mulde_area vs. %s", y)
349363 )
@@ -354,7 +368,8 @@ for (y in c("mulde_height", "filter_hydraulicconductivity", "storage_height")) {
354368dev.off()
355369#kwb.utils::finishAndShowPdf(pdff)
356370
357- pdff <- "simulation_results_optimisation_water-balance.pdf"
371+ pdff <- sprintf("simulation_results_optimisation_%s_water-balance.pdf",
372+ paths$modelname)
358373kwb.utils::preparePdf(pdfFile = pdff)
359374
360375p <- kwb.raindrop::plot_wb_tradeoff_overflows(
@@ -368,7 +383,8 @@ p <- kwb.raindrop::plot_wb_tradeoff_overflows(
368383 plotly_p <- suppressWarnings(plotly::ggplotly(p, tooltip = "text"))
369384 htmlwidgets::saveWidget(
370385 widget = plotly_p,
371- file = "simulation_results_optimisation_water-balance.html",
386+ file = sprintf("simulation_results_optimisation_%s_water-balance.html",
387+ paths$modelname),
372388 selfcontained = TRUE,
373389 title = "Water balance vs overflows"
374390 )
0 commit comments