Factory.cc (2849B)
1 /* Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 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 "Factory.hh" 21 22 // surface models: 23 #include "Anomaly.hh" 24 #include "Elevation.hh" 25 #include "GivenClimate.hh" 26 #include "ISMIP6Climate.hh" 27 #include "ElevationChange.hh" 28 #include "Delta_T.hh" 29 #include "TemperatureIndex.hh" 30 #include "Simple.hh" 31 #include "ConstantPIK.hh" 32 #include "ForceThickness.hh" 33 #include "Cache.hh" 34 35 36 namespace pism { 37 namespace surface { 38 39 Factory::Factory(IceGrid::ConstPtr g, std::shared_ptr<atmosphere::AtmosphereModel> input) 40 : PCFactory<SurfaceModel>(g, "surface.models"), 41 m_input(input) { 42 43 add_surface_model<Elevation>("elevation"); 44 add_surface_model<Given>("given"); 45 add_surface_model<ISMIP6>("ismip6"); 46 add_surface_model<TemperatureIndex>("pdd"); 47 add_surface_model<PIK>("pik"); 48 add_surface_model<Simple>("simple"); 49 50 add_modifier<Anomaly>("anomaly"); 51 add_modifier<Cache>("cache"); 52 add_modifier<Delta_T>("delta_T"); 53 add_modifier<ForceThickness>("forcing"); 54 add_modifier<ElevationChange>("elevation_change"); 55 } 56 57 Factory::~Factory() { 58 // empty 59 } 60 61 std::shared_ptr<SurfaceModel> Factory::create(const std::string &type) { 62 63 std::vector<std::string> choices = split(type, ','); 64 65 // the first element has to be an *actual* model (not a modifier) 66 auto j = choices.begin(); 67 68 auto result = surface_model(*j, m_input); 69 70 ++j; 71 72 // process remaining arguments: 73 for (;j != choices.end(); ++j) { 74 result = modifier(*j, result); 75 } 76 77 return result; 78 } 79 80 std::shared_ptr<SurfaceModel> Factory::surface_model(const std::string &type, 81 std::shared_ptr<InputModel> input) { 82 if (m_surface_models.find(type) == m_surface_models.end()) { 83 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "cannot allocate %s \"%s\".\n" 84 "Available models: %s\n", 85 m_parameter.c_str(), type.c_str(), 86 key_list(m_surface_models).c_str()); 87 } 88 89 return m_surface_models[type]->create(m_grid, input); 90 } 91 92 } // end of namespace surface 93 } // end of namespace pism