tPCFactory.hh - 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
---
tPCFactory.hh (4712B)
---
1 // Copyright (C) 2011, 2013, 2014, 2015, 2016, 2017, 2018, 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 #ifndef _PCFACTORY_H_
20 #define _PCFACTORY_H_
21
22 #include <memory>
23 #include <map>
24
25 #include "pism/util/IceGrid.hh"
26 #include "pism/util/error_handling.hh"
27 #include "pism/util/pism_utilities.hh"
28 #include "pism/util/ConfigInterface.hh"
29
30 namespace pism {
31
32 template <class Model>
33 class PCFactory {
34 public:
35
36 PCFactory<Model>(IceGrid::ConstPtr g, const std::string ¶meter)
37 : m_parameter(parameter), m_grid(g) {}
38 ~PCFactory<Model>() {}
39
40 //! Creates a boundary model. Processes command-line options.
41 virtual std::shared_ptr<Model> create() {
42
43 auto choices = m_grid->ctx()->config()->get_string(m_parameter);
44
45 return create(choices);
46 }
47
48 //! Creates a boundary model.
49 virtual std::shared_ptr<Model> create(const std::string &type) {
50
51 std::vector<std::string> choices = split(type, ',');
52
53 // the first element has to be an *actual* model (not a modifier)
54 auto j = choices.begin();
55
56 auto result = model(*j);
57
58 ++j;
59
60 // process remaining arguments:
61 for (;j != choices.end(); ++j) {
62 result = modifier(*j, result);
63 }
64
65 return result;
66 }
67
68 protected:
69
70 //! Adds a boundary model to the dictionary.
71 template <class M>
72 void add_model(const std::string &name) {
73 m_models[name].reset(new SpecificModelCreator<M>);
74 }
75
76 template <class M>
77 void add_modifier(const std::string &name) {
78 m_modifiers[name].reset(new SpecificModifierCreator<M>);
79 }
80
81 template<typename T>
82 std::string key_list(std::map<std::string, T> list) {
83 std::vector<std::string> keys;
84
85 for (auto i : list) {
86 keys.push_back(i.first);
87 }
88
89 return "[" + join(keys, ", ") + "]";
90 }
91
92 std::shared_ptr<Model> model(const std::string &type) {
93 if (m_models.find(type) == m_models.end()) {
94 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "cannot allocate %s \"%s\".\n"
95 "Available models: %s\n",
96 m_parameter.c_str(), type.c_str(),
97 key_list(m_models).c_str());
98 }
99
100 return m_models[type]->create(m_grid);
101 }
102
103 template<class T>
104 std::shared_ptr<Model> modifier(const std::string &type, std::shared_ptr<T> input) {
105 if (m_modifiers.find(type) == m_modifiers.end()) {
106 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "cannot allocate %s modifier \"%s\".\n"
107 "Available modifiers: %s\n",
108 m_parameter.c_str(), type.c_str(),
109 key_list(m_modifiers).c_str());
110 }
111
112 return m_modifiers[type]->create(m_grid, input);
113 }
114
115 // virtual base class that allows storing different model creators
116 // in the same dictionary
117 class ModelCreator {
118 public:
119 virtual std::shared_ptr<Model> create(IceGrid::ConstPtr g) = 0;
120 virtual ~ModelCreator() {}
121 };
122
123 // Creator for a specific model class M.
124 template <class M>
125 class SpecificModelCreator : public ModelCreator {
126 public:
127 std::shared_ptr<Model> create(IceGrid::ConstPtr g) {
128 return std::shared_ptr<Model>(new M(g));
129 }
130 };
131
132 // virtual base class that allows storing different modifier
133 // creators in the same dictionary
134 class ModifierCreator {
135 public:
136 virtual std::shared_ptr<Model> create(IceGrid::ConstPtr g, std::shared_ptr<Model> input) = 0;
137 virtual ~ModifierCreator() {}
138 };
139
140 // Creator for a specific modifier class M.
141 template <class M>
142 class SpecificModifierCreator : public ModifierCreator {
143 public:
144 std::shared_ptr<Model> create(IceGrid::ConstPtr g, std::shared_ptr<Model> input) {
145 return std::shared_ptr<Model>(new M(g, input));
146 }
147 };
148
149 std::string m_parameter;
150 std::map<std::string, std::shared_ptr<ModelCreator> > m_models;
151 std::map<std::string, std::shared_ptr<ModifierCreator> > m_modifiers;
152 IceGrid::ConstPtr m_grid;
153 };
154
155 } // end of namespace pism
156
157 #endif /* _PCFACTORY_H_ */