/[escript]/branches/schroedinger/escript/src/Data.h
ViewVC logotype

Diff of /branches/schroedinger/escript/src/Data.h

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

trunk/esys2/escript/src/Data/Data.h revision 94 by jgs, Wed Oct 27 00:45:54 2004 UTC trunk/escript/src/Data.h revision 698 by gross, Fri Mar 31 04:52:55 2006 UTC
# Line 1  Line 1 
1  // $Id$  // $Id$
2  /*=============================================================================  /*
3     ************************************************************
4   ******************************************************************************   *          Copyright 2006 by ACcESS MNRF                   *
5   *                                                                            *   *                                                          *
6   *       COPYRIGHT ACcESS 2004 -  All Rights Reserved                         *   *              http://www.access.edu.au                    *
7   *                                                                            *   *       Primary Business: Queensland, Australia            *
8   * This software is the property of ACcESS.  No part of this code             *   *  Licensed under the Open Software License version 3.0    *
9   * may be copied in any form or by any means without the expressed written    *   *     http://www.opensource.org/licenses/osl-3.0.php       *
10   * consent of ACcESS.  Copying, use or modification of this software          *   *                                                          *
11   * by any unauthorised person is illegal unless that                          *   ************************************************************
12   * person has a software license agreement with ACcESS.                       *  */
  *                                                                            *  
  ******************************************************************************  
13    
14  ******************************************************************************/  /** \file Data.h */
15    
16  #ifndef DATA_H  #ifndef DATA_H
17  #define DATA_H  #define DATA_H
18    
19  #include "escript/Data/DataAbstract.h"  #include "DataAbstract.h"
20  #include "escript/Data/DataTagged.h"  #include "DataAlgorithm.h"
21  #include "escript/Data/FunctionSpace.h"  #include "FunctionSpace.h"
22  #include "escript/Data/BinaryOp.h"  #include "BinaryOp.h"
23  #include "escript/Data/UnaryOp.h"  #include "UnaryOp.h"
24    #include "DataException.h"
25    
26  extern "C" {  extern "C" {
27  #include "escript/Data/DataC.h"  #include "DataC.h"
28  }  }
29    
 #include <iostream>  
30  #include <string>  #include <string>
 #include <memory>  
31  #include <algorithm>  #include <algorithm>
32    
33  #include <boost/shared_ptr.hpp>  #include <boost/shared_ptr.hpp>
34  #include <boost/python/object.hpp>  #include <boost/python/object.hpp>
 #include <boost/python/list.hpp>  
