|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2009, 2010, 2011 Jed Brown, Ed Bueler and 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 #include "flowlaw_factory.hh" 00020 #include "pism_const.hh" 00021 00022 #undef ALEN 00023 #define ALEN(a) (sizeof(a)/sizeof(a)[0]) 00024 00025 IceFlowLawFactory::IceFlowLawFactory(MPI_Comm c,const char pre[], const NCConfigVariable &conf) : config(conf) 00026 { 00027 comm = c; 00028 prefix[0] = 0; 00029 if (pre) { 00030 PetscStrncpy(prefix,pre,sizeof(prefix)); 00031 } 00032 if (registerAll()) { 00033 PetscPrintf(comm,"IceFlowLawFactory::registerAll returned an error but we're in a constructor\n"); 00034 PISMEnd(); 00035 } 00036 if (setType(ICE_PB)) { // Set's a default type 00037 PetscPrintf(comm,"IceFlowLawFactory::setType(\"%s\") returned an error, but we're in a constructor\n",ICE_PB); 00038 PISMEnd(); 00039 } 00040 } 00041 00042 IceFlowLawFactory::~IceFlowLawFactory() 00043 { 00044 PetscFListDestroy(&type_list); 00045 } 00046 00047 #undef __FUNCT__ 00048 #define __FUNCT__ "IceFlowLawFactory::registerType" 00049 PetscErrorCode IceFlowLawFactory::registerType(const char tname[], 00050 PetscErrorCode(*icreate)(MPI_Comm,const char[],const NCConfigVariable &, IceFlowLaw**)) 00051 { 00052 PetscErrorCode ierr; 00053 00054 PetscFunctionBegin; 00055 ierr = PetscFListAdd(&type_list,tname,NULL,(void(*)(void))icreate);CHKERRQ(ierr); 00056 PetscFunctionReturn(0); 00057 } 00058 00059 00060 static PetscErrorCode create_custom(MPI_Comm comm,const char pre[], const NCConfigVariable &config, IceFlowLaw **i) { 00061 *i = new (CustomGlenIce)(comm, pre, config); return 0; 00062 } 00063 static PetscErrorCode create_pb(MPI_Comm comm,const char pre[], const NCConfigVariable &config, IceFlowLaw **i) { 00064 *i = new (ThermoGlenIce)(comm, pre, config); return 0; 00065 } 00066 static PetscErrorCode create_gpbld(MPI_Comm comm,const char pre[], const NCConfigVariable &config, IceFlowLaw **i) { 00067 *i = new (GPBLDIce)(comm, pre, config); return 0; 00068 } 00069 static PetscErrorCode create_hooke(MPI_Comm comm,const char pre[], const NCConfigVariable &config, IceFlowLaw **i) { 00070 *i = new (HookeIce)(comm, pre, config); return 0; 00071 } 00072 static PetscErrorCode create_arr(MPI_Comm comm,const char pre[], const NCConfigVariable &config, IceFlowLaw **i) { 00073 *i = new (ThermoGlenArrIce)(comm, pre, config); return 0; 00074 } 00075 static PetscErrorCode create_arrwarm(MPI_Comm comm,const char pre[], const NCConfigVariable &config, IceFlowLaw **i) { 00076 *i = new (ThermoGlenArrIceWarm)(comm, pre, config); return 0; 00077 } 00078 static PetscErrorCode create_hybrid(MPI_Comm comm,const char pre[], const NCConfigVariable &config, IceFlowLaw **i) { 00079 *i = new (HybridIce)(comm, pre, config); return 0; 00080 } 00081 00082 00083 #undef __FUNCT__ 00084 #define __FUNCT__ "IceFlowLawFactory::registerAll" 00085 PetscErrorCode IceFlowLawFactory::registerAll() 00086 { 00087 PetscErrorCode ierr; 00088 00089 PetscFunctionBegin; 00090 ierr = PetscMemzero(&type_list,sizeof(type_list));CHKERRQ(ierr); 00091 ierr = registerType(ICE_CUSTOM, &create_custom); CHKERRQ(ierr); 00092 ierr = registerType(ICE_PB, &create_pb); CHKERRQ(ierr); 00093 ierr = registerType(ICE_GPBLD, &create_gpbld); CHKERRQ(ierr); 00094 ierr = registerType(ICE_HOOKE, &create_hooke); CHKERRQ(ierr); 00095 ierr = registerType(ICE_ARR, &create_arr); CHKERRQ(ierr); 00096 ierr = registerType(ICE_ARRWARM,&create_arrwarm);CHKERRQ(ierr); 00097 ierr = registerType(ICE_HYBRID, &create_hybrid); CHKERRQ(ierr); 00098 PetscFunctionReturn(0); 00099 } 00100 00101 00102 #undef __FUNCT__ 00103 #define __FUNCT__ "IceFlowLawFactory::setType" 00104 PetscErrorCode IceFlowLawFactory::setType(const char type[]) 00105 { 00106 void (*r)(void); 00107 PetscErrorCode ierr; 00108 00109 PetscFunctionBegin; 00110 ierr = PetscFListFind(type_list,comm,type,(void(**)(void))&r);CHKERRQ(ierr); 00111 if (!r) { 00112 ierr = PetscPrintf(comm, "PISM ERROR: Selected ice type \"%s\" is not available.\n",type); CHKERRQ(ierr); 00113 PISMEnd(); 00114 } 00115 ierr = PetscStrncpy(type_name,type,sizeof(type_name));CHKERRQ(ierr); 00116 PetscFunctionReturn(0); 00117 } 00118 00119 #undef __FUNCT__ 00120 #define __FUNCT__ "IceFlowLawFactory::setFromOptions" 00121 PetscErrorCode IceFlowLawFactory::setFromOptions() 00122 { 00123 PetscErrorCode ierr; 00124 PetscTruth flg; 00125 char my_type_name[256]; 00126 00127 PetscFunctionBegin; 00128 // These options will choose Goldsby-Kohlstedt ice by default (see IceModel::setFromOptions()) but if a derived class 00129 // uses a different initialization procedure, we'll recognize them here as well. A better long-term solution would be 00130 // to separate tracking of grain size from a particular flow law (since in principle they are unrelated) but since 00131 // HYBRID is the only one that currently uses grain size, this solution is acceptable. 00132 ierr = PetscOptionsHasName(prefix, "-gk_age", &flg); CHKERRQ(ierr); 00133 if (flg) { 00134 ierr = setType(ICE_HYBRID);CHKERRQ(ierr); 00135 } 00136 // -gk 0 does not make sense, so using PetscOptionsHasName is OK. 00137 ierr = PetscOptionsHasName(prefix, "-gk", &flg); CHKERRQ(ierr); 00138 if (flg) { 00139 ierr = setType(ICE_HYBRID);CHKERRQ(ierr); 00140 } 00141 ierr = PetscOptionsBegin(comm,prefix,"IceFlowLawFactory options","IceFlowLaw");CHKERRQ(ierr); 00142 { 00143 ierr = PetscOptionsList("-ice_type","Ice type","IceFlowLawFactory::setType", 00144 type_list,type_name,my_type_name,sizeof(my_type_name),&flg);CHKERRQ(ierr); 00145 if (flg) {ierr = setType(my_type_name);CHKERRQ(ierr);} 00146 } 00147 ierr = PetscOptionsEnd();CHKERRQ(ierr); 00148 00149 // ierr = PetscPrintf(comm,"IceFlowLawFactory::type_name=%s at end of IceFlowLawFactory::setFromOptions()\n", 00150 // type_name); CHKERRQ(ierr); 00151 PetscFunctionReturn(0); 00152 } 00153 00154 00155 #undef __FUNCT__ 00156 #define __FUNCT__ "IceFlowLawFactory::create" 00157 PetscErrorCode IceFlowLawFactory::create(IceFlowLaw **inice) 00158 { 00159 PetscErrorCode ierr,(*r)(MPI_Comm,const char[],const NCConfigVariable &,IceFlowLaw**); 00160 IceFlowLaw *ice; 00161 00162 PetscFunctionBegin; 00163 PetscValidPointer(inice,3); 00164 *inice = 0; 00165 // find the function that can create selected ice type: 00166 ierr = PetscFListFind(type_list,comm,type_name,(void(**)(void))&r);CHKERRQ(ierr); 00167 if (!r) SETERRQ1(1,"Selected Ice type %s not available, but we shouldn't be able to get here anyway",type_name); 00168 // create an IceFlowLaw instance: 00169 ierr = (*r)(comm,prefix,config,&ice);CHKERRQ(ierr); 00170 *inice = ice; 00171 PetscFunctionReturn(0); 00172 }
1.7.3