URI: 
       tContext.cc - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
  HTML git clone git://src.adamsgaard.dk/pism
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
       tContext.cc (4972B)
       ---
            1 /* Copyright (C) 2014, 2015, 2017, 2019 PISM Authors
            2  *
            3  * This file is part of PISM.
            4  *
            5  * PISM is free software; you can redistribute it and/or modify it under the
            6  * terms of the GNU General Public License as published by the Free Software
            7  * Foundation; either version 3 of the License, or (at your option) any later
            8  * version.
            9  *
           10  * PISM is distributed in the hope that it will be useful, but WITHOUT ANY
           11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
           12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
           13  * details.
           14  *
           15  * You should have received a copy of the GNU General Public License
           16  * along with PISM; if not, write to the Free Software
           17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
           18  */
           19 
           20 #include "Context.hh"
           21 #include "Profiling.hh"
           22 #include "Units.hh"
           23 #include "Config.hh"
           24 #include "Time.hh"
           25 #include "Logger.hh"
           26 #include "pism/util/EnthalpyConverter.hh"
           27 #include "pism/util/error_handling.hh"
           28 #include "pism/pism_config.hh"
           29 
           30 #if (Pism_USE_PIO==1)
           31 // Why do I need this???
           32 #define _NETCDF
           33 #include <pio.h>
           34 #endif
           35 
           36 namespace pism {
           37 
           38 class Context::Impl {
           39 public:
           40   Impl(MPI_Comm c,
           41        UnitsSystemPtr sys,
           42        ConfigPtr conf,
           43        EnthalpyConverterPtr EC,
           44        TimePtr t,
           45        LoggerPtr log,
           46        const std::string &p)
           47     : com(c), unit_system(sys), config(conf), enthalpy_converter(EC), time(t), prefix(p),
           48       logger(log), pio_iosys_id(-1) {
           49     // empty
           50   }
           51   MPI_Comm com;
           52   UnitsSystemPtr unit_system;
           53   ConfigPtr config;
           54   EnthalpyConverterPtr enthalpy_converter;
           55   TimePtr time;
           56   std::string prefix;
           57   Profiling profiling;
           58   LoggerPtr logger;
           59   int pio_iosys_id;
           60 };
           61 
           62 Context::Context(MPI_Comm c, UnitsSystemPtr sys,
           63                  ConfigPtr config, EnthalpyConverterPtr EC, TimePtr t,
           64                  LoggerPtr L,
           65                  const std::string &p)
           66   : m_impl(new Impl(c, sys, config, EC, t, L, p)) {
           67   // empty
           68 }
           69 
           70 Context::~Context() {
           71 
           72 #if (Pism_USE_PIO==1)
           73   if (m_impl->pio_iosys_id != -1 and
           74       PIOc_free_iosystem(m_impl->pio_iosys_id) != PIO_NOERR) {
           75     m_impl->logger->message(1, "Error: failed to de-allocate a ParallelIO I/O system\n");
           76   }
           77 #endif
           78 
           79   delete m_impl;
           80 }
           81 
           82 MPI_Comm Context::com() const {
           83   return m_impl->com;
           84 }
           85 
           86 int Context::size() const {
           87   int S = 0;
           88   MPI_Comm_size(m_impl->com, &S);
           89   return S;
           90 }
           91 
           92 int Context::rank() const {
           93   int R = 0;
           94   MPI_Comm_rank(m_impl->com, &R);
           95   return R;
           96 }
           97 
           98 Context::UnitsSystemPtr Context::unit_system() const {
           99   return m_impl->unit_system;
          100 }
          101 
          102 Context::ConfigPtr Context::config() {
          103   return m_impl->config;
          104 }
          105 
          106 Context::ConstConfigPtr Context::config() const {
          107   return m_impl->config;
          108 }
          109 
          110 Context::EnthalpyConverterPtr Context::enthalpy_converter() const {
          111   return m_impl->enthalpy_converter;
          112 }
          113 
          114 Context::TimePtr Context::time() {
          115   return m_impl->time;
          116 }
          117 
          118 Context::ConstTimePtr Context::time() const {
          119   return m_impl->time;
          120 }
          121 
          122 const std::string& Context::prefix() const {
          123   return m_impl->prefix;
          124 }
          125 
          126 const Profiling& Context::profiling() const {
          127   return m_impl->profiling;
          128 }
          129 
          130 Context::ConstLoggerPtr Context::log() const {
          131   return m_impl->logger;
          132 }
          133 
          134 Context::LoggerPtr Context::log() {
          135   return m_impl->logger;
          136 }
          137 
          138 /*!
          139  * I/O system id (the ParallelIO library)
          140  */
          141 int Context::pio_iosys_id() const {
          142 #if (Pism_USE_PIO==1)
          143   if (m_impl->pio_iosys_id == -1) {
          144     int ierr = PIOc_set_iosystem_error_handling(PIO_DEFAULT, PIO_BCAST_ERROR, NULL);
          145     if (ierr != 0) {
          146       throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Failed to initialize ParallelIO");
          147     }
          148 
          149     int
          150       base      = config()->get_number("output.pio.base"),
          151       stride    = config()->get_number("output.pio.stride"),
          152       n_writers = config()->get_number("output.pio.n_writers");
          153 
          154     if (n_writers > this->size()) {
          155       throw RuntimeError::formatted(PISM_ERROR_LOCATION,
          156                                     "number of ParallelIO writers (%d)"
          157                                     " exceeds the communicator size (%d)",
          158                                     n_writers, this->size());
          159     }
          160 
          161     ierr = PIOc_Init_Intracomm(m_impl->com, n_writers, stride, base, PIO_REARR_BOX,
          162                                &m_impl->pio_iosys_id);
          163     if (ierr != 0) {
          164       throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Failed to initialize ParallelIO");
          165     }
          166   }
          167 #endif
          168   return m_impl->pio_iosys_id;
          169 }
          170 
          171 Context::Ptr context_from_options(MPI_Comm com, const std::string &prefix) {
          172   // unit system
          173   units::System::Ptr sys(new units::System);
          174 
          175   // logger
          176   Logger::Ptr logger = logger_from_options(com);
          177 
          178   // configuration parameters
          179   Config::Ptr config = config_from_options(com, *logger, sys);
          180   print_config(*logger, 3, *config);
          181 
          182   // time manager
          183   Time::Ptr time = time_from_options(com, config, sys);
          184 
          185   // enthalpy converter
          186   EnthalpyConverter::Ptr EC(new EnthalpyConverter(*config));
          187 
          188   return Context::Ptr(new Context(com, sys, config, EC, time, logger, prefix));
          189 }
          190 
          191 
          192 } // end of namespace pism