35  #include <boost/python/tuple.hpp>  #include <boost/python/tuple.hpp>
36  #include <boost/python/numeric.hpp>  #include <boost/python/numeric.hpp>
37    
38    namespace escript {
39    
40    //
41    // Forward declaration for various implementations of Data.
42    class DataConstant;
43    class DataTagged;
44    class DataExpanded;
45    
46  /**  /**
47     \brief     \brief
48     Data is essentially a factory class which creates the appropriate Data     Data creates the appropriate Data object for the given construction
49     object for the given construction arguments. It retains control over     arguments.
    the object created for the lifetime of the object.  
    The type of Data object referred to may change during the lifetime of  
    the Data object.  
50    
51     Description:     Description:
52     Data is essentially a factory class which creates the appropriate Data     Data is essentially a factory class which creates the appropriate Data
# Line 54  extern "C" { Line 55  extern "C" {
55     The type of Data object referred to may change during the lifetime of     The type of Data object referred to may change during the lifetime of
56     the Data object.     the Data object.
57  */  */
   
 namespace escript {  
   
 //  
 // Forward declaration for various implimentations of Data.  
 class DataEmpty;  
 class DataConstant;  
 class DataTagged;  
 class DataExpanded;  
   
58  class Data {  class Data {
59    
60    public:    public:
61    
62      // These typedefs allow function names to be cast to pointers
63      // to functions of the appropriate type when calling unaryOp etc.
64    typedef double (*UnaryDFunPtr)(double);    typedef double (*UnaryDFunPtr)(double);
65    typedef double (*BinaryDFunPtr)(double,double);    typedef double (*BinaryDFunPtr)(double,double);
66    
67    /**    /**
68         Constructors.
69      */
70    
71      /**
72       \brief       \brief
73       Default constructor.       Default constructor.
74       Creates a DataEmpty object.       Creates a DataEmpty object.
# Line 88  class Data { Line 85  class Data {
85    /**    /**
86       \brief       \brief
87       Constructor from another Data object. If "what" is different from the       Constructor from another Data object. If "what" is different from the
88       function space of inData the inData are tried to be interpolated to what       function space of inData the inData are tried to be interpolated to what,
89       otherwise a shallow copy of inData is returned.       otherwise a shallow copy of inData is returned.
90    */    */
91    Data(const Data& inData,    Data(const Data& inData,
# Line 146  class Data { Line 143  class Data {
143       \param what - Input - A description of what this data represents.       \param what - Input - A description of what this data represents.
144       \param expanded - Input - Flag, if true fill the entire container with       \param expanded - Input - Flag, if true fill the entire container with
145                         the appropriate values.                         the appropriate values.
146        ==>*
147    */    */
148    Data(const DataTagged::TagListType& tagKeys,    Data(const DataTagged::TagListType& tagKeys,
149         const DataTagged::ValueListType& values,         const DataTagged::ValueListType& values,
# Line 202  class Data { Line 200  class Data {
200         const boost::python::tuple& shape=boost::python::make_tuple(),         const boost::python::tuple& shape=boost::python::make_tuple(),
201         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
202         bool expanded=false);         bool expanded=false);
   
203    /**    /**
204       \brief       \brief
205       Perform the specified algorithm on the Data and return result.       Destructor
206    */    */
207    template <class UnaryFunction>    ~Data();
   inline double  
   algorithm(UnaryFunction operation) const;  
208    
209    /**    /**
210       \brief       \brief
211       Perform the given unary operation on all of the data's elements.       Perform a deep copy.
212    */    */
   template <class UnaryFunction>  
213    void    void
214    unaryOp(UnaryFunction operation);    copy(const Data& other);
215    
216    /**    /**
217       \brief       Member access methods.
      Perform the given binary operation on all of the data's elements.  
      The underlying type of the right hand side (right) determines the final  
      type of *this after the operation. For example if the right hand side  
      is expanded *this will be expanded if necessary.  
218    */    */
   template <class BinaryFunction>  
   void  
   binaryOp(const Data& right,  
            BinaryFunction operation);  
219    
220    /**    /**
221       \brief       \brief
222       Perform the given binary operation on all of the data's elements.       Return the values of all data-points as a single python numarray object.
223    */    */
224    template <class BinaryFunction>    const boost::python::numeric::array
225    void    convertToNumArray();
   binaryOp(const boost::python::object& right,  
            BinaryFunction operation);  
226    
227    /**    /**
228       \brief       \brief
229       Overloaded operator +=       Return the values of all data-points for the given sample as a single python numarray object.
      \param right - Input - The right hand side.  
230    */    */
231    Data& operator+=(const Data& right);    const boost::python::numeric::array
232    Data& operator+=(const boost::python::object& right);    convertToNumArrayFromSampleNo(int sampleNo);
233    
234    /**    /**
235       \brief       \brief
236       Overloaded operator -=       Return the value of the specified data-point as a single python numarray object.
      \param right - Input - The right hand side.  
   */  
   Data& operator-=(const Data& right);  
   Data& operator-=(const boost::python::object& right);  
   
  /**  
      \brief  
      Overloaded operator *=  
      \param right - Input - The right hand side.  
237    */    */
238    Data& operator*=(const Data& right);    const boost::python::numeric::array
239    Data& operator*=(const boost::python::object& right);    convertToNumArrayFromDPNo(int sampleNo,
240                                int dataPointNo);
241    
242   /**    /**
243       \brief       \brief
244       Overloaded operator /=       Fills the expanded Data object from values of a python numarray object.
      \param right - Input - The right hand side.  
245    */    */
246    Data& operator/=(const Data& right);    void
247    Data& operator/=(const boost::python::object& right);    fillFromNumArray(const boost::python::numeric::array);
248    
249    /**    /**
250       \brief       \brief
251       Return the power of Data.       Return the tag number associated with the given data-point.
252    
253         The data-point number here corresponds to the data-point number in the
254         numarray returned by convertToNumArray.
255    */    */
256    Data powD(const Data& right) const;    int
257    Data powO(const boost::python::object& right) const;    getTagNumber(int dpno);
258    
259    /**    /**
260       \brief       \brief
261       Return the C wrapper for the Data object.       Return the C wrapper for the Data object.
262    */    */
263    escriptDataC getDataC();    escriptDataC
264      getDataC();
265    
266    /**    /**
267       \brief       \brief
268       Return the C wrapper for the Data object - const version.       Return the C wrapper for the Data object - const version.
269    */    */
270    escriptDataC getDataC() const;    escriptDataC
271      getDataC() const;
272    
273    /**    /**
274       \brief       \brief
275       Write the data as a string.       Write the data as a string.
276    */    */
277    std::string toString() const;    inline
278      std::string
279      toString() const
280      {
281        return m_data->toString();
282      }
283    
284    /**    /**
285       \brief       \brief
# Line 312  class Data { Line 296  class Data {
296    
297    /**    /**
298       \brief       \brief
299       Perform a deep copy.       Whatever the current Data type make this into a DataExpanded.
   */  
   void  
   copy(const Data& other);  
   
   /**  
     \brief  
     Copy other Data object into this Data object where mask is positive.  
   */  
   void  
   copyWithMask(const Data& other,  
                const Data& mask);  
   
   /**  
      \brief  
      Whatever the current Data type make it expanded.  
300    */    */
301    void    void
302    expand();    expand();
303    
304    /**    /**
305       \brief       \brief
306       If possible convert the Data type to tagged. This will only allow       If possible convert this Data to DataTagged. This will only allow
307       Constant data to be converted to tagged. An attempt to convert       Constant data to be converted to tagged. An attempt to convert
308       Expanded data to tagged will throw an exception.       Expanded data to tagged will throw an exception.
309        ==>*
310    */    */
311    void    void
312    tag();    tag();
# Line 357  class Data { Line 327  class Data {
327    
328    /**    /**
329       \brief       \brief
330       Return true if this Data is empty.       Return true if this Data is constant.
331    */    */
332    bool    bool
333    isEmpty() const;    isConstant() const;
334    
335    /**    /**
336       \brief       \brief
337       Return true if this Data is constant.       Return true if this Data is empty.
338    */    */
339    bool    bool
340    isConstant() const;    isEmpty() const;
341    
342    /**    /**
343       \brief       \brief
# Line 418  class Data { Line 388  class Data {
388    
389    /**    /**
390       \brief       \brief
391       Return the number of data points per sample.       Return the number of samples.
392    */    */
393    inline    inline
394    int    int
395    getNumDataPointsPerSample() const    getNumSamples() const
396    {    {
397      return m_data->getNumDPPSample();      return m_data->getNumSamples();
398    }    }
399    
400    /**    /**
401       \brief       \brief
402       Return the number of samples.       Return the number of data points per sample.
403    */    */
404      inline
405    int    int
406    getNumSamples() const;    getNumDataPointsPerSample() const
407      {
408    /**      return m_data->getNumDPPSample();
409       \brief    }
      Check *this and the right operand are compatible. Throws  
      an exception if they aren't.  
      \param right - Input - The right hand side.  
   */  
   void  
   operandCheck(const Data& right) const;  
410    
411    /**    /**
412       \brief       \brief
# Line 449  class Data { Line 414  class Data {
414       preferred interface but is provided for use by C code.       preferred interface but is provided for use by C code.
415       \param sampleNo - Input - the given sample no.       \param sampleNo - Input - the given sample no.
416    */    */
417      inline
418    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
419    getSampleData(DataAbstract::ShapeType::size_type sampleNo);    getSampleData(DataAbstract::ValueType::size_type sampleNo)
420      {
421        return m_data->getSampleData(sampleNo);
422      }
423    
424    /**    /**
425       \brief       \brief
# Line 458  class Data { Line 427  class Data {
427       access data that isn't tagged an exception will be thrown.       access data that isn't tagged an exception will be thrown.
428       \param tag - Input - the tag key.       \param tag - Input - the tag key.
429    */    */
430      inline
431    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
432    getSampleDataByTag(int tag);    getSampleDataByTag(int tag)
433      {
434        return m_data->getSampleDataByTag(tag);
435      }
436    
437      /**
438         \brief
439         Assign the given value to the data-points referenced by the given
440         reference number.
441    
442         The value supplied is a python numarray object.  The data from this numarray
443         is unpacked into a DataArray, and this is used to set the corresponding
444         data-points in the underlying Data object.
445    
446         If the underlying Data object cannot be accessed via reference numbers, an
447         exception will be thrown.
448    
449         \param ref - Input - reference number.
450         \param value - Input - value to assign to data-points associated with
451                                the given reference number.
452      */
453      void
454      setRefValue(int ref,
455                  const boost::python::numeric::array& value);
456    
457      /**
458         \brief
459         Return the values associated with the data-points referenced by the given
460         reference number.
461    
462         The value supplied is a python numarray object. The data from the corresponding
463         data-points in this Data object are packed into the given numarray object.
464    
465         If the underlying Data object cannot be accessed via reference numbers, an
466         exception will be thrown.
467    
468         \param ref - Input - reference number.
469         \param value - Output - object to receive values from data-points
470                                 associated with the given reference number.
471      */
472      void
473      getRefValue(int ref,
474                  boost::python::numeric::array& value);
475    
476    /**    /**
477       \brief       \brief
# Line 486  class Data { Line 498  class Data {
498    
499    /**    /**
500       \brief       \brief
501       Return data point shape as a tuple of integers:       Return the data point shape as a tuple of integers.
502    */    */
503    boost::python::tuple    const boost::python::tuple
504    getShapeTuple() const;    getShapeTuple() const;
505    
506    /**    /**
# Line 501  class Data { Line 513  class Data {
513    
514    /**    /**
515       \brief       \brief
516       Return the number of doubles stored for Data.       Return the number of doubles stored for this Data.
517    */    */
518    DataArrayView::ValueType::size_type    DataArrayView::ValueType::size_type
519    getLength() const;    getLength() const;
520    
521    /**    /**
522       \brief       \brief
523       Interpolates this onto the given functionspace and returns the result as a Data object.       Assign the given value to the tag. Implicitly converts this
524         object to type DataTagged. Throws an exception if this object
525         cannot be converted to a DataTagged object.
526         \param tagKey - Input - Integer key.
527         \param value - Input - Value to associate with given key.
528        ==>*
529      */
530      void
531      setTaggedValue(int tagKey,
532                     const boost::python::object& value);
533    
534      /**
535         \brief
536         Assign the given value to the tag. Implicitly converts this
537         object to type DataTagged. Throws an exception if this object
538         cannot be converted to a DataTagged object.
539         \param tagKey - Input - Integer key.
540         \param value - Input - Value to associate with given key.
541        ==>*
542      */
543      void
544      setTaggedValueFromCPP(int tagKey,
545                            const DataArrayView& value);
546    
547      /**
548        \brief
549        Copy other Data object into this Data object where mask is positive.
550      */
551      void
552      copyWithMask(const Data& other,
553                   const Data& mask);
554    
555      /**
556         Data object operation methods and operators.
557      */
558    
559      /**
560         \brief
561         Interpolates this onto the given functionspace and returns
562         the result as a Data object.
563         *
564    */    */
565    Data    Data
566    interpolate(const FunctionSpace& functionspace) const;    interpolate(const FunctionSpace& functionspace) const;
# Line 517  class Data { Line 569  class Data {
569       \brief       \brief
570       Calculates the gradient of the data at the data points of functionspace.       Calculates the gradient of the data at the data points of functionspace.
571       If functionspace is not present the function space of Function(getDomain()) is used.       If functionspace is not present the function space of Function(getDomain()) is used.
572         *
573    */    */
574    Data    Data
575    gradOn(const FunctionSpace& functionspace) const;    gradOn(const FunctionSpace& functionspace) const;
# Line 527  class Data { Line 580  class Data {
580    /**    /**
581       \brief       \brief
582       Calculate the integral over the function space domain.       Calculate the integral over the function space domain.
583         *
584    */    */
585    boost::python::numeric::array    boost::python::numeric::array
586    integrate() const;    integrate() const;
# Line 534  class Data { Line 588  class Data {
588    /**    /**
589       \brief       \brief
590       Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.       Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
591         *
592    */    */
593    Data    Data
594    wherePositive() const;    wherePositive() const;
595    
596    /**    /**
597       \brief       \brief
598       Return a Data with a 1 for +ive values and a 0 for -ive values.       Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
599         *
600      */
601      Data
602      whereNegative() const;
603    
604      /**
605         \brief
606         Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
607         *
608    */    */
609    Data    Data
610    whereNonNegative() const;    whereNonNegative() const;
611    
612    /**    /**
613       \brief       \brief
614       Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.       Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
615         *
616    */    */
617    Data    Data
618    whereNegative() const;    whereNonPositive() const;
619    
620      /**
621         \brief
622         Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
623         *
624      */
625      Data
626      whereZero(double tol=0.0) const;
627    
628      /**
629         \brief
630         Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
631         *
632      */
633      Data
634      whereNonZero(double tol=0.0) const;
635    
636      /**
637         \brief
638         Return the maximum absolute value of this Data object.
639         *
640      */
641      double
642      Lsup() const;
643    
644      /**
645         \brief
646         Return the minimum absolute value of this Data object.
647         *
648      */
649      double
650      Linf() const;
651    
652      /**
653         \brief
654         Return the maximum value of this Data object.
655         *
656      */
657      double
658      sup() const;
659    
660    /**    /**
661       \brief       \brief
662       Return a Data with a 1 for 0 values a 0 for +ive or -ive.       Return the minimum value of this Data object.
663         *
664      */
665      double
666      inf() const;
667    
668      /**
669         \brief
670         Return the absolute value of each data point of this Data object.
671         *
672      */
673      Data
674      abs() const;
675    
676      /**
677         \brief
678         Return the maximum value of each data point of this Data object.
679         *
680      */
681      Data
682      maxval() const;
683    
684      /**
685         \brief
686         Return the minimum value of each data point of this Data object.
687         *
688      */
689      Data
690      minval() const;
691    
692      /**
693         \brief
694         Return the (sample number, data-point number) of the data point with
695         the minimum value in this Data object.
696      */
697      const boost::python::tuple
698      mindp() const;
699    
700      void
701      calc_mindp(int& SampleNo,
702                 int& DataPointNo) const;
703    
704      /**
705         \brief
706         Return the sign of each data point of this Data object.
707         -1 for negative values, zero for zero values, 1 for positive values.
708         *
709      */
710      Data
711      sign() const;
712    
713      /**
714         \brief
715         Return the eigenvalues of the symmetric part at each data point of this Data object in increasing values.
716         Currently this function is restricted to rank 2, square shape, and dimension 3.
717         *
718      */
719      Data
720      eigenvalues() const;
721    
722      /**
723         \brief
724         Return the eigenvalues and corresponding eigenvcetors of the symmetric part at each data point of this Data object.
725         the eigenvalues are ordered in increasing size where eigenvalues with relative difference less than
726         tol are treated as equal. The eigenvectors are orthogonal, normalized and the sclaed such that the
727         first non-zero entry is positive.
728         Currently this function is restricted to rank 2, square shape, and dimension 3
729         *
730      */
731      const boost::python::tuple
732      eigenvalues_and_eigenvectors(const double tol=1.e-12) const;
733    
734      /**
735         \brief
736         Transpose each data point of this Data object around the given axis.
737         --* not implemented yet *--
738         *
739    */    */
740    Data    Data
741    whereZero() const;    transpose(int axis) const;
742    
743    /**    /**
744       \brief       \brief
745       Return the sin of Data.       Calculate the trace of each data point of this Data object.
746         *
747      */
748      Data
749      trace() const;
750    
751      /**
752         \brief
753         Return the sin of each data point of this Data object.
754         *
755    */    */
756    Data    Data
757    sin() const;    sin() const;
758    
759    /**    /**
760       \brief       \brief
761       Return the cos of Data.       Return the cos of each data point of this Data object.
762         *
763    */    */
764    Data    Data
765    cos() const;    cos() const;
766    
767    /**    /**
768       \brief       \brief
769       Return the tan of Data.       Return the tan of each data point of this Data object.
770         *
771    */    */
772    Data    Data
773    tan() const;    tan() const;
774    
775    /**    /**
776       \brief       \brief
777       Return the log to base 10 of Data.       Return the asin of each data point of this Data object.
778         *
779    */    */
780    Data    Data
781    log() const;    asin() const;
782    
783    /**    /**
784       \brief       \brief
785       Return the natural log of Data.       Return the acos of each data point of this Data object.
786         *
787    */    */
788    Data    Data
789    ln() const;    acos() const;
790    
791    /**    /**
792       \brief       \brief
793       Return a Data containing a slice of this Data.       Return the atan of each data point of this Data object.
794         *
795    */    */
796    Data    Data
797    getSlice(const DataArrayView::RegionType& region) const;    atan() const;
798    
799    /**    /**
800       \brief       \brief
801       Copy the specified region from the given value.       Return the sinh of each data point of this Data object.
802       \param value - Input - Data to copy from.       *
      \param region - Input - Region to copy.  
803    */    */
804    void    Data
805    setSlice(const Data& value,    sinh() const;
            const DataArrayView::RegionType& region);  
806    
807    /**    /**
808       \brief       \brief
809       Return the maximum absolute value.       Return the cosh of each data point of this Data object.
810         *
811    */    */
812    double    Data
813    Lsup() const;    cosh() const;
814    
815    /**    /**
816       \brief       \brief
817       Return the maximum value.       Return the tanh of each data point of this Data object.
818         *
819    */    */
820    double    Data
821    sup() const;    tanh() const;
822    
823    /**    /**
824       \brief       \brief
825       Return the minimum value.       Return the asinh of each data point of this Data object.
826         *
827    */    */
828    double    Data
829    inf() const;    asinh() const;
830    
831    /**    /**
832       \brief       \brief
833       Returns a slice from this.       Return the acosh of each data point of this Data object.
834         *
835    */    */
836    Data    Data
837    getItem(const boost::python::object& key) const;    acosh() const;
838    
839    /**    /**
840       \brief       \brief
841       Copies slice from value into this.       Return the atanh of each data point of this Data object.
842         *
843      */
844      Data
845      atanh() const;
846    
847      /**
848         \brief
849         Return the log to base 10 of each data point of this Data object.
850         *
851      */
852      Data
853      log10() const;
854    
855      /**
856         \brief
857         Return the natural log of each data point of this Data object.
858         *
859      */
860      Data
861      log() const;
862    
863      /**
864         \brief
865         Return the exponential function of each data point of this Data object.
866         *
867      */
868      Data
869      exp() const;
870    
871      /**
872         \brief
873         Return the square root of each data point of this Data object.
874         *
875      */
876      Data
877      sqrt() const;
878    
879      /**
880         \brief
881         Return the negation of each data point of this Data object.
882         *
883      */
884      Data
885      neg() const;
886    
887      /**
888         \brief
889         Return the identity of each data point of this Data object.
890         Simply returns this object unmodified.
891         *
892      */
893      Data
894      pos() const;
895    
896      /**
897         \brief
898         Return the given power of each data point of this Data object.
899    
900         \param right Input - the power to raise the object to.
901         *
902      */
903      Data
904      powD(const Data& right) const;
905    
906      /**
907         \brief
908         Return the given power of each data point of this boost python object.
909        
910         \param right Input - the power to raise the object to.
911         *
912       */
913      Data
914      powO(const boost::python::object& right) const;
915    
916      /**
917         \brief
918         writes the object to a file in the DX file format
919    */    */
920    void    void
921    setItem(const boost::python::object& key,    saveDX(std::string fileName) const;
           const Data& value);  
922    
923    /**    /**
924       \brief       \brief
925       Convert the underlying data type to match the RHS.       writes the object to a file in the VTK file format
      \param right - Input - data type to match.  
926    */    */
927    void    void
928    typeMatch(const Data& right);    saveVTK(std::string fileName) const;
929    
930      /**
931         \brief
932         Overloaded operator +=
933         \param right - Input - The right hand side.
934         *
935      */
936      Data& operator+=(const Data& right);
937      Data& operator+=(const boost::python::object& right);
938    
939      /**
940         \brief
941         Overloaded operator -=
942         \param right - Input - The right hand side.
943         *
944      */
945      Data& operator-=(const Data& right);
946      Data& operator-=(const boost::python::object& right);
947    
948     /**
949         \brief
950         Overloaded operator *=
951         \param right - Input - The right hand side.
952         *
953      */
954      Data& operator*=(const Data& right);
955      Data& operator*=(const boost::python::object& right);
956    
957     /**
958         \brief
959         Overloaded operator /=
960         \param right - Input - The right hand side.
961         *
962      */
963      Data& operator/=(const Data& right);
964      Data& operator/=(const boost::python::object& right);
965    
966    /**    /**
967       \brief       \brief
# Line 663  class Data { Line 971  class Data {
971    probeInterpolation(const FunctionSpace& functionspace) const;    probeInterpolation(const FunctionSpace& functionspace) const;
972    
973    /**    /**
974         Data object slicing methods.
975      */
976    
977      /**
978       \brief       \brief
979       Assign the given value to the tag. Implicitly converts this       Returns a slice from this Data object.
980       object to type DataTagged. Throws an exception if this object  
981       cannot be converted to a DataTagged object.       /description
982       \param tagKey - Input - Integer key.       Implements the [] get operator in python.
983       \param value - Input - Value to associate with given key.       Calls getSlice.
984    
985         \param key - Input - python slice tuple specifying
986         slice to return.
987      */
988      Data
989      getItem(const boost::python::object& key) const;
990    
991      /**
992         \brief
993         Copies slice from value into this Data object.
994    
995         Implements the [] set operator in python.
996         Calls setSlice.
997    
998         \param key - Input - python slice tuple specifying
999         slice to copy from value.
1000         \param value - Input - Data object to copy from.
1001    */    */
1002    void    void
1003    setTaggedValue(int tagKey,    setItemD(const boost::python::object& key,
1004                   const boost::python::object& value);             const Data& value);
1005    
1006      void
1007      setItemO(const boost::python::object& key,
1008               const boost::python::object& value);
1009    
1010      // These following public methods should be treated as private.
1011    
1012    /**    /**
1013       \brief       \brief
1014       Assign the given value to the tag. Implicitly converts this       Perform the given unary operation on every element of every data point in
1015       object to type DataTagged. Throws an exception if this object       this Data object.
      cannot be converted to a DataTagged object.  
      \param tagKey - Input - Integer key.  
      \param value - Input - Value to associate with given key.  
      Note: removed for now - this version not needed, and breaks escript.cpp  
1016    */    */
1017    /*    template <class UnaryFunction>
1018      inline
1019    void    void
1020    setTaggedValue(int tagKey,    unaryOp(UnaryFunction operation);
1021                   const DataArrayView& value);  
1022      /**
1023         \brief
1024         Return a Data object containing the specified slice of
1025         this Data object.
1026         \param region - Input - Region to copy.
1027         *
1028      */
1029      Data
1030      getSlice(const DataArrayView::RegionType& region) const;
1031    
1032      /**
1033         \brief
1034         Copy the specified slice from the given value into this
1035         Data object.
1036         \param value - Input - Data to copy from.
1037         \param region - Input - Region to copy.
1038         *
1039    */    */
1040      void
1041      setSlice(const Data& value,
1042               const DataArrayView::RegionType& region);
1043    
1044      /**
1045         \brief
1046         Archive the current Data object to the given file.
1047         \param fileName - Input - file to archive to.
1048      */
1049      void
1050      archiveData(const std::string fileName);
1051    
1052      /**
1053         \brief
1054         Extract the Data object archived in the given file, overwriting
1055         the current Data object.
1056         Note - the current object must be of type DataEmpty.
1057         \param fileName - Input - file to extract from.
1058         \param fspace - Input - a suitable FunctionSpace descibing the data.
1059      */
1060      void
1061      extractData(const std::string fileName,
1062                  const FunctionSpace& fspace);
1063    
1064     protected:
1065    
1066   private:   private:
1067    
1068    /**    /**
1069       \brief       \brief
1070         Check *this and the right operand are compatible. Throws
1071         an exception if they aren't.
1072         \param right - Input - The right hand side.
1073      */
1074      inline
1075      void
1076      operandCheck(const Data& right) const
1077      {
1078        return m_data->operandCheck(*(right.m_data.get()));
1079      }
1080    
1081      /**
1082         \brief
1083         Perform the specified reduction algorithm on every element of every data point in
1084         this Data object according to the given function and return the single value result.
1085      */
1086      template <class BinaryFunction>
1087      inline
1088      double
1089      algorithm(BinaryFunction operation,
1090                double initial_value) const;
1091    
1092      /**
1093         \brief
1094         Reduce each data-point in this Data object using the given operation. Return a Data
1095         object with the same number of data-points, but with each data-point containing only
1096         one value - the result of the reduction operation on the corresponding data-point in
1097         this Data object
1098      */
1099      template <class BinaryFunction>
1100      inline
1101      Data
1102      dp_algorithm(BinaryFunction operation,
1103                   double initial_value) const;
1104    
1105      /**
1106         \brief
1107         Perform the given binary operation on all of the data's elements.
1108         The underlying type of the right hand side (right) determines the final
1109         type of *this after the operation. For example if the right hand side
1110         is expanded *this will be expanded if necessary.
1111         RHS is a Data object.
1112      */
1113      template <class BinaryFunction>
1114      inline
1115      void
1116      binaryOp(const Data& right,
1117               BinaryFunction operation);
1118    
1119      /**
1120         \brief
1121         Perform the given binary operation on all of the data's elements.
1122         RHS is a boost::python object.
1123      */
1124      template <class BinaryFunction>
1125      inline
1126      void
1127      binaryOp(const boost::python::object& right,
1128               BinaryFunction operation);
1129    
1130      /**
1131         \brief
1132         Convert the data type of the RHS to match this.
1133         \param right - Input - data type to match.
1134      */
1135      void
1136      typeMatchLeft(Data& right) const;
1137    
1138      /**
1139         \brief
1140         Convert the data type of this to match the RHS.
1141         \param right - Input - data type to match.
1142      */
1143      void
1144      typeMatchRight(const Data& right);
1145    
1146      /**
1147         \brief
1148       Construct a Data object of the appropriate type.       Construct a Data object of the appropriate type.
1149    */    */
1150    template <class IValueType>    template <class IValueType>
# Line 712  class Data { Line 1164  class Data {
1164    reshapeDataPoint(const DataArrayView::ShapeType& shape);    reshapeDataPoint(const DataArrayView::ShapeType& shape);
1165    
1166    //    //
1167    // pointer to the actual data    // pointer to the actual data object
1168    boost::shared_ptr<DataAbstract> m_data;    boost::shared_ptr<DataAbstract> m_data;
1169    
1170      //
1171      // pointer to the internal profiling data
1172      struct profDataEntry *profData;
1173    
1174  };  };
1175    
1176  template <class IValueType>  template <class IValueType>
# Line 730  Data::initialise(const IValueType& value Line 1186  Data::initialise(const IValueType& value
1186    // within the shared_ptr constructor.    // within the shared_ptr constructor.
1187    if (expanded) {    if (expanded) {
1188      DataAbstract* temp=new DataExpanded(value,what);      DataAbstract* temp=new DataExpanded(value,what);
1189      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1190        m_data=temp_data;
1191    } else {    } else {
1192      DataAbstract* temp=new DataConstant(value,what);      DataAbstract* temp=new DataConstant(value,what);
1193      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1194        m_data=temp_data;
1195    }    }
1196  }  }
1197    
1198  inline  /**
1199  DataAbstract::ValueType::value_type*     Binary Data object operators.
1200  Data::getSampleData(DataAbstract::ValueType::size_type sampleNo)  */
 {  
   return m_data->getSampleData(sampleNo);  
 }  
   
 inline  
 DataAbstract::ValueType::value_type*  
 Data::getSampleDataByTag(int tag)  
 {  
   return m_data->getSampleDataByTag(tag);  
 }  
   
 inline  
 void  
 Data::operandCheck(const Data& right) const  
 {  
   return m_data->operandCheck(*(right.m_data.get()));  
 }  
   
 inline  
 int  
 Data::getNumSamples() const  
 {  
   return m_data->getNumSamples();  
 }  
   
 inline  
 std::string  
 Data::toString() const  
 {  
   return m_data->toString();  
 }  
1201    
1202  /**  /**
1203    \brief    \brief
# Line 876  std::ostream& operator<<(std::ostream& o Line 1303  std::ostream& operator<<(std::ostream& o
1303    NB: this operator does very little at this point, and isn't to    NB: this operator does very little at this point, and isn't to
1304    be relied on. Requires further implementation.    be relied on. Requires further implementation.
1305  */  */
1306  bool operator==(const Data& left, const Data& right);  //bool operator==(const Data& left, const Data& right);
1307    
1308    /**
1309      \brief
1310      Perform the given binary operation with this and right as operands.
1311      Right is a Data object.
1312    */
1313  template <class BinaryFunction>  template <class BinaryFunction>
1314  inline  inline
1315  void  void
# Line 907  Data::binaryOp(const Data& right, Line 1339  Data::binaryOp(const Data& right,
1339     operandCheck(tempRight);     operandCheck(tempRight);
1340     //     //
1341     // ensure this has the right type for the RHS     // ensure this has the right type for the RHS
1342     typeMatch(tempRight);     typeMatchRight(tempRight);
1343     //     //
1344     // Need to cast to the concrete types so that the correct binaryOp     // Need to cast to the concrete types so that the correct binaryOp
1345     // is called.     // is called.
# Line 933  Data::binaryOp(const Data& right, Line 1365  Data::binaryOp(const Data& right,
1365         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1366         escript::binaryOp(*leftC,*rightC,operation);         escript::binaryOp(*leftC,*rightC,operation);
1367       }       }
1368     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1369       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1370       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1371       EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");       EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
# Line 943  Data::binaryOp(const Data& right, Line 1373  Data::binaryOp(const Data& right,
1373     }     }
1374  }  }
1375    
1376    /**
1377      \brief
1378      Perform the given binary operation with this and right as operands.
1379      Right is a boost::python object.
1380    */
1381  template <class BinaryFunction>  template <class BinaryFunction>
1382  inline  inline
1383  void  void
# Line 963  Data::binaryOp(const boost::python::obje Line 1398  Data::binaryOp(const boost::python::obje
1398                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1399       }       }
1400     }     }
   
