Package solvcon :: Module boundcond
[hide private]
[frames] | no frames]

Source Code for Module solvcon.boundcond

  1  # -*- coding: UTF-8 -*- 
  2  # 
  3  # Copyright (C) 2008-2011 Yung-Yu Chen <yyc@solvcon.net>. 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License along 
 16  # with this program; if not, write to the Free Software Foundation, Inc., 
 17  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 18   
 19  """Primitive boundary condition definition.""" 
 20   
 21  from .gendata import TypeNameRegistry, TypeWithBinder 
 22   
 23  bctregy = TypeNameRegistry()  # registry singleton. 
24 -class BCMeta(TypeWithBinder):
25 """ 26 Meta class for boundary condition class. 27 """
28 - def __new__(cls, name, bases, namespace):
29 newcls = super(BCMeta, cls).__new__(cls, name, bases, namespace) 30 bctregy.register(newcls) 31 return newcls
32
33 # Base/abstract BC type. 34 -class BC(object):
35 """ 36 Generic boundary condition abstract class. It's the base class that all 37 boundary condition class should subclass. 38 39 @cvar vnames: settable value names. 40 @type vnames: list 41 @cvar vdefaults: default values. 42 @type vdefaults: dict 43 44 @ivar sern: serial number (for certain block). 45 @type sern: int 46 @ivar name: name. 47 @type name: str 48 @ivar blk: the block associated with this BC object. 49 @type blk: solvcon.block.Block 50 @ivar blkn: serial number of self block. 51 @type blkn: int 52 @ivar svr: solver object. 53 @type svr: solvcon.solver.BaseSolver 54 @ivar facn: list of faces. First column is the face index in block. The 55 second column is the face index in bndfcs. The third column is the 56 face index of the related block (if exists). 57 @type facn: numpy.ndarray 58 @ivar value: attached value for each boundary face. 59 @type value: numpy.ndarray 60 """ 61 62 __metaclass__ = BCMeta 63 64 _pointers_ = [] # for binder. 65 66 vnames = [] # settable value names. 67 vdefaults = {} # defaults to values. 68
69 - def __init__(self, bc=None, fpdtype=None):
70 """ 71 Initialize object with empty values or from another BC object. 72 73 @param bc: Another BC object. 74 @type bc: solvcon.boundcond.BC 75 """ 76 import numpy as np 77 from numpy import empty 78 from .conf import env 79 # determine fpdtype. 80 if fpdtype == None: 81 if bc == None: 82 self.fpdtype = env.fpdtype 83 else: 84 self.fpdtype = bc.fpdtype 85 else: 86 self.fpdtype = fpdtype 87 if isinstance(self.fpdtype, str): 88 self.fpdtype = getattr(np, self.fpdtype) 89 if bc is None: 90 # general data. 91 self.sern = None 92 self.name = None 93 self.blk = None 94 self.blkn = None 95 self.svr = None 96 # face list. 97 self.facn = empty((0,3), dtype='int32') 98 # attached (specified) value. 99 self.value = empty((0,self.nvalue), dtype=self.fpdtype) 100 else: 101 bc.cloneTo(self) 102 super(BC, self).__init__()
103 104 @property
105 - def fpdtypestr(self):
106 from .dependency import str_of 107 return str_of(self.fpdtype)
108 109 @property
110 - def nvalue(self):
111 return len(self.vnames)
112
113 - def __len__(self):
114 return self.facn.shape[0]
115
116 - def __str__(self):
117 return "[%s#%d \"%s\": %d faces with %d values]" % ( 118 self.__class__.__name__, self.sern, self.name, 119 len(self), self.nvalue)
120
121 - def cloneTo(self, another):
122 """ 123 Clone self to passed-in another BC object. 124 125 @param another: Another BC object. 126 @type another: solvcon.boundcond.BC 127 """ 128 assert issubclass(type(another), type(self)) 129 assert another.fpdtype == self.fpdtype 130 another.sern = self.sern 131 another.name = self.name 132 another.blk = self.blk 133 another.blkn = self.blkn 134 another.svr = self.svr 135 another.facn = self.facn.copy() 136 another.value = self.value.copy()
137
138 - def feedValue(self, vdict):
139 """ 140 Get feed values to self boundary condition. 141 142 @param vdict: name and value pairs. 143 @type vdict: dict 144 @return: nothing. 145 """ 146 from numpy import empty 147 # get name-value pairs for each value. 148 vpairs = self.vdefaults.copy() 149 for vn in vdict: 150 if vn in self.vnames: 151 vpairs[vn] = vdict[vn] 152 # set values to array. 153 nbfcs = len(self) 154 nvalue = len(self.vnames) 155 values = empty((nbfcs, nvalue), dtype=self.fpdtype) 156 for iv in range(nvalue): 157 vn = self.vnames[iv] 158 values[:,iv].fill(vpairs[vn]) 159 # save set array. 160 self.value = values
161
162 - def init(self, **kw):
163 """ 164 Initializer. 165 """ 166 pass
167
168 - def final(self, **kw):
169 """ 170 Finalizer. 171 """ 172 pass
173
174 -class unspecified(BC):
175 """ 176 Abstract BC type for unspecified boundary conditions. 177 """
178
179 -class interface(BC):
180 """ 181 Abstract BC type for interface between blocks. 182 183 @ivar rblkn: index number of related block. 184 @itype rblkn: int 185 @ivar rclp: list of related cell pairs. The first column is for the 186 indices of the ghost cells belong to self block. The second column is 187 for the indices of the cells belong to the related block. The third 188 column is for the indices of the cells belong to self block. 189 @itype rclp: numpy.ndarray 190 """ 191
192 - def __init__(self, **kw):
193 from numpy import empty 194 super(interface, self).__init__(**kw) 195 self.rblkn = getattr(self, 'rblkn', -1) 196 self.rblkinfo = empty(6, dtype='int32') 197 self.rclp = empty((0,3), dtype='int32')
198
199 - def cloneTo(self, another):
200 super(interface, self).cloneTo(another) 201 another.rblkn = self.rblkn 202 another.rblkinfo = self.rblkinfo.copy() 203 another.rclp = self.rclp.copy()
204
205 - def relateCells(self, dom):
206 """ 207 Calculate self.rclp[:,:] form the information about related block 208 provided by dom parameter. 209 210 @param dom: Collective domain for information about related block. 211 @type dom: solvcon.domain.Collective 212 @return: nothing. 213 """ 214 from numpy import empty 215 facn = self.facn 216 blk = self.blk 217 rblk = dom[self.rblkn] 218 # fill informations from related block. 219 self.rblkinfo[:] = (rblk.nnode, rblk.ngstnode, 220 rblk.nface, rblk.ngstface, rblk.ncell, rblk.ngstcell) 221 # calculate indices of related cells. 222 self.rclp = empty((len(self),3), dtype='int32') 223 self.rclp[:,0] = blk.fccls[facn[:,0],1] 224 self.rclp[:,1] = rblk.fccls[facn[:,2],0] 225 self.rclp[:,2] = blk.fccls[facn[:,0],0] 226 # assertion. 227 assert (self.rclp[:,0]<0).all() 228 assert (self.rclp[:,1]>=0).all() 229 assert (self.rclp[:,2]>=0).all()
230
231 -class periodic(interface):
232 """ 233 BC type for periodic boundary condition. 234 """ 235
236 - def sort(self, ref):
237 if ref is None: 238 return 239 from numpy import sqrt 240 dist = sqrt(((self.blk.fccnd[self.facn[:,0],:] - ref)**2).sum(axis=1)) 241 slct = dist.argsort() 242 self.facn = self.facn[slct,:]
243
244 - def couple(self, rbc):
245 """ 246 Calculate self.rclp[:,:] form the information about related BC object 247 provided by rbc parameter. 248 249 @param rbc: Related BC object. 250 @type rbc: solvcon.boundcond.periodic 251 @return: nothing. 252 """ 253 from numpy import empty 254 blk = self.blk 255 facn = self.facn 256 facn[:,2] = rbc.facn[:,0] 257 # fill informations from related block. 258 self.rblkinfo[:] = (blk.nnode, blk.ngstnode, 259 blk.nface, blk.ngstface, blk.ncell, blk.ngstcell) 260 # calculate indices of related cells. 261 self.rclp = empty((len(self),3), dtype='int32') 262 self.rclp[:,0] = blk.fccls[facn[:,0],1] 263 self.rclp[:,1] = blk.fccls[facn[:,2],0] 264 self.rclp[:,2] = blk.fccls[facn[:,0],0] 265 # assertion. 266 assert (self.rclp[:,0]<0).all() 267 assert (self.rclp[:,1]>=0).all() 268 assert (self.rclp[:,2]>=0).all() 269 # copy metrics. 270 slctm = self.rclp[:,0] + blk.ngstcell 271 slctr = self.rclp[:,1] + blk.ngstcell 272 blk.shcltpn[slctm] = blk.shcltpn[slctr] 273 blk.shclgrp[slctm] = blk.shclgrp[slctr] 274 blk.shclvol[slctm] = blk.shclvol[slctr] 275 # move coordinates. 276 shf = blk.shclcnd[slctr,:] - blk.fccnd[facn[:,2],:] 277 blk.shclcnd[slctm,:] = self.blk.fccnd[facn[:,0],:] + shf
278 279 @staticmethod
280 - def couple_all(blk, bcmap):
281 """ 282 Couple all periodic boundary conditions. 283 284 @param blk: the block having periodic BCs to be coupled. 285 @type blk: solvcon.block.Block 286 @param bcmap: mapper for periodic BCs. 287 @type bcmap: dict 288 @return: nothing 289 """ 290 from solvcon.boundcond import periodic 291 nmidx = dict([(blk.bclist[idx].name, idx) for idx in 292 range(len(blk.bclist))]) 293 npidx = list() 294 for key in bcmap: 295 bct, vdict = bcmap[key] 296 if not issubclass(bct, periodic): 297 try: 298 if key in nmidx: 299 npidx.append(nmidx[key]) 300 except Exception as e: 301 args = list(e.args) 302 args.append(str(nmidx)) 303 e.args = tuple(args) 304 raise 305 continue 306 val = vdict['link'] 307 ibc0 = nmidx[key] 308 ibc1 = nmidx[val] 309 pbc0 = blk.bclist[ibc0] = bct(bc=blk.bclist[ibc0]) 310 pbc1 = blk.bclist[ibc1] = bct(bc=blk.bclist[ibc1]) 311 ref = vdict.get('ref', None) 312 pbc0.sort(ref) 313 pbc1.sort(ref) 314 pbc0.couple(pbc1) 315 pbc1.couple(pbc0)
316