# Diff of /trunk/escript/py_src/util.py

revision 102 by jgs, Wed Dec 15 07:08:39 2004 UTC revision 149 by jgs, Thu Sep 1 03:31:39 2005 UTC
# Line 3  Line 3
3  ## @file util.py  ## @file util.py
4
5  """  """
6  @brief Utility functions for escript  Utility functions for escript
7
8    @todo:
9
10      - binary operations @ (@=+,-,*,/,**)::
11          (a@b)[:,*]=a[:]@b[:,*] if rank(a)<rank(b)
12          (a@b)[:]=a[:]@b[:] if rank(a)=rank(b)
13          (a@b)[*,:]=a[*,:]@b[:] if rank(a)>rank(b)
14      - implementation of outer::
15          outer(a,b)[:,*]=a[:]*b[*]
16      - trace::
17          trace(arg,axis0=a0,axis1=a1)(:,&,*)=sum_i trace(:,i,&,i,*) (i are at index a0 and a1)
18  """  """
19
20  import numarray  import numarray
21  import escript  import escript
22  #
23  #   escript constants (have to be consistent witj utilC.h  #===========================================================
24  #  # a simple tool box to deal with _differentials of functions
25  UNKNOWN=-1  #===========================================================
26  EPSILON=1.e-15
27  Pi=numarray.pi  class Symbol:
28  # some solver options:     """
29  NO_REORDERING=0     Symbol class.
30  MINIMUM_FILL_IN=1     """
31  NESTED_DISSECTION=2     def __init__(self,name="symbol",shape=(),dim=3,args=[]):
32  # solver methods         """
33  DEFAULT_METHOD=0         Creates an instance of a symbol of shape shape and spatial dimension
34  DIRECT=1         dim.
35  CHOLEVSKY=2
36  PCG=3         The symbol may depending on a list of arguments args which may be
37  CR=4         symbols or other objects. name gives the name of the symbol.
38  CGS=5         """
39  BICGSTAB=6
40  SSOR=7         self.__args=args
41  ILU0=8         self.__name=name
42  ILUT=9         self.__shape=shape
43  JACOBI=10         if hasattr(dim,"getDim"):
44  GMRES=11             self.__dim=dim.getDim()
45  PRES20=12         else:
46               self.__dim=dim
47  METHOD_KEY="method"         #
48  SYMMETRY_KEY="symmetric"         self.__cache_val=None
49  TOLERANCE_KEY="tolerance"         self.__cache_argval=None
50
51  # supported file formats:     def getArgument(self,i):
52  VRML=1         """
53  PNG=2         Returns the i-th argument.
54  JPEG=3         """
55  JPG=3         return self.__args[i]
56  PS=4
57  OOGL=5     def getDim(self):
58  BMP=6         """
59  TIFF=7         Returns the spatial dimension of the symbol.
60  OPENINVENTOR=8         """
61  RENDERMAN=9         return self.__dim
62  PNM=10
63  #     def getRank(self):
64  # wrapper for various functions: if the argument has attribute the function name         """
65  # as an argument it calls the correspong methods. Otherwise the coresponsing numarray         Returns the rank of the symbol.
66  # function is called.         """
67  #         return len(self.getShape())
68  # functions involving the underlying Domain:
69  #     def getShape(self):
70  def grad(arg,where=None):         """
71           Returns the shape of the symbol.
72           """
73           return self.__shape
74
75       def getEvaluatedArguments(self,argval):
76           """
77           Returns the list of evaluated arguments by subsituting symbol u by
78           argval[u].
79           """
80           if argval==self.__cache_argval:
81               print "%s: cached value used"%self
82               return self.__cache_val
83           else:
84               out=[]
85               for a  in self.__args:
86                  if isinstance(a,Symbol):
87                    out.append(a.eval(argval))
88                  else:
89                    out.append(a)
90               self.__cache_argval=argval
91               self.__cache_val=out
92               return out
93
94       def getDifferentiatedArguments(self,arg):
95           """
96           Returns the list of the arguments _differentiated by arg.
97           """
98           out=[]
99           for a in self.__args:
100              if isinstance(a,Symbol):
101                out.append(a.diff(arg))
102              else:
103                out.append(0)
104           return out
105
106       def diff(self,arg):
107           """
108           Returns the _differention of self by arg.
109           """
110           if self==arg:
111              out=numarray.zeros(tuple(2*list(self.getShape())),numarray.Float)
112              if self.getRank()==0:
113                 out=1.
114              elif self.getRank()==1:
115                  for i0 in range(self.getShape()[0]):
116                     out[i0,i0]=1.
117              elif self.getRank()==2:
118                  for i0 in range(self.getShape()[0]):
119                    for i1 in range(self.getShape()[1]):
120                         out[i0,i1,i0,i1]=1.
121              elif self.getRank()==3:
122                  for i0 in range(self.getShape()[0]):
123                    for i1 in range(self.getShape()[1]):
124                      for i2 in range(self.getShape()[2]):
125                         out[i0,i1,i2,i0,i1,i2]=1.
126              elif self.getRank()==4:
127                  for i0 in range(self.getShape()[0]):
128                    for i1 in range(self.getShape()[1]):
129                      for i2 in range(self.getShape()[2]):
130                        for i3 in range(self.getShape()[3]):
131                           out[i0,i1,i2,i3,i0,i1,i2,i3]=1.
132              else:
133                 raise ValueError,"differential support rank<5 only."
134              return out
135           else:
136              return self._diff(arg)
137
138       def _diff(self,arg):
139           """
140           Return derivate of self with respect to arg (!=self).
141
142           This method is overwritten by a particular symbol.
143           """
144           return 0
145
146       def eval(self,argval):
147           """
148           Subsitutes symbol u in self by argval[u] and returns the result. If
149           self is not a key of argval then self is returned.
150           """
151           if argval.has_key(self):
152             return argval[self]
153           else:
154             return self
155
156       def __str__(self):
157           """
158           Returns a string representation of the symbol.
159           """
160           return self.__name
161
163           """
164           Adds other to symbol self. if _testForZero(other) self is returned.
165           """
166           if _testForZero(other):
167              return self
168           else:
169              a=_matchShape([self,other])
171
173           """
174           Adds other to symbol self. if _testForZero(other) self is returned.
175           """
176           return self+other
177
178       def __neg__(self):
179           """
180           Returns -self.
181           """
182           return self*(-1.)
183
184       def __pos__(self):
185           """
186           Returns +self.
187           """
188           return self
189
190       def __abs__(self):
191           """
192           Returns absolute value.
193           """
194           return Abs_Symbol(self)
195
196       def __sub__(self,other):
197           """
198           Subtracts other from symbol self.
199
200           If _testForZero(other) self is returned.
201           """
202           if _testForZero(other):
203              return self
204           else:
205              return self+(-other)
206
207       def __rsub__(self,other):
208           """
209           Subtracts symbol self from other.
210           """
211           return -self+other
212
213       def __div__(self,other):
214           """
215           Divides symbol self by other.
216           """
217           if isinstance(other,Symbol):
218              a=_matchShape([self,other])
219              return Div_Symbol(a[0],a[1])
220           else:
221              return self*(1./other)
222
223       def __rdiv__(self,other):
224           """
225           Dived other by symbol self. if _testForZero(other) 0 is returned.
226           """
227           if _testForZero(other):
228              return 0
229           else:
230              a=_matchShape([self,other])
231              return Div_Symbol(a[0],a[1])
232
233       def __pow__(self,other):
234           """
235           Raises symbol self to the power of other.
236           """
237           a=_matchShape([self,other])
238           return Power_Symbol(a[0],a[1])
239
240       def __rpow__(self,other):
241           """
242           Raises other to the symbol self.
243           """
244           a=_matchShape([self,other])
245           return Power_Symbol(a[1],a[0])
246
247       def __mul__(self,other):
248           """
249           Multiplies other by symbol self. if _testForZero(other) 0 is returned.
250           """
251           if _testForZero(other):
252              return 0
253           else:
254              a=_matchShape([self,other])
255              return Mult_Symbol(a[0],a[1])
256
257       def __rmul__(self,other):
258           """
259           Multiplies other by symbol self. if _testSForZero(other) 0 is returned.
260           """
261           return self*other
262
263       def __getitem__(self,sl):
264              print sl
265
266    class Float_Symbol(Symbol):
267        def __init__(self,name="symbol",shape=(),args=[]):
268            Symbol.__init__(self,dim=0,name="symbol",shape=(),args=[])
269
270    class ScalarSymbol(Symbol):
271       """
272       A scalar symbol.
273       """
274       def __init__(self,dim=3,name="scalar"):
275          """
276          Creates a scalar symbol of spatial dimension dim.
277          """
278          if hasattr(dim,"getDim"):
279               d=dim.getDim()
280          else:
281               d=dim
282          Symbol.__init__(self,shape=(),dim=d,name=name)
283
284    class VectorSymbol(Symbol):
285       """
286       A vector symbol.
287       """
288       def __init__(self,dim=3,name="vector"):
289          """
290          Creates a vector symbol of spatial dimension dim.
291          """
292          if hasattr(dim,"getDim"):
293               d=dim.getDim()
294          else:
295               d=dim
296          Symbol.__init__(self,shape=(d,),dim=d,name=name)
297
298    class TensorSymbol(Symbol):
299       """
300       A tensor symbol.
301       """
302       def __init__(self,dim=3,name="tensor"):
303          """
304          Creates a tensor symbol of spatial dimension dim.
305          """
306          if hasattr(dim,"getDim"):
307               d=dim.getDim()
308          else:
309               d=dim
310          Symbol.__init__(self,shape=(d,d),dim=d,name=name)
311
312    class Tensor3Symbol(Symbol):
313       """
314       A tensor order 3 symbol.
315       """
316       def __init__(self,dim=3,name="tensor3"):
317          """
318          Creates a tensor order 3 symbol of spatial dimension dim.
319          """
320          if hasattr(dim,"getDim"):
321               d=dim.getDim()
322          else:
323               d=dim
324          Symbol.__init__(self,shape=(d,d,d),dim=d,name=name)
325
326    class Tensor4Symbol(Symbol):
327       """
328       A tensor order 4 symbol.
329       """
330       def __init__(self,dim=3,name="tensor4"):
331          """
332          Creates a tensor order 4 symbol of spatial dimension dim.
333          """
334          if hasattr(dim,"getDim"):
335               d=dim.getDim()
336          else:
337               d=dim
338          Symbol.__init__(self,shape=(d,d,d,d),dim=d,name=name)
339
341       """
342       Symbol representing the sum of two arguments.
343       """
344       def __init__(self,arg0,arg1):
345           a=[arg0,arg1]
346           Symbol.__init__(self,dim=_extractDim(a),shape=_extractShape(a),args=a)
347       def __str__(self):
348          return "(%s+%s)"%(str(self.getArgument(0)),str(self.getArgument(1)))
349       def eval(self,argval):
350           a=self.getEvaluatedArguments(argval)
351           return a[0]+a[1]
352       def _diff(self,arg):
353           a=self.getDifferentiatedArguments(arg)
354           return a[0]+a[1]
355
356    class Mult_Symbol(Symbol):
357       """
358       Symbol representing the product of two arguments.
359       """
360       def __init__(self,arg0,arg1):
361           a=[arg0,arg1]
362           Symbol.__init__(self,dim=_extractDim(a),shape=_extractShape(a),args=a)
363       def __str__(self):
364          return "(%s*%s)"%(str(self.getArgument(0)),str(self.getArgument(1)))
365       def eval(self,argval):
366           a=self.getEvaluatedArguments(argval)
367           return a[0]*a[1]
368       def _diff(self,arg):
369           a=self.getDifferentiatedArguments(arg)
370           return self.getArgument(1)*a[0]+self.getArgument(0)*a[1]
371
372    class Div_Symbol(Symbol):
373       """
374       Symbol representing the quotient of two arguments.
375       """
376       def __init__(self,arg0,arg1):
377           a=[arg0,arg1]
378           Symbol.__init__(self,dim=_extractDim(a),shape=_extractShape(a),args=a)
379       def __str__(self):
380          return "(%s/%s)"%(str(self.getArgument(0)),str(self.getArgument(1)))
381       def eval(self,argval):
382           a=self.getEvaluatedArguments(argval)
383           return a[0]/a[1]
384       def _diff(self,arg):
385           a=self.getDifferentiatedArguments(arg)
386           return (a[0]*self.getArgument(1)-self.getArgument(0)*a[1])/ \
387                              (self.getArgument(1)*self.getArgument(1))
388
389    class Power_Symbol(Symbol):
390       """
391       Symbol representing the power of the first argument to the power of the
392       second argument.
393       """
394       def __init__(self,arg0,arg1):
395           a=[arg0,arg1]
396           Symbol.__init__(self,dim=_extractDim(a),shape=_extractShape(a),args=a)
397       def __str__(self):
398          return "(%s**%s)"%(str(self.getArgument(0)),str(self.getArgument(1)))
399       def eval(self,argval):
400           a=self.getEvaluatedArguments(argval)
401           return a[0]**a[1]
402       def _diff(self,arg):
403           a=self.getDifferentiatedArguments(arg)
404           return self*(a[1]*log(self.getArgument(0))+self.getArgument(1)/self.getArgument(0)*a[0])
405
406    class Abs_Symbol(Symbol):
407       """
408       Symbol representing absolute value of its argument.
409       """
410       def __init__(self,arg):
411           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
412       def __str__(self):
413          return "abs(%s)"%str(self.getArgument(0))
414       def eval(self,argval):
415           return abs(self.getEvaluatedArguments(argval)[0])
416       def _diff(self,arg):
417           return sign(self.getArgument(0))*self.getDifferentiatedArguments(arg)[0]
418
419    #=========================================================
420    #   some little helpers
421    #=========================================================
422    def _testForZero(arg):
423       """
424       Returns True is arg is considered to be zero.
425       """
426       if isinstance(arg,int):
427          return not arg>0
428       elif isinstance(arg,float):
429          return not arg>0.
430       elif isinstance(arg,numarray.NumArray):
431          a=abs(arg)
432          while isinstance(a,numarray.NumArray): a=numarray.sometrue(a)
433          return not a>0
434       else:
435          return False
436
437    def _extractDim(args):
438        dim=None
439        for a in args:
440           if hasattr(a,"getDim"):
441              d=a.getDim()
442              if dim==None:
443                 dim=d
444              else:
445                 if dim!=d: raise ValueError,"inconsistent spatial dimension of arguments"
446        if dim==None:
447           raise ValueError,"cannot recover spatial dimension"
448        return dim
449
450    def _identifyShape(arg):
451       """
452       Identifies the shape of arg.
453       """
454       if hasattr(arg,"getShape"):
455           arg_shape=arg.getShape()
456       elif hasattr(arg,"shape"):
457         s=arg.shape
458         if callable(s):
459           arg_shape=s()
460         else:
461           arg_shape=s
462       else:
463           arg_shape=()
464       return arg_shape
465
466    def _extractShape(args):
467        """
468        Extracts the common shape of the list of arguments args.
469        """
470        shape=None
471        for a in args:
472           a_shape=_identifyShape(a)
473           if shape==None: shape=a_shape
474           if shape!=a_shape: raise ValueError,"inconsistent shape"
475        if shape==None:
476           raise ValueError,"cannot recover shape"
477        return shape
478
479    def _matchShape(args,shape=None):
480        """
481        Returns the list of arguments args as object which have all the
482        specified shape.
483
484        If shape is not given the shape "largest" shape of args is used.
485        """
486        # identify the list of shapes:
487        arg_shapes=[]
488        for a in args: arg_shapes.append(_identifyShape(a))
489        # get the largest shape (currently the longest shape):
490        if shape==None: shape=max(arg_shapes)
491
492        out=[]
493        for i in range(len(args)):
494           if shape==arg_shapes[i]:
495              out.append(args[i])
496           else:
497              if len(shape)==0: # then len(arg_shapes[i])>0
498                raise ValueError,"cannot adopt shape of %s to %s"%(str(args[i]),str(shape))
499              else:
500                if len(arg_shapes[i])==0:
501                    out.append(outer(args[i],numarray.ones(shape)))
502                else:
503                    raise ValueError,"cannot adopt shape of %s to %s"%(str(args[i]),str(shape))
504        return out
505
506    #=========================================================
507    #   wrappers for various mathematical functions:
508    #=========================================================
509    def diff(arg,dep):
510        """
511        Returns the derivative of arg with respect to dep.
512
513        If arg is not Symbol object 0 is returned.
514        """
515        if isinstance(arg,Symbol):
516           return arg.diff(dep)
517        elif hasattr(arg,"shape"):
518              if callable(arg.shape):
519                  return numarray.zeros(arg.shape(),numarray.Float)
520              else:
521                  return numarray.zeros(arg.shape,numarray.Float)
522        else:
523           return 0
524
525    def exp(arg):
526      """      """
527      @brief returns the spatial gradient of the Data object arg      Applies the exponential function to arg.
528
529      @param arg: Data object representing the function which gradient to be calculated.      @param arg: argument
@param where: FunctionSpace in which the gradient will be. If None Function(dom) where dom is the
domain of the Data object arg.
530      """      """
531      if where==None:      if isinstance(arg,Symbol):
532         return arg.grad()         return Exp_Symbol(arg)
533        elif hasattr(arg,"exp"):
534           return arg.exp()
535      else:      else:
536         return arg.grad(where)         return numarray.exp(arg)
537
538    class Exp_Symbol(Symbol):
539       """
540       Symbol representing the power of the first argument to the power of the
541       second argument.
542       """
543       def __init__(self,arg):
544           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
545       def __str__(self):
546          return "exp(%s)"%str(self.getArgument(0))
547       def eval(self,argval):
548           return exp(self.getEvaluatedArguments(argval)[0])
549       def _diff(self,arg):
550           return self*self.getDifferentiatedArguments(arg)[0]
551
552  def integrate(arg):  def sqrt(arg):
553      """      """
554      @brief return the integral if the function represented by Data object arg over its domain.      Applies the squre root function to arg.
555
556      @param arg      @param arg: argument
557      """      """
558      return arg.integrate()      if isinstance(arg,Symbol):
559           return Sqrt_Symbol(arg)
560        elif hasattr(arg,"sqrt"):
561           return arg.sqrt()
562        else:
563           return numarray.sqrt(arg)
564
565  def interpolate(arg,where):  class Sqrt_Symbol(Symbol):
566       """
567       Symbol representing square root of argument.
568       """
569       def __init__(self,arg):
570           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
571       def __str__(self):
572          return "sqrt(%s)"%str(self.getArgument(0))
573       def eval(self,argval):
574           return sqrt(self.getEvaluatedArguments(argval)[0])
575       def _diff(self,arg):
576           return (-0.5)/self*self.getDifferentiatedArguments(arg)[0]
577
578    def log(arg):
579        """
580        Applies the logarithmic function bases exp(1.) to arg
581
582        @param arg: argument
583        """
584        if isinstance(arg,Symbol):
585           return Log_Symbol(arg)
586        elif hasattr(arg,"log"):
587           return arg.log()
588        else:
589           return numarray.log(arg)
590
591    class Log_Symbol(Symbol):
592       """
593       Symbol representing logarithm of the argument.
594       """
595       def __init__(self,arg):
596           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
597       def __str__(self):
598          return "log(%s)"%str(self.getArgument(0))
599       def eval(self,argval):
600           return log(self.getEvaluatedArguments(argval)[0])
601       def _diff(self,arg):
602           return self.getDifferentiatedArguments(arg)[0]/self.getArgument(0)
603
604    def ln(arg):
605        """
606        Applies the natural logarithmic function to arg.
607
608        @param arg: argument
609        """
610        if isinstance(arg,Symbol):
611           return Ln_Symbol(arg)
612        elif hasattr(arg,"ln"):
613           return arg.log()
614        else:
615           return numarray.log(arg)
616
617    class Ln_Symbol(Symbol):
618       """
619       Symbol representing natural logarithm of the argument.
620       """
621       def __init__(self,arg):
622           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
623       def __str__(self):
624          return "ln(%s)"%str(self.getArgument(0))
625       def eval(self,argval):
626           return ln(self.getEvaluatedArguments(argval)[0])
627       def _diff(self,arg):
628           return self.getDifferentiatedArguments(arg)[0]/self.getArgument(0)
629
630    def sin(arg):
631      """      """
632      @brief interpolates the function represented by Data object arg into the FunctionSpace where.      Applies the sin function to arg.
633
634      @param arg      @param arg: argument
@param where
635      """      """
636      return arg.interpolate(where)      if isinstance(arg,Symbol):
637           return Sin_Symbol(arg)
638        elif hasattr(arg,"sin"):
639           return arg.sin()
640        else:
641           return numarray.sin(arg)
642
643  # functions returning Data objects:  class Sin_Symbol(Symbol):
644       """
645       Symbol representing sin of the argument.
646       """
647       def __init__(self,arg):
648           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
649       def __str__(self):
650          return "sin(%s)"%str(self.getArgument(0))
651       def eval(self,argval):
652           return sin(self.getEvaluatedArguments(argval)[0])
653       def _diff(self,arg):
654           return cos(self.getArgument(0))*self.getDifferentiatedArguments(arg)[0]
655
656  def transpose(arg,axis=None):  def cos(arg):
657      """      """
658      @brief returns the transpose of the Data object arg.      Applies the cos function to arg.
659
660      @param arg      @param arg: argument
661      """      """
662      if isinstance(arg,escript.Data):      if isinstance(arg,Symbol):
663         if axis==None: axis=arg.getRank()/2         return Cos_Symbol(arg)
664         return arg.transpose(axis)      elif hasattr(arg,"cos"):
665           return arg.cos()
666      else:      else:
667         if axis==None: axis=arg.rank/2         return numarray.cos(arg)
return numarray.transpose(arg,axis=axis)
668
669  def trace(arg):  class Cos_Symbol(Symbol):
670       """
671       Symbol representing cos of the argument.
672       """
673       def __init__(self,arg):
674           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
675       def __str__(self):
676          return "cos(%s)"%str(self.getArgument(0))
677       def eval(self,argval):
678           return cos(self.getEvaluatedArguments(argval)[0])
679       def _diff(self,arg):
680           return -sin(self.getArgument(0))*self.getDifferentiatedArguments(arg)[0]
681
682    def tan(arg):
683      """      """
684      @brief      Applies the tan function to arg.
685
686      @param arg      @param arg: argument
687      """      """
688      if isinstance(arg,escript.Data):      if isinstance(arg,Symbol):
689         return arg.trace()         return Tan_Symbol(arg)
690        elif hasattr(arg,"tan"):
691           return arg.tan()
692      else:      else:
693         return numarray.trace(arg)         return numarray.tan(arg)
694
695  def exp(arg):  class Tan_Symbol(Symbol):
696       """
697       Symbol representing tan of the argument.
698       """
699       def __init__(self,arg):
700           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
701       def __str__(self):
702          return "tan(%s)"%str(self.getArgument(0))
703       def eval(self,argval):
704           return tan(self.getEvaluatedArguments(argval)[0])
705       def _diff(self,arg):
706           s=cos(self.getArgument(0))
707           return 1./(s*s)*self.getDifferentiatedArguments(arg)[0]
708
709    def sign(arg):
710      """      """
711      @brief      Applies the sign function to arg.
712
713      @param arg      @param arg: argument
714      """      """
715      if isinstance(arg,escript.Data):      if isinstance(arg,Symbol):
716         return arg.exp()         return Sign_Symbol(arg)
717        elif hasattr(arg,"sign"):
718           return arg.sign()
719      else:      else:
720         return numarray.exp(arg)         return numarray.greater(arg,numarray.zeros(arg.shape,numarray.Float))- \
721                  numarray.less(arg,numarray.zeros(arg.shape,numarray.Float))
722
723  def sqrt(arg):  class Sign_Symbol(Symbol):
724       """
725       Symbol representing the sign of the argument.
726       """
727       def __init__(self,arg):
728           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
729       def __str__(self):
730          return "sign(%s)"%str(self.getArgument(0))
731       def eval(self,argval):
732           return sign(self.getEvaluatedArguments(argval)[0])
733
734    def maxval(arg):
735      """      """
736      @brief      Returns the maximum value of argument arg.
737
738      @param arg      @param arg: argument
739      """      """
740      if isinstance(arg,escript.Data):      if isinstance(arg,Symbol):
741         return arg.sqrt()         return Max_Symbol(arg)
742        elif hasattr(arg,"maxval"):
743           return arg.maxval()
744        elif hasattr(arg,"max"):
745           return arg.max()
746      else:      else:
747         return numarray.sqrt(arg)         return arg
748
749  def sin(arg):  class Max_Symbol(Symbol):
750       """
751       Symbol representing the maximum value of the argument.
752       """
753       def __init__(self,arg):
754           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
755       def __str__(self):
756          return "maxval(%s)"%str(self.getArgument(0))
757       def eval(self,argval):
758           return maxval(self.getEvaluatedArguments(argval)[0])
759
760    def minval(arg):
761      """      """
762      @brief      Returns the minimum value of argument arg.
763
764      @param arg      @param arg: argument
765      """      """
766      if isinstance(arg,escript.Data):      if isinstance(arg,Symbol):
767         return arg.sin()         return Min_Symbol(arg)
768        elif hasattr(arg,"maxval"):
769           return arg.minval()
770        elif hasattr(arg,"min"):
771           return arg.min()
772      else:      else:
773         return numarray.sin(arg)         return arg
774
775  def tan(arg):  class Min_Symbol(Symbol):
776       """
777       Symbol representing the minimum value of the argument.
778       """
779       def __init__(self,arg):
780           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
781       def __str__(self):
782          return "minval(%s)"%str(self.getArgument(0))
783       def eval(self,argval):
784           return minval(self.getEvaluatedArguments(argval)[0])
785
786    def wherePositive(arg):
787        """
788        Returns the positive values of argument arg.
789
790        @param arg: argument
791        """
792        if _testForZero(arg):
793          return 0
794        elif isinstance(arg,Symbol):
795           return WherePositive_Symbol(arg)
796        elif hasattr(arg,"wherePositive"):
797           return arg.minval()
798        elif hasattr(arg,"wherePositive"):
799           numarray.greater(arg,numarray.zeros(arg.shape,numarray.Float))
800        else:
801           if arg>0:
802              return 1.
803           else:
804              return 0.
805
806    class WherePositive_Symbol(Symbol):
807       """
808       Symbol representing the wherePositive function.
809       """
810       def __init__(self,arg):
811           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
812       def __str__(self):
813          return "wherePositive(%s)"%str(self.getArgument(0))
814       def eval(self,argval):
815           return wherePositive(self.getEvaluatedArguments(argval)[0])
816
817    def whereNegative(arg):
818        """
819        Returns the negative values of argument arg.
820
821        @param arg: argument
822        """
823        if _testForZero(arg):
824          return 0
825        elif isinstance(arg,Symbol):
826           return WhereNegative_Symbol(arg)
827        elif hasattr(arg,"whereNegative"):
828           return arg.whereNegative()
829        elif hasattr(arg,"shape"):
830           numarray.less(arg,numarray.zeros(arg.shape,numarray.Float))
831        else:
832           if arg<0:
833              return 1.
834           else:
835              return 0.
836
837    class WhereNegative_Symbol(Symbol):
838       """
839       Symbol representing the whereNegative function.
840       """
841       def __init__(self,arg):
842           Symbol.__init__(self,shape=arg.getShape(),dim=arg.getDim(),args=[arg])
843       def __str__(self):
844          return "whereNegative(%s)"%str(self.getArgument(0))
845       def eval(self,argval):
846           return whereNegative(self.getEvaluatedArguments(argval)[0])
847
848    def maximum(arg0,arg1):
849        """
850        Return arg1 where arg1 is bigger then arg0 otherwise arg0 is returned.
851        """
852        m=whereNegative(arg0-arg1)
853        return m*arg1+(1.-m)*arg0
854
855    def minimum(arg0,arg1):
856        """
857        Return arg0 where arg1 is bigger then arg0 otherwise arg1 is returned.
858        """
859        m=whereNegative(arg0-arg1)
860        return m*arg0+(1.-m)*arg1
861
862    def outer(arg0,arg1):
863       if _testForZero(arg0) or _testForZero(arg1):
864          return 0
865       else:
866          if isinstance(arg0,Symbol) or isinstance(arg1,Symbol):
867            return Outer_Symbol(arg0,arg1)
868          elif _identifyShape(arg0)==() or _identifyShape(arg1)==():
869            return arg0*arg1
870          elif isinstance(arg0,numarray.NumArray) and isinstance(arg1,numarray.NumArray):
871            return numarray.outer(arg0,arg1)
872          else:
873            if arg0.getRank()==1 and arg1.getRank()==1:
874              out=escript.Data(0,(arg0.getShape()[0],arg1.getShape()[0]),arg1.getFunctionSpace())
875              for i in range(arg0.getShape()[0]):
876                for j in range(arg1.getShape()[0]):
877                    out[i,j]=arg0[i]*arg1[j]
878              return out
879            else:
880              raise ValueError,"outer is not fully implemented yet."
881
882    class Outer_Symbol(Symbol):
883       """
884       Symbol representing the outer product of its two arguments.
885       """
886       def __init__(self,arg0,arg1):
887           a=[arg0,arg1]
888           s=tuple(list(_identifyShape(arg0))+list(_identifyShape(arg1)))
889           Symbol.__init__(self,shape=s,dim=_extractDim(a),args=a)
890       def __str__(self):
891          return "outer(%s,%s)"%(str(self.getArgument(0)),str(self.getArgument(1)))
892       def eval(self,argval):
893           a=self.getEvaluatedArguments(argval)
894           return outer(a[0],a[1])
895       def _diff(self,arg):
896           a=self.getDifferentiatedArguments(arg)
897           return outer(a[0],self.getArgument(1))+outer(self.getArgument(0),a[1])
898
899    def interpolate(arg,where):
900      """      """
901      @brief      Interpolates the function into the FunctionSpace where.
902
903      @param arg      @param arg:    interpolant
904        @param where:  FunctionSpace to interpolate to
905      """      """
906      if isinstance(arg,escript.Data):      if _testForZero(arg):
907         return arg.tan()        return 0
908        elif isinstance(arg,Symbol):
909           return Interpolated_Symbol(arg,where)
910      else:      else:
911         return numarray.tan(arg)         return escript.Data(arg,where)
912
913  def cos(arg):  class Interpolated_Symbol(Symbol):
914      """     """
915      @brief     Symbol representing the integral of the argument.
916       """
917       def __init__(self,arg,where):
918            Symbol.__init__(self,shape=_extractShape(arg),dim=_extractDim([arg]),args=[arg,where])
919       def __str__(self):
920          return "interpolated(%s)"%(str(self.getArgument(0)))
921       def eval(self,argval):
922           a=self.getEvaluatedArguments(argval)
923           return integrate(a[0],where=self.getArgument(1))
924       def _diff(self,arg):
925           a=self.getDifferentiatedArguments(arg)
926           return integrate(a[0],where=self.getArgument(1))
927
928    def div(arg,where=None):
929        """
930        Returns the divergence of arg at where.
931
932        @param arg:   Data object representing the function which gradient to
933                      be calculated.
934        @param where: FunctionSpace in which the gradient will be calculated.
935                      If not present or C{None} an appropriate default is used.
936        """
938
939    def jump(arg):
940        """
941        Returns the jump of arg across a continuity.
942
943        @param arg:   Data object representing the function which gradient
944                      to be calculated.
945        """
946        d=arg.getDomain()
947        return arg.interpolate(escript.FunctionOnContactOne())-arg.interpolate(escript.FunctionOnContactZero())
948
949
950      @param arg  def grad(arg,where=None):
951      """      """
952      if isinstance(arg,escript.Data):      Returns the spatial gradient of arg at where.
953         return arg.cos()
954        @param arg:   Data object representing the function which gradient
955                      to be calculated.
956        @param where: FunctionSpace in which the gradient will be calculated.
957                      If not present or C{None} an appropriate default is used.
958        """
959        if _testForZero(arg):
960          return 0
961        elif isinstance(arg,Symbol):
964           if where==None:
966           else:
968      else:      else:
969         return numarray.cos(arg)         return arg*0.
970
971  def maxval(arg):  class Grad_Symbol(Symbol):
972       """
973       Symbol representing the gradient of the argument.
974       """
975       def __init__(self,arg,where=None):
976           d=_extractDim([arg])
977           s=tuple(list(_identifyShape([arg])).append(d))
978           Symbol.__init__(self,shape=s,dim=_extractDim([arg]),args=[arg,where])
979       def __str__(self):
981       def eval(self,argval):
982           a=self.getEvaluatedArguments(argval)
984       def _diff(self,arg):
985           a=self.getDifferentiatedArguments(arg)
987
988    def integrate(arg,where=None):
989        """
990        Return the integral if the function represented by Data object arg over
991        its domain.
992
993        @param arg:   Data object representing the function which is integrated.
994        @param where: FunctionSpace in which the integral is calculated.
995                      If not present or C{None} an appropriate default is used.
996        """
997        if _testForZero(arg):
998          return 0
999        elif isinstance(arg,Symbol):
1000           return Integral_Symbol(arg,where)
1001        else:
1002           if not where==None: arg=escript.Data(arg,where)
1003           if arg.getRank()==0:
1004             return arg.integrate()[0]
1005           else:
1006             return arg.integrate()
1007
1008    class Integral_Symbol(Float_Symbol):
1009       """
1010       Symbol representing the integral of the argument.
1011       """
1012       def __init__(self,arg,where=None):
1013           Float_Symbol.__init__(self,shape=_identifyShape([arg]),args=[arg,where])
1014       def __str__(self):
1015          return "integral(%s)"%(str(self.getArgument(0)))
1016       def eval(self,argval):
1017           a=self.getEvaluatedArguments(argval)
1018           return integrate(a[0],where=self.getArgument(1))
1019       def _diff(self,arg):
1020           a=self.getDifferentiatedArguments(arg)
1021           return integrate(a[0],where=self.getArgument(1))
1022
1023    #=============================
1024    #
1025    # wrapper for various functions: if the argument has attribute the function name
1026    # as an argument it calls the corresponding methods. Otherwise the corresponding
1027    # numarray function is called.
1028
1029    # functions involving the underlying Domain:
1030
1031
1032    # functions returning Data objects:
1033
1034    def transpose(arg,axis=None):
1035      """      """
1036      @brief      Returns the transpose of the Data object arg.
1037
1038      @param arg      @param arg:
1039      """      """
1040        if axis==None:
1041           r=0
1042           if hasattr(arg,"getRank"): r=arg.getRank()
1043           if hasattr(arg,"rank"): r=arg.rank
1044           axis=r/2
1045        if isinstance(arg,Symbol):
1046           return Transpose_Symbol(arg,axis=r)
1047      if isinstance(arg,escript.Data):      if isinstance(arg,escript.Data):
1048         return arg.maxval()         # hack for transpose
1049           r=arg.getRank()
1050           if r!=2: raise ValueError,"Tranpose only avalaible for rank 2 objects"
1051           s=arg.getShape()
1052           out=escript.Data(0.,(s[1],s[0]),arg.getFunctionSpace())
1053           for i in range(s[0]):
1054              for j in range(s[1]):
1055                 out[j,i]=arg[i,j]
1056           return out
1057           # end hack for transpose
1058           return arg.transpose(axis)
1059      else:      else:
1060         return arg.max()         return numarray.transpose(arg,axis=axis)
1061
1062  def minval(arg):  def trace(arg,axis0=0,axis1=1):
1063      """      """
1064      @brief      Return
1065
1066      @param arg      @param arg:
1067      """      """
1068      if isinstance(arg,escript.Data):      if isinstance(arg,Symbol):
1069         return arg.minval()         s=list(arg.getShape())
1070           s=tuple(s[0:axis0]+s[axis0+1:axis1]+s[axis1+1:])
1071           return Trace_Symbol(arg,axis0=axis0,axis1=axis1)
1072        elif isinstance(arg,escript.Data):
1073           # hack for trace
1074           s=arg.getShape()
1075           if s[axis0]!=s[axis1]:
1076               raise ValueError,"illegal axis in trace"
1077           out=escript.Scalar(0.,arg.getFunctionSpace())
1078           for i in range(s[axis0]):
1079              out+=arg[i,i]
1080           return out
1081           # end hack for trace
1082      else:      else:
1083         return arg.max()         return numarray.trace(arg,axis0=axis0,axis1=axis1)
1084
1085    def Trace_Symbol(Symbol):
1086        pass
1087
1088  def length(arg):  def length(arg):
1089      """      """
@brief
1090
1091      @param arg      @param arg:
1092      """      """
1093      if isinstance(arg,escript.Data):      if isinstance(arg,escript.Data):
1094         return arg.length()         if arg.isEmpty(): return escript.Data()
1095           if arg.getRank()==0:
1096              return abs(arg)
1097           elif arg.getRank()==1:
1098              out=escript.Scalar(0,arg.getFunctionSpace())
1099              for i in range(arg.getShape()[0]):
1100                 out+=arg[i]**2
1101              return sqrt(out)
1102           elif arg.getRank()==2:
1103              out=escript.Scalar(0,arg.getFunctionSpace())
1104              for i in range(arg.getShape()[0]):
1105                 for j in range(arg.getShape()[1]):
1106                    out+=arg[i,j]**2
1107              return sqrt(out)
1108           elif arg.getRank()==3:
1109              out=escript.Scalar(0,arg.getFunctionSpace())
1110              for i in range(arg.getShape()[0]):
1111                 for j in range(arg.getShape()[1]):
1112                    for k in range(arg.getShape()[2]):
1113                       out+=arg[i,j,k]**2
1114              return sqrt(out)
1115           elif arg.getRank()==4:
1116              out=escript.Scalar(0,arg.getFunctionSpace())
1117              for i in range(arg.getShape()[0]):
1118                 for j in range(arg.getShape()[1]):
1119                    for k in range(arg.getShape()[2]):
1120                       for l in range(arg.getShape()[3]):
1121                          out+=arg[i,j,k,l]**2
1122              return sqrt(out)
1123           else:
1124              raise SystemError,"length is not been fully implemented yet"
1125              # return arg.length()
1126        elif isinstance(arg,float):
1127           return abs(arg)
1128      else:      else:
1129         return sqrt((arg**2).sum())         return sqrt((arg**2).sum())
1130
1131  def sign(arg):  def deviator(arg):
1132      """      """
1133      @brief      @param arg:

