mirror of
https://git.gfz-potsdam.de/naaice/poet.git
synced 2025-12-15 12:28:22 +01:00
Add Basic heterogeneous diffusion functionality
This commit is contained in:
parent
a04344e435
commit
0bfc95bb52
@ -28,7 +28,7 @@ master_init <- function(setup) {
|
||||
|
||||
## Setup the directory where we will store the results
|
||||
verb <- FALSE
|
||||
if (local_rank == 0) {
|
||||
# if (local_rank == 0) {
|
||||
verb <- TRUE ## verbosity loading MUFITS results
|
||||
if (!dir.exists(fileout)) {
|
||||
dir.create(fileout)
|
||||
@ -41,25 +41,26 @@ master_init <- function(setup) {
|
||||
} else {
|
||||
msgm("store_result is ", store_result)
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
# } else {
|
||||
|
||||
# }
|
||||
|
||||
setup$iter <- 1
|
||||
setup$maxiter <- setup$iterations
|
||||
setup$timesteps <- setup$timesteps
|
||||
setup$maxiter <- length(setup$timesteps)
|
||||
setup$iterations <- setup$maxiter
|
||||
setup$simulation_time <- 0
|
||||
|
||||
if (is.null(setup[["store_result"]])) {
|
||||
setup$store_result <- TRUE
|
||||
}
|
||||
|
||||
|
||||
if (setup$store_result) {
|
||||
if (is.null(setup[["out_save"]])) {
|
||||
setup$out_save <- seq(1, setup$iterations)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return(setup)
|
||||
}
|
||||
|
||||
@ -67,31 +68,33 @@ master_init <- function(setup) {
|
||||
## calculated time step if store_result is TRUE and increments the
|
||||
## iteration counter
|
||||
master_iteration_end <- function(setup) {
|
||||
iter <- setup$iter
|
||||
# iter <- setup$iter
|
||||
# print(iter)
|
||||
## max digits for iterations
|
||||
dgts <- as.integer(ceiling(log10(setup$iterations + 1)))
|
||||
## string format to use in sprintf
|
||||
iter <- 1
|
||||
dgts <- as.integer(ceiling(log10(1)))
|
||||
## string format to use in sprintf
|
||||
fmt <- paste0("%0", dgts, "d")
|
||||
|
||||
|
||||
## Write on disk state_T and state_C after every iteration
|
||||
## comprised in setup$out_save
|
||||
if (setup$store_result) {
|
||||
if (iter %in% setup$out_save) {
|
||||
nameout <- paste0(fileout, "/iter_", sprintf(fmt=fmt, iter), ".rds")
|
||||
info <- list(
|
||||
tr_req_dt = as.integer(setup$req_dt)
|
||||
## tr_allow_dt = setup$allowed_dt,
|
||||
## tr_inniter = as.integer(setup$inniter)
|
||||
)
|
||||
saveRDS(list(
|
||||
T = setup$state_T, C = setup$state_C,
|
||||
simtime = as.integer(setup$simtime),
|
||||
tr_info = info
|
||||
), file = nameout)
|
||||
msgm("results stored in <", nameout, ">")
|
||||
}
|
||||
}
|
||||
msgm("done iteration", iter, "/", setup$maxiter)
|
||||
# if (setup$store_result) {
|
||||
# if (iter %in% setup$out_save) {
|
||||
nameout <- paste0(fileout, "/iter_", sprintf(fmt = fmt, iter), ".rds")
|
||||
info <- list(
|
||||
tr_req_dt = as.integer(1)
|
||||
## tr_allow_dt = setup$allowed_dt,
|
||||
## tr_inniter = as.integer(setup$inniter)
|
||||
)
|
||||
saveRDS(list(
|
||||
T = setup$state_T, C = setup$state_C,
|
||||
simtime = as.integer(0),
|
||||
tr_info = info
|
||||
), file = nameout)
|
||||
msgm("results stored in <", nameout, ">")
|
||||
# }
|
||||
# }
|
||||
msgm("done iteration", iter, "/", 1)
|
||||
setup$iter <- setup$iter + 1
|
||||
return(setup)
|
||||
}
|
||||
@ -104,41 +107,41 @@ slave_chemistry <- function(setup, data) {
|
||||
immobile <- setup$immobile
|
||||
kin <- setup$kin
|
||||
ann <- setup$ann
|
||||
|
||||
|
||||
iter <- setup$iter
|
||||
timesteps <- setup$timesteps
|
||||
dt <- timesteps[iter]
|
||||
|
||||
|
||||
state_T <- data ## not the global field, but the work-package
|
||||
|
||||
|
||||
## treat special H+/pH, e-/pe cases
|
||||
state_T <- RedModRphree::Act2pH(state_T)
|
||||
|
||||
|
||||
## reduction of the problem
|
||||
if (setup$reduce) {
|
||||
reduced <- ReduceStateOmit(state_T, omit = setup$ann)
|
||||
} else {
|
||||
reduced <- state_T
|
||||
}
|
||||
|
||||
|
||||
## form the PHREEQC input script for the current work package
|
||||
inplist <- SplitMultiKin(
|
||||
data = reduced, procs = 1, base = base, first = first,
|
||||
ann = ann, prop = prop, minerals = immobile, kin = kin, dt = dt
|
||||
)
|
||||
|
||||
|
||||
## if (local_rank==1 & iter==1)
|
||||
## RPhreeWriteInp("FirstInp", inplist)
|
||||
|
||||
|
||||
tmpC <- RunPQC(inplist, procs = 1, second = TRUE)
|
||||
|
||||
|
||||
## recompose after the reduction
|
||||
if (setup$reduce) {
|
||||
state_C <- RecomposeState(tmpC, reduced)
|
||||
} else {
|
||||
state_C <- tmpC
|
||||
}
|
||||
|
||||
|
||||
## the next line is needed since we don't need all columns of
|
||||
## PHREEQC output
|
||||
return(state_C[, prop])
|
||||
@ -147,40 +150,40 @@ slave_chemistry <- function(setup, data) {
|
||||
## This function, called by master
|
||||
master_chemistry <- function(setup, data) {
|
||||
state_T <- setup$state_T
|
||||
|
||||
|
||||
msgm(" chemistry iteration", setup$iter)
|
||||
|
||||
|
||||
## treat special H+/pH, e-/pe cases
|
||||
state_T <- RedModRphree::Act2pH(state_T)
|
||||
|
||||
|
||||
## reduction of the problem
|
||||
if (setup$reduce) {
|
||||
reduced <- ReduceStateOmit(state_T, omit = setup$ann)
|
||||
} else {
|
||||
reduced <- state_T
|
||||
}
|
||||
|
||||
|
||||
## inject data from workers
|
||||
res_C <- data
|
||||
|
||||
|
||||
rownames(res_C) <- NULL
|
||||
|
||||
|
||||
## print(res_C)
|
||||
|
||||
|
||||
if (nrow(res_C) > nrow(reduced)) {
|
||||
res_C <- res_C[seq(2, nrow(res_C), by = 2), ]
|
||||
}
|
||||
|
||||
|
||||
## recompose after the reduction
|
||||
if (setup$reduce) {
|
||||
state_C <- RecomposeState(res_C, reduced)
|
||||
} else {
|
||||
state_C <- res_C
|
||||
}
|
||||
|
||||
|
||||
setup$state_C <- state_C
|
||||
setup$reduced <- reduced
|
||||
|
||||
|
||||
return(setup)
|
||||
}
|
||||
|
||||
@ -188,7 +191,7 @@ master_chemistry <- function(setup, data) {
|
||||
## Adapted version for "reduction"
|
||||
ReduceStateOmit <- function(data, omit = NULL, sign = 6) {
|
||||
require(mgcv)
|
||||
|
||||
|
||||
rem <- colnames(data)
|
||||
if (is.list(omit)) {
|
||||
indomi <- match(names(omit), colnames(data))
|
||||
@ -196,13 +199,13 @@ ReduceStateOmit <- function(data, omit = NULL, sign = 6) {
|
||||
} else {
|
||||
datao <- data
|
||||
}
|
||||
|
||||
|
||||
datao <- signif(datao, sign)
|
||||
red <- mgcv::uniquecombs(datao)
|
||||
inds <- attr(red, "index")
|
||||
now <- ncol(red)
|
||||
|
||||
|
||||
|
||||
|
||||
## reattach the omitted column(s)
|
||||
## FIXME: control if more than one ann is present
|
||||
if (is.list(omit)) {
|
||||
@ -224,11 +227,11 @@ ReduceStateOmit <- function(data, omit = NULL, sign = 6) {
|
||||
## Attach the name of the calling function to the message displayed on
|
||||
## R's stdout
|
||||
msgm <- function(...) {
|
||||
if (local_rank == 0) {
|
||||
fname <- as.list(sys.call(-1))[[1]]
|
||||
prefix <- paste0("R: ", fname, " ::")
|
||||
cat(paste(prefix, ..., "\n"))
|
||||
}
|
||||
# if (local_rank == 0) {
|
||||
fname <- as.list(sys.call(-1))[[1]]
|
||||
prefix <- paste0("R: ", fname, " ::")
|
||||
cat(paste(prefix, ..., "\n"))
|
||||
# }
|
||||
invisible()
|
||||
}
|
||||
|
||||
@ -236,18 +239,17 @@ msgm <- function(...) {
|
||||
## Function called by master R process to store on disk all relevant
|
||||
## parameters for the simulation
|
||||
StoreSetup <- function(setup) {
|
||||
|
||||
to_store <- vector(mode = "list", length = 4)
|
||||
## names(to_store) <- c("Sim", "Flow", "Transport", "Chemistry", "DHT")
|
||||
names(to_store) <- c("Sim", "Transport", "DHT", "Cmdline")
|
||||
|
||||
|
||||
## read the setup R file, which is sourced in kin.cpp
|
||||
tmpbuff <- file(filesim, "r")
|
||||
setupfile <- readLines(tmpbuff)
|
||||
close.connection(tmpbuff)
|
||||
|
||||
|
||||
to_store$Sim <- setupfile
|
||||
|
||||
|
||||
## to_store$Flow <- list(
|
||||
## snapshots = setup$snapshots,
|
||||
## gridfile = setup$gridfile,
|
||||
@ -282,22 +284,22 @@ StoreSetup <- function(setup) {
|
||||
to_store$DHT <- FALSE
|
||||
}
|
||||
|
||||
if (dht_enabled) {
|
||||
to_store$DHT <- list(
|
||||
enabled = dht_enabled,
|
||||
log = dht_log
|
||||
#signif = dht_final_signif,
|
||||
#proptype = dht_final_proptype
|
||||
)
|
||||
} else {
|
||||
to_store$DHT <- FALSE
|
||||
}
|
||||
if (dht_enabled) {
|
||||
to_store$DHT <- list(
|
||||
enabled = dht_enabled,
|
||||
log = dht_log
|
||||
# signif = dht_final_signif,
|
||||
# proptype = dht_final_proptype
|
||||
)
|
||||
} else {
|
||||
to_store$DHT <- FALSE
|
||||
}
|
||||
|
||||
saveRDS(to_store, file = paste0(fileout, "/setup.rds"))
|
||||
msgm("initialization stored in ", paste0(fileout, "/setup.rds"))
|
||||
saveRDS(to_store, file = paste0(fileout, "/setup.rds"))
|
||||
msgm("initialization stored in ", paste0(fileout, "/setup.rds"))
|
||||
}
|
||||
|
||||
GetWorkPackageSizesVector <- function(n_packages, package_size, len) {
|
||||
ids <- rep(1:n_packages, times=package_size, each = 1)[1:len]
|
||||
ids <- rep(1:n_packages, times = package_size, each = 1)[1:len]
|
||||
return(as.integer(table(ids)))
|
||||
}
|
||||
|
||||
4
bench/barite/het/runtime.R
Normal file
4
bench/barite/het/runtime.R
Normal file
@ -0,0 +1,4 @@
|
||||
list(
|
||||
timesteps = c(1),
|
||||
store_result = TRUE
|
||||
)
|
||||
2
ext/tug
2
ext/tug
@ -1 +1 @@
|
||||
Subproject commit 25855da6b2930559b542bbadb16299932332d6a3
|
||||
Subproject commit 8c0687a6cd4a10a79c7a554083a35eda11cc55f0
|
||||
@ -1,274 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 2018-2021 Alexander Lindemann, Max Luebke (University of
|
||||
** Potsdam)
|
||||
**
|
||||
** Copyright (C) 2018-2023 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
**
|
||||
** POET is free software; you can redistribute it and/or modify it under the
|
||||
** terms of the GNU General Public License as published by the Free Software
|
||||
** Foundation; either version 2 of the License, or (at your option) any later
|
||||
** version.
|
||||
**
|
||||
** POET is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
** A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License along with
|
||||
** this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
** Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "Grid.hpp"
|
||||
#include "SimParams.hpp"
|
||||
|
||||
#include <RInside.h>
|
||||
#include <Rcpp.h>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <new>
|
||||
#include <numeric>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace poet;
|
||||
using namespace Rcpp;
|
||||
|
||||
enum { INIT_SCRATCH, INIT_PHREEQC, INIT_RDS };
|
||||
|
||||
static inline int8_t get_type_id(std::string type) {
|
||||
if (type == "scratch") {
|
||||
return INIT_SCRATCH;
|
||||
}
|
||||
if (type == "phreeqc") {
|
||||
return INIT_PHREEQC;
|
||||
}
|
||||
if (type == "rds") {
|
||||
return INIT_RDS;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void poet::Grid::InitModuleFromParams(const poet::GridParams &grid_args) {
|
||||
assert(grid_args.n_cells.size() == grid_args.s_cells.size());
|
||||
|
||||
this->SetGridDimension(grid_args.n_cells.size());
|
||||
|
||||
std::copy(grid_args.n_cells.begin(), grid_args.n_cells.end(),
|
||||
this->n_cells.begin());
|
||||
std::copy(grid_args.s_cells.begin(), grid_args.s_cells.end(),
|
||||
this->grid_size.begin());
|
||||
|
||||
auto init_type = get_type_id(grid_args.type);
|
||||
assert(init_type >= 0);
|
||||
|
||||
switch (init_type) {
|
||||
case INIT_SCRATCH:
|
||||
this->SetPropNames(grid_args.props);
|
||||
this->InitGridFromScratch(grid_args.init_df);
|
||||
break;
|
||||
case INIT_RDS:
|
||||
this->SetPropNames(grid_args.props);
|
||||
this->InitGridFromRDS();
|
||||
break;
|
||||
case INIT_PHREEQC:
|
||||
this->InitGridFromPhreeqc();
|
||||
}
|
||||
}
|
||||
|
||||
void poet::Grid::SetGridDimension(uint8_t dim) {
|
||||
assert(dim < MAX_DIM + 1);
|
||||
|
||||
this->dim = dim;
|
||||
}
|
||||
|
||||
void poet::Grid::SetGridCellCount(uint32_t n_x, uint32_t n_y, uint32_t n_z) {
|
||||
assert(this->dim < MAX_DIM + 1);
|
||||
|
||||
this->n_cells[0] = n_x;
|
||||
this->n_cells[1] = n_y;
|
||||
// this->n_cells[2] = n_z;
|
||||
}
|
||||
|
||||
void poet::Grid::SetGridSize(double s_x, double s_y, double s_z) {
|
||||
assert(this->dim < MAX_DIM + 1);
|
||||
|
||||
this->grid_size[0] = s_x;
|
||||
this->grid_size[1] = s_y;
|
||||
// this->grid_size[2] = s_z;
|
||||
}
|
||||
|
||||
void poet::Grid::SetPropNames(const std::vector<std::string> &prop_names) {
|
||||
this->prop_names = prop_names;
|
||||
}
|
||||
|
||||
void poet::Grid::PushbackModuleFlow(const std::string &input,
|
||||
const std::string &output) {
|
||||
FlowInputOutputInfo element = {input, output};
|
||||
this->flow_vec.push_back(element);
|
||||
}
|
||||
|
||||
void poet::Grid::PreModuleFieldCopy(uint32_t tick) {
|
||||
FlowInputOutputInfo curr_element = this->flow_vec.at(tick);
|
||||
|
||||
const std::string input_module_name = curr_element.input_field;
|
||||
StateMemory *out_state = this->GetStatePointer(curr_element.output_field);
|
||||
|
||||
std::vector<std::string> &mod_props = out_state->props;
|
||||
std::vector<double> &mod_field = out_state->mem;
|
||||
|
||||
// copy output of another module as input for another module
|
||||
for (uint32_t i = 0; i < mod_props.size(); i++) {
|
||||
try {
|
||||
std::vector<double> t_prop_vec =
|
||||
this->GetSpeciesByName(mod_props[i], input_module_name);
|
||||
|
||||
std::copy(t_prop_vec.begin(), t_prop_vec.end(),
|
||||
mod_field.begin() + (i * this->GetTotalCellCount()));
|
||||
} catch (...) {
|
||||
// TODO: there might be something wrong ...
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Grid::Grid() {
|
||||
this->n_cells.fill(0);
|
||||
this->grid_size.fill(0);
|
||||
};
|
||||
|
||||
Grid::~Grid() {
|
||||
for (auto &[key, val] : this->state_register) {
|
||||
delete val;
|
||||
}
|
||||
}
|
||||
|
||||
void poet::Grid::InitGridFromScratch(const Rcpp::DataFrame &init_cell) {
|
||||
const uint32_t vec_size = this->GetTotalCellCount();
|
||||
|
||||
StateMemory *curr_state =
|
||||
this->RegisterState(poet::GRID_MODULE_NAME, this->prop_names);
|
||||
curr_state->props = this->prop_names;
|
||||
|
||||
std::vector<double> &curr_field = curr_state->mem;
|
||||
|
||||
for (auto const &prop : this->prop_names) {
|
||||
// size of the vector shall be 1
|
||||
double prop_val = ((Rcpp::NumericVector)init_cell[prop.c_str()])[0];
|
||||
std::vector<double> prop_vec(vec_size, prop_val);
|
||||
|
||||
curr_field.insert(curr_field.end(), prop_vec.begin(), prop_vec.end());
|
||||
}
|
||||
|
||||
this->grid_init = curr_state;
|
||||
}
|
||||
void poet::Grid::InitGridFromRDS() {
|
||||
// TODO
|
||||
}
|
||||
void poet::Grid::InitGridFromPhreeqc() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
poet::StateMemory *Grid::RegisterState(std::string module_name,
|
||||
std::vector<std::string> props) {
|
||||
poet::StateMemory *mem = new poet::StateMemory;
|
||||
|
||||
mem->props = props;
|
||||
|
||||
const auto [it, success] = this->state_register.insert({module_name, mem});
|
||||
|
||||
if (!success) {
|
||||
delete mem;
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
poet::StateMemory *Grid::GetStatePointer(std::string module_name) {
|
||||
const auto it = this->state_register.find(module_name);
|
||||
|
||||
if (it == this->state_register.end()) {
|
||||
throw std::range_error(
|
||||
std::string("Requested module " + module_name + " was not found"));
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
auto Grid::GetGridSize(uint8_t direction) const -> uint32_t {
|
||||
return this->grid_size.at(direction);
|
||||
}
|
||||
|
||||
auto Grid::GetGridDimension() const -> uint8_t { return this->dim; }
|
||||
|
||||
auto Grid::GetTotalCellCount() const -> uint32_t {
|
||||
uint32_t sum = 1;
|
||||
for (auto const &dim : this->n_cells) {
|
||||
sum *= (dim != 0 ? dim : 1);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
auto Grid::GetGridCellsCount(uint8_t direction) const -> uint32_t {
|
||||
return this->n_cells.at(direction);
|
||||
}
|
||||
|
||||
auto poet::Grid::GetInitialGrid() const -> StateMemory * {
|
||||
return this->grid_init;
|
||||
}
|
||||
|
||||
auto Grid::GetSpeciesCount() const -> uint32_t {
|
||||
return this->prop_names.size();
|
||||
}
|
||||
|
||||
auto Grid::GetPropNames() const -> std::vector<std::string> {
|
||||
return this->prop_names;
|
||||
}
|
||||
|
||||
auto poet::Grid::GetSpeciesByName(std::string name,
|
||||
std::string module_name) const
|
||||
-> std::vector<double> {
|
||||
|
||||
auto const it = this->state_register.find(module_name);
|
||||
|
||||
if (it == this->state_register.end()) {
|
||||
throw std::range_error(
|
||||
std::string("Requested module " + module_name + " was not found"));
|
||||
}
|
||||
|
||||
poet::StateMemory const *module_memory = it->second;
|
||||
|
||||
auto const &prop_vector = module_memory->props;
|
||||
auto const find_res = std::find(prop_vector.begin(), prop_vector.end(), name);
|
||||
if (find_res == prop_vector.end()) {
|
||||
throw std::range_error(std::string(
|
||||
"Species " + name + " was not found for module " + module_name));
|
||||
}
|
||||
uint32_t prop_index = find_res - prop_vector.begin();
|
||||
|
||||
uint32_t begin_vec = prop_index * this->GetTotalCellCount(),
|
||||
end_vec = ((prop_index + 1) * this->GetTotalCellCount());
|
||||
|
||||
return std::vector<double>(module_memory->mem.begin() + begin_vec,
|
||||
module_memory->mem.begin() + end_vec);
|
||||
}
|
||||
|
||||
// HACK: Helper function
|
||||
void poet::Grid::WriteFieldsToR(RInside &R) {
|
||||
|
||||
for (auto const &elem : this->state_register) {
|
||||
std::string field_name = elem.first;
|
||||
StateMemory *field = elem.second;
|
||||
|
||||
const uint32_t n_cells_per_prop = field->mem.size() / field->props.size();
|
||||
|
||||
R["TMP"] = Rcpp::wrap(field->mem);
|
||||
R["TMP_PROPS"] = Rcpp::wrap(field->props);
|
||||
R.parseEval(std::string(
|
||||
"mysetup$" + field_name + " <- setNames(data.frame(matrix(TMP, nrow=" +
|
||||
std::to_string(n_cells_per_prop) + ")), TMP_PROPS)"));
|
||||
}
|
||||
}
|
||||
@ -1,117 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 2018-2021 Alexander Lindemann, Max Luebke (University of
|
||||
** Potsdam)
|
||||
**
|
||||
** Copyright (C) 2018-2023 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
**
|
||||
** POET is free software; you can redistribute it and/or modify it under the
|
||||
** terms of the GNU General Public License as published by the Free Software
|
||||
** Foundation; either version 2 of the License, or (at your option) any later
|
||||
** version.
|
||||
**
|
||||
** POET is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
** A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License along with
|
||||
** this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
** Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef GRID_H
|
||||
#define GRID_H
|
||||
|
||||
#include "SimParams.hpp"
|
||||
|
||||
#include <RInside.h>
|
||||
#include <Rcpp.h>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define MAX_DIM 2
|
||||
|
||||
namespace poet {
|
||||
|
||||
enum { GRID_X_DIR, GRID_Y_DIR, GRID_Z_DIR };
|
||||
|
||||
using StateMemory = struct s_StateMemory {
|
||||
std::vector<double> mem;
|
||||
std::vector<std::string> props;
|
||||
};
|
||||
|
||||
using FlowInputOutputInfo = struct inOut_info {
|
||||
std::string input_field;
|
||||
std::string output_field;
|
||||
};
|
||||
|
||||
constexpr const char *GRID_MODULE_NAME = "grid_init";
|
||||
|
||||
/**
|
||||
* @brief Class describing the grid
|
||||
*
|
||||
* Providing methods to shuffle and unshuffle grid (for the master) as also to
|
||||
* import and export a work package (for worker).
|
||||
*
|
||||
* @todo find better abstraction
|
||||
*
|
||||
*/
|
||||
class Grid {
|
||||
|
||||
public:
|
||||
Grid();
|
||||
|
||||
~Grid();
|
||||
|
||||
void InitModuleFromParams(const poet::GridParams &grid_args);
|
||||
|
||||
void SetGridDimension(uint8_t dim);
|
||||
void SetGridCellCount(uint32_t n_x, uint32_t n_y = 0, uint32_t n_z = 0);
|
||||
void SetGridSize(double s_x, double s_y = 0., double s_z = 0.);
|
||||
void SetPropNames(const std::vector<std::string> &prop_names);
|
||||
|
||||
void PushbackModuleFlow(const std::string &input, const std::string &output);
|
||||
void PreModuleFieldCopy(uint32_t tick);
|
||||
|
||||
void InitGridFromScratch(const Rcpp::DataFrame &init_cell);
|
||||
void InitGridFromRDS();
|
||||
void InitGridFromPhreeqc();
|
||||
|
||||
auto GetGridDimension() const -> uint8_t;
|
||||
auto GetTotalCellCount() const -> uint32_t;
|
||||
auto GetGridCellsCount(uint8_t direction) const -> uint32_t;
|
||||
auto GetGridSize(uint8_t direction) const -> uint32_t;
|
||||
|
||||
auto RegisterState(std::string module_name, std::vector<std::string> props)
|
||||
-> StateMemory *;
|
||||
auto GetStatePointer(std::string module_name) -> StateMemory *;
|
||||
|
||||
auto GetInitialGrid() const -> StateMemory *;
|
||||
|
||||
auto GetSpeciesCount() const -> uint32_t;
|
||||
auto GetPropNames() const -> std::vector<std::string>;
|
||||
|
||||
auto GetSpeciesByName(std::string name,
|
||||
std::string module_name = poet::GRID_MODULE_NAME) const
|
||||
-> std::vector<double>;
|
||||
|
||||
void WriteFieldsToR(RInside &R);
|
||||
|
||||
private:
|
||||
std::vector<FlowInputOutputInfo> flow_vec;
|
||||
|
||||
std::uint8_t dim = 0;
|
||||
std::array<double, MAX_DIM> grid_size;
|
||||
std::array<std::uint32_t, MAX_DIM> n_cells;
|
||||
|
||||
std::map<std::string, StateMemory *> state_register;
|
||||
StateMemory *grid_init = std::nullptr_t();
|
||||
|
||||
std::vector<std::string> prop_names;
|
||||
};
|
||||
} // namespace poet
|
||||
#endif // GRID_H
|
||||
@ -1,10 +1,11 @@
|
||||
// Time-stamp: "Last modified 2023-08-15 12:12:36 delucia"
|
||||
|
||||
/*
|
||||
** Copyright (C) 2018-2021 Alexander Lindemann, Max Luebke (University of
|
||||
** Potsdam)
|
||||
**
|
||||
** Copyright (C) 2018-2023 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
** Copyright (C) 2018-2022 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
**
|
||||
** Copyright (C) 2018-2022 Marco De Lucia (GFZ Potsdam), Max Luebke (University
|
||||
** of Potsdam)
|
||||
**
|
||||
** POET is free software; you can redistribute it and/or modify it under the
|
||||
** terms of the GNU General Public License as published by the Free Software
|
||||
@ -22,104 +23,33 @@
|
||||
|
||||
#include "SimParams.hpp"
|
||||
|
||||
#include "../Chemistry/enums.hpp"
|
||||
#include "Base/Macros.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
#include <RInside.h>
|
||||
#include <Rcpp.h>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "Base/RInsidePOET.hpp"
|
||||
#include "argh.hpp" // Argument handler https://github.com/adishavit/argh
|
||||
|
||||
using namespace poet;
|
||||
using namespace std;
|
||||
using namespace Rcpp;
|
||||
|
||||
poet::GridParams::s_GridParams(RInside &R) {
|
||||
auto tmp_n_cells =
|
||||
Rcpp::as<std::vector<uint32_t>>(R.parseEval("mysetup$grid$n_cells"));
|
||||
assert(tmp_n_cells.size() < 3);
|
||||
RuntimeParameters::RuntimeParameters(RInsidePOET &R, char *argv[],
|
||||
int world_rank_)
|
||||
: world_rank(world_rank_) {
|
||||
|
||||
this->dim = tmp_n_cells.size();
|
||||
|
||||
std::copy(tmp_n_cells.begin(), tmp_n_cells.end(), this->n_cells.begin());
|
||||
|
||||
auto tmp_s_cells =
|
||||
Rcpp::as<std::vector<double>>(R.parseEval("mysetup$grid$s_cells"));
|
||||
|
||||
assert(tmp_s_cells.size() == this->dim);
|
||||
|
||||
std::copy(tmp_s_cells.begin(), tmp_s_cells.end(), this->s_cells.begin());
|
||||
|
||||
this->total_n =
|
||||
(dim == 1 ? this->n_cells[0] : this->n_cells[0] * this->n_cells[1]);
|
||||
|
||||
this->type = Rcpp::as<std::string>(R.parseEval("mysetup$grid$type"));
|
||||
}
|
||||
|
||||
poet::DiffusionParams::s_DiffusionParams(RInside &R) {
|
||||
this->initial_t =
|
||||
Rcpp::as<Rcpp::DataFrame>(R.parseEval("mysetup$diffusion$init"));
|
||||
this->alpha =
|
||||
Rcpp::as<Rcpp::NumericVector>(R.parseEval("mysetup$diffusion$alpha"));
|
||||
if (Rcpp::as<bool>(
|
||||
R.parseEval("'vecinj_inner' %in% names(mysetup$diffusion)"))) {
|
||||
this->vecinj_inner =
|
||||
Rcpp::as<Rcpp::List>(R.parseEval("mysetup$diffusion$vecinj_inner"));
|
||||
}
|
||||
this->vecinj =
|
||||
Rcpp::as<Rcpp::DataFrame>(R.parseEval("mysetup$diffusion$vecinj"));
|
||||
this->vecinj_index =
|
||||
Rcpp::as<Rcpp::DataFrame>(R.parseEval("mysetup$diffusion$vecinj_index"));
|
||||
}
|
||||
|
||||
void poet::ChemistryParams::initFromR(RInsidePOET &R) {
|
||||
this->database_path =
|
||||
Rcpp::as<std::string>(R.parseEval("mysetup$chemistry$database"));
|
||||
this->input_script =
|
||||
Rcpp::as<std::string>(R.parseEval("mysetup$chemistry$input_script"));
|
||||
|
||||
if (R.checkIfExists("dht_species", "mysetup$chemistry")) {
|
||||
this->dht_signifs = Rcpp::as<NamedVector<std::uint32_t>>(
|
||||
R.parseEval(("mysetup$chemistry$dht_species")));
|
||||
}
|
||||
|
||||
if (R.checkIfExists("pht_species", "mysetup$chemistry")) {
|
||||
this->pht_signifs = Rcpp::as<NamedVector<std::uint32_t>>(
|
||||
R.parseEval(("mysetup$chemistry$pht_species")));
|
||||
}
|
||||
this->hooks.dht_fill =
|
||||
RHookFunction<bool>(R, "mysetup$chemistry$hooks$dht_fill");
|
||||
this->hooks.dht_fuzz =
|
||||
RHookFunction<std::vector<double>>(R, "mysetup$chemistry$hooks$dht_fuzz");
|
||||
this->hooks.interp_pre = RHookFunction<std::vector<std::size_t>>(
|
||||
R, "mysetup$chemistry$hooks$interp_pre_func");
|
||||
this->hooks.interp_post =
|
||||
RHookFunction<bool>(R, "mysetup$chemistry$hooks$interp_post_func");
|
||||
}
|
||||
|
||||
SimParams::SimParams(int world_rank_, int world_size_) {
|
||||
this->simparams.world_rank = world_rank_;
|
||||
this->simparams.world_size = world_size_;
|
||||
}
|
||||
|
||||
int SimParams::parseFromCmdl(char *argv[], RInsidePOET &R) {
|
||||
// initialize argh object
|
||||
argh::parser cmdl(argv);
|
||||
|
||||
// if user asked for help
|
||||
if (cmdl[{"help", "h"}]) {
|
||||
if (simparams.world_rank == 0) {
|
||||
if (this->world_rank == 0) {
|
||||
MSG("Todo");
|
||||
MSG("See README.md for further information.");
|
||||
}
|
||||
|
||||
return poet::PARSER_HELP;
|
||||
}
|
||||
// if positional arguments are missing
|
||||
@ -242,11 +172,74 @@ int SimParams::parseFromCmdl(char *argv[], RInsidePOET &R) {
|
||||
this->chem_params.initFromR(R);
|
||||
|
||||
return poet::PARSER_OK;
|
||||
};
|
||||
|
||||
// poet::GridParams::s_GridParams(RInside &R) {
|
||||
// auto tmp_n_cells =
|
||||
// Rcpp::as<std::vector<uint32_t>>(R.parseEval("mysetup$grid$n_cells"));
|
||||
// assert(tmp_n_cells.size() < 3);
|
||||
|
||||
// this->dim = tmp_n_cells.size();
|
||||
|
||||
// std::copy(tmp_n_cells.begin(), tmp_n_cells.end(), this->n_cells.begin());
|
||||
|
||||
// auto tmp_s_cells =
|
||||
// Rcpp::as<std::vector<double>>(R.parseEval("mysetup$grid$s_cells"));
|
||||
|
||||
// assert(tmp_s_cells.size() == this->dim);
|
||||
|
||||
// std::copy(tmp_s_cells.begin(), tmp_s_cells.end(), this->s_cells.begin());
|
||||
|
||||
// this->total_n =
|
||||
// (dim == 1 ? this->n_cells[0] : this->n_cells[0] * this->n_cells[1]);
|
||||
|
||||
// this->type = Rcpp::as<std::string>(R.parseEval("mysetup$grid$type"));
|
||||
// }
|
||||
|
||||
// poet::DiffusionParams::s_DiffusionParams(RInside &R) {
|
||||
// this->initial_t =
|
||||
// Rcpp::as<Rcpp::DataFrame>(R.parseEval("mysetup$diffusion$init"));
|
||||
// this->alpha =
|
||||
// Rcpp::as<Rcpp::NumericVector>(R.parseEval("mysetup$diffusion$alpha"));
|
||||
// if (Rcpp::as<bool>(
|
||||
// R.parseEval("'vecinj_inner' %in% names(mysetup$diffusion)"))) {
|
||||
// this->vecinj_inner =
|
||||
// Rcpp::as<Rcpp::List>(R.parseEval("mysetup$diffusion$vecinj_inner"));
|
||||
// }
|
||||
// this->vecinj =
|
||||
// Rcpp::as<Rcpp::DataFrame>(R.parseEval("mysetup$diffusion$vecinj"));
|
||||
// this->vecinj_index =
|
||||
// Rcpp::as<Rcpp::DataFrame>(R.parseEval("mysetup$diffusion$vecinj_index"));
|
||||
// }
|
||||
|
||||
void poet::ChemistryParams::initFromR(RInsidePOET &R) {
|
||||
// this->database_path =
|
||||
// Rcpp::as<std::string>(R.parseEval("mysetup$chemistry$database"));
|
||||
// this->input_script =
|
||||
// Rcpp::as<std::string>(R.parseEval("mysetup$chemistry$input_script"));
|
||||
|
||||
if (R.checkIfExists("dht_species", "mysetup$chemistry")) {
|
||||
this->dht_signifs = Rcpp::as<NamedVector<std::uint32_t>>(
|
||||
R.parseEval(("mysetup$chemistry$dht_species")));
|
||||
}
|
||||
|
||||
if (R.checkIfExists("pht_species", "mysetup$chemistry")) {
|
||||
this->pht_signifs = Rcpp::as<NamedVector<std::uint32_t>>(
|
||||
R.parseEval(("mysetup$chemistry$pht_species")));
|
||||
}
|
||||
this->hooks.dht_fill =
|
||||
RHookFunction<bool>(R, "mysetup$chemistry$hooks$dht_fill");
|
||||
this->hooks.dht_fuzz =
|
||||
RHookFunction<std::vector<double>>(R, "mysetup$chemistry$hooks$dht_fuzz");
|
||||
this->hooks.interp_pre = RHookFunction<std::vector<std::size_t>>(
|
||||
R, "mysetup$chemistry$hooks$interp_pre_func");
|
||||
this->hooks.interp_post =
|
||||
RHookFunction<bool>(R, "mysetup$chemistry$hooks$interp_post_func");
|
||||
}
|
||||
|
||||
void SimParams::initVectorParams(RInside &R) {}
|
||||
void RuntimeParameters::initVectorParams(RInside &R) {}
|
||||
|
||||
std::list<std::string> SimParams::validateOptions(argh::parser cmdl) {
|
||||
std::list<std::string> RuntimeParameters::validateOptions(argh::parser cmdl) {
|
||||
/* store all unknown parameters here */
|
||||
std::list<std::string> retList;
|
||||
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
**
|
||||
** Copyright (C) 2018-2022 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
**
|
||||
** Copyright (C) 2018-2022 Marco De Lucia (GFZ Potsdam), Max Luebke (University
|
||||
** of Potsdam)
|
||||
**
|
||||
** POET is free software; you can redistribute it and/or modify it under the
|
||||
** terms of the GNU General Public License as published by the Free Software
|
||||
** Foundation; either version 2 of the License, or (at your option) any later
|
||||
@ -18,20 +21,13 @@
|
||||
** Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
#pragma once
|
||||
|
||||
#include "../DataStructures/DataStructures.hpp"
|
||||
#include "Macros.hpp"
|
||||
#include "DataStructures/NamedVector.hpp"
|
||||
#include "RInsidePOET.hpp"
|
||||
|
||||
#include "argh.hpp" // Argument handler https://github.com/adishavit/argh
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <RInside.h>
|
||||
@ -51,7 +47,8 @@ enum { PARSER_OK, PARSER_ERROR, PARSER_HELP };
|
||||
* @brief Defining all simulation parameters
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
struct RuntimeParameters {
|
||||
|
||||
/** Count of processes in MPI_COMM_WORLD */
|
||||
int world_size;
|
||||
/** rank of proces in MPI_COMM_WORLD */
|
||||
@ -79,40 +76,40 @@ typedef struct {
|
||||
bool print_progressbar;
|
||||
|
||||
bool interp_enabled;
|
||||
} t_simparams;
|
||||
|
||||
using GridParams = struct s_GridParams {
|
||||
std::array<uint32_t, 2> n_cells;
|
||||
std::array<double, 2> s_cells;
|
||||
std::uint8_t dim;
|
||||
std::uint32_t total_n;
|
||||
|
||||
std::string type;
|
||||
|
||||
Rcpp::DataFrame init_df;
|
||||
std::string input_script;
|
||||
std::string database_path;
|
||||
|
||||
std::vector<std::string> props;
|
||||
|
||||
s_GridParams(RInside &R);
|
||||
};
|
||||
|
||||
using DiffusionParams = struct s_DiffusionParams {
|
||||
Rcpp::DataFrame initial_t;
|
||||
// using GridParams = struct s_GridParams {
|
||||
// std::array<uint32_t, 2> n_cells;
|
||||
// std::array<double, 2> s_cells;
|
||||
// std::uint8_t dim;
|
||||
// std::uint32_t total_n;
|
||||
|
||||
Rcpp::NumericVector alpha;
|
||||
Rcpp::List vecinj_inner;
|
||||
// std::string type;
|
||||
|
||||
Rcpp::DataFrame vecinj;
|
||||
Rcpp::DataFrame vecinj_index;
|
||||
// Rcpp::DataFrame init_df;
|
||||
// std::string input_script;
|
||||
// std::string database_path;
|
||||
|
||||
s_DiffusionParams(RInside &R);
|
||||
};
|
||||
// std::vector<std::string> props;
|
||||
|
||||
// s_GridParams(RInside &R);
|
||||
// };
|
||||
|
||||
// using DiffusionParams = struct s_DiffusionParams {
|
||||
// Rcpp::DataFrame initial_t;
|
||||
|
||||
// Rcpp::NumericVector alpha;
|
||||
// Rcpp::List vecinj_inner;
|
||||
|
||||
// Rcpp::DataFrame vecinj;
|
||||
// Rcpp::DataFrame vecinj_index;
|
||||
|
||||
// s_DiffusionParams(RInside &R);
|
||||
// };
|
||||
|
||||
struct ChemistryParams {
|
||||
std::string database_path;
|
||||
std::string input_script;
|
||||
// std::string database_path;
|
||||
// std::string input_script;
|
||||
|
||||
bool use_dht;
|
||||
std::uint64_t dht_size;
|
||||
@ -137,6 +134,7 @@ struct ChemistryParams {
|
||||
void initFromR(RInsidePOET &R);
|
||||
};
|
||||
|
||||
} // namespace poet
|
||||
/**
|
||||
* @brief Reads information from program arguments and R runtime
|
||||
*
|
||||
@ -147,129 +145,136 @@ struct ChemistryParams {
|
||||
* Stores and distribute current simulation parameters at any time.
|
||||
*
|
||||
*/
|
||||
class SimParams {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SimParams object
|
||||
*
|
||||
* With all given parameters a new instance of this class will be created.
|
||||
*
|
||||
* @param world_rank Rank of process inside MPI_COMM_WORLD
|
||||
* @param world_size Size of communicator MPI_COMM_WORLD
|
||||
*/
|
||||
SimParams(int world_rank, int world_size);
|
||||
// class SimParams {
|
||||
// public:
|
||||
// /**
|
||||
// * @brief Construct a new SimParams object
|
||||
// *
|
||||
// * With all given parameters a new instance of this class will be created.
|
||||
// *
|
||||
// * @param world_rank Rank of process inside MPI_COMM_WORLD
|
||||
// * @param world_size Size of communicator MPI_COMM_WORLD
|
||||
// */
|
||||
// SimParams(int world_rank);
|
||||
|
||||
/**
|
||||
* @brief Parse program arguments
|
||||
*
|
||||
* This is done by the argh.h library.
|
||||
*
|
||||
* First, the function will check if there is a flag 'help' or 'h'. If this is
|
||||
* the case a help message is printed and the function will return with
|
||||
* PARSER_HELP.
|
||||
*
|
||||
* Second, if there are not 2 positional arguments an error will be printed to
|
||||
* stderr and the function returns with PARSER_ERROR.
|
||||
*
|
||||
* Then all given program parameters and flags will be read and checked, if
|
||||
* there are known by validateOptions. A list of all unknown options might be
|
||||
* returned, printed out and the function will return with PARSER_ERROR.
|
||||
* Oterhwise the function continuos.
|
||||
*
|
||||
* Now all program arguments will be stored inside t_simparams struct, printed
|
||||
* out and the function returns with PARSER_OK.
|
||||
*
|
||||
* Also, all parsed agruments are distributed to the R runtime.
|
||||
*
|
||||
* @param argv Argument value of the program
|
||||
* @param R Instantiated R runtime
|
||||
* @return int Returns with 0 if no error occured, otherwise value less than 0
|
||||
* is returned.
|
||||
*/
|
||||
int parseFromCmdl(char *argv[], RInsidePOET &R);
|
||||
// /**
|
||||
// * @brief Parse program arguments
|
||||
// *
|
||||
// * This is done by the argh.h library.
|
||||
// *
|
||||
// * First, the function will check if there is a flag 'help' or 'h'. If this
|
||||
// is
|
||||
// * the case a help message is printed and the function will return with
|
||||
// * PARSER_HELP.
|
||||
// *
|
||||
// * Second, if there are not 2 positional arguments an error will be printed
|
||||
// to
|
||||
// * stderr and the function returns with PARSER_ERROR.
|
||||
// *
|
||||
// * Then all given program parameters and flags will be read and checked, if
|
||||
// * there are known by validateOptions. A list of all unknown options might
|
||||
// be
|
||||
// * returned, printed out and the function will return with PARSER_ERROR.
|
||||
// * Oterhwise the function continuos.
|
||||
// *
|
||||
// * Now all program arguments will be stored inside t_simparams struct,
|
||||
// printed
|
||||
// * out and the function returns with PARSER_OK.
|
||||
// *
|
||||
// * Also, all parsed agruments are distributed to the R runtime.
|
||||
// *
|
||||
// * @param argv Argument value of the program
|
||||
// * @param R Instantiated R runtime
|
||||
// * @return int Returns with 0 if no error occured, otherwise value less
|
||||
// than 0
|
||||
// * is returned.
|
||||
// */
|
||||
// int parseFromCmdl(char *argv[], RInsidePOET &R);
|
||||
|
||||
/**
|
||||
* @brief Init std::vector values
|
||||
*
|
||||
* This will initialize dht_signif_vector and dht_prop_type_vector internally
|
||||
* depending on whether vectors are defined by R-Simulation file or not.
|
||||
* 'init_chemistry' must be run beforehand.
|
||||
*
|
||||
* @param R R runtime
|
||||
*/
|
||||
void initVectorParams(RInside &R);
|
||||
// /**
|
||||
// * @brief Init std::vector values
|
||||
// *
|
||||
// * This will initialize dht_signif_vector and dht_prop_type_vector
|
||||
// internally
|
||||
// * depending on whether vectors are defined by R-Simulation file or not.
|
||||
// * 'init_chemistry' must be run beforehand.
|
||||
// *
|
||||
// * @param R R runtime
|
||||
// */
|
||||
// void initVectorParams(RInside &R);
|
||||
|
||||
/**
|
||||
* @brief Get the numerical params struct
|
||||
*
|
||||
* Returns a struct which contains all numerical or boolean simulation
|
||||
* parameters.
|
||||
*
|
||||
* @return t_simparams Parameter struct
|
||||
*/
|
||||
auto getNumParams() const { return this->simparams; };
|
||||
// /**
|
||||
// * @brief Get the numerical params struct
|
||||
// *
|
||||
// * Returns a struct which contains all numerical or boolean simulation
|
||||
// * parameters.
|
||||
// *
|
||||
// * @return t_simparams Parameter struct
|
||||
// */
|
||||
// auto getNumParams() const { return this->simparams; };
|
||||
|
||||
/**
|
||||
* @brief Get the DHT_Signif_Vector
|
||||
*
|
||||
* Returns a vector indicating which significant values are used for each
|
||||
* variable of a grid cell.
|
||||
*
|
||||
* @return std::vector<int> Vector of integers containing information about
|
||||
* significant digits
|
||||
*/
|
||||
auto getDHTSignifVector() const { return this->dht_signif_vector; };
|
||||
// /**
|
||||
// * @brief Get the DHT_Signif_Vector
|
||||
// *
|
||||
// * Returns a vector indicating which significant values are used for each
|
||||
// * variable of a grid cell.
|
||||
// *
|
||||
// * @return std::vector<int> Vector of integers containing information about
|
||||
// * significant digits
|
||||
// */
|
||||
// auto getDHTSignifVector() const { return this->dht_signif_vector; };
|
||||
|
||||
auto getPHTSignifVector() const { return this->pht_signif_vector; };
|
||||
// auto getPHTSignifVector() const { return this->pht_signif_vector; };
|
||||
|
||||
auto getPHTBucketSize() const { return this->pht_bucket_size; };
|
||||
auto getPHTMinEntriesNeeded() const { return this->pht_min_entries_needed; };
|
||||
// auto getPHTBucketSize() const { return this->pht_bucket_size; };
|
||||
// auto getPHTMinEntriesNeeded() const { return this->pht_min_entries_needed;
|
||||
// };
|
||||
|
||||
/**
|
||||
* @brief Get the filesim name
|
||||
*
|
||||
* Returns a string containing the absolute path to a R file defining the
|
||||
* simulation.
|
||||
*
|
||||
* @return std::string Absolute path to R file
|
||||
*/
|
||||
auto getFilesim() const { return this->filesim; };
|
||||
// /**
|
||||
// * @brief Get the filesim name
|
||||
// *
|
||||
// * Returns a string containing the absolute path to a R file defining the
|
||||
// * simulation.
|
||||
// *
|
||||
// * @return std::string Absolute path to R file
|
||||
// */
|
||||
// auto getFilesim() const { return this->filesim; };
|
||||
|
||||
/**
|
||||
* @brief Get the output directory
|
||||
*
|
||||
* Returns the name of an absolute path where all output files should be
|
||||
* stored.
|
||||
*
|
||||
* @return std::string Absolute path to output path
|
||||
*/
|
||||
auto getOutDir() const { return this->out_dir; };
|
||||
// /**
|
||||
// * @brief Get the output directory
|
||||
// *
|
||||
// * Returns the name of an absolute path where all output files should be
|
||||
// * stored.
|
||||
// *
|
||||
// * @return std::string Absolute path to output path
|
||||
// */
|
||||
// auto getOutDir() const { return this->out_dir; };
|
||||
|
||||
const auto &getChemParams() const { return chem_params; }
|
||||
// const auto &getChemParams() const { return chem_params; }
|
||||
|
||||
private:
|
||||
std::list<std::string> validateOptions(argh::parser cmdl);
|
||||
// private:
|
||||
// std::list<std::string> validateOptions(argh::parser cmdl);
|
||||
|
||||
const std::set<std::string> flaglist{"ignore-result", "dht", "P", "progress",
|
||||
"interp"};
|
||||
const std::set<std::string> paramlist{
|
||||
"work-package-size", "dht-strategy",
|
||||
"dht-size", "dht-snaps",
|
||||
"dht-file", "interp-size",
|
||||
"interp-min", "interp-bucket-entries"};
|
||||
// const std::set<std::string> flaglist{"ignore-result", "dht", "P",
|
||||
// "progress",
|
||||
// "interp"};
|
||||
// const std::set<std::string> paramlist{
|
||||
// "work-package-size", "dht-strategy",
|
||||
// "dht-size", "dht-snaps",
|
||||
// "dht-file", "interp-size",
|
||||
// "interp-min", "interp-bucket-entries"};
|
||||
|
||||
t_simparams simparams;
|
||||
// t_simparams simparams;
|
||||
|
||||
std::vector<uint32_t> dht_signif_vector;
|
||||
std::vector<uint32_t> pht_signif_vector;
|
||||
// std::vector<uint32_t> dht_signif_vector;
|
||||
// std::vector<uint32_t> pht_signif_vector;
|
||||
|
||||
uint32_t pht_bucket_size;
|
||||
uint32_t pht_min_entries_needed;
|
||||
// uint32_t pht_bucket_size;
|
||||
// uint32_t pht_min_entries_needed;
|
||||
|
||||
std::string filesim;
|
||||
std::string out_dir;
|
||||
// std::string filesim;
|
||||
// std::string out_dir;
|
||||
|
||||
ChemistryParams chem_params;
|
||||
};
|
||||
} // namespace poet
|
||||
#endif // PARSER_H
|
||||
// ChemistryParams chem_params;
|
||||
// };
|
||||
// } // namespace poet
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
add_library(POETLib OBJECT)
|
||||
add_library(POETLib)
|
||||
|
||||
target_sources(
|
||||
POETLib
|
||||
target_sources(POETLib
|
||||
PRIVATE
|
||||
Init/InitialList.cpp
|
||||
Init/GridInit.cpp
|
||||
Init/DiffusionInit.cpp
|
||||
Init/ChemistryInit.cpp
|
||||
PRIVATE
|
||||
DataStructures/Field.cpp
|
||||
Transport/DiffusionModule.cpp
|
||||
)
|
||||
|
||||
target_include_directories(POETLib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
@ -16,7 +15,7 @@ target_link_libraries(
|
||||
POETLib
|
||||
PUBLIC RRuntime
|
||||
PUBLIC IPhreeqcPOET
|
||||
PRIVATE tug
|
||||
PUBLIC tug
|
||||
)
|
||||
|
||||
# add_library(poetlib
|
||||
@ -43,7 +42,7 @@ target_link_libraries(
|
||||
# tug
|
||||
# )
|
||||
|
||||
# target_compile_definitions(poetlib PUBLIC STRICT_R_HEADERS OMPI_SKIP_MPICXX)
|
||||
target_compile_definitions(POETLib PUBLIC STRICT_R_HEADERS OMPI_SKIP_MPICXX)
|
||||
|
||||
# mark_as_advanced(PHREEQCRM_BUILD_MPI PHREEQCRM_DISABLE_OPENMP)
|
||||
# set(PHREEQCRM_DISABLE_OPENMP ON CACHE BOOL "" FORCE)
|
||||
@ -65,9 +64,9 @@ file(READ "${PROJECT_SOURCE_DIR}/R_lib/init_r_lib.R" R_INIT_LIB)
|
||||
|
||||
configure_file(poet.hpp.in poet.hpp @ONLY)
|
||||
|
||||
# add_executable(poet poet.cpp)
|
||||
# target_link_libraries(poet PRIVATE poetlib MPI::MPI_C RRuntime)
|
||||
# target_include_directories(poet PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
add_executable(poet poet.cpp)
|
||||
target_link_libraries(poet PRIVATE POETLib MPI::MPI_C RRuntime)
|
||||
target_include_directories(poet PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
add_executable(poet_init initializer.cpp)
|
||||
target_link_libraries(poet_init PRIVATE POETLib RRuntime)
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
target_sources(POETLib PRIVATE
|
||||
InitialList.cpp
|
||||
GridInit.cpp
|
||||
DiffusionInit.cpp
|
||||
ChemistryInit.cpp
|
||||
)
|
||||
@ -5,6 +5,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "DataStructures/Field.hpp"
|
||||
#include "InitialList.hpp"
|
||||
|
||||
#include <Rcpp/proxy/ProtectedProxy.h>
|
||||
@ -14,6 +15,7 @@
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace poet {
|
||||
@ -175,6 +177,42 @@ void InitialList::initDiffusion(const Rcpp::List &diffusion_input) {
|
||||
// R.parseEval("print(alpha_y)");
|
||||
}
|
||||
|
||||
InitialList::DiffusionInit::BoundaryMap
|
||||
RcppListToBoundaryMap(const std::vector<std::string> &trans_names,
|
||||
const Rcpp::List &bound_list, uint32_t n_cols,
|
||||
uint32_t n_rows) {
|
||||
InitialList::DiffusionInit::BoundaryMap map;
|
||||
|
||||
for (const auto &name : trans_names) {
|
||||
const Rcpp::List &conc_list = bound_list[name];
|
||||
|
||||
tug::Boundary<TugType> bc(n_rows, n_cols);
|
||||
|
||||
for (const auto &[tug_index, r_init_name] : tug_side_mapping) {
|
||||
const Rcpp::List &side_list = conc_list[tug_index];
|
||||
|
||||
const Rcpp::NumericVector &type = side_list["type"];
|
||||
const Rcpp::NumericVector &value = side_list["value"];
|
||||
|
||||
if (type.size() != value.size()) {
|
||||
throw std::runtime_error(
|
||||
"Boundary type and value are not the same length");
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < type.size(); i++) {
|
||||
if (type[i] == tug::BC_TYPE_CONSTANT) {
|
||||
bc.setBoundaryElementConstant(static_cast<tug::BC_SIDE>(tug_index), i,
|
||||
value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map[name] = bc.serialize();
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
InitialList::DiffusionInit InitialList::getDiffusionInit() const {
|
||||
DiffusionInit diff_init;
|
||||
|
||||
@ -189,8 +227,8 @@ InitialList::DiffusionInit InitialList::getDiffusionInit() const {
|
||||
diff_init.constant_cells = this->constant_cells;
|
||||
diff_init.transport_names = this->transport_names;
|
||||
|
||||
diff_init.initial_grid = Field(this->initial_grid);
|
||||
diff_init.boundaries = Field(this->boundaries);
|
||||
diff_init.boundaries = RcppListToBoundaryMap(
|
||||
this->transport_names, this->boundaries, this->n_cols, this->n_rows);
|
||||
diff_init.alpha_x = Field(this->alpha_x);
|
||||
diff_init.alpha_y = Field(this->alpha_y);
|
||||
|
||||
|
||||
@ -38,10 +38,10 @@ void InitialList::importList(const Rcpp::List &setup) {
|
||||
setup[static_cast<int>(ExportList::DIFFU_TRANSPORT)]);
|
||||
this->boundaries =
|
||||
Rcpp::List(setup[static_cast<int>(ExportList::DIFFU_BOUNDARIES)]);
|
||||
this->alpha_x = Rcpp::as<std::vector<double>>(
|
||||
setup[static_cast<int>(ExportList::DIFFU_ALPHA_X)]);
|
||||
this->alpha_y = Rcpp::as<std::vector<double>>(
|
||||
setup[static_cast<int>(ExportList::DIFFU_ALPHA_Y)]);
|
||||
this->alpha_x =
|
||||
Rcpp::List(setup[static_cast<int>(ExportList::DIFFU_ALPHA_X)]);
|
||||
this->alpha_y =
|
||||
Rcpp::List(setup[static_cast<int>(ExportList::DIFFU_ALPHA_Y)]);
|
||||
|
||||
this->database =
|
||||
Rcpp::as<std::string>(setup[static_cast<int>(ExportList::CHEM_DATABASE)]);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <tug/Boundary.hpp>
|
||||
|
||||
#include <RInside.h>
|
||||
#include <Rcpp.h>
|
||||
#include <Rcpp/vector/instantiation.h>
|
||||
@ -8,7 +10,9 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include <IPhreeqcPOET.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <DataStructures/Field.hpp>
|
||||
@ -26,6 +30,8 @@ public:
|
||||
void importList(const Rcpp::List &setup);
|
||||
Rcpp::List exportList();
|
||||
|
||||
Field getInitialGrid() const { return Field(this->initial_grid); }
|
||||
|
||||
private:
|
||||
RInside &R;
|
||||
|
||||
@ -93,6 +99,9 @@ private:
|
||||
|
||||
public:
|
||||
struct DiffusionInit {
|
||||
using BoundaryMap =
|
||||
std::map<std::string, std::vector<tug::BoundaryElement<TugType>>>;
|
||||
|
||||
uint8_t dim;
|
||||
std::uint32_t n_cols;
|
||||
std::uint32_t n_rows;
|
||||
@ -104,8 +113,8 @@ public:
|
||||
|
||||
std::vector<std::string> transport_names;
|
||||
|
||||
Field initial_grid;
|
||||
Field boundaries;
|
||||
BoundaryMap boundaries;
|
||||
|
||||
Field alpha_x;
|
||||
Field alpha_y;
|
||||
};
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
**
|
||||
** Copyright (C) 2018-2022 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
**
|
||||
** Copyright (C) 2023-2024 Marco De Lucia (GFZ Potsdam), Max Luebke (University
|
||||
** of Potsdam)
|
||||
**
|
||||
** POET is free software; you can redistribute it and/or modify it under the
|
||||
** terms of the GNU General Public License as published by the Free Software
|
||||
** Foundation; either version 2 of the License, or (at your option) any later
|
||||
@ -19,174 +22,101 @@
|
||||
*/
|
||||
|
||||
#include "DiffusionModule.hpp"
|
||||
#include "../Base/Macros.hpp"
|
||||
|
||||
#include <tug/BoundaryCondition.hpp>
|
||||
#include <tug/Diffusion.hpp>
|
||||
#include "Base/Macros.hpp"
|
||||
#include "Init/InitialList.hpp"
|
||||
|
||||
#include <Rcpp.h>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <Eigen/src/Core/Map.h>
|
||||
#include <Eigen/src/Core/Matrix.h>
|
||||
#include <Eigen/src/Core/util/Constants.h>
|
||||
#include <chrono>
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <mpi.h>
|
||||
#include "tug/Boundary.hpp"
|
||||
#include "tug/Grid.hpp"
|
||||
#include "tug/Simulation.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace poet;
|
||||
|
||||
static constexpr double ZERO_MULTIPLICATOR = 10E-14;
|
||||
static inline std::vector<TugType>
|
||||
MatrixToVec(const Eigen::MatrixX<TugType> &mat) {
|
||||
std::vector<TugType> vec(mat.rows() * mat.cols());
|
||||
|
||||
constexpr std::array<uint8_t, 4> borders = {
|
||||
tug::bc::BC_SIDE_LEFT, tug::bc::BC_SIDE_RIGHT, tug::bc::BC_SIDE_TOP,
|
||||
tug::bc::BC_SIDE_BOTTOM};
|
||||
|
||||
inline const char *convert_bc_to_config_file(uint8_t in) {
|
||||
switch (in) {
|
||||
case tug::bc::BC_SIDE_TOP:
|
||||
return "N";
|
||||
case tug::bc::BC_SIDE_RIGHT:
|
||||
return "E";
|
||||
case tug::bc::BC_SIDE_BOTTOM:
|
||||
return "S";
|
||||
case tug::bc::BC_SIDE_LEFT:
|
||||
return "W";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
DiffusionModule::DiffusionModule(const poet::DiffusionParams &diffu_args,
|
||||
const poet::GridParams &grid_params)
|
||||
: n_cells_per_prop(grid_params.total_n) {
|
||||
this->diff_input.setGridCellN(grid_params.n_cells[0], grid_params.n_cells[1]);
|
||||
this->diff_input.setDomainSize(grid_params.s_cells[0],
|
||||
grid_params.s_cells[1]);
|
||||
|
||||
this->dim = grid_params.dim;
|
||||
|
||||
this->initialize(diffu_args, grid_params.total_n);
|
||||
}
|
||||
|
||||
void DiffusionModule::initialize(const poet::DiffusionParams &args,
|
||||
std::uint32_t n_grid_cells) {
|
||||
// const poet::DiffusionParams args(this->R);
|
||||
|
||||
// name of props
|
||||
//
|
||||
this->prop_names = Rcpp::as<std::vector<std::string>>(args.initial_t.names());
|
||||
this->prop_count = this->prop_names.size();
|
||||
|
||||
// initialize field and alphas
|
||||
this->alpha.reserve(this->prop_count);
|
||||
|
||||
std::vector<std::vector<double>> initial_values;
|
||||
|
||||
for (uint32_t i = 0; i < this->prop_count; i++) {
|
||||
// get alphas - we cannot assume alphas are provided in same order as
|
||||
// initial input
|
||||
this->alpha.push_back(args.alpha[this->prop_names[i]]);
|
||||
|
||||
const double val = args.initial_t[prop_names[i]];
|
||||
std::vector<double> init_val(n_grid_cells, val);
|
||||
initial_values.push_back(std::move(init_val));
|
||||
|
||||
if (this->dim == this->DIM_2D) {
|
||||
tug::bc::BoundaryCondition bc(diff_input.grid.grid_cells[0],
|
||||
diff_input.grid.grid_cells[1]);
|
||||
this->bc_vec.push_back(bc);
|
||||
} else {
|
||||
tug::bc::BoundaryCondition bc(diff_input.grid.grid_cells[0]);
|
||||
this->bc_vec.push_back(bc);
|
||||
for (std::uint32_t i = 0; i < mat.cols(); i++) {
|
||||
for (std::uint32_t j = 0; j < mat.rows(); j++) {
|
||||
vec[j * mat.cols() + i] = mat(j, i);
|
||||
}
|
||||
}
|
||||
|
||||
this->t_field = Field(n_grid_cells, initial_values, prop_names);
|
||||
|
||||
// apply boundary conditions to each ghost node
|
||||
uint8_t bc_size = (this->dim == this->DIM_1D ? 2 : 4);
|
||||
for (uint8_t i = 0; i < bc_size; i++) {
|
||||
const auto &side = borders[i];
|
||||
std::vector<uint32_t> vecinj_i = Rcpp::as<std::vector<uint32_t>>(
|
||||
args.vecinj_index[convert_bc_to_config_file(side)]);
|
||||
for (int i = 0; i < this->prop_count; i++) {
|
||||
std::vector<double> bc_vec = args.vecinj[this->prop_names[i]];
|
||||
tug::bc::BoundaryCondition &curr_bc = *(this->bc_vec.begin() + i);
|
||||
for (int j = 0; j < vecinj_i.size(); j++) {
|
||||
if (vecinj_i[j] == 0) {
|
||||
continue;
|
||||
}
|
||||
if (this->dim == this->DIM_2D) {
|
||||
curr_bc(side, j) = {tug::bc::BC_TYPE_CONSTANT,
|
||||
bc_vec[vecinj_i[j] - 1]};
|
||||
}
|
||||
if (this->dim == this->DIM_1D) {
|
||||
curr_bc(side) = {tug::bc::BC_TYPE_CONSTANT, bc_vec[vecinj_i[j] - 1]};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply inner grid constant cells
|
||||
// NOTE: opening a scope here for distinguish variable names
|
||||
if (args.vecinj_inner.size() != 0) {
|
||||
// apply inner constant cells for every concentration
|
||||
for (int i = 0; i < this->prop_count; i++) {
|
||||
std::vector<double> bc_vec = args.vecinj[this->prop_names[i]];
|
||||
tug::bc::BoundaryCondition &curr_bc = *(this->bc_vec.begin() + i);
|
||||
for (int j = 0; j < args.vecinj_inner.size(); j++) {
|
||||
std::vector<double> inner_tuple =
|
||||
Rcpp::as<std::vector<double>>(args.vecinj_inner[j]);
|
||||
tug::bc::boundary_condition bc = {tug::bc::BC_TYPE_CONSTANT,
|
||||
bc_vec[inner_tuple[0] - 1]};
|
||||
|
||||
this->index_constant_cells.push_back(inner_tuple[1]);
|
||||
uint32_t x = inner_tuple[1];
|
||||
uint32_t y = (this->dim == this->DIM_1D ? 0 : inner_tuple[2]);
|
||||
|
||||
curr_bc.setInnerBC(bc, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
void DiffusionModule::simulate(double dt) {
|
||||
double sim_a_transport, sim_b_transport;
|
||||
static inline Eigen::MatrixX<TugType>
|
||||
VecToMatrix(const std::vector<TugType> &vec, std::uint32_t n_rows,
|
||||
std::uint32_t n_cols) {
|
||||
Eigen::MatrixX<TugType> mat(n_rows, n_cols);
|
||||
|
||||
sim_b_transport = MPI_Wtime();
|
||||
|
||||
MSG_NOENDL("DiffusionModule::simulate(): Starting diffusion ...");
|
||||
std::cout << std::flush;
|
||||
|
||||
std::vector<std::vector<double>> field_2d = t_field.As2DVector();
|
||||
|
||||
this->diff_input.setTimestep(dt);
|
||||
|
||||
for (int i = 0; i < field_2d.size(); i++) {
|
||||
std::vector<double> in_alpha(this->n_cells_per_prop, this->alpha[i]);
|
||||
this->diff_input.setBoundaryCondition(this->bc_vec[i]);
|
||||
|
||||
if (this->dim == this->DIM_1D) {
|
||||
tug::diffusion::BTCS_1D(this->diff_input, field_2d[i].data(),
|
||||
in_alpha.data());
|
||||
} else {
|
||||
tug::diffusion::ADI_2D(this->diff_input, field_2d[i].data(),
|
||||
in_alpha.data());
|
||||
for (std::uint32_t i = 0; i < n_cols; i++) {
|
||||
for (std::uint32_t j = 0; j < n_rows; j++) {
|
||||
mat(j, i) = vec[j * n_cols + i];
|
||||
}
|
||||
}
|
||||
|
||||
t_field = field_2d;
|
||||
|
||||
sim_a_transport = MPI_Wtime();
|
||||
|
||||
transport_t += sim_a_transport - sim_b_transport;
|
||||
std::cout << " done in " << sim_a_transport - sim_b_transport << "sec"
|
||||
<< std::endl;
|
||||
return mat;
|
||||
}
|
||||
|
||||
void DiffusionModule::end() {
|
||||
// R["simtime_transport"] = transport_t;
|
||||
// R.parseEvalQ("profiling$simtime_transport <- simtime_transport");
|
||||
// static constexpr double ZERO_MULTIPLICATOR = 10E-14;
|
||||
|
||||
void DiffusionModule::simulate(double requested_dt) {
|
||||
MSG("Starting diffusion ...");
|
||||
const auto start_diffusion_t = std::chrono::high_resolution_clock::now();
|
||||
|
||||
const auto &n_rows = this->param_list.n_rows;
|
||||
const auto &n_cols = this->param_list.n_cols;
|
||||
|
||||
tug::Grid<TugType> grid(param_list.n_rows, param_list.n_cols);
|
||||
tug::Boundary boundary(grid);
|
||||
|
||||
grid.setDomain(param_list.s_rows, param_list.s_cols);
|
||||
|
||||
tug::Simulation<TugType> sim(grid, boundary);
|
||||
sim.setIterations(1);
|
||||
|
||||
for (const auto &sol_name : this->param_list.transport_names) {
|
||||
auto &species_conc = this->transport_field[sol_name];
|
||||
|
||||
Eigen::MatrixX<TugType> conc = VecToMatrix(species_conc, n_rows, n_cols);
|
||||
Eigen::MatrixX<TugType> alpha_x =
|
||||
VecToMatrix(this->param_list.alpha_x[sol_name], n_rows, n_cols);
|
||||
Eigen::MatrixX<TugType> alpha_y =
|
||||
VecToMatrix(this->param_list.alpha_y[sol_name], n_rows, n_cols);
|
||||
|
||||
boundary.deserialize(this->param_list.boundaries[sol_name]);
|
||||
|
||||
grid.setAlpha(alpha_x, alpha_y);
|
||||
grid.setConcentrations(conc);
|
||||
|
||||
sim.setTimestep(requested_dt);
|
||||
|
||||
sim.run();
|
||||
|
||||
species_conc = MatrixToVec(grid.getConcentrations());
|
||||
}
|
||||
|
||||
const auto end_diffusion_t = std::chrono::high_resolution_clock::now();
|
||||
|
||||
const auto consumed_time_seconds =
|
||||
std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
end_diffusion_t - start_diffusion_t);
|
||||
|
||||
MSG("Diffusion done in " + std::to_string(consumed_time_seconds.count()) +
|
||||
" [s]");
|
||||
|
||||
transport_t += consumed_time_seconds.count();
|
||||
}
|
||||
|
||||
double DiffusionModule::getTransportTime() { return this->transport_t; }
|
||||
|
||||
@ -21,20 +21,13 @@
|
||||
#ifndef DIFFUSION_MODULE_H
|
||||
#define DIFFUSION_MODULE_H
|
||||
|
||||
#include "../Base/Grid.hpp"
|
||||
#include "../Base/SimParams.hpp"
|
||||
#include "../DataStructures/DataStructures.hpp"
|
||||
#include "DataStructures/Field.hpp"
|
||||
#include "Init/InitialList.hpp"
|
||||
|
||||
#include <tug/BoundaryCondition.hpp>
|
||||
#include <tug/Diffusion.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace poet {
|
||||
|
||||
/**
|
||||
* @brief Class describing transport simulation
|
||||
*
|
||||
@ -53,8 +46,8 @@ public:
|
||||
*
|
||||
* @param R RRuntime object
|
||||
*/
|
||||
DiffusionModule(const poet::DiffusionParams &diffu_args,
|
||||
const poet::GridParams &grid_params);
|
||||
DiffusionModule(const InitialList::DiffusionInit &init_list, Field field)
|
||||
: param_list(init_list), transport_field(field){};
|
||||
|
||||
/**
|
||||
* @brief Run simulation for one iteration
|
||||
@ -64,14 +57,6 @@ public:
|
||||
*/
|
||||
void simulate(double dt);
|
||||
|
||||
/**
|
||||
* @brief End simulation
|
||||
*
|
||||
* All measured timings are distributed to the R runtime
|
||||
*
|
||||
*/
|
||||
void end();
|
||||
|
||||
/**
|
||||
* @brief Get the transport time
|
||||
*
|
||||
@ -84,33 +69,17 @@ public:
|
||||
*
|
||||
* \return Reference to the diffusion field.
|
||||
*/
|
||||
Field &getField() { return this->t_field; }
|
||||
Field &getField() { return this->transport_field; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Instance of RRuntime
|
||||
*
|
||||
*/
|
||||
// RRuntime &R;
|
||||
|
||||
enum { DIM_1D = 1, DIM_2D };
|
||||
InitialList::DiffusionInit param_list;
|
||||
|
||||
void initialize(const poet::DiffusionParams &args,
|
||||
std::uint32_t n_grid_cells);
|
||||
|
||||
uint8_t dim;
|
||||
|
||||
uint32_t prop_count;
|
||||
|
||||
tug::diffusion::TugInput diff_input;
|
||||
std::vector<double> alpha;
|
||||
std::vector<uint32_t> index_constant_cells;
|
||||
std::vector<std::string> prop_names;
|
||||
|
||||
std::vector<tug::bc::BoundaryCondition> bc_vec;
|
||||
Field t_field;
|
||||
|
||||
uint32_t n_cells_per_prop;
|
||||
Field transport_field;
|
||||
|
||||
/**
|
||||
* @brief time spent for transport
|
||||
|
||||
527
src/poet.cpp
527
src/poet.cpp
@ -4,6 +4,8 @@
|
||||
**
|
||||
** Copyright (C) 2018-2022 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
**
|
||||
** Copyright (C) 2023-2024 Max Luebke (University of Potsdam)
|
||||
**
|
||||
** POET is free software; you can redistribute it and/or modify it under the
|
||||
** terms of the GNU General Public License as published by the Free Software
|
||||
** Foundation; either version 2 of the License, or (at your option) any later
|
||||
@ -18,125 +20,308 @@
|
||||
** Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "Base/Grid.hpp"
|
||||
#include "Base/Macros.hpp"
|
||||
#include "Base/RInsidePOET.hpp"
|
||||
#include "Base/SimParams.hpp"
|
||||
#include "Chemistry/ChemistryModule.hpp"
|
||||
// #include "Chemistry/ChemistryModule.hpp"
|
||||
#include "DataStructures/Field.hpp"
|
||||
#include "Init/InitialList.hpp"
|
||||
#include "Transport/DiffusionModule.hpp"
|
||||
|
||||
#include <RInside.h>
|
||||
#include <R_ext/Boolean.h>
|
||||
#include <Rcpp/DataFrame.h>
|
||||
#include <Rcpp/vector/instantiation.h>
|
||||
#include <poet.hpp>
|
||||
|
||||
#include <Rcpp.h>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <mpi.h>
|
||||
|
||||
#include "Base/argh.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace poet;
|
||||
using namespace Rcpp;
|
||||
|
||||
poet::ChemistryModule::SingleCMap DFToHashMap(const Rcpp::DataFrame &df) {
|
||||
std::unordered_map<std::string, double> out_map;
|
||||
vector<string> col_names = Rcpp::as<vector<string>>(df.names());
|
||||
static int MY_RANK = 0;
|
||||
|
||||
for (const auto &name : col_names) {
|
||||
double val = df[name.c_str()];
|
||||
out_map.insert({name, val});
|
||||
}
|
||||
// poet::ChemistryModule::SingleCMap DFToHashMap(const Rcpp::DataFrame &df) {
|
||||
// std::unordered_map<std::string, double> out_map;
|
||||
// vector<string> col_names = Rcpp::as<vector<string>>(df.names());
|
||||
|
||||
return out_map;
|
||||
}
|
||||
// for (const auto &name : col_names) {
|
||||
// double val = df[name.c_str()];
|
||||
// out_map.insert({name, val});
|
||||
// }
|
||||
|
||||
// return out_map;
|
||||
// }
|
||||
|
||||
// HACK: this is a step back as the order and also the count of fields is
|
||||
// predefined, but it will change in the future
|
||||
void writeFieldsToR(RInside &R, const Field &trans, const Field &chem) {
|
||||
R["TMP"] = Rcpp::wrap(trans.AsVector());
|
||||
R["TMP_PROPS"] = Rcpp::wrap(trans.GetProps());
|
||||
R.parseEval(std::string(
|
||||
"mysetup$state_T <- setNames(data.frame(matrix(TMP, nrow=" +
|
||||
std::to_string(trans.GetRequestedVecSize()) + ")), TMP_PROPS)"));
|
||||
void writeFieldsToR(RInside &R, const Field &trans) {
|
||||
// , const Field &chem) {
|
||||
|
||||
R["TMP"] = Rcpp::wrap(chem.AsVector());
|
||||
R["TMP_PROPS"] = Rcpp::wrap(chem.GetProps());
|
||||
R.parseEval(std::string(
|
||||
"mysetup$state_C <- setNames(data.frame(matrix(TMP, nrow=" +
|
||||
std::to_string(chem.GetRequestedVecSize()) + ")), TMP_PROPS)"));
|
||||
Rcpp::DataFrame t_field(trans.asSEXP());
|
||||
|
||||
R["TMP"] = t_field;
|
||||
|
||||
R.parseEval("mysetup$state_T <- TMP");
|
||||
R.parseEval("mysetup$state_C <- TMP");
|
||||
|
||||
// R["TMP"] = Rcpp::wrap(trans.AsVector());
|
||||
// R["TMP_PROPS"] = Rcpp::wrap(trans.GetProps());
|
||||
// R.parseEval(std::string(
|
||||
// "mysetup$state_T <- setNames(data.frame(matrix(TMP, nrow=" +
|
||||
// std::to_string(trans.GetRequestedVecSize()) + ")), TMP_PROPS)"));
|
||||
|
||||
// R["TMP"] = Rcpp::wrap(chem.AsVector());
|
||||
// R["TMP_PROPS"] = Rcpp::wrap(chem.GetProps());
|
||||
// R.parseEval(std::string(
|
||||
// "mysetup$state_C <- setNames(data.frame(matrix(TMP, nrow=" +
|
||||
// std::to_string(chem.GetRequestedVecSize()) + ")), TMP_PROPS)"));
|
||||
}
|
||||
|
||||
void set_chem_parameters(poet::ChemistryModule &chem, uint32_t wp_size,
|
||||
const std::string &database_path) {
|
||||
chem.SetErrorHandlerMode(1);
|
||||
chem.SetComponentH2O(false);
|
||||
chem.SetRebalanceFraction(0.5);
|
||||
chem.SetRebalanceByCell(true);
|
||||
chem.UseSolutionDensityVolume(false);
|
||||
chem.SetPartitionUZSolids(false);
|
||||
enum ParseRet { PARSER_OK, PARSER_ERROR, PARSER_HELP };
|
||||
|
||||
// Set concentration units
|
||||
// 1, mg/L; 2, mol/L; 3, kg/kgs
|
||||
chem.SetUnitsSolution(2);
|
||||
// 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
chem.SetUnitsPPassemblage(1);
|
||||
// 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
chem.SetUnitsExchange(1);
|
||||
// 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
chem.SetUnitsSurface(1);
|
||||
// 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
chem.SetUnitsGasPhase(1);
|
||||
// 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
chem.SetUnitsSSassemblage(1);
|
||||
// 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
chem.SetUnitsKinetics(1);
|
||||
ParseRet parseInitValues(char **argv, RInsidePOET &R,
|
||||
RuntimeParameters ¶ms) {
|
||||
// initialize argh object
|
||||
argh::parser cmdl(argv);
|
||||
|
||||
// Set representative volume
|
||||
std::vector<double> rv;
|
||||
rv.resize(wp_size, 1.0);
|
||||
chem.SetRepresentativeVolume(rv);
|
||||
// if user asked for help
|
||||
if (cmdl[{"help", "h"}]) {
|
||||
if (MY_RANK == 0) {
|
||||
MSG("Todo");
|
||||
MSG("See README.md for further information.");
|
||||
}
|
||||
|
||||
// Set initial porosity
|
||||
std::vector<double> por;
|
||||
por.resize(wp_size, 1);
|
||||
chem.SetPorosity(por);
|
||||
return ParseRet::PARSER_HELP;
|
||||
}
|
||||
// if positional arguments are missing
|
||||
else if (!cmdl(2)) {
|
||||
if (MY_RANK == 0) {
|
||||
ERRMSG("POET needs 2 positional arguments: ");
|
||||
ERRMSG("1) the R script defining your simulation and");
|
||||
ERRMSG("2) the directory prefix where to save results and profiling");
|
||||
}
|
||||
return ParseRet::PARSER_ERROR;
|
||||
}
|
||||
|
||||
// Set initial saturation
|
||||
std::vector<double> sat;
|
||||
sat.resize(wp_size, 1.0);
|
||||
chem.SetSaturation(sat);
|
||||
// parse flags and check for unknown
|
||||
for (const auto &option : cmdl.flags()) {
|
||||
if (!(flaglist.find(option) != flaglist.end())) {
|
||||
if (MY_RANK == 0) {
|
||||
ERRMSG("Unrecognized option: " + option);
|
||||
ERRMSG("Make sure to use available options. Exiting!");
|
||||
}
|
||||
return ParseRet::PARSER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Load database
|
||||
chem.LoadDatabase(database_path);
|
||||
// parse parameters and check for unknown
|
||||
for (const auto &option : cmdl.params()) {
|
||||
if (!(paramlist.find(option.first) != paramlist.end())) {
|
||||
if (MY_RANK == 0) {
|
||||
ERRMSG("Unrecognized option: " + option.first);
|
||||
ERRMSG("Make sure to use available options. Exiting!");
|
||||
}
|
||||
return ParseRet::PARSER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// simparams.print_progressbar = cmdl[{"P", "progress"}];
|
||||
|
||||
// // simparams.print_progressbar = cmdl[{"P", "progress"}];
|
||||
|
||||
// /* Parse DHT arguments */
|
||||
// chem_params.use_dht = cmdl["dht"];
|
||||
// chem_params.use_interp = cmdl["interp"];
|
||||
// // cout << "CPP: DHT is " << ( dht_enabled ? "ON" : "OFF" ) << '\n';
|
||||
|
||||
// cmdl("dht-size", DHT_SIZE_PER_PROCESS_MB) >> chem_params.dht_size;
|
||||
// // cout << "CPP: DHT size per process (Byte) = " << dht_size_per_process <<
|
||||
// // endl;
|
||||
|
||||
// cmdl("dht-snaps", 0) >> chem_params.dht_snaps;
|
||||
|
||||
// cmdl("dht-file") >> chem_params.dht_file;
|
||||
// /*Parse work package size*/
|
||||
// cmdl("work-package-size", WORK_PACKAGE_SIZE_DEFAULT) >> simparams.wp_size;
|
||||
|
||||
// cmdl("interp-size", 100) >> chem_params.pht_size;
|
||||
// cmdl("interp-min", 5) >> chem_params.interp_min_entries;
|
||||
// cmdl("interp-bucket-entries", 20) >> chem_params.pht_max_entries;
|
||||
|
||||
// /*Parse output options*/
|
||||
// simparams.store_result = !cmdl["ignore-result"];
|
||||
|
||||
// /*Parse work package size*/
|
||||
// cmdl("work-package-size", WORK_PACKAGE_SIZE_DEFAULT) >> simparams.wp_size;
|
||||
|
||||
// chem_params.use_interp = cmdl["interp"];
|
||||
// cmdl("interp-size", 100) >> chem_params.pht_size;
|
||||
// cmdl("interp-min", 5) >> chem_params.interp_min_entries;
|
||||
// cmdl("interp-bucket-entries", 20) >> chem_params.pht_max_entries;
|
||||
|
||||
// /*Parse output options*/
|
||||
// simparams.store_result = !cmdl["ignore-result"];
|
||||
|
||||
// if (simparams.world_rank == 0) {
|
||||
// MSG("Complete results storage is " + BOOL_PRINT(simparams.store_result));
|
||||
// MSG("Work Package Size: " + std::to_string(simparams.wp_size));
|
||||
// MSG("DHT is " + BOOL_PRINT(chem_params.use_dht));
|
||||
|
||||
// if (chem_params.use_dht) {
|
||||
// MSG("DHT strategy is " + std::to_string(simparams.dht_strategy));
|
||||
// // MDL: these should be outdated (?)
|
||||
// // MSG("DHT key default digits (ignored if 'signif_vector' is "
|
||||
// // "defined) = "
|
||||
// // << simparams.dht_significant_digits);
|
||||
// // MSG("DHT logarithm before rounding: "
|
||||
// // << (simparams.dht_log ? "ON" : "OFF"));
|
||||
// MSG("DHT size per process (Megabyte) = " +
|
||||
// std::to_string(chem_params.dht_size));
|
||||
// MSG("DHT save snapshots is " + BOOL_PRINT(chem_params.dht_snaps));
|
||||
// MSG("DHT load file is " + chem_params.dht_file);
|
||||
// }
|
||||
|
||||
// if (chem_params.use_interp) {
|
||||
// MSG("PHT interpolation enabled: " +
|
||||
// BOOL_PRINT(chem_params.use_interp)); MSG("PHT interp-size = " +
|
||||
// std::to_string(chem_params.pht_size)); MSG("PHT interp-min = " +
|
||||
// std::to_string(chem_params.interp_min_entries));
|
||||
// MSG("PHT interp-bucket-entries = " +
|
||||
// std::to_string(chem_params.pht_max_entries));
|
||||
// }
|
||||
// }
|
||||
|
||||
std::string init_file;
|
||||
std::string runtime_file;
|
||||
std::string out_dir;
|
||||
|
||||
cmdl(1) >> init_file;
|
||||
cmdl(2) >> runtime_file;
|
||||
cmdl(3) >> out_dir;
|
||||
|
||||
// chem_params.dht_outdir = out_dir;
|
||||
|
||||
/* distribute information to R runtime */
|
||||
// if local_rank == 0 then master else worker
|
||||
R["local_rank"] = MY_RANK;
|
||||
// assign a char* (string) to 'filesim'
|
||||
R["filesim"] = wrap(runtime_file);
|
||||
// assign a char* (string) to 'fileout'
|
||||
R["fileout"] = wrap(out_dir);
|
||||
// pass the boolean "store_result" to the R process
|
||||
// R["store_result"] = simparams.store_result;
|
||||
// // worker count
|
||||
// R["n_procs"] = simparams.world_size - 1;
|
||||
// // work package size
|
||||
// R["work_package_size"] = simparams.wp_size;
|
||||
// // dht enabled?
|
||||
// R["dht_enabled"] = chem_params.use_dht;
|
||||
// // log before rounding?
|
||||
// R["dht_log"] = simparams.dht_log;
|
||||
|
||||
try {
|
||||
Rcpp::Function source("source");
|
||||
Rcpp::Function readRDS("readRDS");
|
||||
|
||||
Rcpp::List init_params_ = readRDS(init_file);
|
||||
params.init_params = init_params_;
|
||||
|
||||
Rcpp::List runtime_params =
|
||||
source(runtime_file, Rcpp::Named("local", true));
|
||||
runtime_params = runtime_params["value"];
|
||||
R[r_runtime_parameters] = runtime_params;
|
||||
|
||||
params.timesteps =
|
||||
Rcpp::as<std::vector<double>>(runtime_params["timesteps"]);
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
ERRMSG("Error while parsing R scripts: " + std::string(e.what()));
|
||||
return ParseRet::PARSER_ERROR;
|
||||
}
|
||||
// eval the init string, ignoring any returns
|
||||
// R.parseEvalQ("source(filesim)");
|
||||
// R.parseEvalQ("mysetup <- setup");
|
||||
|
||||
// this->chem_params.initFromR(R);
|
||||
|
||||
return ParseRet::PARSER_OK;
|
||||
}
|
||||
|
||||
inline double RunMasterLoop(SimParams ¶ms, RInside &R,
|
||||
const GridParams &g_params, uint32_t nxyz_master) {
|
||||
// void set_chem_parameters(poet::ChemistryModule &chem, uint32_t wp_size,
|
||||
// const std::string &database_path) {
|
||||
// chem.SetErrorHandlerMode(1);
|
||||
// chem.SetComponentH2O(false);
|
||||
// chem.SetRebalanceFraction(0.5);
|
||||
// chem.SetRebalanceByCell(true);
|
||||
// chem.UseSolutionDensityVolume(false);
|
||||
// chem.SetPartitionUZSolids(false);
|
||||
|
||||
// // Set concentration units
|
||||
// // 1, mg/L; 2, mol/L; 3, kg/kgs
|
||||
// chem.SetUnitsSolution(2);
|
||||
// // 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
// chem.SetUnitsPPassemblage(1);
|
||||
// // 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
// chem.SetUnitsExchange(1);
|
||||
// // 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
// chem.SetUnitsSurface(1);
|
||||
// // 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
// chem.SetUnitsGasPhase(1);
|
||||
// // 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
// chem.SetUnitsSSassemblage(1);
|
||||
// // 0, mol/L cell; 1, mol/L water; 2 mol/L rock
|
||||
// chem.SetUnitsKinetics(1);
|
||||
|
||||
// // Set representative volume
|
||||
// std::vector<double> rv;
|
||||
// rv.resize(wp_size, 1.0);
|
||||
// chem.SetRepresentativeVolume(rv);
|
||||
|
||||
// // Set initial porosity
|
||||
// std::vector<double> por;
|
||||
// por.resize(wp_size, 1);
|
||||
// chem.SetPorosity(por);
|
||||
|
||||
// // Set initial saturation
|
||||
// std::vector<double> sat;
|
||||
// sat.resize(wp_size, 1.0);
|
||||
// chem.SetSaturation(sat);
|
||||
|
||||
// // Load database
|
||||
// chem.LoadDatabase(database_path);
|
||||
// }
|
||||
|
||||
static double RunMasterLoop(RInside &R, const RuntimeParameters ¶ms,
|
||||
DiffusionModule &diffusion) {
|
||||
|
||||
DiffusionParams d_params{R};
|
||||
DiffusionModule diffusion(d_params, g_params);
|
||||
/* Iteration Count is dynamic, retrieving value from R (is only needed by
|
||||
* master for the following loop) */
|
||||
uint32_t maxiter = R.parseEval("mysetup$iterations");
|
||||
uint32_t maxiter = params.timesteps.size();
|
||||
|
||||
double sim_time = .0;
|
||||
|
||||
ChemistryModule chem(nxyz_master, params.getNumParams().wp_size, maxiter,
|
||||
params.getChemParams(), MPI_COMM_WORLD);
|
||||
// ChemistryModule chem(nxyz_master, params.getNumParams().wp_size, maxiter,
|
||||
// params.getChemParams(), MPI_COMM_WORLD);
|
||||
|
||||
set_chem_parameters(chem, nxyz_master, params.getChemParams().database_path);
|
||||
chem.RunInitFile(params.getChemParams().input_script);
|
||||
// set_chem_parameters(chem, nxyz_master,
|
||||
// params.getChemParams().database_path);
|
||||
// chem.RunInitFile(params.getChemParams().input_script);
|
||||
|
||||
poet::ChemistryModule::SingleCMap init_df = DFToHashMap(d_params.initial_t);
|
||||
chem.initializeField(diffusion.getField());
|
||||
// poet::ChemistryModule::SingleCMap init_df =
|
||||
// DFToHashMap(d_params.initial_t);
|
||||
// chem.initializeField(diffusion.getField());
|
||||
|
||||
if (params.getNumParams().print_progressbar) {
|
||||
chem.setProgressBarPrintout(true);
|
||||
}
|
||||
// if (params.getNumParams().print_progressbar) {
|
||||
// chem.setProgressBarPrintout(true);
|
||||
// }
|
||||
|
||||
/* SIMULATION LOOP */
|
||||
|
||||
@ -147,31 +332,30 @@ inline double RunMasterLoop(SimParams ¶ms, RInside &R,
|
||||
// cout << "CPP: Evaluating next time step" << endl;
|
||||
// R.parseEvalQ("mysetup <- master_iteration_setup(mysetup)");
|
||||
|
||||
double dt = Rcpp::as<double>(
|
||||
R.parseEval("mysetup$timesteps[" + std::to_string(iter) + "]"));
|
||||
double dt = params.timesteps[iter - 1];
|
||||
|
||||
// cout << "CPP: Next time step is " << dt << "[s]" << endl;
|
||||
MSG("Next time step is " + std::to_string(dt) + " [s]");
|
||||
|
||||
/* displaying iteration number, with C++ and R iterator */
|
||||
MSG("Going through iteration " + std::to_string(iter));
|
||||
MSG("R's $iter: " +
|
||||
std::to_string((uint32_t)(R.parseEval("mysetup$iter"))) +
|
||||
". Iteration");
|
||||
// MSG("R's $iter: " +
|
||||
// std::to_string((uint32_t)(R.parseEval("mysetup$iter"))) +
|
||||
// ". Iteration");
|
||||
|
||||
/* run transport */
|
||||
// TODO: transport to diffusion
|
||||
diffusion.simulate(dt);
|
||||
|
||||
chem.getField().update(diffusion.getField());
|
||||
// chem.getField().update(diffusion.getField());
|
||||
|
||||
MSG("Chemistry step");
|
||||
|
||||
chem.SetTimeStep(dt);
|
||||
chem.RunCells();
|
||||
// chem.SetTimeStep(dt);
|
||||
// chem.RunCells();
|
||||
|
||||
writeFieldsToR(R, diffusion.getField(), chem.GetField());
|
||||
diffusion.getField().update(chem.GetField());
|
||||
writeFieldsToR(R, diffusion.getField());
|
||||
// diffusion.getField().update(chem.GetField());
|
||||
|
||||
R["req_dt"] = dt;
|
||||
R["simtime"] = (sim_time += dt);
|
||||
@ -183,7 +367,7 @@ inline double RunMasterLoop(SimParams ¶ms, RInside &R,
|
||||
// state_C after every iteration if the cmdline option
|
||||
// --ignore-results is not given (and thus the R variable
|
||||
// store_result is TRUE)
|
||||
R.parseEvalQ("mysetup <- master_iteration_end(setup=mysetup)");
|
||||
R.parseEval("mysetup <- master_iteration_end(setup=mysetup)");
|
||||
|
||||
MSG("End of *coupling* iteration " + std::to_string(iter) + "/" +
|
||||
std::to_string(maxiter));
|
||||
@ -194,60 +378,60 @@ inline double RunMasterLoop(SimParams ¶ms, RInside &R,
|
||||
dSimTime += end_t - start_t;
|
||||
} // END SIMULATION LOOP
|
||||
|
||||
R.parseEvalQ("profiling <- list()");
|
||||
// R.parseEvalQ("profiling <- list()");
|
||||
|
||||
R["simtime_chemistry"] = chem.GetChemistryTime();
|
||||
R.parseEvalQ("profiling$simtime_chemistry <- simtime_chemistry");
|
||||
// R["simtime_chemistry"] = chem.GetChemistryTime();
|
||||
// R.parseEvalQ("profiling$simtime_chemistry <- simtime_chemistry");
|
||||
|
||||
R["chemistry_loop"] = chem.GetMasterLoopTime();
|
||||
R.parseEvalQ("profiling$chemistry_loop <- chemistry_loop");
|
||||
// R["chemistry_loop"] = chem.GetMasterLoopTime();
|
||||
// R.parseEvalQ("profiling$chemistry_loop <- chemistry_loop");
|
||||
|
||||
R["chemistry_sequential"] = chem.GetMasterSequentialTime();
|
||||
R.parseEvalQ("profiling$simtime_sequential <- chemistry_sequential");
|
||||
// R["chemistry_sequential"] = chem.GetMasterSequentialTime();
|
||||
// R.parseEvalQ("profiling$simtime_sequential <- chemistry_sequential");
|
||||
|
||||
R["idle_master"] = chem.GetMasterIdleTime();
|
||||
R.parseEvalQ("profiling$idle_master <- idle_master");
|
||||
// R["idle_master"] = chem.GetMasterIdleTime();
|
||||
// R.parseEvalQ("profiling$idle_master <- idle_master");
|
||||
|
||||
R["idle_worker"] = Rcpp::wrap(chem.GetWorkerIdleTimings());
|
||||
R.parseEvalQ("profiling$idle_worker <- idle_worker");
|
||||
// R["idle_worker"] = Rcpp::wrap(chem.GetWorkerIdleTimings());
|
||||
// R.parseEvalQ("profiling$idle_worker <- idle_worker");
|
||||
|
||||
R["phreeqc_time"] = Rcpp::wrap(chem.GetWorkerPhreeqcTimings());
|
||||
R.parseEvalQ("profiling$phreeqc <- phreeqc_time");
|
||||
// R["phreeqc_time"] = Rcpp::wrap(chem.GetWorkerPhreeqcTimings());
|
||||
// R.parseEvalQ("profiling$phreeqc <- phreeqc_time");
|
||||
|
||||
R["simtime_transport"] = diffusion.getTransportTime();
|
||||
R.parseEvalQ("profiling$simtime_transport <- simtime_transport");
|
||||
// R["simtime_transport"] = diffusion.getTransportTime();
|
||||
// R.parseEvalQ("profiling$simtime_transport <- simtime_transport");
|
||||
|
||||
// R["phreeqc_count"] = phreeqc_counts;
|
||||
// R.parseEvalQ("profiling$phreeqc_count <- phreeqc_count");
|
||||
|
||||
if (params.getChemParams().use_dht) {
|
||||
R["dht_hits"] = Rcpp::wrap(chem.GetWorkerDHTHits());
|
||||
R.parseEvalQ("profiling$dht_hits <- dht_hits");
|
||||
R["dht_evictions"] = Rcpp::wrap(chem.GetWorkerDHTEvictions());
|
||||
R.parseEvalQ("profiling$dht_evictions <- dht_evictions");
|
||||
R["dht_get_time"] = Rcpp::wrap(chem.GetWorkerDHTGetTimings());
|
||||
R.parseEvalQ("profiling$dht_get_time <- dht_get_time");
|
||||
R["dht_fill_time"] = Rcpp::wrap(chem.GetWorkerDHTFillTimings());
|
||||
R.parseEvalQ("profiling$dht_fill_time <- dht_fill_time");
|
||||
}
|
||||
if (params.getChemParams().use_interp) {
|
||||
R["interp_w"] = Rcpp::wrap(chem.GetWorkerInterpolationWriteTimings());
|
||||
R.parseEvalQ("profiling$interp_write <- interp_w");
|
||||
R["interp_r"] = Rcpp::wrap(chem.GetWorkerInterpolationReadTimings());
|
||||
R.parseEvalQ("profiling$interp_read <- interp_r");
|
||||
R["interp_g"] = Rcpp::wrap(chem.GetWorkerInterpolationGatherTimings());
|
||||
R.parseEvalQ("profiling$interp_gather <- interp_g");
|
||||
R["interp_fc"] =
|
||||
Rcpp::wrap(chem.GetWorkerInterpolationFunctionCallTimings());
|
||||
R.parseEvalQ("profiling$interp_function_calls <- interp_fc");
|
||||
R["interp_calls"] = Rcpp::wrap(chem.GetWorkerInterpolationCalls());
|
||||
R.parseEvalQ("profiling$interp_calls <- interp_calls");
|
||||
R["interp_cached"] = Rcpp::wrap(chem.GetWorkerPHTCacheHits());
|
||||
R.parseEvalQ("profiling$interp_cached <- interp_cached");
|
||||
}
|
||||
// if (params.getChemParams().use_dht) {
|
||||
// R["dht_hits"] = Rcpp::wrap(chem.GetWorkerDHTHits());
|
||||
// R.parseEvalQ("profiling$dht_hits <- dht_hits");
|
||||
// R["dht_evictions"] = Rcpp::wrap(chem.GetWorkerDHTEvictions());
|
||||
// R.parseEvalQ("profiling$dht_evictions <- dht_evictions");
|
||||
// R["dht_get_time"] = Rcpp::wrap(chem.GetWorkerDHTGetTimings());
|
||||
// R.parseEvalQ("profiling$dht_get_time <- dht_get_time");
|
||||
// R["dht_fill_time"] = Rcpp::wrap(chem.GetWorkerDHTFillTimings());
|
||||
// R.parseEvalQ("profiling$dht_fill_time <- dht_fill_time");
|
||||
// }
|
||||
// if (params.getChemParams().use_interp) {
|
||||
// R["interp_w"] = Rcpp::wrap(chem.GetWorkerInterpolationWriteTimings());
|
||||
// R.parseEvalQ("profiling$interp_write <- interp_w");
|
||||
// R["interp_r"] = Rcpp::wrap(chem.GetWorkerInterpolationReadTimings());
|
||||
// R.parseEvalQ("profiling$interp_read <- interp_r");
|
||||
// R["interp_g"] =
|
||||
// Rcpp::wrap(chem.GetWorkerInterpolationGatherTimings());
|
||||
// R.parseEvalQ("profiling$interp_gather <- interp_g");
|
||||
// R["interp_fc"] =
|
||||
// Rcpp::wrap(chem.GetWorkerInterpolationFunctionCallTimings());
|
||||
// R.parseEvalQ("profiling$interp_function_calls <- interp_fc");
|
||||
// R["interp_calls"] = Rcpp::wrap(chem.GetWorkerInterpolationCalls());
|
||||
// R.parseEvalQ("profiling$interp_calls <- interp_calls");
|
||||
// R["interp_cached"] = Rcpp::wrap(chem.GetWorkerPHTCacheHits());
|
||||
// R.parseEvalQ("profiling$interp_cached <- interp_cached");
|
||||
// }
|
||||
|
||||
chem.MasterLoopBreak();
|
||||
diffusion.end();
|
||||
// chem.MasterLoopBreak();
|
||||
|
||||
return dSimTime;
|
||||
}
|
||||
@ -271,24 +455,24 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (world_rank > 0) {
|
||||
{
|
||||
SimParams params(world_rank, world_size);
|
||||
int pret = params.parseFromCmdl(argv, R);
|
||||
// SimParams params(world_rank, world_size);
|
||||
// int pret = params.parseFromCmdl(argv, R);
|
||||
|
||||
if (pret == poet::PARSER_ERROR) {
|
||||
MPI_Finalize();
|
||||
return EXIT_FAILURE;
|
||||
} else if (pret == poet::PARSER_HELP) {
|
||||
MPI_Finalize();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// if (pret == poet::PARSER_ERROR) {
|
||||
// MPI_Finalize();
|
||||
// return EXIT_FAILURE;
|
||||
// } else if (pret == poet::PARSER_HELP) {
|
||||
// MPI_Finalize();
|
||||
// return EXIT_SUCCESS;
|
||||
// }
|
||||
|
||||
// ChemistryModule worker(nxyz, nxyz, MPI_COMM_WORLD);
|
||||
ChemistryModule worker = poet::ChemistryModule::createWorker(
|
||||
MPI_COMM_WORLD, params.getChemParams());
|
||||
set_chem_parameters(worker, worker.GetWPSize(),
|
||||
params.getChemParams().database_path);
|
||||
// // ChemistryModule worker(nxyz, nxyz, MPI_COMM_WORLD);
|
||||
// ChemistryModule worker = poet::ChemistryModule::createWorker(
|
||||
// MPI_COMM_WORLD, params.getChemParams());
|
||||
// set_chem_parameters(worker, worker.GetWPSize(),
|
||||
// params.getChemParams().database_path);
|
||||
|
||||
worker.WorkerLoop();
|
||||
// worker.WorkerLoop();
|
||||
}
|
||||
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
@ -304,33 +488,31 @@ int main(int argc, char *argv[]) {
|
||||
// TODO: kann raus
|
||||
R.parseEvalQ(kin_r_library);
|
||||
|
||||
SimParams params(world_rank, world_size);
|
||||
int pret = params.parseFromCmdl(argv, R);
|
||||
RuntimeParameters run_params;
|
||||
|
||||
if (pret == poet::PARSER_ERROR) {
|
||||
switch (parseInitValues(argv, R, run_params)) {
|
||||
case ParseRet::PARSER_ERROR:
|
||||
case ParseRet::PARSER_HELP:
|
||||
MPI_Finalize();
|
||||
return EXIT_FAILURE;
|
||||
} else if (pret == poet::PARSER_HELP) {
|
||||
MPI_Finalize();
|
||||
return EXIT_SUCCESS;
|
||||
return 0;
|
||||
case ParseRet::PARSER_OK:
|
||||
break;
|
||||
}
|
||||
|
||||
MSG("RInside initialized on process " + std::to_string(world_rank));
|
||||
|
||||
R.parseEvalQ("mysetup <- setup");
|
||||
// if (world_rank == 0) { // get timestep vector from
|
||||
// grid_init function ... //
|
||||
std::string master_init_code = "mysetup <- master_init(setup=setup)";
|
||||
// R.parseEvalQ("mysetup <- setup");
|
||||
// // if (world_rank == 0) { // get timestep vector from
|
||||
// // grid_init function ... //
|
||||
std::string master_init_code = "mysetup <- master_init(setup=mysetup)";
|
||||
R.parseEval(master_init_code);
|
||||
|
||||
GridParams g_params(R);
|
||||
|
||||
params.initVectorParams(R);
|
||||
// run_params.initVectorParams(R);
|
||||
|
||||
// MDL: store all parameters
|
||||
if (world_rank == 0) {
|
||||
MSG("Calling R Function to store calling parameters");
|
||||
R.parseEvalQ("StoreSetup(setup=mysetup)");
|
||||
// R.parseEvalQ("StoreSetup(setup=mysetup)");
|
||||
}
|
||||
|
||||
if (world_rank == 0) {
|
||||
@ -339,23 +521,28 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
uint32_t nxyz_master = (world_size == 1 ? g_params.total_n : 1);
|
||||
InitialList init_list(R);
|
||||
init_list.importList(run_params.init_params);
|
||||
|
||||
dSimTime = RunMasterLoop(params, R, g_params, nxyz_master);
|
||||
DiffusionModule diffusion(init_list.getDiffusionInit(),
|
||||
init_list.getInitialGrid());
|
||||
|
||||
dSimTime = RunMasterLoop(R, run_params, diffusion);
|
||||
|
||||
MSG("finished simulation loop");
|
||||
|
||||
MSG("start timing profiling");
|
||||
|
||||
R["simtime"] = dSimTime;
|
||||
R.parseEvalQ("profiling$simtime <- simtime");
|
||||
// R["simtime"] = dSimTime;
|
||||
// R.parseEvalQ("profiling$simtime <- simtime");
|
||||
|
||||
string r_vis_code;
|
||||
r_vis_code = "saveRDS(profiling, file=paste0(fileout,'/timings.rds'));";
|
||||
R.parseEval(r_vis_code);
|
||||
// string r_vis_code;
|
||||
// r_vis_code = "saveRDS(profiling, file=paste0(fileout,'/timings.rds'));";
|
||||
// R.parseEval(r_vis_code);
|
||||
|
||||
MSG("Done! Results are stored as R objects into <" + params.getOutDir() +
|
||||
"/timings.rds>");
|
||||
// MSG("Done! Results are stored as R objects into <" + run_params.getOutDir()
|
||||
// +
|
||||
// "/timings.rds>");
|
||||
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
|
||||
@ -1,12 +1,79 @@
|
||||
#ifndef POET_H
|
||||
#define POET_H
|
||||
/*
|
||||
** Copyright (C) 2018-2021 Alexander Lindemann, Max Luebke (University of
|
||||
** Potsdam)
|
||||
**
|
||||
** Copyright (C) 2018-2023 Marco De Lucia, Max Luebke (GFZ Potsdam)
|
||||
**
|
||||
** Copyright (C) 2023-2024 Max Luebke (University of Potsdam)
|
||||
**
|
||||
** POET is free software; you can redistribute it and/or modify it under the
|
||||
** terms of the GNU General Public License as published by the Free Software
|
||||
** Foundation; either version 2 of the License, or (at your option) any later
|
||||
** version.
|
||||
**
|
||||
** POET is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
** A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License along with
|
||||
** this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
** Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Rcpp.h>
|
||||
|
||||
static const char *poet_version = "@POET_VERSION@";
|
||||
|
||||
// using the Raw string literal to avoid escaping the quotes
|
||||
static inline std::string kin_r_library = R"(@R_KIN_LIB@)";
|
||||
static const inline std::string kin_r_library = R"(@R_KIN_LIB@)";
|
||||
|
||||
static inline std::string init_r_library = R"(@R_INIT_LIB@)";
|
||||
static const inline std::string init_r_library = R"(@R_INIT_LIB@)";
|
||||
|
||||
#endif // POET_H
|
||||
static const inline std::string r_runtime_parameters = "mysetup";
|
||||
|
||||
const std::set<std::string> flaglist{"ignore-result", "dht", "P", "progress",
|
||||
"interp"};
|
||||
const std::set<std::string> paramlist{
|
||||
"work-package-size", "dht-strategy", "dht-size", "dht-snaps",
|
||||
"dht-file", "interp-size", "interp-min", "interp-bucket-entries"};
|
||||
|
||||
struct RuntimeParameters {
|
||||
std::vector<double> timesteps;
|
||||
|
||||
bool print_progressbar;
|
||||
|
||||
Rcpp::List init_params;
|
||||
|
||||
struct ChemistryParams {
|
||||
// std::string database_path;
|
||||
// std::string input_script;
|
||||
|
||||
// bool use_dht;
|
||||
// std::uint64_t dht_size;
|
||||
// int dht_snaps;
|
||||
// std::string dht_file;
|
||||
// std::string dht_outdir;
|
||||
// NamedVector<std::uint32_t> dht_signifs;
|
||||
|
||||
// bool use_interp;
|
||||
// std::uint64_t pht_size;
|
||||
// std::uint32_t pht_max_entries;
|
||||
// std::uint32_t interp_min_entries;
|
||||
// NamedVector<std::uint32_t> pht_signifs;
|
||||
|
||||
// struct Chem_Hook_Functions {
|
||||
// RHookFunction<bool> dht_fill;
|
||||
// RHookFunction<std::vector<double>> dht_fuzz;
|
||||
// RHookFunction<std::vector<std::size_t>> interp_pre;
|
||||
// RHookFunction<bool> interp_post;
|
||||
// } hooks;
|
||||
|
||||
// void initFromR(RInsidePOET &R);
|
||||
};
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user