# Diff of /trunk/modellib/py_src/geometry.py

revision 819 by gross, Sun Aug 27 23:07:51 2006 UTC revision 1809 by ksteube, Thu Sep 25 06:43:44 2008 UTC
# Line 1  Line 1
# \$Id\$
1
3                      http://www.access.edu.au  #
4                  Primary Business: Queensland, Australia"""  # Copyright (c) 2003-2008 by University of Queensland
5    # Earth Systems Science Computational Center (ESSCC)
6    # http://www.uq.edu.au/esscc
7    #
8    # Primary Business: Queensland, Australia
11    #
12    ########################################################
13
15    Earth Systems Science Computational Center (ESSCC)
16    http://www.uq.edu.au/esscc
20    __url__="http://www.uq.edu.au/esscc/escript-finley"
21
22  from esys.escript import *  from esys.escript import *
23  from esys.escript.modelframe import Model,ParameterSet  from esys.escript.modelframe import Model,ParameterSet
24  from esys import finley  from esys import finley
25
"""
template L{Model} for a domain.

@ivar intergrationOrder: integration order, default -1 (in).
@type intergrationOrder: C{int}
@ivar displacement: displacements applied to the original mesh coordinates
@type displacement: C{None} or L{escript.Vector}
@ivar domain: domain (out)
@type domain: L{escript.Domain}
"""
def __init__(self,debug=False):
"""
initializes the object
"""
super(Domain, self).__init__(debug=debug)
self.declareParameter(displacement=None,\
integrationOrder=-1)

self.__updated=False

def doInitialization(self):
"""
applies an initial L{displacement} to the mesh nodes (if not equal to C{None})
"""
self.__x=self.domain.getX()
if self.displacement:
self.domain.setX(self.__x+self.displacement)

def doStepPreprocessing(self,dt):
"""
applies the final L{displacement} to mesh nodes.
"""
if self.displacement:
self.domain.setX(self.__x+self.displacement)
self.__update=False

def doStep(self,dt):
"""
applies the current L{displacement} to mesh nodes.
"""
if self.displacement:
self.domain.setX(self.__x+self.displacement)
self.__update=False

def doStepPostprocessing(self,dt):
"""
applies the final L{displacement} to mesh nodes.
"""
if self.displacement:
self.domain.setX(self.__x+self.displacement)
self.__update=False

27         """         """
29
30         @ivar source: file name of the finley input file         @ivar source: mesh file in finley or gmsh format
31         @type source: C{str}         @type source: C{DataSource}
32           @ivar intergrationOrder: integration order, default -1 (in).
33           @type intergrationOrder: C{int}
34           @ivar reducedIntegrationOrder: reduced integration order, default -1 (in).
35           @type reducedIntegrationOrder: C{int}
36           @ivar optimizeLabeling: switches on optimization of the labeling of the nodes
37           @type optimizeLabeling: C{bool}
38         """         """
39         def __init__(self,debug=False):         def __init__(self,**kwargs):
41             self.declareParameter(source="none")            initializes the object
42              """
45            self.trace("mesh read from %s"%self.source)                                            dim=None,
47                                                          reducedIntegrationOrder=-1,
48  class RectangularDomain(Domain):                                  integrationOrder=-1)
49              self.__domain=None
50
51
52           def domain(self):
53              """
54              returns the domain
55
56              @return: the domain
57              @rtype: L{Domain}
58              """
59              if self.__domain == None:
60                 if  self.source.fileformat == "fly":
62                 elif self.source.fileformat == "gmsh":
63                    if self.dim==None:
64                       dim=3
65                    else:
66                       dim=self.dim
68                 else:
69                    raise TypeError("unknown mesh file format %s."%self.source.fileformat)
70                 self.trace("mesh read from %s in %s format."%(self.source.getLocalFileName(), self.source.fileformat))
71              return self.__domain
72    class RectangularDomain(ParameterSet):
73         """         """
74         Generates a mesh over a rectangular domain finley.         Generates a mesh over a rectangular domain finley.
75
# Line 94  class RectangularDomain(Domain): Line 83  class RectangularDomain(Domain):
83         @type order: C{int}         @type order: C{int}
84         @ivar periodic: flags for periodicity, default [False,False,False] (in).         @ivar periodic: flags for periodicity, default [False,False,False] (in).
85         @type periodic: C{list} of C{bool}s         @type periodic: C{list} of C{bool}s
86           @ivar intergrationOrder: integration order, default -1 (in).
87           @type intergrationOrder: C{int}
88         """         """
89         def __init__(self,debug=False):         def __init__(self,**kwargs):
90             """             """
91             initializes the object             initializes the object
92             """             """
93             super(RectangularDomain,self).__init__(debug=debug)             super(RectangularDomain,self).__init__(**kwargs)
94             self.declareParameter(dim=2,\             self.declareParameter(dim=2,\
95                                   l=[1.,1.,1.],\                                   l=[1.,1.,1.],\
96                                   n=[10,10,10], \                                   n=[10,10,10], \
97                   order=1,\                   order=1,\
98                                   periodic=[False,False,False])                                   periodic=[False,False,False],
99                                     integrationOrder=-1)
100               self.__domain=None
101
102         def doInitialization(self):         def domain(self):
103             """             """
104             initializes the object             returns the domain
105
106               @return: the domain
107               @rtype: L{Domain}
108             """             """
109             if self.dim==2:             if self.__domain==None:
110                  self.domain=finley.Rectangle(n0=self.n[0],\                if self.dim==2:
111                                               n1=self.n[1],\                     self.__domain=finley.Rectangle(n0=self.n[0],\
112                                               l0=self.l[0],\                                                  n1=self.n[2],\
113                                               l1=self.l[1],\                                                  l0=self.l[0],\
114                                               order=self.order, \                                                  l1=self.l[2],\
115                                               periodic0=self.periodic[0], \                                                  order=self.order, \
116                                               periodic1=self.periodic[1], \                                                  periodic0=self.periodic[0], \
117                                               integrationOrder=self.integrationOrder)                                                  periodic1=self.periodic[2], \
118             else:                                                  integrationOrder=self.integrationOrder)
119                  self.__domain=finley.Brick(n0=self.n[0],\                else:
120                                           n1=self.n[1],\                     self.__domain=finley.Brick(n0=self.n[0],\
121                                           n2=self.n[2],\                                              n1=self.n[1],\
122                                           l0=self.l[0],\                                              n2=self.n[2],\
123                                           l1=self.l[1],\                                              l0=self.l[0],\
124                                           l2=self.l[2],\                                              l1=self.l[1],\
125                                           order=self.order, \                                              l2=self.l[2],\
126                                           periodic0=self.periodic[0], \                                              order=self.order, \
127                                           periodic1=self.periodic[1], \                                              periodic0=self.periodic[0], \
128                                           periodic2=self.periodic[2], \                                              periodic1=self.periodic[1], \
129                                           integrationOrder=self.integrationOrder)                                              periodic2=self.periodic[2], \
130             super(RectangularDomain, self).doInitialization()                                              integrationOrder=self.integrationOrder)
131               return self.__domain
132
133  class ScalarConstrainer(Model):  class UpdateGeometry(Model):
134       """        """
135       Creates a characteristic function for the location of constraints        applies a displacement field to a domain
136       for a scalar value and selects the value from an initial value
137       ate these locations.        @ivar displacement: displacements applied to the original mesh coordinates (in).
138          @type displacement: L{escript.Vector}
139       In the case that the spatial dimension is two, the arguments front and back are ignored.        @ivar domain: domain
140          @type domain: L{escript.Domain}
141       @ivar domain: domain (in).        """
142       @ivar left:  True to set a constraint at the left face of the domain (x[0]=min x[0]), default False (in).        def __init__(self,**kwargs):
143       @ivar right: True to set a constraint at the left face of the domain (x[0]=max x[0]), default False (in).             """
144       @ivar top: True to set a constraint at the left face of the domain (x[1]=min x[1]), default False (in).             set-up the object
145       @ivar bottom: True to set a constraint at the left face of the domain (x[1]=max x[1]), default False (in).             """
146       @ivar front: True to set a constraint at the left face of the domain (x[2]=min x[2]), default False (in).             super(UpdateGeometry, self).__init__(**kwargs)
147       @ivar back: True to set a constraint at the left face of the domain (x[2]=max x[2]), default False (in).             self.declareParameter(domain=None,\
148       @ivar tol: absolute tolerance for "x=max x" condition, default 1.e-8 (in).                                   displacement=None)
149       @ivar location_of_constraint: locations of the constraints (out).
150       @ivar constraint: locations of the constraints (out).
151       """        def doInitialization(self):
152       def __init__(self,debug=False):           """
153             ParameterSet.__init__(self,debug=debug)           initialize model
154             """
155             self.__x=self.domain.getX()
156             self.__reset=True
157
158          def doStepPreprocessing(self,dt):
159             """
160             applies the current L{displacement} to mesh nodes if required.
161             """
162             if self.__reset:
163                self.trace("mesh nodes updated.")
164                self.domain.setX(self.__x+self.displacement)
165             self.__reset=False
166
167          def doStep(self,dt):
168             """
169             applies the current L{displacement} to mesh nodes.
170             """
171             self.trace("mesh nodes updated.")
172             self.domain.setX(self.__x+self.displacement)
173             self.__reset=True
174
175          def doStepPostprocessing(self,dt):
176             """
177             marks nodes as beeing updated.
178             """
179             self.__reset=False
180
181    class ConstrainerOverBox(Model):
182          """
183          Creates a characteristic function for the location of constraints
184          for all components of a value and selects the value from an initial value
185          ate these locations.
186
187          In the case that the spatial dimension is two, the arguments front and back are ignored.
188
189          @ivar domain: domain (in).
190          @ivar left:  True to set a constraint at the left face of the domain (x[0]=min x[0]), default False (in).
191          @ivar right: True to set a constraint at the left face of the domain (x[0]=max x[0]), default False (in).
192          @ivar top: True to set a constraint at the left face of the domain (x[1]=min x[1]), default False (in).
193          @ivar bottom: True to set a constraint at the left face of the domain (x[1]=max x[1]), default False (in).
194          @ivar front: True to set a constraint at the left face of the domain (x[2]=min x[2]), default False (in).
195          @ivar back: True to set a constraint at the left face of the domain (x[2]=max x[2]), default False (in).
196          @ivar tol: absolute tolerance for "x=max x" condition, default 1.e-8 (in).
197          """
198          def __init__(self,**kwargs):
199               super(ConstrainerOverBox, self).__init__(**kwargs)
200               self.declareParameter(domain=None, \
201                                     value=None,  \
202                                     left=False, \
203                                     right=False, \
204                                     top=False, \
205                                     bottom=False, \
206                                     front=False, \
207                                     back=False, \
208                                     tol=1.e-8)
209               self.__value_of_constraint = None
210               self.__location_of_constraint=None
211          def location_of_constraint(self):
212              """
213              return the values used to constrain a solution
214
215              @return: the mask marking the locations of the constraints
216              @rtype: L{escript.Scalar}
217              """
218              if self.__location_of_constraint == None: self.__setOutput()
219              return self.__location_of_constraint
220
221          def value_of_constraint(self):
222              """
223              return the values used to constrain a solution
224
225              @return: values to be used at the locations of the constraints. If
226                      L{value} is not given C{None} is rerturned.
227              @rtype: L{escript.Scalar}
228              """
229              if self.__location_of_constraint == None: self.__setOutput()
230              return self.__value_of_constraint
231
232          def __setOutput(self):
233              if self.__location_of_constraint == None:
234                 x=self.domain.getX()
235                 val=self.value
236                 if isinstance(val, int) or isinstance(val, float):
237                    shape=()
238                 elif isinstance(val, list) or isinstance(val, tuple) :
239                    shape=(len(val),)
240                 elif isinstance(val, numarray.NumArray):
241                     shape=val.shape
242                 elif val == None:
243                      shape=()
244                 else:
245                     shape=val.getShape()
246                 self.__location_of_constraint=Data(0,shape,x.getFunctionSpace())
247                 if self.domain.getDim()==3:
248                       x0,x1,x2=x[0],x[1],x[2]
249                       if self.left: self.__location_of_constraint+=whereZero(x0-inf(x0),self.tol)
250                       if self.right: self.__location_of_constraint+=whereZero(x0-sup(x0),self.tol)
251                       if self.front: self.__location_of_constraint+=whereZero(x1-inf(x1),self.tol)
252                       if self.back: self.__location_of_constraint+=whereZero(x1-sup(x1),self.tol)
253                       if self.bottom: self.__location_of_constraint+=whereZero(x2-inf(x2),self.tol)
254                       if self.top: self.__location_of_constraint+=whereZero(x2-sup(x2),self.tol)
255                 else:
256                       x0,x1=x[0],x[1]
257                       if self.left: self.__location_of_constraint+=whereZero(x0-inf(x0),self.tol)
258                       if self.right: self.__location_of_constraint+=whereZero(x0-sup(x0),self.tol)
259                       if self.bottom: self.__location_of_constraint+=whereZero(x1-inf(x1),self.tol)
260                       if self.top: self.__location_of_constraint+=whereZero(x1-sup(x1),self.tol)
261                 if not self.value == None:
262                       self.__value_of_constraint=self.__location_of_constraint*self.value
263    class ScalarConstrainerOverBox(Model):
264          """
265          Creates a characteristic function for the location of constraints
266          for a scalar value and selects the value from an initial value
267          ate these locations.
268
269          In the case that the spatial dimension is two, the arguments front and back are ignored.
270
271          @ivar domain: domain (in).
272          @ivar left:  True to set a constraint at the left face of the domain (x[0]=min x[0]), default False (in).
273          @ivar right: True to set a constraint at the left face of the domain (x[0]=max x[0]), default False (in).
274          @ivar top: True to set a constraint at the left face of the domain (x[1]=min x[1]), default False (in).
275          @ivar bottom: True to set a constraint at the left face of the domain (x[1]=max x[1]), default False (in).
276          @ivar front: True to set a constraint at the left face of the domain (x[2]=min x[2]), default False (in).
277          @ivar back: True to set a constraint at the left face of the domain (x[2]=max x[2]), default False (in).
278          @ivar tol: absolute tolerance for "x=max x" condition, default 1.e-8 (in).
279          """
280          def __init__(self,**kwargs):
281               super(ScalarConstrainerOverBox, self).__init__(**kwargs)
282             self.declareParameter(domain=None, \             self.declareParameter(domain=None, \
283                                   value=0,  \                                   value=None,  \
284                                   left=False, \                                   left=False, \
285                                   right=False, \                                   right=False, \
286                                   top=False, \                                   top=False, \
287                                   bottom=False, \                                   bottom=False, \
288                                   front=False, \                                   front=False, \
289                                   back=False, \                                   back=False, \
290                                   tol=1.e-8, \                                   tol=1.e-8)
291                                   constraint_value = None,  \             self.__value_of_constraint = None
292                                   location_constrained_value=None)             self.__location_of_constraint=None
293             self._location_of_constraint=None        def location_of_constraint(self):
294              """
295              return the values used to constrain a solution
296
297       def doInitialization(self):            @return: the mask marking the locations of the constraints
298              @rtype: L{escript.Scalar}
299              """
300              if self.__location_of_constraint == None: self.__setOutput()
301              return self.__location_of_constraint
302
303          def value_of_constraint(self):
304            """            """
305            Returns the mask of the location of constraint.            return the values used to constrain a solution
306
307              @return: values to be used at the locations of the constraints. If
308                      L{value} is not given C{None} is rerturned.
309              @rtype: L{escript.Scalar}
310            """            """
311              if self.__location_of_constraint == None: self.__setOutput()
312              return self.__value_of_constraint
313
314          def __setOutput(self):
315            x=self.domain.getX()            x=self.domain.getX()
316            self._location_of_constraint=Scalar(0,x.getFunctionSpace())            self.__location_of_constraint=Scalar(0,x.getFunctionSpace())
317            if self.domain.getDim()==3:            if self.domain.getDim()==3:
318                  x0,x1,x2=x[0],x[1],x[2]                  x0,x1,x2=x[0],x[1],x[2]
319                  if self.left: self._location_of_constraint+=whereZero(x0-inf(x0),self.tol)                  if self.left: self.__location_of_constraint+=whereZero(x0-inf(x0),self.tol)
320                  if self.right: self._location_of_constraint+=whereZero(x0-sup(x0),self.tol)                  if self.right: self.__location_of_constraint+=whereZero(x0-sup(x0),self.tol)
321                  if self.front: self._location_of_constraint+=whereZero(x1-inf(x1),self.tol)                  if self.front: self.__location_of_constraint+=whereZero(x1-inf(x1),self.tol)
322                  if self.back: self._location_of_constraint+=whereZero(x1-sup(x1),self.tol)                  if self.back: self.__location_of_constraint+=whereZero(x1-sup(x1),self.tol)
323                  if self.bottom: self._location_of_constraint+=whereZero(x2-inf(x2),self.tol)                  if self.bottom: self.__location_of_constraint+=whereZero(x2-inf(x2),self.tol)
324                  if self.top: self._location_of_constraint+=whereZero(x2-sup(x2),self.tol)                  if self.top: self.__location_of_constraint+=whereZero(x2-sup(x2),self.tol)
325            else:            else:
326                  x0,x1=x[0],x[1]                  x0,x1=x[0],x[1]
327                  if self.left: self._location_of_constraint+=whereZero(x0-inf(x0),self.tol)                  if self.left: self.__location_of_constraint+=whereZero(x0-inf(x0),self.tol)
328                  if self.right: self._location_of_constraint+=whereZero(x0-sup(x0),self.tol)                  if self.right: self.__location_of_constraint+=whereZero(x0-sup(x0),self.tol)
329                  if self.bottom: self._location_of_constraint+=whereZero(x1-inf(x1),self.tol)                  if self.bottom: self.__location_of_constraint+=whereZero(x1-inf(x1),self.tol)
330                  if self.top: self._location_of_constraint+=whereZero(x1-sup(x1),self.tol)                  if self.top: self.__location_of_constraint+=whereZero(x1-sup(x1),self.tol)
331            self.constraint_value=self.location_constrained_value*self.value            if not self.value == None:
332                  self.__value_of_constraint=self.__location_of_constraint*self.value
333
334  class VectorConstrainer(Model):  class VectorConstrainerOverBox(Model):
335        """        """
336        Creates a characteristic function for the location of constraints vector value.        Creates a characteristic function for the location of constraints vector value.
337        In the case that the spatial dimension is two, the arguments front and        In the case that the spatial dimension is two, the arguments front and
# Line 210  class VectorConstrainer(Model): Line 351  class VectorConstrainer(Model):
351        @ivar back: list of three boolean. left[i]==True sets a constraint for the i-th component at the back face of the domain (x[2]=max x[2]),        @ivar back: list of three boolean. left[i]==True sets a constraint for the i-th component at the back face of the domain (x[2]=max x[2]),
352                  default [False,False,False] (in).                  default [False,False,False] (in).
353        @ivar tol: absolute tolerance for "x=max x" condition, default 1.e-8 (in).        @ivar tol: absolute tolerance for "x=max x" condition, default 1.e-8 (in).
354        @ivar location_of_constraint: locations of the constraints (out).        """
355        @ivar constraint: locations of the constraints (out).        def __init__(self, **kwargs):
356               super(VectorConstrainerOverBox, self).__init__(**kwargs)
357               self.declareParameter(domain=None, \
358                                     value=None,  \
359                                     left=[False ,False ,False ],  \
360                                     right=[False ,False ,False ],  \
361                                     top=[False ,False ,False ],  \
362                                     bottom=[False ,False ,False ],  \
363                                     front=[False ,False ,False ], \
364                                     back=[False ,False ,False ], \
365                                     tol=1.e-8)
366               self.__value_of_constraint = None
367               self.__location_of_constraint=None
368
369          def location_of_constraint(self):
370              """
371              return the values used to constrain a solution
372
373              @return: the mask marking the locations of the constraints
374              @rtype: L{escript.Vector}
375              """
376              if self.__location_of_constraint == None: self.__setOutput()
377              return self.__location_of_constraint
378
379          def value_of_constraint(self):
380              """
381              return the values used to constrain a solution
382
383              @return: values to be used at the locations of the constraints. If
384                      L{value} is not given C{None} is rerturned.
385              @rtype: L{escript.Vector}
386              """
387              if self.__location_of_constraint == None: self.__setOutput()
388              return self.__value_of_constraint
389
390          def __setOutput(self):
391              x=self.domain.getX()
392              self.__location_of_constraint=Vector(0,x.getFunctionSpace())
393              if self.domain.getDim()==3:
394                 x0,x1,x2=x[0],x[1],x[2]
419                 if not self.value == None:
420                    self.__value_of_constraint=self.__location_of_constraint*self.value
421              else:
422                 x0,x1=x[0],x[1]
435                 if not self.value == None:
436                    self.__value_of_constraint=self.__location_of_constraint*self.value[:2]
437
438    class ConstrainerAtBoxVertex(Model):
439        """        """
440        def __init__(self,debug=False):        Creates a characteristic function for the location of constraints
441             ParameterSet.__init__(self,debug=debug)        for all components of a value and selects the value from an initial value
442          ate these locations.
443
444          In the case that the spatial dimension is two, the arguments front and back are ignored.
445
446          @ivar domain: domain (in).
447          @ivar tol: absolute tolerance for "x=left, front, bottom vertex" condition, default 1.e-8 (in).
448          """
449          def __init__(self,**kwargs):
450               super(ConstrainerAtBoxVertex, self).__init__(**kwargs)
451             self.declareParameter(domain=None, \             self.declareParameter(domain=None, \
452                                   value=0,  \                                   value=None,  \
453                                   left=[0,0,0],  \                                   tol=1.e-8)
454                                   right=[0,0,0],  \             self.__value_of_constraint = None
455                                   top=[0,0,0],  \             self.__location_of_constraint=None
456                                   bottom=[0,0,0],  \        def location_of_constraint(self):
front=[0,0,0], \
ack=[0,0,0], \
tol=1.e-8, \
constraint_value = None,  \
location_constrained_value=None)
self._location_of_constraint=None
def doInitialization(self):
457            """            """
458            sets the location_constrained_value and constraint_value to be kept throughout the simulation.            return the values used to constrain a solution
459
460              @return: the mask marking the locations of the constraints
461              @rtype: L{escript.Scalar}
462              """
463              if self.__location_of_constraint == None: self.__setOutput()
464              return self.__location_of_constraint
465
466          def value_of_constraint(self):
467              """
468              return the values used to constrain a solution
469
470              @return: values to be used at the locations of the constraints. If
471                      L{value} is not given C{None} is rerturned.
472              @rtype: L{escript.Scalar}
473            """            """
474            if self._location_of_constraint==None:            if self.__location_of_constraint == None: self.__setOutput()
475              return self.__value_of_constraint
476
477          def __setOutput(self):
478              if self.__location_of_constraint == None:
479               x=self.domain.getX()               x=self.domain.getX()
480               self._location_of_constraint=Vector(0,x.getFunctionSpace())               val=self.value
481                 if isinstance(val, int) or isinstance(val, float):
482                    shape=()
483                 elif isinstance(val, list) or isinstance(val, tuple) :
484                    shape=(len(val),)
485                 elif isinstance(val, numarray.NumArray):
486                     shape=val.shape
487                 elif val == None:
488                      shape=()
489                 else:
490                     shape=val.getShape()
491               if self.domain.getDim()==3:               if self.domain.getDim()==3:
492                  x0,x1,x2=x[0],x[1],x[2]                     vertex=[inf(x[0]),inf(x[1]),inf(x[2])]
493               else:               else:
494                  x0,x1=x[0],x[1]                     vertex=[inf(x[0]),inf(x[1])]
496                  if self.left[0]: self._location_of_constraint+=left_mask*[1.,0.]               if not self.value == None:
500                  if self.right[1]: self._location_of_constraint+=right_mask*[0.,1.]        Creates a characteristic function for the location of constraints
501                  bottom_mask=whereZero(x1-inf(x1),self.tol)        for a scalar value and selects the value from an initial value
502                  if self.bottom[0]: self._location_of_constraint+=bottom_mask*[1.,0.]        ate these locations.
504                  top_mask=whereZero(x1-sup(x1),self.tol)        In the case that the spatial dimension is two, the arguments front and back are ignored.
506                  if self.top[1]: self._location_of_constraint+=top_mask*[0.,1.]        @ivar domain: domain (in).
507            self.constraint_value=self.location_constrained_value*self.value        @ivar tol: absolute tolerance for "x=left, front, bottom vertex" condition, default 1.e-8 (in).
508          """
509          def __init__(self,**kwargs):
510               super(ScalarConstrainerAtBoxVertex, self).__init__(**kwargs)
511               self.declareParameter(domain=None, \
512                                     value=None,  \
513                                     tol=1.e-8)
514               self.__value_of_constraint = None
515               self.__location_of_constraint=None
516          def location_of_constraint(self):
517              """
518              return the values used to constrain a solution
519
520              @return: the mask marking the locations of the constraints
521              @rtype: L{escript.Scalar}
522              """
523              if self.__location_of_constraint == None: self.__setOutput()
524              return self.__location_of_constraint
525
526          def value_of_constraint(self):
527              """
528              return the values used to constrain a solution
529
530              @return: values to be used at the locations of the constraints. If
531                      L{value} is not given C{None} is rerturned.
532              @rtype: L{escript.Scalar}
533              """
534              if self.__location_of_constraint == None: self.__setOutput()
535              return self.__value_of_constraint
536
537          def __setOutput(self):
538              x=self.domain.getX()
539              self.__location_of_constraint=Scalar(0,x.getFunctionSpace())
540              if self.domain.getDim()==3:
541                       vertex=[inf(x[0]),inf(x[1]),inf(x[2])]
542              else:
543                     vertex=[inf(x[0]),inf(x[1])]
544              self.__location_of_constraint=whereZero(length(x-vertex),self.tol)
545              if not self.value == None:
546                  self.__value_of_constraint=self.__location_of_constraint*self.value
547
548    class VectorConstrainerAtBoxVertex(Model):
549          """
550          Creates a characteristic function for the location of constraints vector value.
551          In the case that the spatial dimension is two, the arguments front and
552          back as well as the third component of each argument is ignored.
553
554          @ivar domain: domain
555          @ivar comp_mask: list of three boolean. comp_mask[i]==True sets a constraint for the i-th component at the left, front, bottom vertex, default [False,False,False] (in).
556          @ivar tol: absolute tolerance for "x=left, front, bottom vertex" condition, default 1.e-8 (in).
557          """
558          def __init__(self, **kwargs):
559               super(VectorConstrainerAtBoxVertex, self).__init__(**kwargs)
560               self.declareParameter(domain=None, \
561                                     value=None,  \
563                                     tol=1.e-8)
564               self.__value_of_constraint = None
565               self.__location_of_constraint=None
566
567          def location_of_constraint(self):
568              """
569              return the values used to constrain a solution
570
571              @return: the mask marking the locations of the constraints
572              @rtype: L{escript.Vector}
573              """
574              if self.__location_of_constraint == None: self.__setOutput()
575              return self.__location_of_constraint
576
577          def value_of_constraint(self):
578              """
579              return the values used to constrain a solution
580
581              @return: values to be used at the locations of the constraints. If
582                      L{value} is not given C{None} is rerturned.
583              @rtype: L{escript.Vector}
584              """
585              if self.__location_of_constraint == None: self.__setOutput()
586              return self.__value_of_constraint
587
588          def __setOutput(self):
589              x=self.domain.getX()
590              self.__location_of_constraint=Vector(0,x.getFunctionSpace())
591              if self.domain.getDim()==3:
592                 vertex=[inf(x[0]),inf(x[1]),inf(x[2])]
593                 msk=numarray.zeros((3,))
597              else:
598                 vertex=[inf(x[0]),inf(x[1])]
599                 msk=numarray.zeros((2,))