1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """Primitive boundary condition definition."""
20
21 from .gendata import TypeNameRegistry, TypeWithBinder
22
23 bctregy = TypeNameRegistry()
32
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_ = []
65
66 vnames = []
67 vdefaults = {}
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
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
91 self.sern = None
92 self.name = None
93 self.blk = None
94 self.blkn = None
95 self.svr = None
96
97 self.facn = empty((0,3), dtype='int32')
98
99 self.value = empty((0,self.nvalue), dtype=self.fpdtype)
100 else:
101 bc.cloneTo(self)
102 super(BC, self).__init__()
103
104 @property
108
109 @property
112
114 return self.facn.shape[0]
115
117 return "[%s#%d \"%s\": %d faces with %d values]" % (
118 self.__class__.__name__, self.sern, self.name,
119 len(self), self.nvalue)
120
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
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
148 vpairs = self.vdefaults.copy()
149 for vn in vdict:
150 if vn in self.vnames:
151 vpairs[vn] = vdict[vn]
152
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
160 self.value = values
161
162 - def init(self, **kw):
163 """
164 Initializer.
165 """
166 pass
167
169 """
170 Finalizer.
171 """
172 pass
173
175 """
176 Abstract BC type for unspecified boundary conditions.
177 """
178
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
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
200 super(interface, self).cloneTo(another)
201 another.rblkn = self.rblkn
202 another.rblkinfo = self.rblkinfo.copy()
203 another.rclp = self.rclp.copy()
204
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
219 self.rblkinfo[:] = (rblk.nnode, rblk.ngstnode,
220 rblk.nface, rblk.ngstface, rblk.ncell, rblk.ngstcell)
221
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
227 assert (self.rclp[:,0]<0).all()
228 assert (self.rclp[:,1]>=0).all()
229 assert (self.rclp[:,2]>=0).all()
230
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
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
258 self.rblkinfo[:] = (blk.nnode, blk.ngstnode,
259 blk.nface, blk.ngstface, blk.ncell, blk.ngstcell)
260
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
266 assert (self.rclp[:,0]<0).all()
267 assert (self.rclp[:,1]>=0).all()
268 assert (self.rclp[:,2]>=0).all()
269
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
276 shf = blk.shclcnd[slctr,:] - blk.fccnd[facn[:,2],:]
277 blk.shclcnd[slctm,:] = self.blk.fccnd[facn[:,0],:] + shf
278
279 @staticmethod
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