1401     if (isExpanded()) {     if (isExpanded()) {
      //  
      // Expanded data will be done in parallel  
1402       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1403       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1404       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
# Line 974  Data::binaryOp(const boost::python::obje Line 1406  Data::binaryOp(const boost::python::obje
1406       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1407       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1408       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1409     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1410       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1411       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1412       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1413     }     }
1414  }  }
1415    
1416    /**
1417      \brief
1418      Perform the given unary operation on other and return the result.
1419      Given operation is performed on each element of each data point, thus
1420      argument object is a rank n Data object, and returned object is a rank n
1421      Data object.
1422      Calls Data::unaryOp.
1423    */
1424    template <class UnaryFunction>
1425    inline
1426    Data
1427    unaryOp(const Data& other,
1428            UnaryFunction operation)
1429    {
1430      Data result;
1431      result.copy(other);
1432      result.unaryOp(operation);
1433      return result;
1434    }
1435    
1436    /**
1437      \brief
1438      Perform the given unary operation on this.
1439      Given operation is performed on each element of each data point.
1440      Calls escript::unaryOp.
1441    */
1442  template <class UnaryFunction>  template <class UnaryFunction>
1443  inline  inline
1444  void  void
1445  Data::unaryOp(UnaryFunction operation)  Data::unaryOp(UnaryFunction operation)
1446  {  {
1447    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1448      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1449      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1450      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
# Line 998  Data::unaryOp(UnaryFunction operation) Line 1452  Data::unaryOp(UnaryFunction operation)
1452      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1453      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1454      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1455    } else {    } else if (isConstant()) {
1456      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1457      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1458      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1459    }    }
1460  }  }
1461    
1462  template <class UnaryFunction>  /**
1463      \brief
1464      Perform the given Data object reduction algorithm on this and return the result.
1465      Given operation combines each element of each data point, thus argument
1466      object (*this) is a rank n Data object, and returned object is a scalar.
1467      Calls escript::algorithm.
1468    */
1469    template <class BinaryFunction>
1470  inline  inline
1471  double  double
1472  Data::algorithm(UnaryFunction operation) const  Data::algorithm(BinaryFunction operation, double initial_value) const
1473  {  {
1474    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1475      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1476      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1477      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1478    }    } else if (isTagged()) {
   else if (isTagged()) {  
1479      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1480      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1481      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1482    } else {    } else if (isConstant()) {
1483      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1484      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1485      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1486    }    }
1487      return 0;
1488  }  }
1489    
1490  template <class UnaryFunction>  /**
1491      \brief
1492      Perform the given data point reduction algorithm on data and return the result.
1493      Given operation combines each element within each data point into a scalar,
1494      thus argument object is a rank n Data object, and returned object is a
1495      rank 0 Data object.
1496      Calls escript::dp_algorithm.
1497    */
1498    template <class BinaryFunction>
1499  inline  inline
1500  Data  Data
1501  unaryOp(const Data& other,  Data::dp_algorithm(BinaryFunction operation, double initial_value) const
         UnaryFunction operation)  