@param arg
1134      """      """
1135      if isinstance(arg,escript.Data):      if isinstance(arg,escript.Data):
1136         return arg.sign()          shape=arg.getShape()
1137      else:      else:
1138         return numarray.greater(arg,numarray.zeros(arg.shape))-numarray.less(arg,numarray.zeros(arg.shape))          shape=arg.shape
1139        if len(shape)!=2:
1140              raise ValueError,"Deviator requires rank 2 object"
1141        if shape[0]!=shape[1]:
1142              raise ValueError,"Deviator requires a square matrix"
1143        return arg-1./(shape[0]*1.)*trace(arg)*kronecker(shape[0])
1144
1145  # reduction operations:  def inner(arg0,arg1):
1146        """
1147        @param arg0:
1148        @param arg1:
1149        """
1150        if isinstance(arg0,escript.Data):
1151           arg=arg0
1152        else:
1153           arg=arg1
1154
1155        out=escript.Scalar(0,arg.getFunctionSpace())
1156        if arg.getRank()==0:
1157              return arg0*arg1
1158        elif arg.getRank()==1:
1159             out=escript.Scalar(0,arg.getFunctionSpace())
1160             for i in range(arg.getShape()[0]):
1161                out+=arg0[i]*arg1[i]
1162        elif arg.getRank()==2:
1163            out=escript.Scalar(0,arg.getFunctionSpace())
1164            for i in range(arg.getShape()[0]):
1165               for j in range(arg.getShape()[1]):
1166                  out+=arg0[i,j]*arg1[i,j]
1167        elif arg.getRank()==3:
1168            out=escript.Scalar(0,arg.getFunctionSpace())
1169            for i in range(arg.getShape()[0]):
1170                for j in range(arg.getShape()[1]):
1171                   for k in range(arg.getShape()[2]):
1172                      out+=arg0[i,j,k]*arg1[i,j,k]
1173        elif arg.getRank()==4:
1174            out=escript.Scalar(0,arg.getFunctionSpace())
1175            for i in range(arg.getShape()[0]):
1176               for j in range(arg.getShape()[1]):
1177                  for k in range(arg.getShape()[2]):
1178                     for l in range(arg.getShape()[3]):
1179                        out+=arg0[i,j,k,l]*arg1[i,j,k,l]
1180        else:
1181              raise SystemError,"inner is not been implemented yet"
1182        return out
1183
1184    def tensormult(arg0,arg1):
1185        # check LinearPDE!!!!
1186        raise SystemError,"tensormult is not implemented yet!"
1187
1188    def matrixmult(arg0,arg1):
1189
1190        if isinstance(arg1,numarray.NumArray) and isinstance(arg0,numarray.NumArray):
1191            numarray.matrixmult(arg0,arg1)
1192        else:
1193          # escript.matmult(arg0,arg1)
1194          if isinstance(arg1,escript.Data) and not isinstance(arg0,escript.Data):
1195            arg0=escript.Data(arg0,arg1.getFunctionSpace())
1196          elif isinstance(arg0,escript.Data) and not isinstance(arg1,escript.Data):
1197            arg1=escript.Data(arg1,arg0.getFunctionSpace())
1198          if arg0.getRank()==2 and arg1.getRank()==1:
1199              out=escript.Data(0,(arg0.getShape()[0],),arg0.getFunctionSpace())
1200              for i in range(arg0.getShape()[0]):
1201                 for j in range(arg0.getShape()[1]):
1202                   # uses Data object slicing, plus Data * and += operators
1203                   out[i]+=arg0[i,j]*arg1[j]
1204              return out
1205          elif arg0.getRank()==1 and arg1.getRank()==1:
1206              return inner(arg0,arg1)
1207          else:
1208              raise SystemError,"matrixmult is not fully implemented yet!"
1209
1210    #=========================================================
1211    # reduction operations:
1212    #=========================================================
1213  def sum(arg):  def sum(arg):
1214      """      """
1215      @brief      @param arg:

