29 #include <gsl/gsl_version.h>
35 #include "pism/pism_config.hh"
40 #define MPI_INCLUDED 1
44 #if (Pism_USE_PROJ==1)
45 #include "pism/util/Proj.hh"
48 #if (Pism_USE_JANSSON==1)
52 #include <petsctime.h>
65 std::string tmp = input;
68 tmp.erase(0, tmp.find_first_not_of(
" \t"));
71 tmp.substr(tmp.find_last_not_of(
" \t"));
77 bool ends_with(
const std::string &str,
const std::string &suffix) {
78 if (suffix.size() > str.size()) {
82 return (str.rfind(suffix) + suffix.size() == str.size());
86 std::string
join_impl(
const T& input,
const std::string& separator) {
87 auto j = input.begin();
88 std::string result = *j;
90 while (j != input.end()) {
91 result += separator + *j;
98 std::string
join(
const std::vector<std::string> &strings,
const std::string &separator) {
102 std::string
set_join(
const std::set<std::string> &input,
const std::string& separator) {
113 for (
const char &c : input) {
114 result += c == from ? to : c;
121 std::vector<std::string>
split(
const std::string &input,
char separator) {
122 std::istringstream input_list(input);
124 std::vector<std::string> result;
126 while (getline(input_list, token, separator)) {
127 if (not token.empty()) {
128 result.emplace_back(token);
135 std::set<std::string>
set_split(
const std::string &input,
char separator) {
136 std::set<std::string> result;
137 for (
const auto &token :
split(input, separator)) {
138 result.insert(token);
145 int len = (int)a.size();
146 for (
int k = 0;
k < len-1;
k++) {
147 if (a[
k] >= a[
k+1]) {
154 bool member(
const std::string &
string,
const std::set<std::string> &set) {
155 return (set.find(
string) != set.end());
159 assert(local != result);
160 int err = MPI_Allreduce(local, result,
count, MPI_DOUBLE, op, comm);
165 assert(local != result);
166 int err = MPI_Allreduce(local, result,
count, MPI_INT, op, comm);
190 unsigned int GlobalSum(MPI_Comm comm,
unsigned int input) {
192 int err = MPI_Allreduce(&input, &result, 1, MPI_UNSIGNED, MPI_SUM, comm);
199 int err = MPI_Allreduce(&input, &result, 1, MPI_INT, MPI_SUM, comm);
229 result +=
pism::printf(
"CMake %s.\n", pism::cmake_version);
234 result +=
pism::printf(
"PETSc configure: %s\n", pism::petsc_configure_flags);
241 OMPI_RELEASE_VERSION);
245 MPI_Get_library_version(buffer, &string_length);
250 result +=
pism::printf(
"NetCDF %s.\n", nc_inq_libvers());
254 #if (Pism_USE_PROJ==1)
258 #if (Pism_USE_JANSSON==1)
259 result +=
pism::printf(
"Jansson %s.\n", JANSSON_VERSION);
262 #if (Pism_BUILD_PYTHON_BINDINGS==1)
263 result +=
pism::printf(
"SWIG %s.\n", pism::swig_version);
264 result +=
pism::printf(
"petsc4py %s.\n", pism::petsc4py_version);
276 MPI_Comm_rank(com, &rank);
281 const double seconds_per_hour = 3600.0;
289 MPI_Bcast(&result, 1, MPI_DOUBLE, 0, com);
300 localtime_r(&now, &tm_now);
303 strftime(date_str,
sizeof(date_str),
"%F %T %Z", &tm_now);
305 MPI_Bcast(date_str, 50, MPI_CHAR, 0, com);
307 return std::string(date_str);
315 ierr = PetscGetUserName(username,
sizeof(username));
321 ierr = PetscGetHostName(hostname,
sizeof(hostname));
327 std::ostringstream message;
328 message << username <<
"@" << hostname <<
" " <<
timestamp(com) <<
": ";
330 std::string result = message.str();
331 unsigned int length = result.size();
332 MPI_Bcast(&length, 1, MPI_UNSIGNED, 0, com);
334 result.resize(length);
335 MPI_Bcast(&result[0], length, MPI_CHAR, 0, com);
345 PetscErrorCode ierr = PetscGetArgs(&argc, &argv);
349 std::string argument;
350 for (
int j = 0; j < argc; j++) {
354 if (argument.find(
' ') != std::string::npos) {
355 argument =
"\"" + argument +
"\"";
358 cmdstr += std::string(
" ") + argument;
373 const std::string &separator,
374 const std::string &suffix) {
375 std::string basename = filename;
379 std::string::size_type j = basename.rfind(separator);
380 if (j == std::string::npos) {
381 j = basename.rfind(
".nc");
385 if (j == std::string::npos) {
390 basename.resize(
static_cast<int>(j));
392 result = basename + separator + suffix;
402 PetscLogDouble result;
403 PetscErrorCode ierr = PetscTime(&result);
PISM_CHK(ierr,
"PetscTime");
407 std::string
printf(
const char *format, ...) {
408 std::string result(1024,
' ');
412 va_start(arglist, format);
413 if((length = vsnprintf(&result[0], result.size(), format, arglist)) > result.size()) {
414 result.reserve(length);
415 vsnprintf(&result[0], result.size(), format, arglist);
418 return result.substr(0, length);
428 if (format.find(
"%s") == std::string::npos) {
433 if (format.find(
'%') != format.rfind(
'%')) {
440 double my_min = input[0];
441 for (
auto x : input) {
448 double my_max = input[0];
449 for (
auto x : input) {
466 static const size_t block_size = 92681;
470 while (length != 0) {
471 size_t block =
std::min(block_size, length);
473 for (
size_t i = 0; i < block; ++i) {
478 c0 = c0 % UINT32_MAX;
479 c1 =
c1 % UINT32_MAX;
481 length = length > block_size ? length - block_size : 0;
483 return (
c1 << 32 | c0);
490 const std::vector<double> &data,
493 MPI_Comm_rank(com, &rank);
495 uint64_t
sum =
fletcher64((uint32_t*)data.data(), data.size() * 2);
497 PetscPrintf(PETSC_COMM_SELF,
"[%d] %s: %016llx\n",
498 rank, label, (
unsigned long long int)
sum);
502 const std::vector<double> &data,
505 MPI_Comm_rank(com, &rank);
507 std::vector<std::string> tmp;
508 for (
const auto &f : data) {
512 auto str =
join(tmp,
",");
514 PetscPrintf(PETSC_COMM_SELF,
"[%d] %s: %s\n",
515 rank, label, str.c_str());
519 const std::vector<int> &data,
522 MPI_Comm_rank(com, &rank);
524 std::vector<std::string> tmp;
525 for (
const auto &f : data) {
529 auto str =
join(tmp,
",");
531 PetscPrintf(PETSC_COMM_SELF,
"[%d] %s: %s\n",
532 rank, label, str.c_str());
540 double floatation_level,
double rho_ice,
541 double rho_water,
double g) {
543 double ice_bottom =
std::max(bed, floatation_level -
rho_ice / rho_water * ice_thickness);
544 double water_column_height =
std::max(floatation_level - ice_bottom, 0.0);
546 if (ice_thickness > 0.0) {
547 return 0.5 * rho_water *
g * pow(water_column_height, 2.0) / ice_thickness;
554 double result = strtod(input.c_str(), &endptr);
555 if (*endptr !=
'\0') {
557 "Can't parse %s (expected a floating point number)",
565 long int result = strtol(input.c_str(), &endptr, 10);
566 if (*endptr !=
'\0') {
568 "Can't parse %s (expected an integer)",
void failed()
Indicates a failure of a parallel section.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
#define PISM_CHK(errcode, name)
#define PISM_ERROR_LOCATION
#define PISM_C_CHK(errcode, success, name)
bool is_increasing(const std::vector< double > &a)
Checks if a vector of doubles is strictly increasing.
double parse_number(const std::string &input)
double max(const IceModelVec2S &input)
Finds maximum over all the values in an IceModelVec2S object. Ignores ghosts.
double average_water_column_pressure(double ice_thickness, double bed, double floatation_level, double rho_ice, double rho_water, double g)
double wall_clock_hours(MPI_Comm com, double start_time)
Return time since the beginning of the run, in hours.
static double start_time(const Config &config, const Logger &log, const File *file, const std::string &reference_date, const std::string &calendar, const units::Unit &time_units)
void print_checksum(MPI_Comm com, const std::vector< double > &data, const char *label)
bool ends_with(const std::string &str, const std::string &suffix)
Returns true if str ends with suffix and false otherwise.
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)
std::string set_join(const std::set< std::string > &input, const std::string &separator)
std::string printf(const char *format,...)
void print_vector(MPI_Comm com, const std::vector< double > &data, const char *label)
uint64_t fletcher64(const uint32_t *data, size_t length)
void validate_format_string(const std::string &format)
std::set< std::string > set_split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a set of strings.
double vector_min(const std::vector< double > &input)
std::string string_strip(const std::string &input)
std::string filename_add_suffix(const std::string &filename, const std::string &separator, const std::string &suffix)
Adds a suffix to a filename.
std::string timestamp(MPI_Comm com)
Creates a time-stamp used for the history NetCDF attribute.
bool member(const std::string &string, const std::set< std::string > &set)
double min(const IceModelVec2S &input)
Finds minimum over all the values in an IceModelVec2S object. Ignores ghosts.
void GlobalMin(MPI_Comm comm, double *local, double *result, int count)
std::string args_string()
Uses argc and argv to create the string with current PISM command-line arguments.
long int parse_integer(const std::string &input)
static const int TEMPORARY_STRING_LENGTH
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)
std::string username_prefix(MPI_Comm com)
Creates a string with the user name, hostname and the time-stamp (for history strings).
std::string join_impl(const T &input, const std::string &separator)
void GlobalReduce(MPI_Comm comm, double *local, double *result, int count, MPI_Op op)
std::string replace_character(const std::string &input, char from, char to)
double sum(const IceModelVec2S &input)
Sums up all the values in an IceModelVec2S object. Ignores ghosts.
double vector_max(const std::vector< double > &input)
std::vector< std::string > split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a vector of strings.