|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2010, 2011 Constantine Khroulev 00002 // 00003 // This file is part of PISM. 00004 // 00005 // PISM is free software; you can redistribute it and/or modify it under the 00006 // terms of the GNU General Public License as published by the Free Software 00007 // Foundation; either version 2 of the License, or (at your option) any later 00008 // version. 00009 // 00010 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY 00011 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00012 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00013 // details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with PISM; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 // Implementation of "surface", "atmosphere" and "ocean" model factories: C++ 00020 // classes processing -surface, -atmosphere and -ocean command-line options, 00021 // creating corresponding models and stringing them together to get requested 00022 // data-flow. 00023 00024 #include "PISMAtmosphere.hh" 00025 #include "PISMSurface.hh" 00026 #include "PISMOcean.hh" 00027 #include <map> 00028 00029 template <class Model, class Modifier> 00030 class PCFactory { 00031 public: 00032 PCFactory<Model,Modifier>(IceGrid& g, const NCConfigVariable& conf) 00033 : grid(g), config(conf) {} 00034 virtual ~PCFactory<Model,Modifier>() {} 00035 00037 virtual PetscErrorCode set_default(string name) { 00038 void (*func) (IceGrid&, const NCConfigVariable&, Model*&); 00039 00040 func = models[name]; 00041 if (!func) { 00042 SETERRQ1(1,"ERROR: type %s is not registered", name.c_str()); 00043 } else { 00044 default_type = name; 00045 } 00046 return 0; 00047 } 00048 00050 virtual PetscErrorCode create(Model* &result) { 00051 void (*F) (IceGrid&, const NCConfigVariable&, Model*&); 00052 PetscErrorCode ierr; 00053 vector<string> choices; 00054 string model_list, modifier_list, descr; 00055 bool flag = false; 00056 00057 // build a list of available models: 00058 typename map<string,void(*)(IceGrid&, const NCConfigVariable&, Model*&)>::iterator k; 00059 k = models.begin(); 00060 model_list = "[" + (k++)->first; 00061 for(; k != models.end(); k++) { 00062 model_list += ", " + k->first; 00063 } 00064 model_list += "]"; 00065 00066 // build a list of available modifiers: 00067 typename map<string,void(*)(IceGrid&, const NCConfigVariable&, Model*, Modifier*&)>::iterator p; 00068 p = modifiers.begin(); 00069 modifier_list = "[" + (p++)->first; 00070 for(; p != modifiers.end(); p++) { 00071 modifier_list += ", " + p->first; 00072 } 00073 modifier_list += "]"; 00074 00075 descr = "Sets up the PISM " + option + " model. Available models: " + model_list + 00076 " Available modifiers: " + modifier_list; 00077 00078 // Get the command-line option: 00079 ierr = PISMOptionsStringArray("-" + option, descr, default_type.c_str(), choices, flag); CHKERRQ(ierr); 00080 00081 if (choices.empty()) { 00082 if (flag) { 00083 PetscPrintf(grid.com, "ERROR: option -%s requires an argument.\n", option.c_str()); 00084 PISMEnd(); 00085 } 00086 choices.push_back(default_type); 00087 } 00088 00089 // the first element has to be an *actual* model (not a modifier), so we 00090 // create it: 00091 vector<string>::iterator j = choices.begin(); 00092 00093 F = models[*j]; 00094 if (!F) { 00095 PetscPrintf(grid.com, 00096 "ERROR: %s model \"%s\" is not available.\n" 00097 " Available models: %s\n" 00098 " Available modifiers: %s\n", 00099 option.c_str(), j->c_str(), 00100 model_list.c_str(), modifier_list.c_str()); 00101 PISMEnd(); 00102 } 00103 00104 (*F)(grid, config, result); 00105 00106 ++j; 00107 00108 // process remaining arguments: 00109 while (j != choices.end()) { 00110 void (*M) (IceGrid&, const NCConfigVariable&, Model*, Modifier*&); 00111 Modifier *mod; 00112 00113 M = modifiers[*j]; 00114 if (!M) { 00115 PetscPrintf(grid.com, 00116 "ERROR: %s modifier \"%s\" is not available.\n" 00117 " Available modifiers: %s\n", 00118 option.c_str(), j->c_str(), modifier_list.c_str()); 00119 PISMEnd(); 00120 } 00121 00122 (*M)(grid, config, result, mod); 00123 00124 result = mod; 00125 00126 ++j; 00127 } 00128 00129 return 0; 00130 } 00131 00133 virtual void add_model(string name, void(*func)(IceGrid&, const NCConfigVariable&, Model*&)) { 00134 models[name] = func; 00135 } 00136 00137 virtual void add_modifier(string name, void(*func)(IceGrid&, const NCConfigVariable&, Model*, Modifier*&)) { 00138 modifiers[name] = func; 00139 } 00140 00142 virtual void remove_model(string name) { 00143 models.erase(name); 00144 } 00145 00146 virtual void remove_modifier(string name) { 00147 modifiers.erase(name); 00148 } 00149 00151 virtual void clear_models() { 00152 models.clear(); 00153 } 00154 00155 virtual void clear_modifiers() { 00156 modifiers.clear(); 00157 } 00158 protected: 00159 virtual void add_standard_types() {} 00160 string default_type, option; 00161 map<string,void(*)(IceGrid&, const NCConfigVariable&, Model*&)> models; 00162 map<string,void(*)(IceGrid&, const NCConfigVariable&, Model*, Modifier*&)> modifiers; 00163 IceGrid& grid; 00164 const NCConfigVariable& config; 00165 }; 00166 00167 class PAFactory : public PCFactory<PISMAtmosphereModel,PAModifier> { 00168 public: 00169 PAFactory(IceGrid& g, const NCConfigVariable& conf) 00170 : PCFactory<PISMAtmosphereModel,PAModifier>(g, conf) 00171 { 00172 add_standard_types(); 00173 option = "atmosphere"; 00174 } 00175 virtual ~PAFactory() {} 00176 virtual void add_standard_types(); 00177 }; 00178 00179 class PSFactory : public PCFactory<PISMSurfaceModel,PSModifier> { 00180 public: 00181 PSFactory(IceGrid& g, const NCConfigVariable& conf) 00182 : PCFactory<PISMSurfaceModel,PSModifier>(g, conf) 00183 { 00184 add_standard_types(); 00185 option = "surface"; 00186 } 00187 00188 virtual ~PSFactory() {} 00189 virtual void add_standard_types(); 00190 }; 00191 00192 class POFactory : public PCFactory<PISMOceanModel,POModifier> { 00193 public: 00194 POFactory(IceGrid& g, const NCConfigVariable& conf) 00195 : PCFactory<PISMOceanModel,POModifier>(g, conf) 00196 { 00197 add_standard_types(); 00198 option = "ocean"; 00199 } 00200 virtual ~POFactory() {} 00201 virtual void add_standard_types(); 00202 };
1.7.3