@param arg
1216      """      """
1217      return arg.sum()      return arg.sum()
1218
1219  def sup(arg):  def sup(arg):
1220      """      """
1221      @brief      @param arg:

@param arg
1222      """      """
1223      if isinstance(arg,escript.Data):      if isinstance(arg,escript.Data):
1224         return arg.sup()         return arg.sup()
1225        elif isinstance(arg,float) or isinstance(arg,int):
1226           return arg
1227      else:      else:
1228         return arg.max()         return arg.max()
1229
1230  def inf(arg):  def inf(arg):
1231      """      """
1232      @brief      @param arg:

@param arg
1233      """      """
1234      if isinstance(arg,escript.Data):      if isinstance(arg,escript.Data):
1235         return arg.inf()         return arg.inf()
1236        elif isinstance(arg,float) or isinstance(arg,int):
1237           return arg
1238      else:      else:
1239         return arg.min()         return arg.min()
1240
1241  def L2(arg):  def L2(arg):
1242      """      """
1243      @brief returns the L2-norm of the      Returns the L2-norm of the argument
1244
1245      @param arg      @param arg:
1246      """      """
1247      return arg.L2()      if isinstance(arg,escript.Data):
1248           return arg.L2()
1249        elif isinstance(arg,float) or isinstance(arg,int):
1250           return abs(arg)
1251        else:
1252           return numarry.sqrt(dot(arg,arg))
1253
1254  def Lsup(arg):  def Lsup(arg):
1255      """      """
1256      @brief      @param arg:

