Changeset 23783
- Timestamp:
- 03/08/19 14:58:19 (6 years ago)
- Location:
- issm/trunk-jpl/src/m
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/classes/constants.py
r22267 r23783 49 49 def checkconsistency(self,md,solution,analyses): # {{{ 50 50 51 md = checkfield(md,'fieldname','constants.g','>=',0,'size',[1 ,1])52 md = checkfield(md,'fieldname','constants.omega','>=',0,'size',[1 ,1])53 md = checkfield(md,'fieldname','constants.yts','>',0,'size',[1 ,1])54 md = checkfield(md,'fieldname','constants.referencetemperature','size',[1 ,1])51 md = checkfield(md,'fieldname','constants.g','>=',0,'size',[1]) 52 md = checkfield(md,'fieldname','constants.omega','>=',0,'size',[1]) 53 md = checkfield(md,'fieldname','constants.yts','>',0,'size',[1]) 54 md = checkfield(md,'fieldname','constants.referencetemperature','size',[1]) 55 55 56 56 return md -
issm/trunk-jpl/src/m/classes/transient.py
r23770 r23783 4 4 5 5 class transient(object): 6 7 6 """ 7 TRANSIENT class definition 8 8 9 10 11 9 Usage: 10 transient=transient(); 11 """ 12 12 13 14 self.issmb= False15 16 17 18 19 20 21 22 23 24 25 26 27 28 13 def __init__(self): # {{{ 14 self.issmb = False 15 self.ismasstransport = False 16 self.isstressbalance = False 17 self.isthermal = False 18 self.isgroundingline = False 19 self.isgia = False 20 self.isesa = False 21 self.isdamageevolution = False 22 self.ismovingfront = False 23 self.ishydrology = False 24 self.isslr = False 25 self.iscoupler = False 26 self.amr_frequency = 0 27 self.isoceancoupling = False 28 self.requested_outputs = [] 29 29 30 31 30 #set defaults 31 self.setdefaultparameters() 32 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 33 #}}} 34 def __repr__(self): # {{{ 35 string=' transient solution parameters:' 36 string="%s\n%s"%(string,fielddisplay(self,'issmb','indicates if a surface mass balance solution is used in the transient')) 37 string="%s\n%s"%(string,fielddisplay(self,'ismasstransport','indicates if a masstransport solution is used in the transient')) 38 string="%s\n%s"%(string,fielddisplay(self,'isstressbalance','indicates if a stressbalance solution is used in the transient')) 39 string="%s\n%s"%(string,fielddisplay(self,'isthermal','indicates if a thermal solution is used in the transient')) 40 string="%s\n%s"%(string,fielddisplay(self,'isgroundingline','indicates if a groundingline migration is used in the transient')) 41 string="%s\n%s"%(string,fielddisplay(self,'isgia','indicates if a postglacial rebound is used in the transient')) 42 string="%s\n%s"%(string,fielddisplay(self,'isesa','indicates whether an elastic adjustment model is used in the transient')) 43 string="%s\n%s"%(string,fielddisplay(self,'isdamageevolution','indicates whether damage evolution is used in the transient')) 44 string="%s\n%s"%(string,fielddisplay(self,'ismovingfront','indicates whether a moving front capability is used in the transient')) 45 string="%s\n%s"%(string,fielddisplay(self,'ishydrology','indicates whether an hydrology model is used')) 46 string="%s\n%s"%(string,fielddisplay(self,'isslr','indicates if a sea level rise solution is used in the transient')) 47 string="%s\n%s"%(string,fielddisplay(self,'isoceancoupling','indicates whether coupling with an ocean model is used in the transient')) 48 string="%s\n%s"%(string,fielddisplay(self,'iscoupler','indicates whether different models are being run with need for coupling')) 49 string="%s\n%s"%(string,fielddisplay(self,'amr_frequency','frequency at which mesh is refined in simulations with multiple time_steps')) 50 string="%s\n%s"%(string,fielddisplay(self,'requested_outputs','list of additional outputs requested')) 51 return string 52 #}}} 53 def defaultoutputs(self,md): # {{{ 54 54 55 56 57 58 55 if self.issmb: 56 return ['SmbMassBalance'] 57 else: 58 return [] 59 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 self.amr_frequency= 060 #}}} 61 def setallnullparameters(self): # {{{ 62 63 #Nothing done 64 self.issmb = False 65 self.ismasstransport = False 66 self.isstressbalance = False 67 self.isthermal = False 68 self.isgroundingline = False 69 self.isgia = False 70 self.isesa = False 71 self.isdamageevolution = False 72 self.ismovingfront = False 73 self.ishydrology = False 74 self.isoceancoupling = False 75 self.isslr = False 76 self.iscoupler = False 77 self.amr_frequency = 0 78 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 79 #default output 80 self.requested_outputs=[] 81 return self 82 #}}} 83 def deactivateall(self):#{{{ 84 self.issmb = False 85 self.ismasstransport = False 86 self.isstressbalance = False 87 self.isthermal = False 88 self.isgroundingline = False 89 self.isgia = False 90 self.isesa = False 91 self.isdamageevolution = False 92 self.ismovingfront = False 93 self.ishydrology = False 94 self.isslr = False 95 self.isoceancoupling = False 96 self.iscoupler = False 97 self.amr_frequency = 0 98 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 99 #default output 100 self.requested_outputs=[] 101 return self 102 #}}} 103 def setdefaultparameters(self): # {{{ 104 105 #full analysis: Stressbalance, Masstransport and Thermal but no groundingline migration for now 106 self.issmb = True 107 self.ismasstransport = True 108 self.isstressbalance = True 109 self.isthermal = True 110 self.isgroundingline = False 111 self.isgia = False 112 self.isesa = False 113 self.isdamageevolution = False 114 self.ismovingfront = False 115 self.ishydrology = False 116 self.isslr = False 117 self.isoceancoupling = False 118 self.iscoupler = False 119 self.amr_frequency = 0 120 120 121 122 123 124 125 121 #default output 122 self.requested_outputs=['default'] 123 return self 124 #}}} 125 def checkconsistency(self,md,solution,analyses): # {{{ 126 126 127 128 129 127 #Early return 128 if not solution=='TransientSolution': 129 return md 130 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 131 md = checkfield(md,'fieldname','transient.issmb','numel',[1],'values',[0,1]) 132 md = checkfield(md,'fieldname','transient.ismasstransport','numel',[1],'values',[0,1]) 133 md = checkfield(md,'fieldname','transient.isstressbalance','numel',[1],'values',[0,1]) 134 md = checkfield(md,'fieldname','transient.isthermal','numel',[1],'values',[0,1]) 135 md = checkfield(md,'fieldname','transient.isgroundingline','numel',[1],'values',[0,1]) 136 md = checkfield(md,'fieldname','transient.isgia','numel',[1],'values',[0,1]) 137 md = checkfield(md,'fieldname','transient.isesa','numel',[1],'values',[0,1]) 138 md = checkfield(md,'fieldname','transient.isdamageevolution','numel',[1],'values',[0,1]) 139 md = checkfield(md,'fieldname','transient.ishydrology','numel',[1],'values',[0,1]) 140 md = checkfield(md,'fieldname','transient.ismovingfront','numel',[1],'values',[0,1]); 141 md = checkfield(md,'fieldname','transient.isslr','numel',[1],'values',[0,1]) 142 md = checkfield(md,'fieldname','transient.isoceancoupling','numel',[1],'values',[0,1]) 143 md = checkfield(md,'fieldname','transient.iscoupler','numel',[1],'values',[0,1]) 144 md = checkfield(md,'fieldname','transient.amr_frequency','numel',[1],'>=',0,'NaN',1,'Inf',1) 145 md = checkfield(md,'fieldname','transient.requested_outputs','stringrow',1) 146 146 147 148 149 150 147 if (solution!='TransientSolution') and (md.transient.iscoupling): 148 md.checkmessage("Coupling with ocean can only be done in transient simulations!") 149 if (md.transient.isdamageevolution and not hasattr(md.materials,'matdamageice')): 150 md.checkmessage("requesting damage evolution but md.materials is not of class matdamageice") 151 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 152 return md 153 # }}} 154 def marshall(self,prefix,md,fid): # {{{ 155 WriteData(fid,prefix,'object',self,'fieldname','issmb','format','Boolean') 156 WriteData(fid,prefix,'object',self,'fieldname','ismasstransport','format','Boolean') 157 WriteData(fid,prefix,'object',self,'fieldname','isstressbalance','format','Boolean') 158 WriteData(fid,prefix,'object',self,'fieldname','isthermal','format','Boolean') 159 WriteData(fid,prefix,'object',self,'fieldname','isgroundingline','format','Boolean') 160 WriteData(fid,prefix,'object',self,'fieldname','isgia','format','Boolean') 161 WriteData(fid,prefix,'object',self,'fieldname','isesa','format','Boolean') 162 WriteData(fid,prefix,'object',self,'fieldname','isdamageevolution','format','Boolean') 163 WriteData(fid,prefix,'object',self,'fieldname','ishydrology','format','Boolean') 164 WriteData(fid,prefix,'object',self,'fieldname','ismovingfront','format','Boolean') 165 WriteData(fid,prefix,'object',self,'fieldname','isslr','format','Boolean') 166 WriteData(fid,prefix,'object',self,'fieldname','isoceancoupling','format','Boolean') 167 WriteData(fid,prefix,'object',self,'fieldname','iscoupler','format','Boolean') 168 WriteData(fid,prefix,'object',self,'fieldname','amr_frequency','format','Integer') 169 169 170 171 172 173 174 175 176 177 170 #process requested outputs 171 outputs = self.requested_outputs 172 indices = [i for i, x in enumerate(outputs) if x == 'default'] 173 if len(indices) > 0: 174 outputscopy=outputs[0:max(0,indices[0]-1)]+self.defaultoutputs(md)+outputs[indices[0]+1:] 175 outputs =outputscopy 176 WriteData(fid,prefix,'data',outputs,'name','md.transient.requested_outputs','format','StringArray') 177 # }}} -
issm/trunk-jpl/src/m/consistency/checkfield.m
r23773 r23783 98 98 for i=1:numel(fieldsize) 99 99 if ~isnan(fieldsize(i)) & (size(field,i)~=fieldsize(i)) 100 md = checkmessage(md,getfieldvalue(options,'message',['field ''' fieldname ''' dimension # ' num2str(i) ' should be of size ' num2str(fieldsize( 2))]));100 md = checkmessage(md,getfieldvalue(options,'message',['field ''' fieldname ''' dimension # ' num2str(i) ' should be of size ' num2str(fieldsize(i))])); 101 101 end 102 102 end -
issm/trunk-jpl/src/m/consistency/checkfield.py
r23761 r23783 7 7 8 8 def checkfield(md,*args): 9 10 11 12 13 14 9 """ 10 CHECKFIELD - check field consistency 11 12 Used to check model consistency., 13 Requires: 14 'field' or 'fieldname' option. If 'fieldname' is provided, it will retrieve it from the model md. (md.(fieldname)) 15 15 If 'field' is provided, it will assume the argument following 'field' is a numeric array. 16 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 17 Available options: 18 - NaN: 1 if check that there is no NaN 19 - size: [lines cols], NaN for non checked dimensions, or 'universal' for any input type (nodal, element, time series, etc) 20 - >: greater than provided value 21 - >=: greater or equal to provided value 22 - <: smallerthan provided value 23 - <=: smaller or equal to provided value 24 - < vec: smallerthan provided values on each vertex 25 - timeseries: 1 if check time series consistency (size and time) 26 - values: cell of strings or vector of acceptable values 27 - numel: list of acceptable number of elements 28 - cell: 1 if check that is cell 29 - empty: 1 if check that non empty 30 - message: overloaded error message 31 32 Usage: 33 md = checkfield(md,fieldname,options); 34 """ 35 36 #get options 37 options=pairoptions(*args) 38 39 #get field from model 40 if options.exist('field'): 41 field=options.getfieldvalue('field') 42 fieldname=options.getfieldvalue('fieldname','no fieldname') 43 else: 44 fieldname=options.getfieldvalue('fieldname') 45 fieldprefix=split(r'\[(.*?)\]',fieldname)[0] 46 fieldindexes=findall(r'\[(.*?)\]',fieldname) 47 field=attrgetter(fieldprefix)(md) 48 for index in fieldindexes: 49 try: 50 field=field[index.strip("\'")] 51 except TypeError: 52 field=field[int(index)] #looking for an index and not a key 53 53 54 54 # that works for py2 55 # exec("field=md.{}".format(fieldname)) 56 # exec("field=md.{}".format(fieldname),namespace) 57 58 59 if isinstance(field,(bool,int,float)): 60 field=np.array([field]) 61 62 #check empty 63 if options.exist('empty'): 64 if not field: 65 md = md.checkmessage(options.getfieldvalue('message', 66 "field '%s' is empty" % fieldname)) 67 68 #Check size 69 if options.exist('size'): 70 fieldsize=options.getfieldvalue('size') 71 if type(fieldsize) == str: 72 if m.strcmp(fieldsize,'universal'): 73 74 #Check that vector size will not be confusing for ModelProcessorx 75 if (md.mesh.numberofvertices==md.mesh.numberofelements): 76 raise RuntimeError('number of vertices is the same as number of elements') 77 elif (md.mesh.numberofvertices+1==md.mesh.numberofelements): 78 raise RuntimeError('number of vertices +1 is the same as number of elements') 79 elif (md.mesh.numberofvertices==md.mesh.numberofelements+1): 80 raise RuntimeError('number of vertices is the same as number of elements +1') 81 82 #Uniform field 83 if (np.size(field,0)==1): 84 if (np.shape(field,1)!=1): 85 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 86 87 #vertex oriented input, only one column allowed 88 elif (np.shape(field,0)==md.mesh.numberofvertices): 89 if (np.shape(field,1)!=1): 90 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 91 92 #element oriented input, one or more column (patch) is ok 93 elif (np.shape(field,0)==md.mesh.numberofelements): 94 pass 95 #nothing to do here (either constant per element, or defined on nodes) 96 97 #vertex time series 98 elif (np.shape(field,0)==md.mesh.numberofvertices+1): 99 if (np.shape(field,1)<=1): 100 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 101 102 #element time series 103 elif (np.shape(field,0)==md.mesh.numberofelements+1): 104 if (np.shape(field,1)<=1): 105 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 106 107 #else not supported 108 else: 109 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 110 111 else: 112 raise RuntimeError("fieldsize '{}' not supported yet".format(fieldsize)) 113 114 else: 115 if len(fieldsize) == 1: 116 if np.isnan(fieldsize[0]): 117 pass 118 elif np.ndim(field)==1: 119 if not np.size(field)==fieldsize[0]: 120 md = md.checkmessage(options.getfieldvalue('message',"field {} size should be {}".format(fieldname,fieldsize[0]))) 121 else: 122 try: 123 exec("md.{}=np.squeeze(field)".format(fieldname)) 124 print(("{} had been squeezed if it was a matrix with only one column".format(fieldname))) 125 except IndexError: 126 md = md.checkmessage(options.getfieldvalue('message',"field {} should have {} dimension".format(fieldname,len(fieldsize)))) 127 elif len(fieldsize) == 2: 128 if np.isnan(fieldsize[0]): 129 if not np.size(field,1)==fieldsize[1]: 130 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have %d columns" % (fieldname,fieldsize[1]))) 131 elif np.isnan(fieldsize[1]): 132 if not np.size(field,0)==fieldsize[0]: 133 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have %d lines" % (fieldname,fieldsize[0]))) 134 elif fieldsize[1]==1: 135 if (not np.size(field,0)==fieldsize[0]): 136 md = md.checkmessage(options.getfieldvalue('message',"field '%s' size should be %d x %d" % (fieldname,fieldsize[0],fieldsize[1]))) 137 else: 138 if (not np.size(field,0)==fieldsize[0]) or (not np.size(field,1)==fieldsize[1]): 139 md = md.checkmessage(options.getfieldvalue('message',"field '%s' size should be %d x %d" % (fieldname,fieldsize[0],fieldsize[1]))) 140 141 #Check numel 142 if options.exist('numel'): 143 fieldnumel=options.getfieldvalue('numel') 144 if (type(fieldnumel) == int and np.size(field) != fieldnumel) or (type(fieldnumel) == list and np.size(field) not in fieldnumel): 145 if len(fieldnumel)==1: 146 md = md.checkmessage(options.getfieldvalue('message',\ 147 "field '%s' size should be %d" % (fieldname,fieldnumel))) 148 elif len(fieldnumel)==2: 149 md = md.checkmessage(options.getfieldvalue('message',\ 150 "field '%s' size should be %d or %d" % (fieldname,fieldnumel[0],fieldnumel[1]))) 151 else: 152 md = md.checkmessage(options.getfieldvalue('message',\ 153 "field '%s' size should be %s" % (fieldname,fieldnumel))) 154 155 #check NaN 156 if options.getfieldvalue('NaN',0): 157 if np.any(np.isnan(field)): 158 md = md.checkmessage(options.getfieldvalue('message',\ 159 "NaN values found in field '%s'" % fieldname)) 160 161 162 #check Inf 163 if options.getfieldvalue('Inf',0): 164 if np.any(np.isinf(field)): 165 md = md.checkmessage(options.getfieldvalue('message',\ 166 "Inf values found in field '%s'" % fieldname)) 167 168 169 #check cell 170 if options.getfieldvalue('cell',0): 171 if not isinstance(field,(tuple,list,dict)): 172 md = md.checkmessage(options.getfieldvalue('message',\ 173 "field '%s' should be a cell" % fieldname)) 174 175 #check values 176 if options.exist('values'): 177 fieldvalues=options.getfieldvalue('values') 178 if False in m.ismember(field,fieldvalues): 179 if len(fieldvalues)==1: 180 md = md.checkmessage(options.getfieldvalue('message',\ 181 "field '%s' value should be '%s'" % (fieldname,fieldvalues[0]))) 182 elif len(fieldvalues)==2: 183 md = md.checkmessage(options.getfieldvalue('message',\ 184 "field '%s' values should be '%s' or '%s'" % (fieldname,fieldvalues[0],fieldvalues[1]))) 185 else: 186 md = md.checkmessage(options.getfieldvalue('message',\ 187 "field '%s' should have values in %s" % (fieldname,fieldvalues))) 188 189 #check greater 190 if options.exist('>='): 191 lowerbound = options.getfieldvalue('>=') 192 if type(lowerbound) is str: 193 lowerbound=attrgetter(lowerbound)(md) 194 if np.size(lowerbound)>1: #checking elementwise 195 if any(field<upperbound): 196 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 197 else: 198 minval=np.nanmin(field) 199 if options.getfieldvalue('timeseries',0): 200 minval=np.nanmin(field[:-1]) 201 elif options.getfieldvalue('singletimeseries',0): 202 if np.size(field)==1: #some singletimeseries are just one value 203 minval=field 204 else: 205 minval=np.nanmin(field[0]) 206 207 if minval<lowerbound: 208 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values above %d" % (fieldname,lowerbound))) 209 210 if options.exist('>'): 211 lowerbound=options.getfieldvalue('>') 212 if type(lowerbound) is str: 213 lowerbound=attrgetter(lowerbound)(md) 214 if np.size(lowerbound)>1: #checking elementwise 215 if any(field<=upperbound): 216 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 217 else: 218 minval=np.nanmin(field) 219 if options.getfieldvalue('timeseries',0) : 220 minval=np.nanmin(field[:-1]) 221 elif options.getfieldvalue('singletimeseries',0): 222 if np.size(field)==1: #some singletimeseries are just one value 223 minval=field 224 else: 225 minval=np.nanmin(field[0]) 226 227 if minval<=lowerbound: 228 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values above %d" % (fieldname,lowerbound))) 229 230 #check smaller 231 if options.exist('<='): 232 upperbound=options.getfieldvalue('<=') 233 if type(upperbound) is str: 234 upperbound=attrgetter(upperbound)(md) 235 if np.size(upperbound)>1: #checking elementwise 236 if any(field>upperbound): 237 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 238 else: 239 maxval=np.nanmax(field) 240 if options.getfieldvalue('timeseries',0): 241 maxval=np.nanmax(field[:-1]) 242 elif options.getfieldvalue('singletimeseries',0): 243 if np.size(field)==1: #some singletimeseries are just one value 244 maxval=field 245 else: 246 maxval=np.nanmax(field[0]) 247 elif hasattr(field, 'fov_forward_indices'): 248 maxval=field.fov_forward_indices[0] 249 if maxval>upperbound: 250 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 251 252 if options.exist('<'): 253 upperbound=options.getfieldvalue('<') 254 if type(upperbound) is str: 255 upperbound=attrgetter(upperbound)(md) 256 if np.size(upperbound)>1: #checking elementwise 257 if any(field>=upperbound): 258 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 259 260 else: 261 maxval=np.nanmax(field) 262 if options.getfieldvalue('timeseries',0): 263 maxval=np.nanmax(field[:-1]) 264 elif options.getfieldvalue('singletimeseries',0): 265 if np.size(field)==1: #some singletimeseries are just one value 266 maxval=field.copy() 267 else: 268 maxval=np.nanmax(field[0]) 269 270 if maxval>=upperbound: 271 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 272 273 #check file 274 if options.getfieldvalue('file',0): 275 if not os.path.exists(field): 276 md = md.checkmessage("file provided in '%s': '%s' does not exist" % (fieldname,field)) 277 278 #Check row of strings 279 if options.exist('stringrow'): 280 if not isinstance(field,list): 281 md = md.checkmessage(options.getfieldvalue('message',\ 282 "field '%s' should be a list" %fieldname)) 283 284 #Check forcings (size and times) 285 if options.getfieldvalue('timeseries',0): 286 if np.size(field,0)==md.mesh.numberofvertices or np.size(field,0)==md.mesh.numberofelements: 287 if np.ndim(field)>1 and not np.size(field,1)==1: 288 md = md.checkmessage(options.getfieldvalue('message',\ 289 "field '%s' should have only one column as there are md.mesh.numberofvertices lines" % fieldname)) 290 elif np.size(field,0)==md.mesh.numberofvertices+1 or np.size(field,0)==md.mesh.numberofelements+1: 291 if np.ndim(field) > 1 and not all(field[-1,:]==np.sort(field[-1,:])): 292 md = md.checkmessage(options.getfieldvalue('message',\ 293 "field '%s' columns should be sorted chronologically" % fieldname)) 294 if np.ndim(field) > 1 and any(field[-1,0:-1]==field[-1,1:]): 295 md = md.checkmessage(options.getfieldvalue('message',\ 296 "field '%s' columns must not contain duplicate timesteps" % fieldname)) 297 else: 298 md = md.checkmessage(options.getfieldvalue('message',\ 299 "field '%s' should have md.mesh.numberofvertices or md.mesh.numberofvertices+1 lines" % fieldname)) 300 301 #Check single value forcings (size and times) 302 if options.getfieldvalue('singletimeseries',0): 303 if np.size(field,0)==2: 304 if not all(field[-1,:]==np.sort(field[-1,:])): 305 md = md.checkmessage(options.getfieldvalue('message',\ 306 "field '%s' columns should be sorted chronologically" % fieldname)) 307 if any(field[-1,0:-1]==field[-1,1:]): 308 md = md.checkmessage(options.getfieldvalue('message',\ 309 "field '%s' columns must not contain duplicate timesteps" % fieldname)) 310 elif np.size(field,0) == 1: 311 if np.ndim(field) > 1 and not np.size(field,1) == 1: 312 md = md.checkmessage(options.getfieldvalue('message',\ 313 "field '%s' should be either a scalar or have 2 lines" % fieldname)) 314 else: 315 md = md.checkmessage(options.getfieldvalue('message',\ 316 "field '%s' should have 2 lines or be a scalar" % fieldname)) 317 318 return md 55 # exec("field=md.{}".format(fieldname)) 56 # exec("field=md.{}".format(fieldname),namespace) 57 58 59 if isinstance(field,(bool,int,float)): 60 field=np.array([field]) 61 62 #check empty 63 if options.exist('empty'): 64 if not field: 65 md = md.checkmessage(options.getfieldvalue('message', 66 "field '%s' is empty" % fieldname)) 67 68 #Check size 69 if options.exist('size'): 70 fieldsize=options.getfieldvalue('size') 71 if type(fieldsize) == str: 72 if m.strcmp(fieldsize,'universal'): 73 74 #Check that vector size will not be confusing for ModelProcessorx 75 if (md.mesh.numberofvertices==md.mesh.numberofelements): 76 raise RuntimeError('number of vertices is the same as number of elements') 77 elif (md.mesh.numberofvertices+1==md.mesh.numberofelements): 78 raise RuntimeError('number of vertices +1 is the same as number of elements') 79 elif (md.mesh.numberofvertices==md.mesh.numberofelements+1): 80 raise RuntimeError('number of vertices is the same as number of elements +1') 81 82 #Uniform field 83 if (np.size(field,0)==1): 84 if (np.shape(field)[1]!=1): 85 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 86 87 #vertex oriented input, only one column allowed 88 elif (np.shape(field)[0]==md.mesh.numberofvertices): 89 if (np.shape(field)[1]!=1): 90 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 91 92 #element oriented input, one or more column (patch) is ok 93 elif (np.shape(field)[0]==md.mesh.numberofelements): 94 pass 95 #nothing to do here (either constant per element, or defined on nodes) 96 97 #vertex time series 98 elif (np.shape(field)[0]==md.mesh.numberofvertices+1): 99 if (np.shape(field)[1]<=1): 100 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 101 102 #element time series 103 elif (np.shape(field)[0]==md.mesh.numberofelements+1): 104 if (np.shape(field)[1]<=1): 105 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 106 107 #else not supported 108 else: 109 md = md.checkmessage(options.getfieldvalue('message',"field '{}' is not supported".format(fieldname))) 110 111 else: 112 raise RuntimeError("fieldsize '{}' not supported yet".format(fieldsize)) 113 114 else: 115 for i in range(np.size(fieldsize)): 116 if (not np.isnan(fieldsize[i])) and (np.shape(field)[i] != fieldsize[i]): 117 md = md.checkmessage(options.getfieldvalue('message',"field {} dimension # {} should be of size {}".format(fieldname,i,fieldsize[i]))) 118 119 #Check numel 120 if options.exist('numel'): 121 fieldnumel=options.getfieldvalue('numel') 122 if (type(fieldnumel) == int and np.size(field) != fieldnumel) or (type(fieldnumel) == list and np.size(field) not in fieldnumel): 123 if len(fieldnumel)==1: 124 md = md.checkmessage(options.getfieldvalue('message',\ 125 "field '%s' size should be %d" % (fieldname,fieldnumel))) 126 elif len(fieldnumel)==2: 127 md = md.checkmessage(options.getfieldvalue('message',\ 128 "field '%s' size should be %d or %d" % (fieldname,fieldnumel[0],fieldnumel[1]))) 129 else: 130 md = md.checkmessage(options.getfieldvalue('message',\ 131 "field '%s' size should be %s" % (fieldname,fieldnumel))) 132 133 #check NaN 134 if options.getfieldvalue('NaN',0): 135 if np.any(np.isnan(field)): 136 md = md.checkmessage(options.getfieldvalue('message',\ 137 "NaN values found in field '%s'" % fieldname)) 138 139 140 #check Inf 141 if options.getfieldvalue('Inf',0): 142 if np.any(np.isinf(field)): 143 md = md.checkmessage(options.getfieldvalue('message',\ 144 "Inf values found in field '%s'" % fieldname)) 145 146 147 #check cell 148 if options.getfieldvalue('cell',0): 149 if not isinstance(field,(tuple,list,dict)): 150 md = md.checkmessage(options.getfieldvalue('message',\ 151 "field '%s' should be a cell" % fieldname)) 152 153 #check values 154 if options.exist('values'): 155 fieldvalues=options.getfieldvalue('values') 156 if False in m.ismember(field,fieldvalues): 157 if len(fieldvalues)==1: 158 md = md.checkmessage(options.getfieldvalue('message',\ 159 "field '%s' value should be '%s'" % (fieldname,fieldvalues[0]))) 160 elif len(fieldvalues)==2: 161 md = md.checkmessage(options.getfieldvalue('message',\ 162 "field '%s' values should be '%s' or '%s'" % (fieldname,fieldvalues[0],fieldvalues[1]))) 163 else: 164 md = md.checkmessage(options.getfieldvalue('message',\ 165 "field '%s' should have values in %s" % (fieldname,fieldvalues))) 166 167 #check greater 168 if options.exist('>='): 169 lowerbound = options.getfieldvalue('>=') 170 if type(lowerbound) is str: 171 lowerbound=attrgetter(lowerbound)(md) 172 if np.size(lowerbound)>1: #checking elementwise 173 if any(field<upperbound): 174 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 175 else: 176 minval=np.nanmin(field) 177 if options.getfieldvalue('timeseries',0): 178 minval=np.nanmin(field[:-1]) 179 elif options.getfieldvalue('singletimeseries',0): 180 if np.size(field)==1: #some singletimeseries are just one value 181 minval=field 182 else: 183 minval=np.nanmin(field[0]) 184 185 if minval<lowerbound: 186 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values above %d" % (fieldname,lowerbound))) 187 188 if options.exist('>'): 189 lowerbound=options.getfieldvalue('>') 190 if type(lowerbound) is str: 191 lowerbound=attrgetter(lowerbound)(md) 192 if np.size(lowerbound)>1: #checking elementwise 193 if any(field<=upperbound): 194 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 195 else: 196 minval=np.nanmin(field) 197 if options.getfieldvalue('timeseries',0) : 198 minval=np.nanmin(field[:-1]) 199 elif options.getfieldvalue('singletimeseries',0): 200 if np.size(field)==1: #some singletimeseries are just one value 201 minval=field 202 else: 203 minval=np.nanmin(field[0]) 204 205 if minval<=lowerbound: 206 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values above %d" % (fieldname,lowerbound))) 207 208 #check smaller 209 if options.exist('<='): 210 upperbound=options.getfieldvalue('<=') 211 if type(upperbound) is str: 212 upperbound=attrgetter(upperbound)(md) 213 if np.size(upperbound)>1: #checking elementwise 214 if any(field>upperbound): 215 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 216 else: 217 maxval=np.nanmax(field) 218 if options.getfieldvalue('timeseries',0): 219 maxval=np.nanmax(field[:-1]) 220 elif options.getfieldvalue('singletimeseries',0): 221 if np.size(field)==1: #some singletimeseries are just one value 222 maxval=field 223 else: 224 maxval=np.nanmax(field[0]) 225 elif hasattr(field, 'fov_forward_indices'): 226 maxval=field.fov_forward_indices[0] 227 if maxval>upperbound: 228 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 229 230 if options.exist('<'): 231 upperbound=options.getfieldvalue('<') 232 if type(upperbound) is str: 233 upperbound=attrgetter(upperbound)(md) 234 if np.size(upperbound)>1: #checking elementwise 235 if any(field>=upperbound): 236 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 237 238 else: 239 maxval=np.nanmax(field) 240 if options.getfieldvalue('timeseries',0): 241 maxval=np.nanmax(field[:-1]) 242 elif options.getfieldvalue('singletimeseries',0): 243 if np.size(field)==1: #some singletimeseries are just one value 244 maxval=field.copy() 245 else: 246 maxval=np.nanmax(field[0]) 247 248 if maxval>=upperbound: 249 md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have values below %d" % (fieldname,upperbound))) 250 251 #check file 252 if options.getfieldvalue('file',0): 253 if not os.path.exists(field): 254 md = md.checkmessage("file provided in '%s': '%s' does not exist" % (fieldname,field)) 255 256 #Check row of strings 257 if options.exist('stringrow'): 258 if not isinstance(field,list): 259 md = md.checkmessage(options.getfieldvalue('message',\ 260 "field '%s' should be a list" %fieldname)) 261 262 #Check forcings (size and times) 263 if options.getfieldvalue('timeseries',0): 264 if np.size(field,0)==md.mesh.numberofvertices or np.size(field,0)==md.mesh.numberofelements: 265 if np.ndim(field)>1 and not np.size(field,1)==1: 266 md = md.checkmessage(options.getfieldvalue('message',\ 267 "field '%s' should have only one column as there are md.mesh.numberofvertices lines" % fieldname)) 268 elif np.size(field,0)==md.mesh.numberofvertices+1 or np.size(field,0)==md.mesh.numberofelements+1: 269 if np.ndim(field) > 1 and not all(field[-1,:]==np.sort(field[-1,:])): 270 md = md.checkmessage(options.getfieldvalue('message',\ 271 "field '%s' columns should be sorted chronologically" % fieldname)) 272 if np.ndim(field) > 1 and any(field[-1,0:-1]==field[-1,1:]): 273 md = md.checkmessage(options.getfieldvalue('message',\ 274 "field '%s' columns must not contain duplicate timesteps" % fieldname)) 275 else: 276 md = md.checkmessage(options.getfieldvalue('message',\ 277 "field '%s' should have md.mesh.numberofvertices or md.mesh.numberofvertices+1 lines" % fieldname)) 278 279 #Check single value forcings (size and times) 280 if options.getfieldvalue('singletimeseries',0): 281 if np.size(field,0)==2: 282 if not all(field[-1,:]==np.sort(field[-1,:])): 283 md = md.checkmessage(options.getfieldvalue('message',\ 284 "field '%s' columns should be sorted chronologically" % fieldname)) 285 if any(field[-1,0:-1]==field[-1,1:]): 286 md = md.checkmessage(options.getfieldvalue('message',\ 287 "field '%s' columns must not contain duplicate timesteps" % fieldname)) 288 elif np.size(field,0) == 1: 289 if np.ndim(field) > 1 and not np.size(field,1) == 1: 290 md = md.checkmessage(options.getfieldvalue('message',\ 291 "field '%s' should be either a scalar or have 2 lines" % fieldname)) 292 else: 293 md = md.checkmessage(options.getfieldvalue('message',\ 294 "field '%s' should have 2 lines or be a scalar" % fieldname)) 295 296 return md
Note:
See TracChangeset
for help on using the changeset viewer.