Changeset 23787
- Timestamp:
- 03/11/19 03:04:31 (6 years ago)
- Location:
- issm/trunk-jpl/src/m
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/classes/model.py
r23771 r23787 71 71 #}}} 72 72 73 73 74 class model(object): 74 #properties 75 def __init__(self):#{{{ 76 77 # classtype=model.properties 78 79 # for classe in dict.keys(classtype): 80 # print classe 81 # self.__dict__[classe] = classtype[str(classe)] 82 83 self.mesh = mesh2d() 84 self.mask = mask() 85 self.geometry = geometry() 86 self.constants = constants() 87 self.smb = SMBforcing() 88 self.basalforcings = basalforcings() 89 self.materials = matice() 90 self.damage = damage() 91 self.friction = friction() 92 self.flowequation = flowequation() 93 self.timestepping = timestepping() 94 self.initialization = initialization() 95 self.rifts = rifts() 96 self.slr = slr() 97 98 self.debug = debug() 99 self.verbose = verbose() 100 self.settings = issmsettings() 101 self.toolkits = toolkits() 102 self.cluster = generic() 103 104 self.balancethickness = balancethickness() 105 self.stressbalance = stressbalance() 106 self.groundingline = groundingline() 107 self.hydrology = hydrologyshreve() 108 self.masstransport = masstransport() 109 self.thermal = thermal() 110 self.steadystate = steadystate() 111 self.transient = transient() 112 self.levelset = levelset() 113 self.calving = calving() 114 self.frontalforcings = frontalforcings() 115 self.gia = giaivins() 116 self.love = fourierlove() 117 self.esa = esa() 118 self.autodiff = autodiff() 119 self.inversion = inversion() 120 self.qmu = qmu() 121 self.amr = amr() 122 123 self.results = results() 124 self.outputdefinition = outputdefinition() 125 self.radaroverlay = radaroverlay() 126 self.miscellaneous = miscellaneous() 127 self.private = private() 128 #}}} 129 def properties(self): # {{{ 130 # ordered list of properties since vars(self) is random 131 return ['mesh', 132 'mask', 133 'geometry', 134 'constants', 135 'smb', 136 'basalforcings', 137 'materials', 138 'damage', 139 'friction', 140 'flowequation', 141 'timestepping', 142 'initialization', 143 'rifts', 144 'slr', 145 'debug', 146 'verbose', 147 'settings', 148 'toolkits', 149 'cluster', 150 'balancethickness', 151 'stressbalance', 152 'groundingline', 153 'hydrology', 154 'masstransport', 155 'thermal', 156 'steadystate', 157 'transient', 158 'levelset', 159 'calving', 160 'frontalforcings', 161 'love', 162 'gia', 163 'esa', 164 'autodiff', 165 'inversion', 166 'qmu', 167 'amr', 168 'outputdefinition', 169 'results', 170 'radaroverlay', 171 'miscellaneous', 172 'private'] 173 # }}} 174 def __repr__(obj): #{{{ 175 #print "Here %s the number: %d" % ("is", 37) 176 string="%19s: %-22s -- %s" % ("mesh","[%s,%s]" % ("1x1",obj.mesh.__class__.__name__),"mesh properties") 177 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("mask","[%s,%s]" % ("1x1",obj.mask.__class__.__name__),"defines grounded and floating elements")) 178 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("geometry","[%s,%s]" % ("1x1",obj.geometry.__class__.__name__),"surface elevation, bedrock topography, ice thickness,...")) 179 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("constants","[%s,%s]" % ("1x1",obj.constants.__class__.__name__),"physical constants")) 180 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("smb","[%s,%s]" % ("1x1",obj.smb.__class__.__name__),"surface mass balance")) 181 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("basalforcings","[%s,%s]" % ("1x1",obj.basalforcings.__class__.__name__),"bed forcings")) 182 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("materials","[%s,%s]" % ("1x1",obj.materials.__class__.__name__),"material properties")) 183 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("damage","[%s,%s]" % ("1x1",obj.damage.__class__.__name__),"damage propagation laws")) 184 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("friction","[%s,%s]" % ("1x1",obj.friction.__class__.__name__),"basal friction/drag properties")) 185 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("flowequation","[%s,%s]" % ("1x1",obj.flowequation.__class__.__name__),"flow equations")) 186 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("timestepping","[%s,%s]" % ("1x1",obj.timestepping.__class__.__name__),"time stepping for transient models")) 187 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("initialization","[%s,%s]" % ("1x1",obj.initialization.__class__.__name__),"initial guess/state")) 188 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("rifts","[%s,%s]" % ("1x1",obj.rifts.__class__.__name__),"rifts properties")) 189 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("slr","[%s,%s]" % ("1x1",obj.slr.__class__.__name__),"slr forcings")) 190 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("debug","[%s,%s]" % ("1x1",obj.debug.__class__.__name__),"debugging tools (valgrind, gprof)")) 191 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("verbose","[%s,%s]" % ("1x1",obj.verbose.__class__.__name__),"verbosity level in solve")) 192 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("settings","[%s,%s]" % ("1x1",obj.settings.__class__.__name__),"settings properties")) 193 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("toolkits","[%s,%s]" % ("1x1",obj.toolkits.__class__.__name__),"PETSc options for each solution")) 194 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("cluster","[%s,%s]" % ("1x1",obj.cluster.__class__.__name__),"cluster parameters (number of cpus...)")) 195 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("balancethickness","[%s,%s]" % ("1x1",obj.balancethickness.__class__.__name__),"parameters for balancethickness solution")) 196 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("stressbalance","[%s,%s]" % ("1x1",obj.stressbalance.__class__.__name__),"parameters for stressbalance solution")) 197 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("groundingline","[%s,%s]" % ("1x1",obj.groundingline.__class__.__name__),"parameters for groundingline solution")) 198 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("hydrology","[%s,%s]" % ("1x1",obj.hydrology.__class__.__name__),"parameters for hydrology solution")) 199 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("masstransport","[%s,%s]" % ("1x1",obj.masstransport.__class__.__name__),"parameters for masstransport solution")) 200 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("thermal","[%s,%s]" % ("1x1",obj.thermal.__class__.__name__),"parameters for thermal solution")) 201 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("steadystate","[%s,%s]" % ("1x1",obj.steadystate.__class__.__name__),"parameters for steadystate solution")) 202 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("transient","[%s,%s]" % ("1x1",obj.transient.__class__.__name__),"parameters for transient solution")) 203 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("levelset","[%s,%s]" % ("1x1",obj.levelset.__class__.__name__),"parameters for moving boundaries (level-set method)")) 204 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("calving","[%s,%s]" % ("1x1",obj.calving.__class__.__name__),"parameters for calving")) 205 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("frontalforcings","[%s,%s]" % ("1x1",obj.frontalforcings.__class__.__name__),"parameters for frontalforcings")) 206 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("gia","[%s,%s]" % ("1x1",obj.gia.__class__.__name__),"parameters for gia solution")) 207 string="%s\n%s" % (string,'%19s: %-22s -- %s' % ("love","[%s,%s]" % ("1x1",obj.love.__class__.__name__),"parameters for love solution")) 208 string="%s\n%s" % (string,'%19s: %-22s -- %s' % ("esa","[%s,%s]" % ("1x1",obj.esa.__class__.__name__),"parameters for elastic adjustment solution")) 209 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("autodiff","[%s,%s]" % ("1x1",obj.autodiff.__class__.__name__),"automatic differentiation parameters")) 210 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("inversion","[%s,%s]" % ("1x1",obj.inversion.__class__.__name__),"parameters for inverse methods")) 211 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("qmu","[%s,%s]" % ("1x1",obj.qmu.__class__.__name__),"dakota properties")) 212 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("amr","[%s,%s]" % ("1x1",obj.amr.__class__.__name__),"adaptive mesh refinement properties")) 213 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("outputdefinition","[%s,%s]" % ("1x1",obj.outputdefinition.__class__.__name__),"output definition")) 214 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("results","[%s,%s]" % ("1x1",obj.results.__class__.__name__),"model results")) 215 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("radaroverlay","[%s,%s]" % ("1x1",obj.radaroverlay.__class__.__name__),"radar image for plot overlay")) 216 string="%s\n%s" % (string,"%19s: %-22s -- %s" % ("miscellaneous","[%s,%s]" % ("1x1",obj.miscellaneous.__class__.__name__),"miscellaneous fields")) 217 return string 218 # }}} 219 def checkmessage(self,string): # {{{ 220 print(("model not consistent: ", string)) 221 self.private.isconsistent=False 222 return self 223 # }}} 224 #@staticmethod 225 def extract(self,area): # {{{ 226 """ 227 extract - extract a model according to an Argus contour or flag list 228 229 This routine extracts a submodel from a bigger model with respect to a given contour 230 md must be followed by the corresponding exp file or flags list 231 It can either be a domain file (argus type, .exp extension), or an array of element flags. 232 If user wants every element outside the domain to be 233 extract2d, add '~' to the name of the domain file (ex: '~HO.exp') 234 an empty string '' will be considered as an empty domain 235 a string 'all' will be considered as the entire domain 236 237 Usage: 238 md2=extract(md,area) 239 240 Examples: 241 md2=extract(md,'Domain.exp') 242 243 See also: EXTRUDE, COLLAPSE 244 """ 245 246 #copy model 247 md1=copy.deepcopy(self) 248 249 #get elements that are inside area 250 flag_elem=FlagElements(md1,area) 251 if not np.any(flag_elem): 252 raise RuntimeError("extracted model is empty") 253 254 #kick out all elements with 3 dirichlets 255 spc_elem=np.nonzero(np.logical_not(flag_elem))[0] 256 spc_node=np.unique(md1.mesh.elements[spc_elem,:])-1 257 flag=np.ones(md1.mesh.numberofvertices) 258 flag[spc_node]=0 259 pos=np.nonzero(np.logical_not(np.sum(flag[md1.mesh.elements-1],axis=1)))[0] 260 flag_elem[pos]=0 261 262 #extracted elements and nodes lists 263 pos_elem=np.nonzero(flag_elem)[0] 264 pos_node=np.unique(md1.mesh.elements[pos_elem,:])-1 265 266 #keep track of some fields 267 numberofvertices1=md1.mesh.numberofvertices 268 numberofelements1=md1.mesh.numberofelements 269 numberofvertices2=np.size(pos_node) 270 numberofelements2=np.size(pos_elem) 271 flag_node=np.zeros(numberofvertices1) 272 flag_node[pos_node]=1 273 274 #Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements) 275 Pelem=np.zeros(numberofelements1,int) 276 Pelem[pos_elem]=np.arange(1,numberofelements2+1) 277 Pnode=np.zeros(numberofvertices1,int) 278 Pnode[pos_node]=np.arange(1,numberofvertices2+1) 279 280 #renumber the elements (some node won't exist anymore) 281 elements_1=copy.deepcopy(md1.mesh.elements) 282 elements_2=elements_1[pos_elem,:] 283 elements_2[:,0]=Pnode[elements_2[:,0]-1] 284 elements_2[:,1]=Pnode[elements_2[:,1]-1] 285 elements_2[:,2]=Pnode[elements_2[:,2]-1] 286 if md1.mesh.__class__.__name__=='mesh3dprisms': 287 elements_2[:,3]=Pnode[elements_2[:,3]-1] 288 elements_2[:,4]=Pnode[elements_2[:,4]-1] 289 elements_2[:,5]=Pnode[elements_2[:,5]-1] 290 291 #OK, now create the new model! 292 293 #take every field from model 294 md2=copy.deepcopy(md1) 295 296 #automatically modify fields 297 298 #loop over model fields 299 model_fields=vars(md1) 300 for fieldi in model_fields: 301 #get field 302 field=getattr(md1,fieldi) 303 fieldsize=np.shape(field) 304 if hasattr(field,'__dict__') and not fieldi in ['results']: #recursive call 305 object_fields=vars(field) 306 for fieldj in object_fields: 307 #get field 308 field=getattr(getattr(md1,fieldi),fieldj) 309 fieldsize=np.shape(field) 310 if len(fieldsize): 311 #size = number of nodes * n 312 if fieldsize[0]==numberofvertices1: 313 setattr(getattr(md2,fieldi),fieldj,field[pos_node]) 314 elif fieldsize[0]==numberofvertices1+1: 315 setattr(getattr(md2,fieldi),fieldj,np.vstack((field[pos_node],field[-1,:]))) 316 #size = number of elements * n 317 elif fieldsize[0]==numberofelements1: 318 setattr(getattr(md2,fieldi),fieldj,field[pos_elem]) 319 else: 320 if len(fieldsize): 321 #size = number of nodes * n 322 if fieldsize[0]==numberofvertices1: 323 setattr(md2,fieldi,field[pos_node]) 324 elif fieldsize[0]==numberofvertices1+1: 325 setattr(md2,fieldi,np.hstack((field[pos_node],field[-1,:]))) 326 #size = number of elements * n 327 elif fieldsize[0]==numberofelements1: 328 setattr(md2,fieldi,field[pos_elem]) 329 330 #modify some specific fields 331 332 #Mesh 333 md2.mesh.numberofelements=numberofelements2 334 md2.mesh.numberofvertices=numberofvertices2 335 md2.mesh.elements=elements_2 336 337 #mesh.uppervertex mesh.lowervertex 338 if md1.mesh.__class__.__name__=='mesh3dprisms': 339 md2.mesh.uppervertex=md1.mesh.uppervertex[pos_node] 340 pos=np.where(~np.isnan(md2.mesh.uppervertex))[0] 341 md2.mesh.uppervertex[pos]=Pnode[md2.mesh.uppervertex[pos].astype(int)-1] 342 343 md2.mesh.lowervertex=md1.mesh.lowervertex[pos_node] 344 pos=np.where(~np.isnan(md2.mesh.lowervertex))[0] 345 md2.mesh.lowervertex[pos]=Pnode[md2.mesh.lowervertex[pos].astype(int)-1] 346 347 md2.mesh.upperelements=md1.mesh.upperelements[pos_elem] 348 pos=np.where(~np.isnan(md2.mesh.upperelements))[0] 349 md2.mesh.upperelements[pos]=Pelem[md2.mesh.upperelements[pos].astype(int)-1] 350 351 md2.mesh.lowerelements=md1.mesh.lowerelements[pos_elem] 352 pos=np.where(~np.isnan(md2.mesh.lowerelements))[0] 353 md2.mesh.lowerelements[pos]=Pelem[md2.mesh.lowerelements[pos].astype(int)-1] 354 355 #Initial 2d mesh 356 if md1.mesh.__class__.__name__=='mesh3dprisms': 357 flag_elem_2d=flag_elem[np.arange(0,md1.mesh.numberofelements2d)] 358 pos_elem_2d=np.nonzero(flag_elem_2d)[0] 359 flag_node_2d=flag_node[np.arange(0,md1.mesh.numberofvertices2d)] 360 pos_node_2d=np.nonzero(flag_node_2d)[0] 361 362 md2.mesh.numberofelements2d=np.size(pos_elem_2d) 363 md2.mesh.numberofvertices2d=np.size(pos_node_2d) 364 md2.mesh.elements2d=md1.mesh.elements2d[pos_elem_2d,:] 365 md2.mesh.elements2d[:,0]=Pnode[md2.mesh.elements2d[:,0]-1] 366 md2.mesh.elements2d[:,1]=Pnode[md2.mesh.elements2d[:,1]-1] 367 md2.mesh.elements2d[:,2]=Pnode[md2.mesh.elements2d[:,2]-1] 368 369 md2.mesh.x2d=md1.mesh.x[pos_node_2d] 370 md2.mesh.y2d=md1.mesh.y[pos_node_2d] 371 372 #Edges 373 if md1.mesh.domaintype()=='2Dhorizontal': 374 if np.ndim(md2.mesh.edges)>1 and np.size(md2.mesh.edges,axis=1)>1: #do not use ~isnan because there are some np.nans... 375 #renumber first two columns 376 pos=np.nonzero(md2.mesh.edges[:,3]!=-1)[0] 377 md2.mesh.edges[:,0]=Pnode[md2.mesh.edges[:,0]-1] 378 md2.mesh.edges[:,1]=Pnode[md2.mesh.edges[:,1]-1] 379 md2.mesh.edges[:,2]=Pelem[md2.mesh.edges[:,2]-1] 380 md2.mesh.edges[pos,3]=Pelem[md2.mesh.edges[pos,3]-1] 381 #remove edges when the 2 vertices are not in the domain. 382 md2.mesh.edges=md2.mesh.edges[np.nonzero(np.logical_and(md2.mesh.edges[:,0],md2.mesh.edges[:,1]))[0],:] 383 #Replace all zeros by -1 in the last two columns 384 pos=np.nonzero(md2.mesh.edges[:,2]==0)[0] 385 md2.mesh.edges[pos,2]=-1 386 pos=np.nonzero(md2.mesh.edges[:,3]==0)[0] 387 md2.mesh.edges[pos,3]=-1 388 #Invert -1 on the third column with last column (Also invert first two columns!!) 389 pos=np.nonzero(md2.mesh.edges[:,2]==-1)[0] 390 md2.mesh.edges[pos,2]=md2.mesh.edges[pos,3] 391 md2.mesh.edges[pos,3]=-1 392 values=md2.mesh.edges[pos,1] 393 md2.mesh.edges[pos,1]=md2.mesh.edges[pos,0] 394 md2.mesh.edges[pos,0]=values 395 #Finally remove edges that do not belong to any element 396 pos=np.nonzero(np.logical_and(md2.mesh.edges[:,1]==-1,md2.mesh.edges[:,2]==-1))[0] 397 md2.mesh.edges=np.delete(md2.mesh.edges,pos,axis=0) 398 399 #Penalties 400 if np.any(np.logical_not(np.isnan(md2.stressbalance.vertex_pairing))): 401 for i in range(np.size(md1.stressbalance.vertex_pairing,axis=0)): 402 md2.stressbalance.vertex_pairing[i,:]=Pnode[md1.stressbalance.vertex_pairing[i,:]] 403 md2.stressbalance.vertex_pairing=md2.stressbalance.vertex_pairing[np.nonzero(md2.stressbalance.vertex_pairing[:,0])[0],:] 404 if np.any(np.logical_not(np.isnan(md2.masstransport.vertex_pairing))): 405 for i in range(np.size(md1.masstransport.vertex_pairing,axis=0)): 406 md2.masstransport.vertex_pairing[i,:]=Pnode[md1.masstransport.vertex_pairing[i,:]] 407 md2.masstransport.vertex_pairing=md2.masstransport.vertex_pairing[np.nonzero(md2.masstransport.vertex_pairing[:,0])[0],:] 408 409 #recreate segments 410 if md1.mesh.__class__.__name__=='mesh2d': 411 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices)[0] 412 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity)[0] 413 md2.mesh.segments=contourenvelope(md2) 414 md2.mesh.vertexonboundary=np.zeros(numberofvertices2,bool) 415 md2.mesh.vertexonboundary[md2.mesh.segments[:,0:2]-1]=True 416 else: 417 #First do the connectivity for the contourenvelope in 2d 418 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements2d,md2.mesh.numberofvertices2d)[0] 419 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements2d,md2.mesh.vertexconnectivity)[0] 420 segments=contourenvelope(md2) 421 md2.mesh.vertexonboundary=np.zeros(int(numberofvertices2/md2.mesh.numberoflayers),bool) 422 md2.mesh.vertexonboundary[segments[:,0:2]-1]=True 423 md2.mesh.vertexonboundary=np.tile(md2.mesh.vertexonboundary,md2.mesh.numberoflayers) 424 #Then do it for 3d as usual 425 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices)[0] 426 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity)[0] 427 428 #Boundary conditions: Dirichlets on new boundary 429 #Catch the elements that have not been extracted 430 orphans_elem=np.nonzero(np.logical_not(flag_elem))[0] 431 orphans_node=np.unique(md1.mesh.elements[orphans_elem,:])-1 432 #Figure out which node are on the boundary between md2 and md1 433 nodestoflag1=np.intersect1d(orphans_node,pos_node) 434 nodestoflag2=Pnode[nodestoflag1].astype(int)-1 435 if np.size(md1.stressbalance.spcvx)>1 and np.size(md1.stressbalance.spcvy)>1 and np.size(md1.stressbalance.spcvz)>1: 436 if np.size(md1.inversion.vx_obs)>1 and np.size(md1.inversion.vy_obs)>1: 437 md2.stressbalance.spcvx[nodestoflag2]=md2.inversion.vx_obs[nodestoflag2] 438 md2.stressbalance.spcvy[nodestoflag2]=md2.inversion.vy_obs[nodestoflag2] 439 else: 440 md2.stressbalance.spcvx[nodestoflag2]=np.nan 441 md2.stressbalance.spcvy[nodestoflag2]=np.nan 442 print("\n!! extract warning: spc values should be checked !!\n\n") 443 #put 0 for vz 444 md2.stressbalance.spcvz[nodestoflag2]=0 445 if np.any(np.logical_not(np.isnan(md1.thermal.spctemperature))): 446 md2.thermal.spctemperature[nodestoflag2]=1 447 448 #Results fields 449 if md1.results: 450 md2.results=results() 451 for solutionfield,field in list(md1.results.__dict__.items()): 452 if isinstance(field,list): 453 setattr(md2.results,solutionfield,[]) 454 #get time step 455 for i,fieldi in enumerate(field): 456 if isinstance(fieldi,results) and fieldi: 457 getattr(md2.results,solutionfield).append(results()) 458 fieldr=getattr(md2.results,solutionfield)[i] 459 #get subfields 460 for solutionsubfield,subfield in list(fieldi.__dict__.items()): 461 if np.size(subfield)==numberofvertices1: 462 setattr(fieldr,solutionsubfield,subfield[pos_node]) 463 elif np.size(subfield)==numberofelements1: 464 setattr(fieldr,solutionsubfield,subfield[pos_elem]) 465 else: 466 setattr(fieldr,solutionsubfield,subfield) 467 else: 468 getattr(md2.results,solutionfield).append(None) 469 elif isinstance(field,results): 470 setattr(md2.results,solutionfield,results()) 471 if isinstance(field,results) and field: 472 fieldr=getattr(md2.results,solutionfield) 473 #get subfields 474 for solutionsubfield,subfield in list(field.__dict__.items()): 475 if np.size(subfield)==numberofvertices1: 476 setattr(fieldr,solutionsubfield,subfield[pos_node]) 477 elif np.size(subfield)==numberofelements1: 478 setattr(fieldr,solutionsubfield,subfield[pos_elem]) 479 else: 480 setattr(fieldr,solutionsubfield,subfield) 481 482 #OutputDefinitions fields 483 if md1.outputdefinition.definitions: 484 for solutionfield,field in list(md1.outputdefinition.__dict__.items()): 485 if isinstance(field,list): 486 #get each definition 487 for i,fieldi in enumerate(field): 488 if fieldi: 489 fieldr=getattr(md2.outputdefinition,solutionfield)[i] 490 #get subfields 491 for solutionsubfield,subfield in list(fieldi.__dict__.items()): 492 if np.size(subfield)==numberofvertices1: 493 setattr(fieldr,solutionsubfield,subfield[pos_node]) 494 elif np.size(subfield)==numberofelements1: 495 setattr(fieldr,solutionsubfield,subfield[pos_elem]) 496 else: 497 setattr(fieldr,solutionsubfield,subfield) 498 499 #Keep track of pos_node and pos_elem 500 md2.mesh.extractedvertices=pos_node+1 501 md2.mesh.extractedelements=pos_elem+1 502 503 return md2 504 # }}} 505 def extrude(md,*args): # {{{ 506 """ 507 EXTRUDE - vertically extrude a 2d mesh 508 509 vertically extrude a 2d mesh and create corresponding 3d mesh. 510 The vertical distribution can: 511 - follow a polynomial law 512 - follow two polynomial laws, one for the lower part and one for the upper part of the mesh 513 - be discribed by a list of coefficients (between 0 and 1) 514 515 516 Usage: 517 md=extrude(md,numlayers,extrusionexponent) 518 md=extrude(md,numlayers,lowerexponent,upperexponent) 519 md=extrude(md,listofcoefficients) 520 521 Example: 522 md=extrude(md,15,1.3); 523 md=extrude(md,15,1.3,1.2); 524 md=extrude(md,[0 0.2 0.5 0.7 0.9 0.95 1]) 525 526 See also: MODELEXTRACT, COLLAPSE 527 """ 528 529 #some checks on list of arguments 530 if len(args)>3 or len(args)<1: 531 raise RuntimeError("extrude error message") 532 533 #Extrude the mesh 534 if len(args)==1: #list of coefficients 535 clist=args[0] 536 if any(clist<0) or any(clist>1): 537 raise TypeError("extrusioncoefficients must be between 0 and 1") 538 clist.extend([0.,1.]) 539 clist.sort() 540 extrusionlist=list(set(clist)) 541 numlayers=len(extrusionlist) 542 543 elif len(args)==2: #one polynomial law 544 if args[1]<=0: 545 raise TypeError("extrusionexponent must be >=0") 546 numlayers=args[0] 547 extrusionlist=(np.arange(0.,float(numlayers-1)+1.,1.)/float(numlayers-1))**args[1] 548 549 elif len(args)==3: #two polynomial laws 550 numlayers=args[0] 551 lowerexp=args[1] 552 upperexp=args[2] 553 554 if args[1]<=0 or args[2]<=0: 555 raise TypeError("lower and upper extrusionexponents must be >=0") 556 557 lowerextrusionlist=(np.arange(0.,1.+2./float(numlayers-1),2./float(numlayers-1)))**lowerexp/2. 558 upperextrusionlist=(np.arange(0.,1.+2./float(numlayers-1),2./float(numlayers-1)))**upperexp/2. 559 extrusionlist=np.unique(np.concatenate((lowerextrusionlist,1.-upperextrusionlist))) 560 561 if numlayers<2: 562 raise TypeError("number of layers should be at least 2") 563 if md.mesh.__class__.__name__=='mesh3dprisms': 564 raise TypeError("Cannot extrude a 3d mesh (extrude cannot be called more than once)") 565 566 #Initialize with the 2d mesh 567 mesh2d = md.mesh 568 md.mesh=mesh3dprisms() 569 md.mesh.x = mesh2d.x 570 md.mesh.y = mesh2d.y 571 md.mesh.elements = mesh2d.elements 572 md.mesh.numberofelements = mesh2d.numberofelements 573 md.mesh.numberofvertices = mesh2d.numberofvertices 574 575 md.mesh.lat = mesh2d.lat 576 md.mesh.long = mesh2d.long 577 md.mesh.epsg = mesh2d.epsg 578 md.mesh.scale_factor = mesh2d.scale_factor 579 580 md.mesh.vertexonboundary = mesh2d.vertexonboundary 581 md.mesh.vertexconnectivity = mesh2d.vertexconnectivity 582 md.mesh.elementconnectivity = mesh2d.elementconnectivity 583 md.mesh.average_vertex_connectivity = mesh2d.average_vertex_connectivity 584 585 md.mesh.extractedvertices = mesh2d.extractedvertices 586 md.mesh.extractedelements = mesh2d.extractedelements 587 588 x3d=np.empty((0)) 589 y3d=np.empty((0)) 590 z3d=np.empty((0)) #the lower node is on the bed 591 thickness3d=md.geometry.thickness #thickness and bed for these nodes 592 bed3d=md.geometry.base 593 594 #Create the new layers 595 for i in range(numlayers): 596 x3d=np.concatenate((x3d,md.mesh.x)) 597 y3d=np.concatenate((y3d,md.mesh.y)) 598 #nodes are distributed between bed and surface accordingly to the given exponent 599 z3d=np.concatenate((z3d,(bed3d+thickness3d*extrusionlist[i]).reshape(-1))) 600 number_nodes3d=np.size(x3d) #number of 3d nodes for the non extruded part of the mesh 601 602 #Extrude elements 603 elements3d=np.empty((0,6),int) 604 for i in range(numlayers-1): 605 elements3d=np.vstack((elements3d,np.hstack((md.mesh.elements+i*md.mesh.numberofvertices,md.mesh.elements+(i+1)*md.mesh.numberofvertices)))) #Create the elements of the 3d mesh for the non extruded part 606 number_el3d=np.size(elements3d,axis=0) #number of 3d nodes for the non extruded part of the mesh 607 608 #Keep a trace of lower and upper nodes 609 lowervertex=np.nan*np.ones(number_nodes3d,int) 610 uppervertex=np.nan*np.ones(number_nodes3d,int) 611 lowervertex[md.mesh.numberofvertices:]=np.arange(1,(numlayers-1)*md.mesh.numberofvertices+1) 612 uppervertex[:(numlayers-1)*md.mesh.numberofvertices]=np.arange(md.mesh.numberofvertices+1,number_nodes3d+1) 613 md.mesh.lowervertex=lowervertex 614 md.mesh.uppervertex=uppervertex 615 616 #same for lower and upper elements 617 lowerelements=np.nan*np.ones(number_el3d,int) 618 upperelements=np.nan*np.ones(number_el3d,int) 619 lowerelements[md.mesh.numberofelements:]=np.arange(1,(numlayers-2)*md.mesh.numberofelements+1) 620 upperelements[:(numlayers-2)*md.mesh.numberofelements]=np.arange(md.mesh.numberofelements+1,(numlayers-1)*md.mesh.numberofelements+1) 621 md.mesh.lowerelements=lowerelements 622 md.mesh.upperelements=upperelements 623 624 #Save old mesh 625 md.mesh.x2d=md.mesh.x 626 md.mesh.y2d=md.mesh.y 627 md.mesh.elements2d=md.mesh.elements 628 md.mesh.numberofelements2d=md.mesh.numberofelements 629 md.mesh.numberofvertices2d=md.mesh.numberofvertices 630 631 #Build global 3d mesh 632 md.mesh.elements=elements3d 633 md.mesh.x=x3d 634 md.mesh.y=y3d 635 md.mesh.z=z3d 636 md.mesh.numberofelements=number_el3d 637 md.mesh.numberofvertices=number_nodes3d 638 md.mesh.numberoflayers=numlayers 639 640 #Ok, now deal with the other fields from the 2d mesh: 641 642 #bedinfo and surface info 643 md.mesh.vertexonbase=project3d(md,'vector',np.ones(md.mesh.numberofvertices2d,bool),'type','node','layer',1) 644 md.mesh.vertexonsurface=project3d(md,'vector',np.ones(md.mesh.numberofvertices2d,bool),'type','node','layer',md.mesh.numberoflayers) 645 md.mesh.vertexonboundary=project3d(md,'vector',md.mesh.vertexonboundary,'type','node') 646 647 #lat long 648 md.mesh.lat=project3d(md,'vector',md.mesh.lat,'type','node') 649 md.mesh.long=project3d(md,'vector',md.mesh.long,'type','node') 650 md.mesh.scale_factor=project3d(md,'vector',md.mesh.scale_factor,'type','node') 651 652 md.geometry.extrude(md) 653 md.friction.extrude(md) 654 md.inversion.extrude(md) 655 md.smb.extrude(md) 656 md.initialization.extrude(md) 657 md.flowequation.extrude(md) 658 659 md.stressbalance.extrude(md) 660 md.thermal.extrude(md) 661 md.masstransport.extrude(md) 662 663 # Calving variables 664 md.hydrology.extrude(md) 665 md.levelset.extrude(md) 666 md.calving.extrude(md) 667 md.frontalforcings.extrude(md) 668 669 #connectivity 670 md.mesh.elementconnectivity=np.tile(md.mesh.elementconnectivity,(numlayers-1,1)) 671 md.mesh.elementconnectivity[np.nonzero(md.mesh.elementconnectivity==0)]=-sys.maxsize-1 672 if not np.isnan(md.mesh.elementconnectivity).all(): 673 for i in range(1,numlayers-1): 674 md.mesh.elementconnectivity[i*md.mesh.numberofelements2d:(i+1)*md.mesh.numberofelements2d,:] \ 675 =md.mesh.elementconnectivity[i*md.mesh.numberofelements2d:(i+1)*md.mesh.numberofelements2d,:]+md.mesh.numberofelements2d 676 md.mesh.elementconnectivity[np.nonzero(md.mesh.elementconnectivity<0)]=0 677 678 md.materials.extrude(md) 679 if md.damage.isdamage==1: 680 md.damage.extrude(md) 681 md.gia.extrude(md) 682 md.mask.extrude(md) 683 md.qmu.extrude(md) 684 md.basalforcings.extrude(md) 685 md.outputdefinition.extrude(md) 686 687 #increase connectivity if less than 25: 688 if md.mesh.average_vertex_connectivity<=25: 689 md.mesh.average_vertex_connectivity=100 690 691 return md 692 # }}} 693 def collapse(md): #{{{ 694 ''' 695 collapses a 3d mesh into a 2d mesh 696 697 This routine collapses a 3d model into a 2d model and collapses all 698 the fileds of the 3d model by taking their depth-averaged values 699 700 Usage: 701 md=collapse(md) 702 ''' 703 704 #Check that the model is really a 3d model 705 if md.mesh.domaintype().lower() != '3d': 706 raise Exception("only a 3D model can be collapsed") 707 708 #dealing with the friction law 709 #drag is limited to nodes that are on the bedrock. 710 if hasattr(md.friction,'coefficient'): 711 md.friction.coefficient=project2d(md,md.friction.coefficient,1) 712 713 #p and q (same deal, except for element that are on the bedrock: ) 714 if hasattr(md.friction,'p'): 715 md.friction.p=project2d(md,md.friction.p,1) 716 if hasattr(md.friction,'q'): 717 md.friction.q=project2d(md,md.friction.q,1) 718 719 if hasattr(md.friction,'coefficientcoulomb'): 720 md.friction.coefficientcoulomb=project2d(md,md.friction.coefficientcoulomb,1) 721 if hasattr(md.friction,'C'): 722 md.friction.C=project2d(md,md.friction.C,1) 723 if hasattr(md.friction,'As'): 724 md.friction.As=project2d(md,md.friction.As,1) 725 if hasattr(md.friction,'effective_pressure') and not np.isnan(md.friction.effective_pressure).all(): 726 md.friction.effective_pressure=project2d(md,md.friction.effective_pressure,1) 727 if hasattr(md.friction,'water_layer'): 728 md.friction.water_layer=project2d(md,md.friction.water_layer,1) 729 if hasattr(md.friction,'m'): 730 md.friction.m=project2d(md,md.friction.m,1) 731 732 #observations 733 if not np.isnan(md.inversion.vx_obs).all(): 734 md.inversion.vx_obs=project2d(md,md.inversion.vx_obs,md.mesh.numberoflayers) 735 if not np.isnan(md.inversion.vy_obs).all(): 736 md.inversion.vy_obs=project2d(md,md.inversion.vy_obs,md.mesh.numberoflayers) 737 if not np.isnan(md.inversion.vel_obs).all(): 738 md.inversion.vel_obs=project2d(md,md.inversion.vel_obs,md.mesh.numberoflayers) 739 if not np.isnan(md.inversion.cost_functions_coefficients).all(): 740 md.inversion.cost_functions_coefficients=project2d(md,md.inversion.cost_functions_coefficients,md.mesh.numberoflayers) 741 if isinstance(md.inversion.min_parameters,np.ndarray): 742 if md.inversion.min_parameters.size>1: 743 md.inversion.min_parameters=project2d(md,md.inversion.min_parameters,md.mesh.numberoflayers) 744 if isinstance(md.inversion.max_parameters,np.ndarray): 745 if md.inversion.max_parameters.size>1: 746 md.inversion.max_parameters=project2d(md,md.inversion.max_parameters,md.mesh.numberoflayers) 747 if not np.isnan(md.smb.mass_balance).all(): 748 md.smb.mass_balance=project2d(md,md.smb.mass_balance,md.mesh.numberoflayers) 749 750 #results 751 if not np.isnan(md.initialization.vx).all(): 752 md.initialization.vx=DepthAverage(md,md.initialization.vx) 753 if not np.isnan(md.initialization.vy).all(): 754 md.initialization.vy=DepthAverage(md,md.initialization.vy) 755 if not np.isnan(md.initialization.vz).all(): 756 md.initialization.vz=DepthAverage(md,md.initialization.vz) 757 if not np.isnan(md.initialization.vel).all(): 758 md.initialization.vel=DepthAverage(md,md.initialization.vel) 759 if not np.isnan(md.initialization.temperature).all(): 760 md.initialization.temperature=DepthAverage(md,md.initialization.temperature) 761 if not np.isnan(md.initialization.pressure).all(): 762 md.initialization.pressure=project2d(md,md.initialization.pressure,1) 763 if not np.isnan(md.initialization.sediment_head).all(): 764 md.initialization.sediment_head=project2d(md,md.initialization.sediment_head,1) 765 if not np.isnan(md.initialization.epl_head).all(): 766 md.initialization.epl_head=project2d(md,md.initialization.epl_head,1) 767 if not np.isnan(md.initialization.epl_thickness).all(): 768 md.initialization.epl_thickness=project2d(md,md.initialization.epl_thickness,1) 769 770 #giaivins 771 if not np.isnan(md.gia.mantle_viscosity).all(): 772 md.gia.mantle_viscosity=project2d(md,md.gia.mantle_viscosity,1) 773 if not np.isnan(md.gia.lithosphere_thickness).all(): 774 md.gia.lithosphere_thickness=project2d(md,md.gia.lithosphere_thickness,1) 775 776 #elementstype 777 if not np.isnan(md.flowequation.element_equation).all(): 778 md.flowequation.element_equation=project2d(md,md.flowequation.element_equation,1) 779 md.flowequation.vertex_equation=project2d(md,md.flowequation.vertex_equation,1) 780 md.flowequation.borderSSA=project2d(md,md.flowequation.borderSSA,1) 781 md.flowequation.borderHO=project2d(md,md.flowequation.borderHO,1) 782 md.flowequation.borderFS=project2d(md,md.flowequation.borderFS,1) 783 784 # Hydrologydc variables 785 if type(md.hydrology) is 'hydrologydc': 786 md.hydrology.spcsediment_head=project2d(md,md.hydrology.spcsediment_head,1) 787 md.hydrology.sediment_transmitivity=project2d(md,md.hydrology.sediment_transmitivity,1) 788 md.hydrology.basal_moulin_input=project2d(md,md.hydrology.basal_moulin_input,1) 789 md.hydrology.mask_thawed_node=project2d(md,md.hydrology.mask_thawed_node,1) 790 if md.hydrology.isefficientlayer == 1: 791 md.hydrology.mask_eplactive_node=project2d(md,md.hydrology.mask_eplactive_node,1) 792 md.hydrology.spcepl_head=project2d(md,md.hydrology.spcepl_head,1) 793 794 #boundary conditions 795 md.stressbalance.spcvx=project2d(md,md.stressbalance.spcvx,md.mesh.numberoflayers) 796 md.stressbalance.spcvy=project2d(md,md.stressbalance.spcvy,md.mesh.numberoflayers) 797 md.stressbalance.spcvz=project2d(md,md.stressbalance.spcvz,md.mesh.numberoflayers) 798 md.stressbalance.referential=project2d(md,md.stressbalance.referential,md.mesh.numberoflayers) 799 md.stressbalance.loadingforce=project2d(md,md.stressbalance.loadingforce,md.mesh.numberoflayers) 800 md.masstransport.spcthickness=project2d(md,md.masstransport.spcthickness,md.mesh.numberoflayers) 801 md.thermal.spctemperature=project2d(md,md.thermal.spctemperature,md.mesh.numberoflayers-1) 802 if not np.isnan(md.damage.spcdamage).all(): 803 md.damage.spcdamage=project2d(md,md.damage.spcdamage,md.mesh.numberoflayers-1) 804 805 #materials 806 md.materials.rheology_B=DepthAverage(md,md.materials.rheology_B) 807 md.materials.rheology_n=project2d(md,md.materials.rheology_n,1) 808 809 #damage: 810 if md.damage.isdamage: 811 md.damage.D=DepthAverage(md,md.damage.D) 812 813 #special for thermal modeling: 814 md.basalforcings.groundedice_melting_rate=project2d(md,md.basalforcings.groundedice_melting_rate,1) 815 md.basalforcings.floatingice_melting_rate=project2d(md,md.basalforcings.floatingice_melting_rate,1) 816 md.basalforcings.geothermalflux=project2d(md,md.basalforcings.geothermalflux,1) #bedrock only gets geothermal flux 817 818 #update of connectivity matrix 819 md.mesh.average_vertex_connectivity=25 820 821 #Collapse the mesh 822 nodes2d=md.mesh.numberofvertices2d 823 elements2d=md.mesh.numberofelements2d 824 825 #parameters 826 md.geometry.surface=project2d(md,md.geometry.surface,1) 827 md.geometry.thickness=project2d(md,md.geometry.thickness,1) 828 md.geometry.base=project2d(md,md.geometry.base,1) 829 if isinstance(md.geometry.bed,np.ndarray): 830 md.geometry.bed=project2d(md,md.geometry.bed,1) 831 md.mask.groundedice_levelset=project2d(md,md.mask.groundedice_levelset,1) 832 md.mask.ice_levelset=project2d(md,md.mask.ice_levelset,1) 833 834 #OutputDefinitions 835 if md.outputdefinition.definitions: 836 for solutionfield,field in list(md.outputdefinition.__dict__.items()): 837 if isinstance(field,list): 838 #get each definition 839 for i,fieldi in enumerate(field): 840 if fieldi: 841 fieldr=getattr(md.outputdefinition,solutionfield)[i] 842 #get subfields 843 for solutionsubfield,subfield in list(fieldi.__dict__.items()): 844 if np.size(subfield)==md.mesh.numberofvertices: 845 setattr(fieldr,solutionsubfield,project2d(md,subfield,1)) 846 elif np.size(subfield)==md.mesh.numberofelements: 847 setattr(fieldr,solutionsubfield,project2d(md,subfield,1)) 848 849 850 #Initialize with the 2d mesh 851 mesh=mesh2d() 852 mesh.x=md.mesh.x2d 853 mesh.y=md.mesh.y2d 854 mesh.numberofvertices=md.mesh.numberofvertices2d 855 mesh.numberofelements=md.mesh.numberofelements2d 856 mesh.elements=md.mesh.elements2d 857 if not np.isnan(md.mesh.vertexonboundary).all(): 858 mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1) 859 if not np.isnan(md.mesh.elementconnectivity).all(): 860 mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1) 861 if isinstance(md.mesh.lat,np.ndarray): 862 if md.mesh.lat.size==md.mesh.numberofvertices: 863 mesh.lat=project2d(md,md.mesh.lat,1) 864 if isinstance(md.mesh.long,np.ndarray): 865 if md.mesh.long.size==md.mesh.numberofvertices: 866 md.mesh.long=project2d(md,md.mesh.long,1) 867 mesh.epsg=md.mesh.epsg 868 if isinstance(md.mesh.scale_factor,np.ndarray): 869 if md.mesh.scale_factor.size==md.mesh.numberofvertices: 870 md.mesh.scale_factor=project2d(md,md.mesh.scale_factor,1) 871 md.mesh=mesh 872 md.mesh.vertexconnectivity=NodeConnectivity(md.mesh.elements,md.mesh.numberofvertices)[0] 873 md.mesh.elementconnectivity=ElementConnectivity(md.mesh.elements,md.mesh.vertexconnectivity)[0] 874 md.mesh.segments=contourenvelope(md) 875 876 return md 75 #properties 76 def __init__(self): #{{{ 77 78 # classtype = model.properties 79 80 # for classe in dict.keys(classtype): 81 # print classe 82 # self.__dict__[classe] = classtype[str(classe)] 83 84 self.mesh = mesh2d() 85 self.mask = mask() 86 self.geometry = geometry() 87 self.constants = constants() 88 self.smb = SMBforcing() 89 self.basalforcings = basalforcings() 90 self.materials = matice() 91 self.damage = damage() 92 self.friction = friction() 93 self.flowequation = flowequation() 94 self.timestepping = timestepping() 95 self.initialization = initialization() 96 self.rifts = rifts() 97 self.slr = slr() 98 99 self.debug = debug() 100 self.verbose = verbose() 101 self.settings = issmsettings() 102 self.toolkits = toolkits() 103 self.cluster = generic() 104 105 self.balancethickness = balancethickness() 106 self.stressbalance = stressbalance() 107 self.groundingline = groundingline() 108 self.hydrology = hydrologyshreve() 109 self.masstransport = masstransport() 110 self.thermal = thermal() 111 self.steadystate = steadystate() 112 self.transient = transient() 113 self.levelset = levelset() 114 self.calving = calving() 115 self.frontalforcings = frontalforcings() 116 self.gia = giaivins() 117 self.love = fourierlove() 118 self.esa = esa() 119 self.autodiff = autodiff() 120 self.inversion = inversion() 121 self.qmu = qmu() 122 self.amr = amr() 123 124 self.results = results() 125 self.outputdefinition = outputdefinition() 126 self.radaroverlay = radaroverlay() 127 self.miscellaneous = miscellaneous() 128 self.private = private() 129 #}}} 130 131 def properties(self): # {{{ 132 # ordered list of properties since vars(self) is random 133 return ['mesh', 134 'mask', 135 'geometry', 136 'constants', 137 'smb', 138 'basalforcings', 139 'materials', 140 'damage', 141 'friction', 142 'flowequation', 143 'timestepping', 144 'initialization', 145 'rifts', 146 'slr', 147 'debug', 148 'verbose', 149 'settings', 150 'toolkits', 151 'cluster', 152 'balancethickness', 153 'stressbalance', 154 'groundingline', 155 'hydrology', 156 'masstransport', 157 'thermal', 158 'steadystate', 159 'transient', 160 'levelset', 161 'calving', 162 'frontalforcings', 163 'love', 164 'gia', 165 'esa', 166 'autodiff', 167 'inversion', 168 'qmu', 169 'amr', 170 'outputdefinition', 171 'results', 172 'radaroverlay', 173 'miscellaneous', 174 'private'] 175 # }}} 176 177 def __repr__(obj): #{{{ 178 #print "Here %s the number: %d" % ("is", 37) 179 string = "%19s: %-22s -- %s" % ("mesh", "[%s, %s]" % ("1x1", obj.mesh.__class__.__name__), "mesh properties") 180 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("mask", "[%s, %s]" % ("1x1", obj.mask.__class__.__name__), "defines grounded and floating elements")) 181 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("geometry", "[%s, %s]" % ("1x1", obj.geometry.__class__.__name__), "surface elevation, bedrock topography, ice thickness, ...")) 182 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("constants", "[%s, %s]" % ("1x1", obj.constants.__class__.__name__), "physical constants")) 183 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("smb", "[%s, %s]" % ("1x1", obj.smb.__class__.__name__), "surface mass balance")) 184 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("basalforcings", "[%s, %s]" % ("1x1", obj.basalforcings.__class__.__name__), "bed forcings")) 185 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("materials", "[%s, %s]" % ("1x1", obj.materials.__class__.__name__), "material properties")) 186 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("damage", "[%s, %s]" % ("1x1", obj.damage.__class__.__name__), "damage propagation laws")) 187 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("friction", "[%s, %s]" % ("1x1", obj.friction.__class__.__name__), "basal friction/drag properties")) 188 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("flowequation", "[%s, %s]" % ("1x1", obj.flowequation.__class__.__name__), "flow equations")) 189 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("timestepping", "[%s, %s]" % ("1x1", obj.timestepping.__class__.__name__), "time stepping for transient models")) 190 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("initialization", "[%s, %s]" % ("1x1", obj.initialization.__class__.__name__), "initial guess/state")) 191 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("rifts", "[%s, %s]" % ("1x1", obj.rifts.__class__.__name__), "rifts properties")) 192 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("slr", "[%s, %s]" % ("1x1", obj.slr.__class__.__name__), "slr forcings")) 193 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("debug", "[%s, %s]" % ("1x1", obj.debug.__class__.__name__), "debugging tools (valgrind, gprof)")) 194 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("verbose", "[%s, %s]" % ("1x1", obj.verbose.__class__.__name__), "verbosity level in solve")) 195 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("settings", "[%s, %s]" % ("1x1", obj.settings.__class__.__name__), "settings properties")) 196 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("toolkits", "[%s, %s]" % ("1x1", obj.toolkits.__class__.__name__), "PETSc options for each solution")) 197 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("cluster", "[%s, %s]" % ("1x1", obj.cluster.__class__.__name__), "cluster parameters (number of cpus...)")) 198 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("balancethickness", "[%s, %s]" % ("1x1", obj.balancethickness.__class__.__name__), "parameters for balancethickness solution")) 199 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("stressbalance", "[%s, %s]" % ("1x1", obj.stressbalance.__class__.__name__), "parameters for stressbalance solution")) 200 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("groundingline", "[%s, %s]" % ("1x1", obj.groundingline.__class__.__name__), "parameters for groundingline solution")) 201 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("hydrology", "[%s, %s]" % ("1x1", obj.hydrology.__class__.__name__), "parameters for hydrology solution")) 202 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("masstransport", "[%s, %s]" % ("1x1", obj.masstransport.__class__.__name__), "parameters for masstransport solution")) 203 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("thermal", "[%s, %s]" % ("1x1", obj.thermal.__class__.__name__), "parameters for thermal solution")) 204 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("steadystate", "[%s, %s]" % ("1x1", obj.steadystate.__class__.__name__), "parameters for steadystate solution")) 205 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("transient", "[%s, %s]" % ("1x1", obj.transient.__class__.__name__), "parameters for transient solution")) 206 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("levelset", "[%s, %s]" % ("1x1", obj.levelset.__class__.__name__), "parameters for moving boundaries (level-set method)")) 207 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("calving", "[%s, %s]" % ("1x1", obj.calving.__class__.__name__), "parameters for calving")) 208 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("frontalforcings", "[%s, %s]" % ("1x1", obj.frontalforcings.__class__.__name__), "parameters for frontalforcings")) 209 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("gia", "[%s, %s]" % ("1x1", obj.gia.__class__.__name__), "parameters for gia solution")) 210 string = "%s\n%s" % (string, '%19s: %-22s -- %s' % ("love", "[%s, %s]" % ("1x1", obj.love.__class__.__name__), "parameters for love solution")) 211 string = "%s\n%s" % (string, '%19s: %-22s -- %s' % ("esa", "[%s, %s]" % ("1x1", obj.esa.__class__.__name__), "parameters for elastic adjustment solution")) 212 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("autodiff", "[%s, %s]" % ("1x1", obj.autodiff.__class__.__name__), "automatic differentiation parameters")) 213 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("inversion", "[%s, %s]" % ("1x1", obj.inversion.__class__.__name__), "parameters for inverse methods")) 214 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("qmu", "[%s, %s]" % ("1x1", obj.qmu.__class__.__name__), "dakota properties")) 215 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("amr", "[%s, %s]" % ("1x1", obj.amr.__class__.__name__), "adaptive mesh refinement properties")) 216 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("outputdefinition", "[%s, %s]" % ("1x1", obj.outputdefinition.__class__.__name__), "output definition")) 217 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("results", "[%s, %s]" % ("1x1", obj.results.__class__.__name__), "model results")) 218 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("radaroverlay", "[%s, %s]" % ("1x1", obj.radaroverlay.__class__.__name__), "radar image for plot overlay")) 219 string = "%s\n%s" % (string, "%19s: %-22s -- %s" % ("miscellaneous", "[%s, %s]" % ("1x1", obj.miscellaneous.__class__.__name__), "miscellaneous fields")) 220 return string 221 # }}} 222 223 def checkmessage(self, string): # {{{ 224 print("model not consistent: {}".format(string)) 225 self.private.isconsistent = False 226 return self 227 # }}} 228 #@staticmethod 229 230 def extract(self, area): # {{{ 231 """ 232 extract - extract a model according to an Argus contour or flag list 233 234 This routine extracts a submodel from a bigger model with respect to a given contour 235 md must be followed by the corresponding exp file or flags list 236 It can either be a domain file (argus type, .exp extension), or an array of element flags. 237 If user wants every element outside the domain to be 238 extract2d, add '~' to the name of the domain file (ex: '~HO.exp') 239 an empty string '' will be considered as an empty domain 240 a string 'all' will be considered as the entire domain 241 242 Usage: 243 md2 = extract(md, area) 244 245 Examples: 246 md2 = extract(md, 'Domain.exp') 247 248 See also: EXTRUDE, COLLAPSE 249 """ 250 251 #copy model 252 md1 = copy.deepcopy(self) 253 254 #get elements that are inside area 255 flag_elem = FlagElements(md1, area) 256 if not np.any(flag_elem): 257 raise RuntimeError("extracted model is empty") 258 259 #kick out all elements with 3 dirichlets 260 spc_elem = np.nonzero(np.logical_not(flag_elem))[0] 261 spc_node = np.unique(md1.mesh.elements[spc_elem, :]) - 1 262 flag = np.ones(md1.mesh.numberofvertices) 263 flag[spc_node] = 0 264 pos = np.nonzero(np.logical_not(np.sum(flag[md1.mesh.elements - 1], axis=1)))[0] 265 flag_elem[pos] = 0 266 267 #extracted elements and nodes lists 268 pos_elem = np.nonzero(flag_elem)[0] 269 pos_node = np.unique(md1.mesh.elements[pos_elem, :]) - 1 270 271 #keep track of some fields 272 numberofvertices1 = md1.mesh.numberofvertices 273 numberofelements1 = md1.mesh.numberofelements 274 numberofvertices2 = np.size(pos_node) 275 numberofelements2 = np.size(pos_elem) 276 flag_node = np.zeros(numberofvertices1) 277 flag_node[pos_node] = 1 278 279 #Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements) 280 Pelem = np.zeros(numberofelements1, int) 281 Pelem[pos_elem] = np.arange(1, numberofelements2 + 1) 282 Pnode = np.zeros(numberofvertices1, int) 283 Pnode[pos_node] = np.arange(1, numberofvertices2 + 1) 284 285 #renumber the elements (some node won't exist anymore) 286 elements_1 = copy.deepcopy(md1.mesh.elements) 287 elements_2 = elements_1[pos_elem, :] 288 elements_2[:, 0] = Pnode[elements_2[:, 0] - 1] 289 elements_2[:, 1] = Pnode[elements_2[:, 1] - 1] 290 elements_2[:, 2] = Pnode[elements_2[:, 2] - 1] 291 if md1.mesh.__class__.__name__ == 'mesh3dprisms': 292 elements_2[:, 3] = Pnode[elements_2[:, 3] - 1] 293 elements_2[:, 4] = Pnode[elements_2[:, 4] - 1] 294 elements_2[:, 5] = Pnode[elements_2[:, 5] - 1] 295 296 #OK, now create the new model! 297 298 #take every field from model 299 md2 = copy.deepcopy(md1) 300 301 #automatically modify fields 302 303 #loop over model fields 304 model_fields = vars(md1) 305 for fieldi in model_fields: 306 #get field 307 field = getattr(md1, fieldi) 308 fieldsize = np.shape(field) 309 if hasattr(field, '__dict__') and fieldi not in ['results']: #recursive call 310 object_fields = vars(field) 311 for fieldj in object_fields: 312 #get field 313 field = getattr(getattr(md1, fieldi), fieldj) 314 fieldsize = np.shape(field) 315 if len(fieldsize): 316 #size = number of nodes * n 317 if fieldsize[0] == numberofvertices1: 318 setattr(getattr(md2, fieldi), fieldj, field[pos_node]) 319 elif fieldsize[0] == numberofvertices1 + 1: 320 setattr(getattr(md2, fieldi), fieldj, np.vstack((field[pos_node], field[-1, :]))) 321 #size = number of elements * n 322 elif fieldsize[0] == numberofelements1: 323 setattr(getattr(md2, fieldi), fieldj, field[pos_elem]) 324 else: 325 if len(fieldsize): 326 #size = number of nodes * n 327 if fieldsize[0] == numberofvertices1: 328 setattr(md2, fieldi, field[pos_node]) 329 elif fieldsize[0] == numberofvertices1 + 1: 330 setattr(md2, fieldi, np.hstack((field[pos_node], field[-1, :]))) 331 #size = number of elements * n 332 elif fieldsize[0] == numberofelements1: 333 setattr(md2, fieldi, field[pos_elem]) 334 335 #modify some specific fields 336 337 #Mesh 338 md2.mesh.numberofelements = numberofelements2 339 md2.mesh.numberofvertices = numberofvertices2 340 md2.mesh.elements = elements_2 341 342 #mesh.uppervertex mesh.lowervertex 343 if md1.mesh.__class__.__name__ == 'mesh3dprisms': 344 md2.mesh.uppervertex = md1.mesh.uppervertex[pos_node] 345 pos = np.where(~np.isnan(md2.mesh.uppervertex))[0] 346 md2.mesh.uppervertex[pos] = Pnode[md2.mesh.uppervertex[pos].astype(int) - 1] 347 348 md2.mesh.lowervertex = md1.mesh.lowervertex[pos_node] 349 pos = np.where(~np.isnan(md2.mesh.lowervertex))[0] 350 md2.mesh.lowervertex[pos] = Pnode[md2.mesh.lowervertex[pos].astype(int) - 1] 351 352 md2.mesh.upperelements = md1.mesh.upperelements[pos_elem] 353 pos = np.where(~np.isnan(md2.mesh.upperelements))[0] 354 md2.mesh.upperelements[pos] = Pelem[md2.mesh.upperelements[pos].astype(int) - 1] 355 356 md2.mesh.lowerelements = md1.mesh.lowerelements[pos_elem] 357 pos = np.where(~np.isnan(md2.mesh.lowerelements))[0] 358 md2.mesh.lowerelements[pos] = Pelem[md2.mesh.lowerelements[pos].astype(int) - 1] 359 360 #Initial 2d mesh 361 if md1.mesh.__class__.__name__ == 'mesh3dprisms': 362 flag_elem_2d = flag_elem[np.arange(0, md1.mesh.numberofelements2d)] 363 pos_elem_2d = np.nonzero(flag_elem_2d)[0] 364 flag_node_2d = flag_node[np.arange(0, md1.mesh.numberofvertices2d)] 365 pos_node_2d = np.nonzero(flag_node_2d)[0] 366 367 md2.mesh.numberofelements2d = np.size(pos_elem_2d) 368 md2.mesh.numberofvertices2d = np.size(pos_node_2d) 369 md2.mesh.elements2d = md1.mesh.elements2d[pos_elem_2d, :] 370 md2.mesh.elements2d[:, 0] = Pnode[md2.mesh.elements2d[:, 0] - 1] 371 md2.mesh.elements2d[:, 1] = Pnode[md2.mesh.elements2d[:, 1] - 1] 372 md2.mesh.elements2d[:, 2] = Pnode[md2.mesh.elements2d[:, 2] - 1] 373 374 md2.mesh.x2d = md1.mesh.x[pos_node_2d] 375 md2.mesh.y2d = md1.mesh.y[pos_node_2d] 376 377 #Edges 378 if md1.mesh.domaintype() == '2Dhorizontal': 379 if np.ndim(md2.mesh.edges) > 1 and np.size(md2.mesh.edges, axis=1) > 1: #do not use ~isnan because there are some np.nans... 380 #renumber first two columns 381 pos = np.nonzero(md2.mesh.edges[:, 3] != -1)[0] 382 md2.mesh.edges[:, 0] = Pnode[md2.mesh.edges[:, 0] - 1] 383 md2.mesh.edges[:, 1] = Pnode[md2.mesh.edges[:, 1] - 1] 384 md2.mesh.edges[:, 2] = Pelem[md2.mesh.edges[:, 2] - 1] 385 md2.mesh.edges[pos, 3] = Pelem[md2.mesh.edges[pos, 3] - 1] 386 #remove edges when the 2 vertices are not in the domain. 387 md2.mesh.edges = md2.mesh.edges[np.nonzero(np.logical_and(md2.mesh.edges[:, 0], md2.mesh.edges[:, 1]))[0], :] 388 #Replace all zeros by -1 in the last two columns 389 pos = np.nonzero(md2.mesh.edges[:, 2] == 0)[0] 390 md2.mesh.edges[pos, 2] = -1 391 pos = np.nonzero(md2.mesh.edges[:, 3] == 0)[0] 392 md2.mesh.edges[pos, 3] = -1 393 #Invert -1 on the third column with last column (Also invert first two columns!!) 394 pos = np.nonzero(md2.mesh.edges[:, 2] == -1)[0] 395 md2.mesh.edges[pos, 2] = md2.mesh.edges[pos, 3] 396 md2.mesh.edges[pos, 3] = - 1 397 values = md2.mesh.edges[pos, 1] 398 md2.mesh.edges[pos, 1] = md2.mesh.edges[pos, 0] 399 md2.mesh.edges[pos, 0] = values 400 #Finally remove edges that do not belong to any element 401 pos = np.nonzero(np.logical_and(md2.mesh.edges[:, 1] == - 1, md2.mesh.edges[:, 2] == - 1))[0] 402 md2.mesh.edges = np.delete(md2.mesh.edges, pos, axis=0) 403 404 #Penalties 405 if np.any(np.logical_not(np.isnan(md2.stressbalance.vertex_pairing))): 406 for i in range(np.size(md1.stressbalance.vertex_pairing, axis=0)): 407 md2.stressbalance.vertex_pairing[i, :] = Pnode[md1.stressbalance.vertex_pairing[i, :]] 408 md2.stressbalance.vertex_pairing = md2.stressbalance.vertex_pairing[np.nonzero(md2.stressbalance.vertex_pairing[:, 0])[0], :] 409 if np.any(np.logical_not(np.isnan(md2.masstransport.vertex_pairing))): 410 for i in range(np.size(md1.masstransport.vertex_pairing, axis=0)): 411 md2.masstransport.vertex_pairing[i, :] = Pnode[md1.masstransport.vertex_pairing[i, :]] 412 md2.masstransport.vertex_pairing = md2.masstransport.vertex_pairing[np.nonzero(md2.masstransport.vertex_pairing[:, 0])[0], :] 413 414 #recreate segments 415 if md1.mesh.__class__.__name__ == 'mesh2d': 416 md2.mesh.vertexconnectivity = NodeConnectivity(md2.mesh.elements, md2.mesh.numberofvertices)[0] 417 md2.mesh.elementconnectivity = ElementConnectivity(md2.mesh.elements, md2.mesh.vertexconnectivity)[0] 418 md2.mesh.segments = contourenvelope(md2) 419 md2.mesh.vertexonboundary = np.zeros(numberofvertices2, bool) 420 md2.mesh.vertexonboundary[md2.mesh.segments[:, 0:2] - 1] = True 421 else: 422 #First do the connectivity for the contourenvelope in 2d 423 md2.mesh.vertexconnectivity = NodeConnectivity(md2.mesh.elements2d, md2.mesh.numberofvertices2d)[0] 424 md2.mesh.elementconnectivity = ElementConnectivity(md2.mesh.elements2d, md2.mesh.vertexconnectivity)[0] 425 segments = contourenvelope(md2) 426 md2.mesh.vertexonboundary = np.zeros(int(numberofvertices2 / md2.mesh.numberoflayers), bool) 427 md2.mesh.vertexonboundary[segments[:, 0:2] - 1] = True 428 md2.mesh.vertexonboundary = np.tile(md2.mesh.vertexonboundary, md2.mesh.numberoflayers) 429 #Then do it for 3d as usual 430 md2.mesh.vertexconnectivity = NodeConnectivity(md2.mesh.elements, md2.mesh.numberofvertices)[0] 431 md2.mesh.elementconnectivity = ElementConnectivity(md2.mesh.elements, md2.mesh.vertexconnectivity)[0] 432 433 #Boundary conditions: Dirichlets on new boundary 434 #Catch the elements that have not been extracted 435 orphans_elem = np.nonzero(np.logical_not(flag_elem))[0] 436 orphans_node = np.unique(md1.mesh.elements[orphans_elem, :]) - 1 437 #Figure out which node are on the boundary between md2 and md1 438 nodestoflag1 = np.intersect1d(orphans_node, pos_node) 439 nodestoflag2 = Pnode[nodestoflag1].astype(int) - 1 440 if np.size(md1.stressbalance.spcvx) > 1 and np.size(md1.stressbalance.spcvy) > 2 and np.size(md1.stressbalance.spcvz) > 2: 441 if np.size(md1.inversion.vx_obs) > 1 and np.size(md1.inversion.vy_obs) > 1: 442 md2.stressbalance.spcvx[nodestoflag2] = md2.inversion.vx_obs[nodestoflag2] 443 md2.stressbalance.spcvy[nodestoflag2] = md2.inversion.vy_obs[nodestoflag2] 444 else: 445 md2.stressbalance.spcvx[nodestoflag2] = np.nan 446 md2.stressbalance.spcvy[nodestoflag2] = np.nan 447 print("\n!! extract warning: spc values should be checked !!\n\n") 448 #put 0 for vz 449 md2.stressbalance.spcvz[nodestoflag2] = 0 450 if np.any(np.logical_not(np.isnan(md1.thermal.spctemperature))): 451 md2.thermal.spctemperature[nodestoflag2] = 1 452 453 #Results fields 454 if md1.results: 455 md2.results = results() 456 for solutionfield, field in list(md1.results.__dict__.items()): 457 if isinstance(field, list): 458 setattr(md2.results, solutionfield, []) 459 #get time step 460 for i, fieldi in enumerate(field): 461 if isinstance(fieldi, results) and fieldi: 462 getattr(md2.results, solutionfield).append(results()) 463 fieldr = getattr(md2.results, solutionfield)[i] 464 #get subfields 465 for solutionsubfield, subfield in list(fieldi.__dict__.items()): 466 if np.size(subfield) == numberofvertices1: 467 setattr(fieldr, solutionsubfield, subfield[pos_node]) 468 elif np.size(subfield) == numberofelements1: 469 setattr(fieldr, solutionsubfield, subfield[pos_elem]) 470 else: 471 setattr(fieldr, solutionsubfield, subfield) 472 else: 473 getattr(md2.results, solutionfield).append(None) 474 elif isinstance(field, results): 475 setattr(md2.results, solutionfield, results()) 476 if isinstance(field, results) and field: 477 fieldr = getattr(md2.results, solutionfield) 478 #get subfields 479 for solutionsubfield, subfield in list(field.__dict__.items()): 480 if np.size(subfield) == numberofvertices1: 481 setattr(fieldr, solutionsubfield, subfield[pos_node]) 482 elif np.size(subfield) == numberofelements1: 483 setattr(fieldr, solutionsubfield, subfield[pos_elem]) 484 else: 485 setattr(fieldr, solutionsubfield, subfield) 486 487 #OutputDefinitions fields 488 if md1.outputdefinition.definitions: 489 for solutionfield, field in list(md1.outputdefinition.__dict__.items()): 490 if isinstance(field, list): 491 #get each definition 492 for i, fieldi in enumerate(field): 493 if fieldi: 494 fieldr = getattr(md2.outputdefinition, solutionfield)[i] 495 #get subfields 496 for solutionsubfield, subfield in list(fieldi.__dict__.items()): 497 if np.size(subfield) == numberofvertices1: 498 setattr(fieldr, solutionsubfield, subfield[pos_node]) 499 elif np.size(subfield) == numberofelements1: 500 setattr(fieldr, solutionsubfield, subfield[pos_elem]) 501 else: 502 setattr(fieldr, solutionsubfield, subfield) 503 504 #Keep track of pos_node and pos_elem 505 md2.mesh.extractedvertices = pos_node + 1 506 md2.mesh.extractedelements = pos_elem + 1 507 508 return md2 509 # }}} 510 511 def extrude(md, *args): # {{{ 512 """ 513 EXTRUDE - vertically extrude a 2d mesh 514 515 vertically extrude a 2d mesh and create corresponding 3d mesh. 516 The vertical distribution can: 517 - follow a polynomial law 518 - follow two polynomial laws, one for the lower part and one for the upper part of the mesh 519 - be discribed by a list of coefficients (between 0 and 1) 520 521 522 Usage: 523 md = extrude(md, numlayers, extrusionexponent) 524 md = extrude(md, numlayers, lowerexponent, upperexponent) 525 md = extrude(md, listofcoefficients) 526 527 Example: 528 md = extrude(md, 15, 1.3); 529 md = extrude(md, 15, 1.3, 1.2); 530 md = extrude(md, [0 0.2 0.5 0.7 0.9 0.95 1]) 531 532 See also: MODELEXTRACT, COLLAPSE 533 """ 534 535 #some checks on list of arguments 536 if len(args) > 3 or len(args) < 1: 537 raise RuntimeError("extrude error message") 538 539 #Extrude the mesh 540 if len(args) == 1: #list of coefficients 541 clist = args[0] 542 if any(clist < 0) or any(clist > 1): 543 raise TypeError("extrusioncoefficients must be between 0 and 1") 544 clist.extend([0., 1.]) 545 clist.sort() 546 extrusionlist = list(set(clist)) 547 numlayers = len(extrusionlist) 548 549 elif len(args) == 2: #one polynomial law 550 if args[1] <= 0: 551 raise TypeError("extrusionexponent must be >=0") 552 numlayers = args[0] 553 extrusionlist = (np.arange(0., float(numlayers - 1) + 1., 1.) / float(numlayers - 1))**args[1] 554 555 elif len(args) == 3: #two polynomial laws 556 numlayers = args[0] 557 lowerexp = args[1] 558 upperexp = args[2] 559 560 if args[1] <= 0 or args[2] <= 0: 561 raise TypeError("lower and upper extrusionexponents must be >=0") 562 563 lowerextrusionlist = (np.arange(0., 1. + 2. / float(numlayers - 1), 2. / float(numlayers - 1)))**lowerexp / 2. 564 upperextrusionlist = (np.arange(0., 1. + 2. / float(numlayers - 1), 2. / float(numlayers - 1)))**upperexp / 2. 565 extrusionlist = np.unique(np.concatenate((lowerextrusionlist, 1. - upperextrusionlist))) 566 567 if numlayers < 2: 568 raise TypeError("number of layers should be at least 2") 569 if md.mesh.__class__.__name__ == 'mesh3dprisms': 570 raise TypeError("Cannot extrude a 3d mesh (extrude cannot be called more than once)") 571 572 #Initialize with the 2d mesh 573 mesh2d = md.mesh 574 md.mesh = mesh3dprisms() 575 md.mesh.x = mesh2d.x 576 md.mesh.y = mesh2d.y 577 md.mesh.elements = mesh2d.elements 578 md.mesh.numberofelement = mesh2d.numberofelements 579 md.mesh.numberofvertice = mesh2d.numberofvertices 580 581 md.mesh.lat = mesh2d.lat 582 md.mesh.long = mesh2d.long 583 md.mesh.epsg = mesh2d.epsg 584 md.mesh.scale_factor = mesh2d.scale_factor 585 586 md.mesh.vertexonboundary = mesh2d.vertexonboundary 587 md.mesh.vertexconnectivity = mesh2d.vertexconnectivity 588 md.mesh.elementconnectivity = mesh2d.elementconnectivity 589 md.mesh.average_vertex_connectivity = mesh2d.average_vertex_connectivity 590 591 md.mesh.extractedvertices = mesh2d.extractedvertices 592 md.mesh.extractedelements = mesh2d.extractedelements 593 594 x3d = np.empty((0)) 595 y3d = np.empty((0)) 596 z3d = np.empty((0)) #the lower node is on the bed 597 thickness3d = md.geometry.thickness #thickness and bed for these nodes 598 bed3d = md.geometry.base 599 600 #Create the new layers 601 for i in range(numlayers): 602 x3d = np.concatenate((x3d, md.mesh.x)) 603 y3d = np.concatenate((y3d, md.mesh.y)) 604 #nodes are distributed between bed and surface accordingly to the given exponent 605 z3d = np.concatenate((z3d, (bed3d + thickness3d * extrusionlist[i]).reshape(-1))) 606 number_nodes3d = np.size(x3d) #number of 3d nodes for the non extruded part of the mesh 607 608 #Extrude elements 609 elements3d = np.empty((0, 6), int) 610 for i in range(numlayers - 1): 611 elements3d = np.vstack((elements3d, np.hstack((md.mesh.elements + i * md.mesh.numberofvertices, 612 md.mesh.elements + (i + 1) * md.mesh.numberofvertices)))) #Create the elements of the 3d mesh for the non extruded part 613 number_el3d = np.size(elements3d, axis=0) #number of 3d nodes for the non extruded part of the mesh 614 615 #Keep a trace of lower and upper nodes 616 lowervertex = np.nan * np.ones(number_nodes3d, int) 617 uppervertex = np.nan * np.ones(number_nodes3d, int) 618 lowervertex[md.mesh.numberofvertices:] = np.arange(1, (numlayers - 1) * md.mesh.numberofvertices + 1) 619 uppervertex[:(numlayers - 1) * md.mesh.numberofvertices] = np.arange(md.mesh.numberofvertices + 1, number_nodes3d + 1) 620 md.mesh.lowervertex = lowervertex 621 md.mesh.uppervertex = uppervertex 622 623 #same for lower and upper elements 624 lowerelements = np.nan * np.ones(number_el3d, int) 625 upperelements = np.nan * np.ones(number_el3d, int) 626 lowerelements[md.mesh.numberofelements:] = np.arange(1, (numlayers - 2) * md.mesh.numberofelements + 1) 627 upperelements[:(numlayers - 2) * md.mesh.numberofelements] = np.arange(md.mesh.numberofelements + 1, (numlayers - 1) * md.mesh.numberofelements + 1) 628 md.mesh.lowerelements = lowerelements 629 md.mesh.upperelements = upperelements 630 631 #Save old mesh 632 md.mesh.x2d = md.mesh.x 633 md.mesh.y2d = md.mesh.y 634 md.mesh.elements2d = md.mesh.elements 635 md.mesh.numberofelements2d = md.mesh.numberofelements 636 md.mesh.numberofvertices2d = md.mesh.numberofvertices 637 638 #Build global 3d mesh 639 md.mesh.elements = elements3d 640 md.mesh.x = x3d 641 md.mesh.y = y3d 642 md.mesh.z = z3d 643 md.mesh.numberofelements = number_el3d 644 md.mesh.numberofvertices = number_nodes3d 645 md.mesh.numberoflayers = numlayers 646 647 #Ok, now deal with the other fields from the 2d mesh: 648 649 #bedinfo and surface info 650 md.mesh.vertexonbase = project3d(md, 'vector', np.ones(md.mesh.numberofvertices2d, bool), 'type', 'node', 'layer', 1) 651 md.mesh.vertexonsurface = project3d(md, 'vector', np.ones(md.mesh.numberofvertices2d, bool), 'type', 'node', 'layer', md.mesh.numberoflayers) 652 md.mesh.vertexonboundary = project3d(md, 'vector', md.mesh.vertexonboundary, 'type', 'node') 653 654 #lat long 655 md.mesh.lat = project3d(md, 'vector', md.mesh.lat, 'type', 'node') 656 md.mesh.long = project3d(md, 'vector', md.mesh.long, 'type', 'node') 657 md.mesh.scale_factor = project3d(md, 'vector', md.mesh.scale_factor, 'type', 'node') 658 659 md.geometry.extrude(md) 660 md.friction.extrude(md) 661 md.inversion.extrude(md) 662 md.smb.extrude(md) 663 md.initialization.extrude(md) 664 md.flowequation.extrude(md) 665 666 md.stressbalance.extrude(md) 667 md.thermal.extrude(md) 668 md.masstransport.extrude(md) 669 670 # Calving variables 671 md.hydrology.extrude(md) 672 md.levelset.extrude(md) 673 md.calving.extrude(md) 674 md.frontalforcings.extrude(md) 675 676 #connectivity 677 md.mesh.elementconnectivity = np.tile(md.mesh.elementconnectivity, (numlayers - 1, 1)) 678 md.mesh.elementconnectivity[np.nonzero(md.mesh.elementconnectivity == 0)] = -sys.maxsize - 1 679 if not np.isnan(md.mesh.elementconnectivity).all(): 680 for i in range(1, numlayers - 1): 681 connect1 = i * md.mesh.numberofelements2d 682 connect2 = (i + 1) * md.mesh.numberofelements2d 683 md.mesh.elementconnectivity[connect1:connect2, :] = md.mesh.elementconnectivity[connect1:connect2, :] + md.mesh.numberofelements2d 684 md.mesh.elementconnectivity[np.nonzero(md.mesh.elementconnectivity < 0)] = 0 685 686 md.materials.extrude(md) 687 if md.damage.isdamage == 1: 688 md.damage.extrude(md) 689 md.gia.extrude(md) 690 md.mask.extrude(md) 691 md.qmu.extrude(md) 692 md.basalforcings.extrude(md) 693 md.outputdefinition.extrude(md) 694 695 #increase connectivity if less than 25: 696 if md.mesh.average_vertex_connectivity <= 25: 697 md.mesh.average_vertex_connectivity = 100 698 699 return md 700 # }}} 701 702 def collapse(md): #{{{ 703 ''' 704 collapses a 3d mesh into a 2d mesh 705 706 This routine collapses a 3d model into a 2d model and collapses all 707 the fileds of the 3d model by taking their depth-averaged values 708 709 Usage: 710 md = collapse(md) 711 ''' 712 713 #Check that the model is really a 3d model 714 if md.mesh.domaintype().lower() != '3d': 715 raise Exception("only a 3D model can be collapsed") 716 717 #dealing with the friction law 718 #drag is limited to nodes that are on the bedrock. 719 if hasattr(md.friction, 'coefficient'): 720 md.friction.coefficient = project2d(md, md.friction.coefficient, 1) 721 722 #p and q (same deal, except for element that are on the bedrock: ) 723 if hasattr(md.friction, 'p'): 724 md.friction.p = project2d(md, md.friction.p, 1) 725 if hasattr(md.friction, 'q'): 726 md.friction.q = project2d(md, md.friction.q, 1) 727 728 if hasattr(md.friction, 'coefficientcoulomb'): 729 md.friction.coefficientcoulomb = project2d(md, md.friction.coefficientcoulomb, 1) 730 if hasattr(md.friction, 'C'): 731 md.friction.C = project2d(md, md.friction.C, 1) 732 if hasattr(md.friction, 'As'): 733 md.friction.As = project2d(md, md.friction.As, 1) 734 if hasattr(md.friction, 'effective_pressure') and not np.isnan(md.friction.effective_pressure).all(): 735 md.friction.effective_pressure = project2d(md, md.friction.effective_pressure, 1) 736 if hasattr(md.friction, 'water_layer'): 737 md.friction.water_layer = project2d(md, md.friction.water_layer, 1) 738 if hasattr(md.friction, 'm'): 739 md.friction.m = project2d(md, md.friction.m, 1) 740 741 #observations 742 if not np.isnan(md.inversion.vx_obs).all(): 743 md.inversion.vx_obs = project2d(md, md.inversion.vx_obs, md.mesh.numberoflayers) 744 if not np.isnan(md.inversion.vy_obs).all(): 745 md.inversion.vy_obs = project2d(md, md.inversion.vy_obs, md.mesh.numberoflayers) 746 if not np.isnan(md.inversion.vel_obs).all(): 747 md.inversion.vel_obs = project2d(md, md.inversion.vel_obs, md.mesh.numberoflayers) 748 if not np.isnan(md.inversion.cost_functions_coefficients).all(): 749 md.inversion.cost_functions_coefficients = project2d(md, md.inversion.cost_functions_coefficients, md.mesh.numberoflayers) 750 if isinstance(md.inversion.min_parameters, np.ndarray): 751 if md.inversion.min_parameters.size > 1: 752 md.inversion.min_parameters = project2d(md, md.inversion.min_parameters, md.mesh.numberoflayers) 753 if isinstance(md.inversion.max_parameters, np.ndarray): 754 if md.inversion.max_parameters.size > 1: 755 md.inversion.max_parameters = project2d(md, md.inversion.max_parameters, md.mesh.numberoflayers) 756 if not np.isnan(md.smb.mass_balance).all(): 757 md.smb.mass_balance = project2d(md, md.smb.mass_balance, md.mesh.numberoflayers) 758 759 #results 760 if not np.isnan(md.initialization.vx).all(): 761 md.initialization.vx = DepthAverage(md, md.initialization.vx) 762 if not np.isnan(md.initialization.vy).all(): 763 md.initialization.vy = DepthAverage(md, md.initialization.vy) 764 if not np.isnan(md.initialization.vz).all(): 765 md.initialization.vz = DepthAverage(md, md.initialization.vz) 766 if not np.isnan(md.initialization.vel).all(): 767 md.initialization.vel = DepthAverage(md, md.initialization.vel) 768 if not np.isnan(md.initialization.temperature).all(): 769 md.initialization.temperature = DepthAverage(md, md.initialization.temperature) 770 if not np.isnan(md.initialization.pressure).all(): 771 md.initialization.pressure = project2d(md, md.initialization.pressure, 1) 772 if not np.isnan(md.initialization.sediment_head).all(): 773 md.initialization.sediment_head = project2d(md, md.initialization.sediment_head, 1) 774 if not np.isnan(md.initialization.epl_head).all(): 775 md.initialization.epl_head = project2d(md, md.initialization.epl_head, 1) 776 if not np.isnan(md.initialization.epl_thickness).all(): 777 md.initialization.epl_thickness = project2d(md, md.initialization.epl_thickness, 1) 778 779 #giaivins 780 if not np.isnan(md.gia.mantle_viscosity).all(): 781 md.gia.mantle_viscosity = project2d(md, md.gia.mantle_viscosity, 1) 782 if not np.isnan(md.gia.lithosphere_thickness).all(): 783 md.gia.lithosphere_thickness = project2d(md, md.gia.lithosphere_thickness, 1) 784 785 #elementstype 786 if not np.isnan(md.flowequation.element_equation).all(): 787 md.flowequation.element_equation = project2d(md, md.flowequation.element_equation, 1) 788 md.flowequation.vertex_equation = project2d(md, md.flowequation.vertex_equation, 1) 789 md.flowequation.borderSSA = project2d(md, md.flowequation.borderSSA, 1) 790 md.flowequation.borderHO = project2d(md, md.flowequation.borderHO, 1) 791 md.flowequation.borderFS = project2d(md, md.flowequation.borderFS, 1) 792 793 # Hydrologydc variables 794 hydrofields = md.hydrology.__dict__.keys() 795 for field in hydrofields: 796 try: 797 isvector = np.logical_or(np.shape(md.hydrology.__dict__[field])[0] == md.mesh.numberofelements, 798 np.shape(md.hydrology.__dict__[field])[0] == md.mesh.numberofvertices) 799 except IndexError: 800 isvector = False 801 #we colpase only fields that are vertices or element based 802 if isvector: 803 md.hydrology.__dict__[field] = project2d(md, md.hydrology.__dict__[field], 1) 804 805 806 #boundary conditions 807 md.stressbalance.spcvx = project2d(md, md.stressbalance.spcvx, md.mesh.numberoflayers) 808 md.stressbalance.spcvy = project2d(md, md.stressbalance.spcvy, md.mesh.numberoflayers) 809 md.stressbalance.spcvz = project2d(md, md.stressbalance.spcvz, md.mesh.numberoflayers) 810 md.stressbalance.referential = project2d(md, md.stressbalance.referential, md.mesh.numberoflayers) 811 md.stressbalance.loadingforce = project2d(md, md.stressbalance.loadingforce, md.mesh.numberoflayers) 812 md.masstransport.spcthickness = project2d(md, md.masstransport.spcthickness, md.mesh.numberoflayers) 813 md.thermal.spctemperature = project2d(md, md.thermal.spctemperature, md.mesh.numberoflayers - 1) 814 if not np.isnan(md.damage.spcdamage).all(): 815 md.damage.spcdamage = project2d(md, md.damage.spcdamage, md.mesh.numberoflayers - 1) 816 817 #materials 818 md.materials.rheology_B = DepthAverage(md, md.materials.rheology_B) 819 md.materials.rheology_n = project2d(md, md.materials.rheology_n, 1) 820 821 #damage: 822 if md.damage.isdamage: 823 md.damage.D = DepthAverage(md, md.damage.D) 824 825 #special for thermal modeling: 826 md.basalforcings.groundedice_melting_rate = project2d(md, md.basalforcings.groundedice_melting_rate, 1) 827 md.basalforcings.floatingice_melting_rate = project2d(md, md.basalforcings.floatingice_melting_rate, 1) 828 md.basalforcings.geothermalflux = project2d(md, md.basalforcings.geothermalflux, 1) #bedrock only gets geothermal flux 829 830 #update of connectivity matrix 831 md.mesh.average_vertex_connectivity = 25 832 833 #parameters 834 md.geometry.surface = project2d(md, md.geometry.surface, 1) 835 md.geometry.thickness = project2d(md, md.geometry.thickness, 1) 836 md.geometry.base = project2d(md, md.geometry.base, 1) 837 if isinstance(md.geometry.bed, np.ndarray): 838 md.geometry.bed = project2d(md, md.geometry.bed, 1) 839 md.mask.groundedice_levelset = project2d(md, md.mask.groundedice_levelset, 1) 840 md.mask.ice_levelset = project2d(md, md.mask.ice_levelset, 1) 841 842 #OutputDefinitions 843 if md.outputdefinition.definitions: 844 for solutionfield, field in list(md.outputdefinition.__dict__.items()): 845 if isinstance(field, list): 846 #get each definition 847 for i, fieldi in enumerate(field): 848 if fieldi: 849 fieldr = getattr(md.outputdefinition, solutionfield)[i] 850 #get subfields 851 for solutionsubfield, subfield in list(fieldi.__dict__.items()): 852 if np.size(subfield) == md.mesh.numberofvertices: 853 setattr(fieldr, solutionsubfield, project2d(md, subfield, 1)) 854 elif np.size(subfield) == md.mesh.numberofelements: 855 setattr(fieldr, solutionsubfield, project2d(md, subfield, 1)) 856 857 #Initialize with the 2d mesh 858 mesh = mesh2d() 859 mesh.x = md.mesh.x2d 860 mesh.y = md.mesh.y2d 861 mesh.numberofvertices = md.mesh.numberofvertices2d 862 mesh.numberofelements = md.mesh.numberofelements2d 863 mesh.elements = md.mesh.elements2d 864 if not np.isnan(md.mesh.vertexonboundary).all(): 865 mesh.vertexonboundary = project2d(md, md.mesh.vertexonboundary, 1) 866 if not np.isnan(md.mesh.elementconnectivity).all(): 867 mesh.elementconnectivity = project2d(md, md.mesh.elementconnectivity, 1) 868 if isinstance(md.mesh.lat, np.ndarray): 869 if md.mesh.lat.size == md.mesh.numberofvertices: 870 mesh.lat = project2d(md, md.mesh.lat, 1) 871 if isinstance(md.mesh.long, np.ndarray): 872 if md.mesh.long.size == md.mesh.numberofvertices: 873 md.mesh.long = project2d(md, md.mesh.long, 1) 874 mesh.epsg = md.mesh.epsg 875 if isinstance(md.mesh.scale_factor, np.ndarray): 876 if md.mesh.scale_factor.size == md.mesh.numberofvertices: 877 md.mesh.scale_factor = project2d(md, md.mesh.scale_factor, 1) 878 md.mesh = mesh 879 md.mesh.vertexconnectivity = NodeConnectivity(md.mesh.elements, md.mesh.numberofvertices)[0] 880 md.mesh.elementconnectivity = ElementConnectivity(md.mesh.elements, md.mesh.vertexconnectivity)[0] 881 md.mesh.segments = contourenvelope(md) 882 883 return md 877 884 878 885 #}}} -
issm/trunk-jpl/src/m/extrusion/DepthAverage.py
r23716 r23787 1 import numpy as 1 import numpy as np 2 2 from project2d import project2d 3 3 4 def DepthAverage(md,vector):5 '''6 computes depth average of 3d vector using the trapezoidal rule, and returns7 the value on the 2d mesh.8 9 Usage:10 vector_average=DepthAverage(md,vector)11 12 Example:13 vel_bar=DepthAverage(md,md.initialization.vel)14 '''15 4 16 #check that the model given in input is 3d 17 if md.mesh.elementtype() != 'Penta': 18 raise TypeError('DepthAverage error message: the model given in input must be 3d') 5 def DepthAverage(md, vector): 6 ''' 7 computes depth average of 3d vector using the trapezoidal rule, and returns 8 the value on the 2d mesh. 19 9 20 # coerce to array in case float is passed 21 if type(vector)!=np.ndarray: 22 print('coercing array') 23 vector=np.array(value) 10 Usage: 11 vector_average=DepthAverage(md,vector) 24 12 25 vec2d=False 26 if vector.ndim==2: 27 vec2d=True 28 vector=vector.reshape(-1,) 13 Example: 14 vel_bar=DepthAverage(md,md.initialization.vel) 15 ''' 29 16 30 #nods data 31 if vector.shape[0]==md.mesh.numberofvertices: 32 vector_average=np.zeros(md.mesh.numberofvertices2d) 33 for i in range(1,md.mesh.numberoflayers): 34 vector_average=vector_average+(project2d(md,vector,i)+project2d(md,vector,i+1))/2.*(project2d(md,md.mesh.z,i+1)-project2d(md,md.mesh.z,i)) 35 vector_average=vector_average/project2d(md,md.geometry.thickness,1) 36 37 #element data 38 elif vector.shape[0]==md.mesh.numberofelements: 39 vector_average=np.zeros(md.mesh.numberofelements2d) 40 for i in range(1,md.mesh.numberoflayers): 41 vector_average=vector_average+project2d(md,vector,i)*(project2d(md,md.mesh.z,i+1)-project2d(md,md.mesh.z,i)) 42 vector_average=vector_average/project2d(md,md.geometry.thickness,1) 43 44 else: 45 raise ValueError('vector size not supported yet'); 17 #check that the model given in input is 3d 18 if md.mesh.elementtype() != 'Penta': 19 raise TypeError('DepthAverage error message: the model given in input must be 3d') 46 20 47 if vec2d: 48 vector_average=vector_average.reshape(-1,) 21 # coerce to array in case float is passed 22 if type(vector) not in [np.ndarray, np.ma.core.MaskedArray]: 23 print('coercing array') 24 vector = np.array(vector) 49 25 50 return vector_average 26 vec2d = False 27 if vector.ndim == 2: 28 vec2d = True 29 vector = vector.reshape(-1,) 30 31 #nods data 32 if vector.shape[0] == md.mesh.numberofvertices: 33 vector_average = np.zeros(md.mesh.numberofvertices2d) 34 for i in range(1, md.mesh.numberoflayers): 35 vector_average = vector_average + (project2d(md, vector, i) + project2d(md, vector, i + 1)) / 2. * (project2d(md, md.mesh.z, i + 1) - project2d(md, md.mesh.z, i)) 36 vector_average = vector_average / project2d(md, md.geometry.thickness, 1) 37 38 #element data 39 elif vector.shape[0] == md.mesh.numberofelements: 40 vector_average = np.zeros(md.mesh.numberofelements2d) 41 for i in range(1, md.mesh.numberoflayers): 42 vector_average = vector_average + project2d(md, vector, i) * (project2d(md, md.mesh.z, i + 1) - project2d(md, md.mesh.z, i)) 43 vector_average = vector_average / project2d(md, md.geometry.thickness, 1) 44 45 else: 46 raise ValueError('vector size not supported yet') 47 48 if vec2d: 49 vector_average = vector_average.reshape(-1,) 50 51 return vector_average -
issm/trunk-jpl/src/m/extrusion/project2d.py
r23716 r23787 1 import numpy as 1 import numpy as np 2 2 3 3 def project2d(md3d,value,layer): 4 ''' 5 returns the value of a field for a given layer of the mesh 6 4 ''' 5 returns the value of a field for a given layer of the mesh 7 6 8 returns the value of a vector for a given layer from extruded mesh onto the 2d mesh9 used to do the extrusion. This function is used to compare values between different10 layers of a 3d mesh.7 returns the value of a vector for a given layer from extruded mesh onto the 2d mesh 8 used to do the extrusion. This function is used to compare values between different 9 layers of a 3d mesh. 11 10 12 Usage:11 Usage: 13 12 projection_value=project2d(md3d,value,layer) 14 13 15 Example:14 Example: 16 15 vel2=project2d(md3d,md3d.initialization.vel,2); 17 16 returns the velocity of the second layer (1 is the base) 18 17 ''' 19 18 20 21 19 if md3d.mesh.domaintype().lower() != '3d': 20 raise Exception("model passed to project2d function should be 3D") 22 21 23 if layer<1 or layer>md3d.mesh.numberoflayers: 24 raise ValueError("layer must be between 0 and %i" % md3d.mesh.numberoflayers) 25 26 # coerce to array in case float is passed 27 if type(value)!=np.ndarray: 28 print('coercing array') 29 value=np.array(value) 22 if layer < 1 or layer > md3d.mesh.numberoflayers: 23 raise ValueError("layer must be between 0 and {}".format(md3d.mesh.numberoflayers)) 30 24 31 vec2d=False 32 if value.ndim==2 and value.shape[1]==1: 33 value=value.reshape(-1,)34 vec2d=True 25 # coerce to array in case float is passed 26 if type(value) not in [np.ndarray, np.ma.core.MaskedArray]: 27 print('coercing array') 28 value = np.array(value) 35 29 36 if value.size==1: 37 projection_value=value[(layer-1)*md3d.mesh.numberofelements2d:layer*md3d.mesh.numberofelements2d] 38 elif value.shape[0]==md3d.mesh.numberofvertices: 39 #print 'indices: ', (layer-1)*md3d.mesh.numberofvertices2d, layer*md3d.mesh.numberofvertices2d 40 projection_value=value[(layer-1)*md3d.mesh.numberofvertices2d:layer*md3d.mesh.numberofvertices2d] 41 elif value.shape[0]==md3d.mesh.numberofvertices+1: 42 projection_value=[value[(layer-1)*md3d.mesh.numberofvertices2d:layer*md3d.mesh.numberofvertices2d], value[-1]] 43 else: 44 projection_value=value[(layer-1)*md3d.mesh.numberofelements2d:layer*md3d.mesh.numberofelements2d] 30 vec2d = False 31 if value.ndim == 2 and value.shape[1] == 1: 32 value = value.reshape(-1,) 33 vec2d = True 45 34 46 if vec2d: 47 projection_value=projection_value.reshape(-1,) 35 if value.size == 1: 36 projection_value = value[(layer - 1) * md3d.mesh.numberofelements2d:layer * md3d.mesh.numberofelements2d] 37 elif value.shape[0] == md3d.mesh.numberofvertices: 38 #print 'indices: ', (layer-1)*md3d.mesh.numberofvertices2d, layer*md3d.mesh.numberofvertices2d 39 projection_value = value[(layer - 1) * md3d.mesh.numberofvertices2d:layer * md3d.mesh.numberofvertices2d] 40 elif value.shape[0] == md3d.mesh.numberofvertices + 1: 41 projection_value = [value[(layer - 1) * md3d.mesh.numberofvertices2d:layer * md3d.mesh.numberofvertices2d], value[-1]] 42 else: 43 projection_value = value[(layer - 1) * md3d.mesh.numberofelements2d:layer * md3d.mesh.numberofelements2d] 48 44 49 return projection_value 45 if vec2d: 46 projection_value = projection_value.reshape(-1,) 47 48 return projection_value
Note:
See TracChangeset
for help on using the changeset viewer.