/[escript]/trunk/escript/py_src/util.py
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 88 by jgs, Wed Oct 27 00:23:36 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
22  #   escript constants:  
23  #  #===========================================================
24  FALSE=0  # a simple tool box to deal with _differentials of functions
25  TRUE=1  #===========================================================
26  UNKNOWN=-1  
27  EPSILON=1.e-15  class Symbol:
28  Pi=3.1415926535897931     """
29  # matrix types     Symbol class.
30  CSC=0       """
31  CSR=1     def __init__(self,name="symbol",shape=(),dim=3,args=[]):
32  LUMPED=10         """
33  # some solver options:         Creates an instance of a symbol of shape shape and spatial dimension
34  NO_REORDERING=0         dim.
35  MINIMUM_FILL_IN=1        
36  NESTED_DISSECTION=2         The symbol may depending on a list of arguments args which may be
37  DEFAULT_METHOD=0         symbols or other objects. name gives the name of the symbol.
38  PCG=1         """
39  CR=2  
40  CGS=3         self.__args=args
41  BICGSTAB=4         self.__name=name
42  SSOR=5         self.__shape=shape
43  ILU0=6         if hasattr(dim,"getDim"):
44  ILUT=7             self.__dim=dim.getDim()
45  JACOBI=8         else:    
46  # supported file formats:             self.__dim=dim
47  VRML=1         #
48  PNG=2         self.__cache_val=None
49  JPEG=3         self.__cache_argval=None
50  JPG=3  
51  PS=4     def getArgument(self,i):
52  OOGL=5         """
53  BMP=6         Returns the i-th argument.
54  TIFF=7         """
55  OPENINVENTOR=8         return self.__args[i]
56  RENDERMAN=9  
57  PNM=10     def getDim(self):
58  #         """
59  # wrapper for various functions: if the argument has attribute the function name         Returns the spatial dimension of the symbol.
60  # as an argument it calls the correspong methods. Otherwise the coresponsing numarray         """
61  # function is called.         return self.__dim
62  #  
63  def L2(arg):     def getRank(self):
64           """
65           Returns the rank of the symbol.
66           """
67           return len(self.getShape())
68    
69       def getShape(self):
70           """
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    
162       def __add__(self,other):
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])
170              return Add_Symbol(a[0],a[1])
171    
172       def __radd__(self,other):
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    
340    class Add_Symbol(Symbol):
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      Applies the exponential function to arg.
528    
529      @param arg      @param arg: argument
530      """      """
531      return arg.L2()      if isinstance(arg,Symbol):
532           return Exp_Symbol(arg)
533        elif hasattr(arg,"exp"):
534           return arg.exp()
535        else:
536           return numarray.exp(arg)
537    
538  def grad(arg,where=None):  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 sqrt(arg):
553      """      """
554      @brief      Applies the squre root function to arg.
555    
556      @param arg      @param arg: argument
     @param where  
557      """      """
558      if where==None:      if isinstance(arg,Symbol):
559         return arg.grad()         return Sqrt_Symbol(arg)
560        elif hasattr(arg,"sqrt"):
561           return arg.sqrt()
562      else:      else:
563         return arg.grad(where)         return numarray.sqrt(arg)      
564    
565  def integrate(arg):  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      Applies the sin function to arg.
633    
634      @param arg      @param arg: argument
635      """      """
636      return arg.integrate()      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  def interpolate(arg,where):  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 cos(arg):
657      """      """
658      @brief      Applies the cos function to arg.
659    
660      @param arg      @param arg: argument
     @param where  
661      """      """
662      return arg.interpolate(where)      if isinstance(arg,Symbol):
663           return Cos_Symbol(arg)
664        elif hasattr(arg,"cos"):
665           return arg.cos()
666        else:
667           return numarray.cos(arg)
668    
669    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        Applies the tan function to arg.
685    
686        @param arg: argument
687        """
688        if isinstance(arg,Symbol):
689           return Tan_Symbol(arg)
690        elif hasattr(arg,"tan"):
691           return arg.tan()
692        else:
693           return numarray.tan(arg)
694    
695  def transpose(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 hasattr(arg,"transpose"):      if isinstance(arg,Symbol):
716         return arg.transpose()         return Sign_Symbol(arg)
717        elif hasattr(arg,"sign"):
718           return arg.sign()
719      else:      else:
720         return numarray.transpose(arg,axis=None)         return numarray.greater(arg,numarray.zeros(arg.shape,numarray.Float))- \
721                  numarray.less(arg,numarray.zeros(arg.shape,numarray.Float))
722    
723    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 trace(arg):  def maxval(arg):
735      """      """
736      @brief      Returns the maximum value of argument arg.
737    
738      @param arg      @param arg: argument
739      """      """
740      if hasattr(arg,"trace"):      if isinstance(arg,Symbol):
741         return arg.trace()         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.trace(arg,k=0)         return arg
748    
749  def exp(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 hasattr(arg,"exp"):      if isinstance(arg,Symbol):
767         return arg.exp()         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.exp(arg)         return arg
774    
775  def sqrt(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 hasattr(arg,"sqrt"):      if _testForZero(arg):
907         return arg.sqrt()        return 0
908        elif isinstance(arg,Symbol):
909           return Interpolated_Symbol(arg,where)
910      else:      else:
911         return numarray.sqrt(arg)         return escript.Data(arg,where)
912    
913  def sin(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        """
937        return trace(grad(arg,where))
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 hasattr(arg,"sin"):      Returns the spatial gradient of arg at where.
953         return arg.sin()  
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):
962           return Grad_Symbol(arg,where)
963        elif hasattr(arg,"grad"):
964           if where==None:
965              return arg.grad()
966           else:
967              return arg.grad(where)
968      else:      else:
969         return numarray.sin(arg)         return arg*0.
970    
971  def cos(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):
980          return "grad(%s)"%(str(self.getArgument(0)))
981       def eval(self,argval):
982           a=self.getEvaluatedArguments(argval)
983           return grad(a[0],where=self.getArgument(1))
984       def _diff(self,arg):
985           a=self.getDifferentiatedArguments(arg)
986           return grad(a[0],where=self.getArgument(1))
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        Returns the transpose of the Data object arg.
1037    
1038        @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):
1048           # 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:
1060           return numarray.transpose(arg,axis=axis)
1061    
1062    def trace(arg,axis0=0,axis1=1):
1063      """      """
1064      @brief      Return
1065    
1066      @param arg      @param arg:
1067      """      """
1068      if hasattr(arg,"cos"):      if isinstance(arg,Symbol):
1069         return arg.cos()         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 numarray.cos(arg)         return numarray.trace(arg,axis0=axis0,axis1=axis1)
1084    
1085  def maxval(arg):  def Trace_Symbol(Symbol):
1086        pass
1087    
1088    def length(arg):
1089      """      """
     @brief  
1090    
1091      @param arg      @param arg:
1092      """      """
1093      return arg.maxval()      if isinstance(arg,escript.Data):
1094           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:
1129           return sqrt((arg**2).sum())
1130    
1131  def minval(arg):  def deviator(arg):
1132        """
1133        @param arg:
1134      """      """
1135      @brief      if isinstance(arg,escript.Data):
1136            shape=arg.getShape()
1137        else:
1138            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      @param arg  def inner(arg0,arg1):
1146        """
1147        @param arg0:
1148        @param arg1:
1149      """      """
1150      return arg.minval()      if isinstance(arg0,escript.Data):
1151           arg=arg0
1152        else:
1153           arg=arg1
1154    
1155  def sup(arg):      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):
1214        """
1215        @param arg:
1216      """      """
1217      @brief      return arg.sum()
1218    
1219      @param arg  def sup(arg):
1220        """
1221        @param arg:
1222      """      """
1223      return arg.sup()      if isinstance(arg,escript.Data):
1224           return arg.sup()
1225        elif isinstance(arg,float) or isinstance(arg,int):
1226           return arg
1227        else:
1228           return arg.max()
1229    
1230  def inf(arg):  def inf(arg):
1231      """      """
1232      @brief      @param arg:
   
     @param arg  
1233      """      """
1234      return arg.inf()      if isinstance(arg,escript.Data):
1235           return arg.inf()
1236        elif isinstance(arg,float) or isinstance(arg,int):
1237           return arg
1238        else:
1239           return arg.min()
1240    
1241  def Lsup(arg):  def L2(arg):
1242      """      """
1243      @brief      Returns the L2-norm of the argument
1244    
1245      @param arg      @param arg:
1246      """      """
1247      return arg.Lsup()      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 length(arg):  def Lsup(arg):
1255      """      """
1256      @brief      @param arg:
   
     @param arg  
1257      """      """
1258      return arg.length()      if isinstance(arg,escript.Data):
1259           return arg.Lsup()
1260        elif isinstance(arg,float) or isinstance(arg,int):
1261           return abs(arg)
1262        else:
1263           return numarray.abs(arg).max()
1264    
1265  def sign(arg):  def dot(arg0,arg1):
1266      """      """
1267      @brief      @param arg0:
1268        @param arg1:
     @param arg  
1269      """      """
1270      return arg.sign()      if isinstance(arg0,escript.Data):
1271           return arg0.dot(arg1)
1272        elif isinstance(arg1,escript.Data):
1273           return arg1.dot(arg0)
1274        else:
1275           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    
1342      g=grad(u)
1343      print diff(5*g,g)
1344      4*(g+transpose(g))/2+6*trace(g)*kronecker(3)
1345    
1346  #  #
1347  # $Log$  # $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  # Revision 1.2  2004/10/27 00:23:36  jgs
1460  # fixed minor syntax error  # fixed minor syntax error
1461  #  #
# Line 225  def sign(arg): Line 1472  def sign(arg):
1472  # Bug in Assemble_NodeCoordinates fixed  # Bug in Assemble_NodeCoordinates fixed
1473  #  #
1474  #  #
1475    
1476    # vim: expandtab shiftwidth=4:

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

  ViewVC Help
Powered by ViewVC 1.1.26