1502  {  {
1503    //    if (isExpanded()) {
1504    // Perform the given operation on a copy of the input data and return the result      Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1505    Data result;      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1506    //      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1507    // perform a deep copy      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1508    result.copy(other);      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1509    result.unaryOp(operation);      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1510    return result;      return result;
1511      } else if (isTagged()) {
1512        DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1513        DataArrayView::ShapeType viewShape;
1514        DataArrayView::ValueType viewData(1);
1515        viewData[0]=0;
1516        DataArrayView defaultValue(viewData,viewShape);
1517        DataTagged::TagListType keys;
1518        DataTagged::ValueListType values;
1519        DataTagged::DataMapType::const_iterator i;
1520        for (i=dataT->getTagLookup().begin();i!=dataT->getTagLookup().end();i++) {
1521          keys.push_back(i->first);
1522          values.push_back(defaultValue);
1523        }
1524        Data result(keys,values,defaultValue,getFunctionSpace());
1525        DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1526        EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1527        EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1528        escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1529        return result;
1530      } else if (isConstant()) {
1531        Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1532        DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1533        DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1534        EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1535        EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1536        escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1537        return result;
1538      }
1539      Data falseRetVal; // to keep compiler quiet
1540      return falseRetVal;
1541  }  }
1542    
1543  }  }
   
1544  #endif  #endif

Legend:
Removed from v.94  
changed lines
  Added in v.698

  ViewVC Help
Powered by ViewVC 1.1.26