From ee6051111d87e35f1f407d2722c95a1421ab71ff Mon Sep 17 00:00:00 2001 From: bangerth Date: Thu, 25 Aug 2011 19:02:42 +0000 Subject: [PATCH] Add Utilities::string_to_double. git-svn-id: https://svn.dealii.org/trunk@24202 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/news/changes.h | 4 ++ deal.II/include/deal.II/base/utilities.h | 37 ++++++++--- deal.II/source/base/utilities.cc | 81 +++++++++++++++++------- 3 files changed, 88 insertions(+), 34 deletions(-) diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index 7c28b89c31..13ff612dff 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -281,6 +281,10 @@ and DoF handlers embedded in higher dimensional space have been added.

Specific improvements

    +
  1. New: There are now two new functions Utilities::string_to_double. +
    +(Wolfgang Bangerth, 2011/08/25) +
  2. Changed: The function VectorTools::compute_no_normal_flux_constraints used to compute its constraints by evaluating the normal vector to the surface as described by the mapping, rather than using the normal to diff --git a/deal.II/include/deal.II/base/utilities.h b/deal.II/include/deal.II/base/utilities.h index 0fc6374cfd..bababba4d8 100644 --- a/deal.II/include/deal.II/base/utilities.h +++ b/deal.II/include/deal.II/base/utilities.h @@ -90,6 +90,23 @@ namespace Utilities std::vector string_to_int (const std::vector &s); + /** + * Given a string, convert it to an + * double. Throw an assertion if that is + * not possible. + */ + double + string_to_double (const std::string &s); + + + /** + * Given a list of strings, convert it to a + * list of doubles. Throw an assertion if + * that is not possible. + */ + std::vector + string_to_double (const std::vector &s); + /** * Given a string that contains text * separated by a @p delimiter, split it into @@ -220,7 +237,7 @@ namespace Utilities lower_bound (Iterator first, Iterator last, const T &val); - + /** * The same function as above, but taking @@ -234,7 +251,7 @@ namespace Utilities Iterator last, const T &val, const Comp comp); - + /** * Given a permutation vector (i.e. a * vector $p_0\ldots p_{N-1}$ where each @@ -290,8 +307,8 @@ namespace Utilities unsigned long int VmHWM; /** peak resident memory size in kB */ unsigned long int VmRSS; /** current resident memory size in kB */ }; - - + + /** * Fills the @param stats structure with * information about the memory @@ -299,7 +316,7 @@ namespace Utilities * only implemented on Linux. */ void get_memory_stats (MemoryStats & stats); - + /** * Return the name of the host this @@ -444,9 +461,9 @@ namespace Utilities void calculate_collective_mpi_min_max_avg(const MPI_Comm &mpi_communicator, const double my_value, MinMaxAvg & result); - - + + /** * A class that is used to initialize the * MPI system at the beginning of a @@ -749,7 +766,7 @@ namespace Utilities { return Utilities::lower_bound (first, last, val, std::less()); - } + } @@ -837,7 +854,7 @@ namespace Utilities else len = half; } - } + } } /** @@ -898,7 +915,7 @@ namespace Utilities } return first; } - + DEAL_II_NAMESPACE_CLOSE diff --git a/deal.II/source/base/utilities.cc b/deal.II/source/base/utilities.cc index c6f83dc9ea..03802b0f5f 100644 --- a/deal.II/source/base/utilities.cc +++ b/deal.II/source/base/utilities.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 2005, 2006, 2008, 2009, 2010 by the deal.II authors +// Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -162,6 +162,39 @@ namespace Utilities + double + string_to_double (const std::string &s) + { + std::istringstream ss(s); + +#ifdef HAVE_STD_NUMERIC_LIMITS + static const double max_double = std::numeric_limits::max(); +#else + static const double max_double = DBL_MAX; +#endif + + double i = max_double; + ss >> i; + + // check for errors + AssertThrow (i != max_double, ExcCantConvertString (s)); + + return i; + } + + + + std::vector + string_to_double (const std::vector &s) + { + std::vector tmp (s.size()); + for (unsigned int i=0; i split_string_list (const std::string &s, const char delimiter) @@ -425,7 +458,7 @@ namespace Utilities #endif - + void get_memory_stats (MemoryStats & stats) { stats.VmPeak = stats.VmSize = stats.VmHWM = stats.VmRSS = 0; @@ -433,7 +466,7 @@ namespace Utilities // parsing /proc/self/stat would be a // lot easier, but it does not contain // VmHWM, so we use /status instead. -#if defined(__linux__) +#if defined(__linux__) std::ifstream file("/proc/self/status"); std::string line; std::string name; @@ -451,13 +484,13 @@ namespace Utilities file >> stats.VmRSS; break; //this is always the last entry } - + getline(file, line); } #endif } - - + + std::string get_hostname () { @@ -552,7 +585,7 @@ namespace Utilities } - namespace + namespace { // custom MIP_Op for // calculate_collective_mpi_min_max_avg @@ -563,9 +596,9 @@ namespace Utilities { const MinMaxAvg * in_lhs = static_cast(in_lhs_); MinMaxAvg * inout_rhs = static_cast(inout_rhs_); - + Assert(*len==1, ExcInternalError()); - + inout_rhs->sum += in_lhs->sum; if (inout_rhs->min>in_lhs->min) { @@ -577,7 +610,7 @@ namespace Utilities if (inout_rhs->min_index > in_lhs->min_index) inout_rhs->min_index = in_lhs->min_index; } - + if (inout_rhs->max < in_lhs->max) { inout_rhs->max = in_lhs->max; @@ -592,7 +625,7 @@ namespace Utilities } - + void calculate_collective_mpi_min_max_avg(const MPI_Comm &mpi_communicator, double my_value, MinMaxAvg & result) @@ -601,37 +634,37 @@ namespace Utilities = dealii::Utilities::System::get_this_mpi_process(mpi_communicator); const unsigned int numproc = dealii::Utilities::System::get_n_mpi_processes(mpi_communicator); - + MPI_Op op; int ierr = MPI_Op_create((MPI_User_function *)&max_reduce, true, &op); AssertThrow(ierr == MPI_SUCCESS, ExcInternalError()); - + MinMaxAvg in; in.sum = in.min = in.max = my_value; in.min_index = in.max_index = my_id; - + MPI_Datatype type; int lengths[]={3,2}; MPI_Aint displacements[]={0,offsetof(MinMaxAvg, min_index)}; MPI_Datatype types[]={MPI_DOUBLE, MPI_INT}; - + ierr = MPI_Type_struct(2, lengths, displacements, types, &type); AssertThrow(ierr == MPI_SUCCESS, ExcInternalError()); - + ierr = MPI_Type_commit(&type); ierr = MPI_Allreduce ( &in, &result, 1, type, op, mpi_communicator ); AssertThrow(ierr == MPI_SUCCESS, ExcInternalError()); - + ierr = MPI_Type_free (&type); AssertThrow(ierr == MPI_SUCCESS, ExcInternalError()); - + ierr = MPI_Op_free(&op); AssertThrow(ierr == MPI_SUCCESS, ExcInternalError()); result.avg = result.sum / numproc; } - + std::vector compute_point_to_point_communication_pattern (const MPI_Comm & mpi_comm, const std::vector & destinations) @@ -721,7 +754,7 @@ namespace Utilities return 0; } - + void calculate_collective_mpi_min_max_avg(const MPI_Comm &, double my_value, MinMaxAvg & result) @@ -731,9 +764,9 @@ namespace Utilities result.min = my_value; result.max = my_value; result.min_index = 0; - result.max_index = 0; + result.max_index = 0; } - + MPI_Comm duplicate_communicator (const MPI_Comm &mpi_communicator) { @@ -813,7 +846,7 @@ namespace Utilities MPI_has_been_started != 0) { if (std::uncaught_exception()) - { + { std::cerr << "ERROR: Uncaught exception in MPI_InitFinalize on proc " << get_this_mpi_process(MPI_COMM_WORLD) << ". Skipping MPI_Finalize() to avoid a deadlock." @@ -822,7 +855,7 @@ namespace Utilities else mpi_err = MPI_Finalize(); } - + AssertThrow (mpi_err == 0, ExcMessage ("An error occurred while calling MPI_Finalize()")); -- 2.39.5