20#include "pism/util/pism_utilities.hh"
29#include <gsl/gsl_version.h>
31#include "pism/pism_config.hh"
40#include <netcdf_meta.h>
44#include "pism/util/Proj.hh"
47#if (Pism_USE_JANSSON==1)
55#include "pism/util/error_handling.hh"
64 std::string tmp = input;
67 tmp.erase(0, tmp.find_first_not_of(
" \t"));
70 tmp.substr(tmp.find_last_not_of(
" \t"));
76bool ends_with(
const std::string &str,
const std::string &suffix) {
77 if (suffix.size() > str.size()) {
81 return (str.rfind(suffix) + suffix.size() == str.size());
76bool ends_with(
const std::string &str,
const std::string &suffix) {
…}
85std::string
join_impl(
const T& input,
const std::string& separator) {
90 auto j = input.begin();
91 std::string result = *j;
93 while (j != input.end()) {
94 result += separator + *j;
85std::string
join_impl(
const T& input,
const std::string& separator) {
…}
101std::string
join(
const std::vector<std::string> &strings,
const std::string &separator) {
101std::string
join(
const std::vector<std::string> &strings,
const std::string &separator) {
…}
105std::string
set_join(
const std::set<std::string> &input,
const std::string& separator) {
105std::string
set_join(
const std::set<std::string> &input,
const std::string& separator) {
…}
116 for (
const char &c : input) {
117 result += c == from ? to : c;
124std::vector<std::string>
split(
const std::string &input,
char separator) {
125 std::istringstream input_list(input);
127 std::vector<std::string> result;
129 while (getline(input_list, token, separator)) {
130 if (not token.empty()) {
131 result.emplace_back(token);
124std::vector<std::string>
split(
const std::string &input,
char separator) {
…}
138std::set<std::string>
set_split(
const std::string &input,
char separator) {
139 std::set<std::string> result;
140 for (
const auto &token :
split(input, separator)) {
141 result.insert(token);
138std::set<std::string>
set_split(
const std::string &input,
char separator) {
…}
148 int len = (
int)a.size();
149 for (
int k = 0;
k < len-1;
k++) {
150 if (a[
k] >= a[
k+1]) {
157bool member(
const std::string &
string,
const std::set<std::string> &set) {
158 return (set.find(
string) != set.end());
157bool member(
const std::string &
string,
const std::set<std::string> &set) {
…}
162 assert(local != result);
163 int err = MPI_Allreduce(local, result,
count, MPI_DOUBLE, op, comm);
168 assert(local != result);
169 int err = MPI_Allreduce(local, result,
count, MPI_INT, op, comm);
193unsigned int GlobalSum(MPI_Comm comm,
unsigned int input) {
195 int err = MPI_Allreduce(&input, &result, 1, MPI_UNSIGNED, MPI_SUM, comm);
202 int err = MPI_Allreduce(&input, &result, 1, MPI_INT, MPI_SUM, comm);
232 result +=
pism::printf(
"CMake %s.\n", pism::cmake_version);
237 result +=
pism::printf(
"PETSc configure: %s\n", pism::petsc_configure_flags);
244 OMPI_RELEASE_VERSION);
248 MPI_Get_library_version(buffer, &string_length);
252 result +=
pism::printf(
"NetCDF %s.\n", nc_inq_libvers());
256#if (Pism_USE_PROJ==1)
260#if (Pism_USE_JANSSON==1)
261 result +=
pism::printf(
"Jansson %s.\n", JANSSON_VERSION);
264#if (Pism_BUILD_PYTHON_BINDINGS==1)
265 result +=
pism::printf(
"SWIG %s.\n", pism::swig_version);
266 result +=
pism::printf(
"petsc4py %s.\n", pism::petsc4py_version);
274 return 100 * NC_VERSION_MAJOR + 10 * NC_VERSION_MINOR + NC_VERSION_PATCH;
283 const double seconds_per_hour = 3600.0;
291 MPI_Comm_rank(com, &rank);
298 localtime_r(&now, &tm_now);
301 strftime(date_str,
sizeof(date_str),
"%F %T %Z", &tm_now);
304 MPI_Bcast(date_str, 50, MPI_CHAR, 0, com);
306 return std::string(date_str);
314 ierr = PetscGetUserName(username,
sizeof(username));
320 ierr = PetscGetHostName(hostname,
sizeof(hostname));
327 std::string result =
pism::printf(
"%s@%s %s: ", username, hostname, time.c_str());
329 unsigned int length = result.size();
330 MPI_Bcast(&length, 1, MPI_UNSIGNED, 0, com);
332 result.resize(length);
333 MPI_Bcast(&result[0], length, MPI_CHAR, 0, com);
343 PetscErrorCode ierr = PetscGetArgs(&argc, &argv);
347 std::string argument;
348 for (
int j = 0; j < argc; j++) {
352 if (argument.find(
' ') != std::string::npos) {
353 argument =
"\"" + argument +
"\"";
356 cmdstr += std::string(
" ") + argument;
371 const std::string &suffix) {
372 std::string basename = filename;
376 std::string::size_type j = basename.rfind(separator);
377 if (j == std::string::npos) {
378 j = basename.rfind(
".nc");
382 if (j == std::string::npos) {
387 basename.resize(
static_cast<int>(j));
389 result = basename + separator + suffix;
402 MPI_Comm_rank(comm, &rank);
408 PetscErrorCode ierr = PetscTime(&tmp);
PISM_CHK(ierr,
"PetscTime");
416 MPI_Bcast(&result, 1, MPI_DOUBLE, 0, comm);
421std::string
printf(
const char *format, ...) {
422 std::string result(1024,
' ');
426 va_start(arglist, format);
427 if((length = vsnprintf(&result[0], result.size(), format, arglist)) > result.size()) {
428 result.reserve(length);
429 vsnprintf(&result[0], result.size(), format, arglist);
432 return result.substr(0, length);
421std::string
printf(
const char *format, ...) {
…}
442 if (format.find(
"%s") == std::string::npos) {
447 if (format.find(
'%') != format.rfind(
'%')) {
454 double my_min = input[0];
455 for (
auto x : input) {
456 my_min = std::min(x, my_min);
462 double my_max = input[0];
463 for (
auto x : input) {
464 my_max = std::max(x, my_max);
480 static const size_t block_size = 92681;
484 while (length != 0) {
485 size_t block = std::min(block_size, length);
487 for (
size_t i = 0; i < block; ++i) {
492 c0 = c0 % UINT32_MAX;
493 c1 =
c1 % UINT32_MAX;
495 length = length > block_size ? length - block_size : 0;
497 return (
c1 << 32 | c0);
504 const std::vector<double> &data,
507 MPI_Comm_rank(com, &rank);
509 uint64_t sum =
fletcher64((uint32_t*)data.data(), data.size() * 2);
511 PetscPrintf(PETSC_COMM_SELF,
"[%d] %s: %016llx\n",
512 rank, label, (
unsigned long long int)sum);
516 const std::vector<double> &data,
519 MPI_Comm_rank(com, &rank);
521 std::vector<std::string> tmp;
522 tmp.reserve(data.size());
523 for (
const auto &f : data) {
527 auto str =
join(tmp,
",");
529 PetscPrintf(PETSC_COMM_SELF,
"[%d] %s: %s\n",
530 rank, label, str.c_str());
534 const std::vector<int> &data,
537 MPI_Comm_rank(com, &rank);
539 std::vector<std::string> tmp;
540 tmp.reserve(data.size());
541 for (
const auto &f : data) {
545 auto str =
join(tmp,
",");
547 PetscPrintf(PETSC_COMM_SELF,
"[%d] %s: %s\n",
548 rank, label, str.c_str());
556 double floatation_level,
double rho_ice,
557 double rho_water,
double g) {
559 double ice_bottom = std::max(bed, floatation_level -
rho_ice / rho_water * ice_thickness);
560 double water_column_height = std::max(floatation_level - ice_bottom, 0.0);
562 if (ice_thickness > 0.0) {
563 return 0.5 * rho_water *
g * pow(water_column_height, 2.0) / ice_thickness;
570 double result = strtod(input.c_str(), &endptr);
571 if (*endptr !=
'\0') {
573 "Can't parse %s (expected a floating point number)",
580 std::vector<double> result;
582 for (
const auto &p :
split(input,
',')) {
590 long int result = strtol(input.c_str(), &endptr, 10);
591 if (*endptr !=
'\0') {
593 "Can't parse %s (expected an integer)",
600 std::vector<long> result;
602 for (
const auto &p :
split(input,
',')) {
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)
double get_time(MPI_Comm comm)
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 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.
std::vector< long > parse_integer_list(const std::string &input)
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.
std::vector< double > parse_number_list(const std::string &input)
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,...)
int netcdf_version()
return NetCDF version as an integer
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)
void GlobalMin(MPI_Comm comm, double *local, double *result, int count)
static double start_time(const Config &config, const File *file, const std::string &reference_date, const std::string &calendar, const units::Unit &time_units)
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 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.