@param arg
1257      """      """
1258      if isinstance(arg,escript.Data):      if isinstance(arg,escript.Data):
1259         return arg.Lsup()         return arg.Lsup()
1260        elif isinstance(arg,float) or isinstance(arg,int):
1261           return abs(arg)
1262      else:      else:
1263         return arg.max(numarray.abs(arg))         return numarray.abs(arg).max()
1264
1265  def dot(arg1,arg2):  def dot(arg0,arg1):
1266      """      """
1267      @brief      @param arg0:
1268        @param arg1:
@param arg
1269      """      """
1270      if isinstance(arg1,escript.Data):      if isinstance(arg0,escript.Data):
1271         return arg1.dot(arg2)         return arg0.dot(arg1)
1272      elif isinstance(arg1,escript.Data):      elif isinstance(arg1,escript.Data):
1273         return arg2.dot(arg1)         return arg1.dot(arg0)
1274      else:      else:
1275         return numarray.dot(arg1,arg2)         return numarray.dot(arg0,arg1)
1276
1277    def kronecker(d):
1278       if hasattr(d,"getDim"):
1279          return numarray.identity(d.getDim())*1.
1280       else:
1281          return numarray.identity(d)*1.
1282
1283    def unit(i,d):
1284       """
1285       Return a unit vector of dimension d with nonzero index i.
1286
1287       @param d: dimension
1288       @param i: index
1289       """
1290       e = numarray.zeros((d,),numarray.Float)
1291       e[i] = 1.0
1292       return e
1293
1294    # ============================================
1295    #   testing
1296    # ============================================
1297
1298    if __name__=="__main__":
1299      u=ScalarSymbol(dim=2,name="u")
1300      v=ScalarSymbol(dim=2,name="v")
1301      v=VectorSymbol(2,"v")
1302      u=VectorSymbol(2,"u")
1303
1304      print u+5,(u+5).diff(u)
1305      print 5+u,(5+u).diff(u)
1306      print u+v,(u+v).diff(u)
1307      print v+u,(v+u).diff(u)
1308
1309      print u*5,(u*5).diff(u)
1310      print 5*u,(5*u).diff(u)
1311      print u*v,(u*v).diff(u)
1312      print v*u,(v*u).diff(u)
1313
1314      print u-5,(u-5).diff(u)
1315      print 5-u,(5-u).diff(u)
1316      print u-v,(u-v).diff(u)
1317      print v-u,(v-u).diff(u)
1318
1319      print u/5,(u/5).diff(u)
1320      print 5/u,(5/u).diff(u)
1321      print u/v,(u/v).diff(u)
1322      print v/u,(v/u).diff(u)
1323
1324      print u**5,(u**5).diff(u)
1325      print 5**u,(5**u).diff(u)
1326      print u**v,(u**v).diff(u)
1327      print v**u,(v**u).diff(u)
1328
1329      print exp(u),exp(u).diff(u)
1330      print sqrt(u),sqrt(u).diff(u)
1331      print log(u),log(u).diff(u)
1332      print sin(u),sin(u).diff(u)
1333      print cos(u),cos(u).diff(u)
1334      print tan(u),tan(u).diff(u)
1335      print sign(u),sign(u).diff(u)
1336      print abs(u),abs(u).diff(u)
1337      print wherePositive(u),wherePositive(u).diff(u)
1338      print whereNegative(u),whereNegative(u).diff(u)
1339      print maxval(u),maxval(u).diff(u)
1340      print minval(u),minval(u).diff(u)
1341
1343      print diff(5*g,g)
1344      4*(g+transpose(g))/2+6*trace(g)*kronecker(3)
1345
1346    #
1347    # \$Log\$
1348    # Revision 1.17  2005/09/01 03:31:28  jgs
1349    # Merge of development branch dev-02 back to main trunk on 2005-09-01
1350    #
1351    # Revision 1.16  2005/08/23 01:24:28  jgs
1352    # Merge of development branch dev-02 back to main trunk on 2005-08-23
1353    #
1354    # Revision 1.15  2005/08/12 01:45:36  jgs
1355    # erge of development branch dev-02 back to main trunk on 2005-08-12
1356    #
1357    # Revision 1.14.2.8  2005/08/26 05:06:37  cochrane
1358    # Corrected errors in docstrings.  Improved output formatting of docstrings.
1359    # Other minor improvements to code and docs (eg spelling etc).
1360    #
1361    # Revision 1.14.2.7  2005/08/26 04:45:40  cochrane
1362    # Fixed and tidied markup and docstrings.  Some *Symbol classes were defined
1363    # as functions, so changed them to classes (hopefully this was the right thing
1364    # to do).
1365    #
1366    # Revision 1.14.2.6  2005/08/26 04:30:13  gross
1367    # gneric unit testing for linearPDE
1368    #
1369    # Revision 1.14.2.5  2005/08/24 02:02:52  gross
1370    # jump function added
1371    #
1372    # Revision 1.14.2.4  2005/08/18 04:39:32  gross
1373    # the constants have been removed from util.py as they not needed anymore. PDE related constants are accessed through LinearPDE attributes now
1374    #
1375    # Revision 1.14.2.3  2005/08/03 09:55:33  gross
1376    # ContactTest is passing now./mk install!
1377    #
1378    # Revision 1.14.2.2  2005/08/02 03:15:14  gross
1379    # bug inb trace fixed!
1380    #
1381    # Revision 1.14.2.1  2005/07/29 07:10:28  gross
1382    # new functions in util and a new pde type in linearPDEs
1383    #
1384    # Revision 1.2.2.21  2005/07/28 04:19:23  gross
1385    # new functions maximum and minimum introduced.
1386    #
1387    # Revision 1.2.2.20  2005/07/25 01:26:27  gross
1388    # bug in inner fixed
1389    #
1390    # Revision 1.2.2.19  2005/07/21 04:01:28  jgs
1391    # minor comment fixes
1392    #
1393    # Revision 1.2.2.18  2005/07/21 01:02:43  jgs
1394    # commit ln() updates to development branch version
1395    #
1396    # Revision 1.12  2005/07/20 06:14:58  jgs
1397    # added ln(data) style wrapper for data.ln() - also added corresponding
1398    # implementation of Ln_Symbol class (not sure if this is right though)
1399    #
1400    # Revision 1.11  2005/07/08 04:07:35  jgs
1401    # Merge of development branch back to main trunk on 2005-07-08
1402    #
1403    # Revision 1.10  2005/06/09 05:37:59  jgs
1404    # Merge of development branch back to main trunk on 2005-06-09
1405    #
1406    # Revision 1.2.2.17  2005/07/07 07:28:58  gross
1407    # some stuff added to util.py to improve functionality
1408    #
1409    # Revision 1.2.2.16  2005/06/30 01:53:55  gross
1410    # a bug in coloring fixed
1411    #
1412    # Revision 1.2.2.15  2005/06/29 02:36:43  gross
1413    # Symbols have been introduced and some function clarified. needs much more work
1414    #
1415    # Revision 1.2.2.14  2005/05/20 04:05:23  gross
1416    # some work on a darcy flow started
1417    #
1418    # Revision 1.2.2.13  2005/03/16 05:17:58  matt
1419    # Implemented unit(idx, dim) to create cartesian unit basis vectors to
1420    # complement kronecker(dim) function.
1421    #
1422    # Revision 1.2.2.12  2005/03/10 08:14:37  matt
1423    # Added non-member Linf utility function to complement Data::Linf().
1424    #
1425    # Revision 1.2.2.11  2005/02/17 05:53:25  gross
1426    # some bug in saveDX fixed: in fact the bug was in
1427    # DataC/getDataPointShape
1428    #
1429    # Revision 1.2.2.10  2005/01/11 04:59:36  gross
1430    # automatic interpolation in integrate switched off
1431    #
1432    # Revision 1.2.2.9  2005/01/11 03:38:13  gross
1433    # Bug in Data.integrate() fixed for the case of rank 0. The problem is not totallly resolved as the method should return a scalar rather than a numarray object in the case of rank 0. This problem is fixed by the util.integrate wrapper.
1434    #
1435    # Revision 1.2.2.8  2005/01/05 04:21:41  gross
1436    # FunctionSpace checking/matchig in slicing added
1437    #
1438    # Revision 1.2.2.7  2004/12/29 05:29:59  gross
1439    # AdvectivePDE successfully tested for Peclet number 1000000. there is still a problem with setValue and Data()
1440    #
1441    # Revision 1.2.2.6  2004/12/24 06:05:41  gross
1442    # some changes in linearPDEs to add AdevectivePDE
1443    #
1444    # Revision 1.2.2.5  2004/12/17 00:06:53  gross
1445    # mk sets ESYS_ROOT is undefined
1446    #
1447    # Revision 1.2.2.4  2004/12/07 03:19:51  gross
1448    # options for GMRES and PRES20 added
1449    #
1450    # Revision 1.2.2.3  2004/12/06 04:55:18  gross
1451    # function wraper extended
1452    #
1453    # Revision 1.2.2.2  2004/11/22 05:44:07  gross
1454    # a few more unitary functions have been added but not implemented in Data yet
1455    #
1456    # Revision 1.2.2.1  2004/11/12 06:58:15  gross
1457    # a lot of changes to get the linearPDE class running: most important change is that there is no matrix format exposed to the user anymore. the format is chosen by the Domain according to the solver and symmetry
1458    #
1459    # Revision 1.2  2004/10/27 00:23:36  jgs
1460    # fixed minor syntax error
1461    #
1462    # Revision 1.1.1.1  2004/10/26 06:53:56  jgs
1463    # initial import of project esys2
1464    #
1465    # Revision 1.1.2.3  2004/10/26 06:43:48  jgs
1466    # committing Lutz's and Paul's changes to brach jgs
1467    #
1468    # Revision 1.1.4.1  2004/10/20 05:32:51  cochrane
1469    # Added incomplete Doxygen comments to files, or merely put the docstrings that already exist into Doxygen form.
1470    #
1471    # Revision 1.1  2004/08/05 03:58:27  gross
1472    # Bug in Assemble_NodeCoordinates fixed
1473    #
1474    #
1475
1476    # vim: expandtab shiftwidth=4:

Legend:
 Removed from v.102 changed lines Added in v.149