Newer
Older
#' ogs_run_simulation
#' @description Wrapper function that calls \code{ogs_export_sim_files()},
#' \code{ogs_call_ogs6()} and \code{ogs_read_output_files()}.
#' @param ogs6_obj OGS6: Simulation object
#' @param write_logfile flag: Should output be written to a logfile? If
#' \code{FALSE}, output will be written to console. If \code{TRUE}, logfile
#' directory will be created in \code{ogs6$sim_path} directory
#' @param ogs_bin_path string: Optional: OpenGeoSys 6 bin folder path. Defaults
#' to \code{options("r2ogs6.default_ogs_bin_path")}
#' @param verbose flag
#' @export
ogs_run_simulation <- function(ogs6_obj,
write_logfile = TRUE,
ogs_bin_path,
verbose = F) {
# Export (and / or copy referenced) simulation files
ogs_export_sim_files(ogs6_obj = ogs6_obj,
test_mode = FALSE)
exit_code <- ogs_call_ogs6(ogs6_obj = ogs6_obj,
write_logfile = write_logfile,
ogs_bin_path = ogs_bin_path,
verbose = verbose)
ogs_read_output_files(ogs6_obj = ogs6_obj)
return(invisible(exit_code))
}
#===== ogs_export_sim_files =====
#' ogs_export_sim_files
#' @description Creates \code{ogs6$sim_path} directory if it does not exist yet
#' and exports and / or copies all simulation files to it.
#' @param ogs6_obj OGS6: Simulation object
#' @param test_mode flag: If \code{TRUE}, Will not check status of
#' \code{ogs6_obj} before exporting files. Defaults to \code{FALSE}
#' @export
ogs_export_sim_files <- function(ogs6_obj,
test_mode = FALSE){
assertthat::assert_that(inherits(ogs6_obj, "OGS6"))
# Call all validators
if(!test_mode &&
!ogs6_obj$get_status(print_status = FALSE)){
stop("There are some components missing from your OGS6 object.",
call. = FALSE)
}
# Create the simulation folder
if (!dir.exists(ogs6_obj$sim_path)) {
dir.create(ogs6_obj$sim_path)
} else{
warning(
paste0("sim_path directory '", ogs6_obj$sim_path,
"' is not empty. Files may be overwritten."
),
call. = FALSE
)
}
}
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
if(!is.null(ogs6_obj$gml)){
export_gml(ogs6_obj$gml,
paste0(ogs6_obj$sim_path, basename(ogs6_obj$geometry)))
}else if(!is.null(ogs6_obj$geometry)){
file.copy(ogs6_obj$geometry, ogs6_obj$sim_path)
}
# If processes tag only contains reference, copy referenced file
if(names(ogs6_obj$processes)[[1]] == "include"){
include_dir <- paste0(ogs6_obj$sim_path, "include/")
if(!dir.exists(include_dir)){
dir.create(include_dir)
}
file.copy(ogs6_obj$processes[[1]][["file"]], include_dir)
new_ref_path <- paste0(include_dir,
basename(ogs6_obj$processes[[1]][["file"]]))
ogs6_obj$processes <- new_ref_path
}
# Copy all referenced .vtu files to ogs6_obj$sim_path
lapply(ogs6_obj$meshes, function(x){
file.copy(x, ogs6_obj$sim_path)
})
if(!is.null(ogs6_obj$python_script)){
file.copy(ogs6_obj$python_script, ogs6_obj$sim_path)
}
export_prj(ogs6_obj)
return(invisible())
}
#===== ogs_call_ogs6 =====
#' ogs_call_ogs6
#' @description Makes system call to OpenGeoSys 6 and retrieves exit code.
#' @param ogs6_obj OGS6: Simulation object
#' @param write_logfile flag: Should output be written to a logfile? If
#' \code{FALSE}, output will be written to console. If \code{TRUE}, logfile
#' directory will be created in \code{ogs6$sim_path} directory
#' @param ogs_bin_path string: Optional: OpenGeoSys 6 bin folder path. Defaults
#' to \code{options("r2ogs6.default_ogs_bin_path")}
#' @param verbose flag
#' @export
ogs_call_ogs6 <- function(ogs6_obj,
write_logfile = TRUE,
ogs_bin_path,
verbose = F){
assertthat::assert_that(inherits(ogs6_obj, "OGS6"))
assertthat::assert_that(assertthat::is.flag(write_logfile))
if(missing(ogs_bin_path)){
ogs_bin_path <- unlist(options("r2ogs6.default_ogs_bin_path"))
}
assertthat::assert_that(assertthat::is.string(ogs_bin_path))
assertthat::assert_that(assertthat::is.flag(verbose))
exe_str <- ifelse(Sys.info()["sysname"] == "Windows",
"ogs.exe",
"ogs")
ogs6_command_str <- paste0(ogs_bin_path, exe_str)
sim_path_full <- paste0(ogs6_obj$sim_path,
ogs6_obj$sim_name,
".prj")
ogs6_args <- c(sim_path_full, "-o", ogs6_obj$sim_path)
# Finally, make the system call to start the simulation
if (write_logfile) {
# Create logfile directory
logfile_dir <- paste0(ogs6_obj$sim_path, "logfiles/")
# Set logfile parameter of simulation object
ogs6_obj$logfile <- paste0(logfile_dir, ogs6_obj$sim_name, "_log.txt")
if(!dir.exists(logfile_dir)){
dir.create(logfile_dir)
}
assertthat::assert_that(!file.exists(ogs6_obj$logfile))
file.create(ogs6_obj$logfile)
if(verbose){
cat("\nRunning simulation '", ogs6_obj$sim_name, "'\n", sep = "")
}
exit_code <- system2(command = ogs6_command_str,
args = ogs6_args,
stdout = ogs6_obj$logfile)
} else{
exit_code <- system2(command = ogs6_command_str,
args = ogs6_args)
}
#' ogs_read_output_files
#' @description Read in generated \code{.pvd} files and add it to ogs6_obj
#' @param ogs6_obj OGS6: Simulation object
#' @export
assertthat::assert_that(inherits(ogs6_obj, "OGS6"))
pvd_paths <- list.files(ogs6_obj$sim_path,
"\\.pvd$",
full.names = TRUE)
for(i in seq_len(length(pvd_paths))){
ogs6_obj$pvds <- c(ogs6_obj$pvds,
list(OGS6_pvd$new(pvd_path = pvd_paths[[i]])))
}
return(invisible())
}
#' run_benchmark
#' @description Utility function for quick benchmark runs
#' @param prj_path string:
#' @param ogs_bin_path string:
#' @param sim_path string: Path where simulation files will be saved
run_benchmark <- function(prj_path,
ogs_bin_path,
sim_path){
if(missing(ogs_bin_path)){
ogs_bin_path <- unlist(options("r2ogs6.default_ogs_bin_path"))
sim_path <- unlist(options("r2ogs6.default_sim_path"))
}
assertthat::assert_that(assertthat::is.string(prj_path))
assertthat::assert_that(assertthat::is.string(ogs_bin_path))
assertthat::assert_that(assertthat::is.string(sim_path))
sim_name <- tools::file_path_sans_ext(basename(prj_path))
ogs6_obj <- OGS6$new(sim_name = sim_name,
sim_id = 1,
read_in_prj(ogs6_obj = ogs6_obj,
}
#' run_all_benchmarks
#' @description Utility function, for quick benchmark runs. Calls
#' run_benchmark internally.
#' @param path string: Path to benchmark folder
#' @param ogs_processlib_path string: Path to OpenGeoSys 6 ProcessLib folder
#' which contains relevant Tests.cmake files
#' @param ogs_bin_path string:
#' @param sim_path string: Path where simulation files will be saved
#' @param starting_from_prj_path string: \code{.prj} path to start from
#' @param print_results flag: Print results in the end?
run_all_benchmarks <- function(path,
ogs_bin_path,
starting_from_prj_path = "",
path <- unlist(options("r2ogs6.default_benchmark_path"))
}
if(missing(ogs_processlib_path)){
ogs_processlib_path <-
unlist(options("r2ogs6.default_ogs_processlib_path"))
}
if(missing(ogs_bin_path)){
ogs_bin_path <- unlist(options("r2ogs6.default_ogs_bin_path"))
}
sim_path <- unlist(options("r2ogs6.default_sim_path"))
}
assertthat::assert_that(assertthat::is.string(path))
assertthat::assert_that(assertthat::is.string(ogs_processlib_path))
assertthat::assert_that(assertthat::is.string(ogs_bin_path))
assertthat::assert_that(assertthat::is.string(sim_path))
assertthat::assert_that(assertthat::is.string(starting_from_prj_path))
# Get relevant .prj paths from ProcessLib Tests.cmake files
prj_paths <-
lapply(get_benchmark_paths(ogs_processlib_path), function(x){
paste0(path, x)
})
# If we know the benchmarks up to a specific file are working, skip them
if(starting_from_prj_path != ""){
if(is.na(match(starting_from_prj_path, prj_paths))){
warning(paste("Couldn't find path to start from.",
"Returning all paths."),
call. = FALSE)
}else{
start_index <- match(starting_from_prj_path, prj_paths)
prj_paths <- prj_paths[start_index:length(prj_paths)]
}
}
# Filter nonexisting files from prj_paths
nonexisting_prj_paths <- prj_paths[!file.exists(prj_paths)]
prj_paths <- prj_paths[!prj_paths %in% nonexisting_prj_paths]
# Filter invalid XML from prj_paths
invalid_xml_paths <- filter_invalid_xml(prj_paths)
prj_paths <- prj_paths[!prj_paths %in% invalid_xml_paths]
# Read in valid .prj files and try to run simulations
failed_paths <- character()
exit_codes <- numeric()
for(i in seq_len(length(prj_paths))){
cat("\nAttempting to run Benchmark", prj_paths[[i]])
sim_name <- tools::file_path_sans_ext(basename(prj_paths[[i]]))
sim_subdir_path <- paste0(sim_path,
basename(dirname(prj_paths[[i]])),
"_",
sim_name)
out<- tryCatch(
{
exit_code <- run_benchmark(prj_path = prj_paths[[i]],
ogs_bin_path = ogs_bin_path,
sim_path = sim_subdir_path)
error = function(cond){
message(paste("\nrun_benchmark() failed for",
prj_paths[[i]], ". Original error message:"))
message(cond)
failed_paths <<- c(failed_paths, prj_paths[[i]])
}
)
}
if(print_results){
print_run_all_benchmarks(
nonexisting_prj_paths,
invalid_xml_paths,
failed_paths,
run_started_paths,
exit_codes)
}
return(invisible(list(nonexisting_prj_paths = nonexisting_prj_paths,
invalid_xml_paths = invalid_xml_paths,
failed_paths = failed_paths,
run_started_paths = run_started_paths,
exit_codes = exit_codes)))
}
print_run_all_benchmarks <- function(nonexisting_prj_paths,
invalid_xml_paths,
failed_paths,
run_started_paths,
exit_codes) {
if(length(nonexisting_prj_paths) > 0){
cat("\nCould not find the following .prj files ",
"referenced in Tests.cmake:\n",
paste(nonexisting_prj_paths, collapse = "\n"), "\n", sep = "")
}
if(length(invalid_xml_paths) > 0){
cat("\nCould not parse the following .prj files as XML:\n",
paste(invalid_xml_paths, collapse = "\n"), "\n", sep = "")
}
if(length(failed_paths) > 0){
cat("\nThere was something else wrong with the following .prj files:\n",
paste(failed_paths, collapse = "\n"), "\n", sep = "")
}
if(length(exit_codes) > 0){
cat("\nOpenGeoSys produced the following exit codes:\n",
paste(run_started_paths,
exit_codes,
sep = " produced exit code ",
collapse = "\n"), "\n", sep = "")
}
return(invisible())
}
#' get_benchmark_paths
#' @description Gets paths to all benchmarks that should work
#' @param ogs_processlib_path string: Path to OpenGeoSys 6 ProcessLib folder
#' which contains relevant Tests.cmake files
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
get_benchmark_paths <- function(ogs_processlib_path){
tests_cmake_files <- list.files(path = ogs_processlib_path,
pattern = "^Tests\\.cmake$",
recursive = TRUE,
full.names = TRUE)
benchmark_paths <- list()
for(i in seq_len(length(tests_cmake_files))){
file_content <- readLines(tests_cmake_files[[i]])
file_content <- paste(file_content[!grepl("^#", file_content)],
collapse = "\n")
# Get AddTest blocks
add_test_blocks <-
stringr::str_extract_all(file_content,
"AddTest\\([^\\)]*\\)",
simplify = TRUE)
mesh_sizes <- character()
if(grepl("foreach(mesh_size", file_content, fixed = TRUE)){
foreach_start <-
stringr::str_extract(file_content,
"foreach\\(mesh_size[^\\)]*\\)")
foreach_content <-
stringr::str_remove_all(foreach_start,
"(foreach\\(mesh_size )|(\\))")
mesh_sizes <- unlist(strsplit(foreach_content, " "))
}
# Get .prj paths from blocks
for(j in seq_len(length(add_test_blocks))){
atb <- add_test_blocks[[j]]
benchmark_dir <- stringr::str_extract(atb,
"PATH[:space:]*[^ ]*")
benchmark_dir <-
stringr::str_remove_all(benchmark_dir,
"^PATH|[:space:]")
prj_filename <-
stringr::str_extract(atb,
"EXECUTABLE_ARGS [^ ]*")
prj_filename <-
stringr::str_remove_all(prj_filename,
"^EXECUTABLE_ARGS |[:space:]")
# We just take the first size so far, eventally put loop here later
if(length(mesh_sizes) != 0){
prj_filename <- gsub("${mesh_size}",
mesh_sizes[[1]],
prj_filename,
fixed = TRUE)
}
benchmark_path <- paste0(benchmark_dir, "/", prj_filename)
# cat("Benchmark path: ", benchmark_path, "\n",
# "Test.cmake file:", tests_cmake_files[[i]], "\n")
benchmark_paths <- c(benchmark_paths, benchmark_path)
}
}