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

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

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

revision 1092 by gross, Fri Apr 13 03:39:49 2007 UTC revision 1332 by matt, Tue Oct 23 03:28:51 2007 UTC
# Line 1  Line 1 
1  // $Id$  
2  /*  /* $Id$ */
3   ************************************************************  
4   *          Copyright 2006 by ACcESS MNRF                   *  /*******************************************************
5   *                                                          *   *
6   *              http://www.access.edu.au                    *   *           Copyright 2003-2007 by ACceSS MNRF
7   *       Primary Business: Queensland, Australia            *   *       Copyright 2007 by University of Queensland
8   *  Licensed under the Open Software License version 3.0    *   *
9   *     http://www.opensource.org/licenses/osl-3.0.php       *   *                http://esscc.uq.edu.au
10   *                                                          *   *        Primary Business: Queensland, Australia
11   ************************************************************   *  Licensed under the Open Software License version 3.0
12  */   *     http://www.opensource.org/licenses/osl-3.0.php
13     *
14     *******************************************************/
15    
16  /** \file Data.h */  /** \file Data.h */
17    
# Line 26  Line 28 
28    
29  extern "C" {  extern "C" {
30  #include "DataC.h"  #include "DataC.h"
31  #include "paso/Paso.h"  /* #include "paso/Paso.h" doesn't belong in this file...causes trouble for BruceFactory.cpp */
32  }  }
33    
34  #ifndef PASO_MPI  #include "esysmpi.h"
 #define MPI_Comm long  
 #endif  
   
35  #include <string>  #include <string>
36  #include <algorithm>  #include <algorithm>
37    
# Line 51  class DataExpanded; Line 50  class DataExpanded;
50    
51  /**  /**
52     \brief     \brief
53     Data creates the appropriate Data object for the given construction     Data creates the appropriate Data object for the given construction
54     arguments.     arguments.
55    
56     Description:     Description:
57     Data is essentially a factory class which creates the appropriate Data     Data is essentially a factory class which creates the appropriate Data
# Line 214  class Data { Line 213  class Data {
213       Constructor which creates a DataConstant of "shape" with constant value.       Constructor which creates a DataConstant of "shape" with constant value.
214    */    */
215    ESCRIPT_DLL_API    ESCRIPT_DLL_API
216    Data(double value,    Data(double value,
217         const boost::python::tuple& shape=boost::python::make_tuple(),         const boost::python::tuple& shape=boost::python::make_tuple(),
218         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
219         bool expanded=false);         bool expanded=false);
220    /**    /**
# Line 239  class Data { Line 238  class Data {
238    
239    /**    /**
240       \brief       \brief
241       switches on update protection       switches on update protection
242    
243    */    */
244    ESCRIPT_DLL_API    ESCRIPT_DLL_API
# Line 257  class Data { Line 256  class Data {
256    
257    /**    /**
258       \brief       \brief
259       Return the values of a data point on this process       Return the values of a data point on this process
260    */    */
261    ESCRIPT_DLL_API    ESCRIPT_DLL_API
262    const boost::python::numeric::array    const boost::python::numeric::array
# Line 487  class Data { Line 486  class Data {
486    }    }
487    /**    /**
488       \brief       \brief
489       dumps the object into a netCDF file       dumps the object into a netCDF file
490    */    */
491    ESCRIPT_DLL_API    ESCRIPT_DLL_API
   inline  
492    void    void
493    dump(const std::string fileName) const    dump(const std::string fileName) const;
   {  
     return m_data->dump(fileName);  
   }  
   
494    /**    /**
495       \brief       \brief
496       Return the sample data for the given sample no. This is not the       Return the sample data for the given sample no. This is not the
# Line 539  class Data { Line 533  class Data {
533    getDataPoint(int sampleNo,    getDataPoint(int sampleNo,
534                 int dataPointNo)                 int dataPointNo)
535    {    {
536          return m_data->getDataPoint(sampleNo,dataPointNo);                  return m_data->getDataPoint(sampleNo,dataPointNo);
537    }    }
538    
539    /**    /**
# Line 634  class Data { Line 628  class Data {
628    
629    /**    /**
630       \brief       \brief
631         set all values to zero
632         *
633      */
634      ESCRIPT_DLL_API
635      void
636      setToZero();
637    
638      /**
639         \brief
640       Interpolates this onto the given functionspace and returns       Interpolates this onto the given functionspace and returns
641       the result as a Data object.       the result as a Data object.
642       *       *
# Line 641  class Data { Line 644  class Data {
644    ESCRIPT_DLL_API    ESCRIPT_DLL_API
645    Data    Data
646    interpolate(const FunctionSpace& functionspace) const;    interpolate(const FunctionSpace& functionspace) const;
   
647    /**    /**
648       \brief       \brief
649       Calculates the gradient of the data at the data points of functionspace.       Calculates the gradient of the data at the data points of functionspace.
# Line 738  class Data { Line 740  class Data {
740    
741    /**    /**
742       \brief       \brief
      Return the minimum absolute value of this Data object.  
      *  
   */  
   ESCRIPT_DLL_API  
   double  
   Linf() const;  
   
   /**  
      \brief  
743       Return the maximum value of this Data object.       Return the maximum value of this Data object.
744       *       *
745    */    */
# Line 861  class Data { Line 854  class Data {
854    /**    /**
855       \brief       \brief
856       Return the eigenvalues and corresponding eigenvcetors of the symmetric part at each data point of this Data object.       Return the eigenvalues and corresponding eigenvcetors of the symmetric part at each data point of this Data object.
857       the eigenvalues are ordered in increasing size where eigenvalues with relative difference less than       the eigenvalues are ordered in increasing size where eigenvalues with relative difference less than
858       tol are treated as equal. The eigenvectors are orthogonal, normalized and the sclaed such that the       tol are treated as equal. The eigenvectors are orthogonal, normalized and the sclaed such that the
859       first non-zero entry is positive.       first non-zero entry is positive.
860       Currently this function is restricted to rank 2, square shape, and dimension 3       Currently this function is restricted to rank 2, square shape, and dimension 3
861       *       *
# Line 1066  class Data { Line 1059  class Data {
1059    /**    /**
1060       \brief       \brief
1061       Return the given power of each data point of this boost python object.       Return the given power of each data point of this boost python object.
1062        
1063       \param right Input - the power to raise the object to.       \param right Input - the power to raise the object to.
1064       *       *
1065     */     */
# Line 1077  class Data { Line 1070  class Data {
1070    /**    /**
1071       \brief       \brief
1072       Return the given power of each data point of this boost python object.       Return the given power of each data point of this boost python object.
1073        
1074       \param left Input - the bases       \param left Input - the bases
1075       *       *
1076     */     */
# Line 1113  class Data { Line 1106  class Data {
1106    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1107    Data& operator+=(const boost::python::object& right);    Data& operator+=(const boost::python::object& right);
1108    
1109      ESCRIPT_DLL_API
1110      Data& operator=(const Data& other);
1111    
1112    /**    /**
1113       \brief       \brief
1114       Overloaded operator -=       Overloaded operator -=
# Line 1256  class Data { Line 1252  class Data {
1252    
1253    /**    /**
1254       \brief       \brief
1255       print the data values to stdout. Used for debugging       print the data values to stdout. Used for debugging
1256    */    */
1257    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1258    void    void
1259      print(void);          print(void);
1260    
1261    /**    /**
1262       \brief       \brief
1263       return the MPI rank number of the local data       return the MPI rank number of the local data
1264           MPI_COMM_WORLD is assumed and the result of MPI_Comm_size()                   MPI_COMM_WORLD is assumed and the result of MPI_Comm_size()
1265           is returned                   is returned
1266    */    */
1267    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1268      int          int
1269      get_MPIRank(void) const;          get_MPIRank(void) const;
1270    
1271    /**    /**
1272       \brief       \brief
1273       return the MPI rank number of the local data       return the MPI rank number of the local data
1274           MPI_COMM_WORLD is assumed and the result of MPI_Comm_rank()                   MPI_COMM_WORLD is assumed and the result of MPI_Comm_rank()
1275           is returned                   is returned
1276    */    */
1277    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1278      int          int
1279      get_MPISize(void) const;          get_MPISize(void) const;
1280    
1281    /**    /**
1282       \brief       \brief
1283       return the MPI rank number of the local data       return the MPI rank number of the local data
1284           MPI_COMM_WORLD is assumed and returned.                   MPI_COMM_WORLD is assumed and returned.
1285    */    */
1286    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1287      MPI_Comm          MPI_Comm
1288      get_MPIComm(void) const;          get_MPIComm(void) const;
1289    
1290    /**    /**
1291       \brief       \brief
1292       return the object produced by the factory, which is a DataConstant or DataExpanded       return the object produced by the factory, which is a DataConstant or DataExpanded
1293    */    */
1294    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1295      DataAbstract*          DataAbstract*
1296      borrowData(void) const;          borrowData(void) const;
1297    
1298   protected:   protected:
1299    
# Line 1415  Data::initialise(const IValueType& value Line 1411  Data::initialise(const IValueType& value
1411  /**  /**
1412     Binary Data object operators.     Binary Data object operators.
1413  */  */
1414  inline double rpow(double x,double y)  inline double rpow(double x,double y)
1415  {  {
1416      return pow(y,x);      return pow(y,x);
1417  }  }
# Line 1512  ESCRIPT_DLL_API Data operator*(const boo Line 1508  ESCRIPT_DLL_API Data operator*(const boo
1508  */  */
1509  ESCRIPT_DLL_API Data operator/(const boost::python::object& left, const Data& right);  ESCRIPT_DLL_API Data operator/(const boost::python::object& left, const Data& right);
1510    
1511    
1512    
1513  /**  /**
1514    \brief    \brief
1515    Output operator    Output operator
# Line 1533  C_GeneralTensorProduct(Data& arg0, Line 1531  C_GeneralTensorProduct(Data& arg0,
1531                       int axis_offset=0,                       int axis_offset=0,
1532                       int transpose=0);                       int transpose=0);
1533    
1534    
1535    /**
1536      \brief
1537      Compute a tensor operation with two Data objects
1538      \param arg0 - Input - Data object
1539      \param arg1 - Input - Data object
1540      \param operation - Input - Binary op functor
1541    */
1542    template <typename BinaryFunction>
1543    ESCRIPT_DLL_API
1544    Data
1545    C_TensorBinaryOperation(Data const &arg0,
1546                            Data const &arg1,
1547                            BinaryFunction operation);
1548    
1549  /**  /**
1550    \brief    \brief
1551    Return true if operands are equivalent, else return false.    Return true if operands are equivalent, else return false.
1552    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
1553    be relied on. Requires further implementation.    be relied on. Requires further implementation.
1554  */  */
1555  //ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);  // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);
1556    
1557  /**  /**
1558    \brief    \brief
# Line 1563  Data::binaryOp(const Data& right, Line 1576  Data::binaryOp(const Data& right,
1576     if (getFunctionSpace()!=right.getFunctionSpace()) {     if (getFunctionSpace()!=right.getFunctionSpace()) {
1577       if (right.probeInterpolation(getFunctionSpace())) {       if (right.probeInterpolation(getFunctionSpace())) {
1578         //         //
1579         // an interpolation is required so create a new Data         // an interpolation is required so create a new Data
1580         tempRight=Data(right,this->getFunctionSpace());         tempRight=Data(right,this->getFunctionSpace());
1581       } else if (probeInterpolation(right.getFunctionSpace())) {       } else if (probeInterpolation(right.getFunctionSpace())) {
1582         //         //
# Line 1687  Data::algorithm(BinaryFunction operation Line 1700  Data::algorithm(BinaryFunction operation
1700    \brief    \brief
1701    Perform the given data point reduction algorithm on data and return the result.    Perform the given data point reduction algorithm on data and return the result.
1702    Given operation combines each element within each data point into a scalar,    Given operation combines each element within each data point into a scalar,
1703    thus argument object is a rank n Data object, and returned object is a    thus argument object is a rank n Data object, and returned object is a
1704    rank 0 Data object.    rank 0 Data object.
1705    Calls escript::dp_algorithm.    Calls escript::dp_algorithm.
1706  */  */
# Line 1736  Data::dp_algorithm(BinaryFunction operat Line 1749  Data::dp_algorithm(BinaryFunction operat
1749    return falseRetVal;    return falseRetVal;
1750  }  }
1751    
1752    template <typename BinaryFunction>
1753    Data
1754    C_TensorBinaryOperation(Data const &arg_0,
1755                            Data const &arg_1,
1756                            BinaryFunction operation)
1757    {
1758      // Interpolate if necessary and find an appropriate function space
1759      Data arg_0_Z, arg_1_Z;
1760      if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {
1761        if (arg_0.probeInterpolation(arg_1.getFunctionSpace())) {
1762          arg_0_Z = arg_0.interpolate(arg_1.getFunctionSpace());
1763          arg_1_Z = Data(arg_1);
1764        }
1765        else if (arg_1.probeInterpolation(arg_0.getFunctionSpace())) {
1766          arg_1_Z=arg_1.interpolate(arg_0.getFunctionSpace());
1767          arg_0_Z =Data(arg_0);
1768        }
1769        else {
1770          throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible function spaces.");
1771        }
1772      } else {
1773          arg_0_Z = Data(arg_0);
1774          arg_1_Z = Data(arg_1);
1775      }
1776      // Get rank and shape of inputs
1777      int rank0 = arg_0_Z.getDataPointRank();
1778      int rank1 = arg_1_Z.getDataPointRank();
1779      DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();
1780      DataArrayView::ShapeType shape1 = arg_1_Z.getDataPointShape();
1781      int size0 = arg_0_Z.getDataPointSize();
1782      int size1 = arg_1_Z.getDataPointSize();
1783    
1784      // Declare output Data object
1785      Data res;
1786    
1787      if (shape0 == shape1) {
1788    
1789        if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
1790          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
1791          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1792          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1793          double *ptr_2 = &((res.getPointDataView().getData())[0]);
1794          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1795        }
1796        else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
1797    
1798          // Prepare the DataConstant input
1799          DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1800    
1801          // Borrow DataTagged input from Data object
1802          DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1803    
1804          // Prepare a DataTagged output 2
1805          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataTagged output
1806          res.tag();
1807          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1808    
1809          // Prepare offset into DataConstant
1810          int offset_0 = tmp_0->getPointOffset(0,0);
1811          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1812          // Get the views
1813          DataArrayView view_1 = tmp_1->getDefaultValue();
1814          DataArrayView view_2 = tmp_2->getDefaultValue();
1815          // Get the pointers to the actual data
1816          double *ptr_1 = &((view_1.getData())[0]);
1817          double *ptr_2 = &((view_2.getData())[0]);
1818          // Compute a result for the default
1819          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1820          // Compute a result for each tag
1821          const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1822          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1823          for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1824            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1825            DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1826            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1827            double *ptr_1 = &view_1.getData(0);
1828            double *ptr_2 = &view_2.getData(0);
1829            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1830          }
1831    
1832        }
1833        else if (arg_0_Z.isConstant()   && arg_1_Z.isExpanded()) {
1834    
1835          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1836          DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1837          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1838          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1839    
1840          int sampleNo_1,dataPointNo_1;
1841          int numSamples_1 = arg_1_Z.getNumSamples();
1842          int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
1843          int offset_0 = tmp_0->getPointOffset(0,0);
1844          #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
1845          for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
1846            for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1847              int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1848              int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1849              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1850              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1851              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1852              tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1853            }
1854          }
1855    
1856        }
1857        else if (arg_0_Z.isTagged()     && arg_1_Z.isConstant()) {
1858    
1859          // Borrow DataTagged input from Data object
1860          DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1861    
1862          // Prepare the DataConstant input
1863          DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
1864    
1865          // Prepare a DataTagged output 2
1866          res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataTagged output
1867          res.tag();
1868          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1869    
1870          // Prepare offset into DataConstant
1871          int offset_1 = tmp_1->getPointOffset(0,0);
1872          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1873          // Get the views
1874          DataArrayView view_0 = tmp_0->getDefaultValue();
1875          DataArrayView view_2 = tmp_2->getDefaultValue();
1876          // Get the pointers to the actual data
1877          double *ptr_0 = &((view_0.getData())[0]);
1878          double *ptr_2 = &((view_2.getData())[0]);
1879          // Compute a result for the default
1880          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1881          // Compute a result for each tag
1882          const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1883          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1884          for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1885            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1886            DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1887            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1888            double *ptr_0 = &view_0.getData(0);
1889            double *ptr_2 = &view_2.getData(0);
1890            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1891          }
1892    
1893        }
1894        else if (arg_0_Z.isTagged()     && arg_1_Z.isTagged()) {
1895    
1896          // Borrow DataTagged input from Data object
1897          DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1898    
1899          // Borrow DataTagged input from Data object
1900          DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1901    
1902          // Prepare a DataTagged output 2
1903          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
1904          res.tag();        // DataTagged output
1905          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1906    
1907          // Get the views
1908          DataArrayView view_0 = tmp_0->getDefaultValue();
1909          DataArrayView view_1 = tmp_1->getDefaultValue();
1910          DataArrayView view_2 = tmp_2->getDefaultValue();
1911          // Get the pointers to the actual data
1912          double *ptr_0 = &((view_0.getData())[0]);
1913          double *ptr_1 = &((view_1.getData())[0]);
1914          double *ptr_2 = &((view_2.getData())[0]);
1915          // Compute a result for the default
1916          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1917          // Merge the tags
1918          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1919          const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1920          const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1921          for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1922            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
1923          }
1924          for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1925            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1926          }
1927          // Compute a result for each tag
1928          const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1929          for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1930            DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1931            DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1932            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1933            double *ptr_0 = &view_0.getData(0);
1934            double *ptr_1 = &view_1.getData(0);
1935            double *ptr_2 = &view_2.getData(0);
1936            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1937          }
1938    
1939        }
1940        else if (arg_0_Z.isTagged()     && arg_1_Z.isExpanded()) {
1941    
1942          // After finding a common function space above the two inputs have the same numSamples and num DPPS
1943          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1944          DataTagged*   tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1945          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1946          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1947    
1948          int sampleNo_0,dataPointNo_0;
1949          int numSamples_0 = arg_0_Z.getNumSamples();
1950          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1951          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1952          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1953            int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
1954            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1955            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1956              int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
1957              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1958              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1959              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1960              tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1961            }
1962          }
1963    
1964        }
1965        else if (arg_0_Z.isExpanded()   && arg_1_Z.isConstant()) {
1966    
1967          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1968          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
1969          DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
1970          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1971    
1972          int sampleNo_0,dataPointNo_0;
1973          int numSamples_0 = arg_0_Z.getNumSamples();
1974          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1975          int offset_1 = tmp_1->getPointOffset(0,0);
1976          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1977          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1978            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1979              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
1980              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1981              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1982              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1983              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1984              tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1985            }
1986          }
1987    
1988        }
1989        else if (arg_0_Z.isExpanded()   && arg_1_Z.isTagged()) {
1990    
1991          // After finding a common function space above the two inputs have the same numSamples and num DPPS
1992          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1993          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
1994          DataTagged*   tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1995          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1996    
1997          int sampleNo_0,dataPointNo_0;
1998          int numSamples_0 = arg_0_Z.getNumSamples();
1999          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2000          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2001          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2002            int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2003            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2004            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2005              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2006              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2007              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2008              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2009              tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2010            }
2011          }
2012    
2013        }
2014        else if (arg_0_Z.isExpanded()   && arg_1_Z.isExpanded()) {
2015    
2016          // After finding a common function space above the two inputs have the same numSamples and num DPPS
2017          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2018          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2019          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2020          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2021    
2022          int sampleNo_0,dataPointNo_0;
2023          int numSamples_0 = arg_0_Z.getNumSamples();
2024          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2025          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2026          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2027            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2028              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2029              int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2030              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2031              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2032              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2033              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2034              tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2035            }
2036          }
2037    
2038        }
2039        else {
2040          throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2041        }
2042    
2043      } else if (0 == rank0) {
2044    
2045        if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2046          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output
2047          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2048          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
2049          double *ptr_2 = &((res.getPointDataView().getData())[0]);
2050          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2051        }
2052        else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
2053    
2054          // Prepare the DataConstant input
2055          DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2056    
2057          // Borrow DataTagged input from Data object
2058          DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2059    
2060          // Prepare a DataTagged output 2
2061          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataTagged output
2062          res.tag();
2063          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2064    
2065          // Prepare offset into DataConstant
2066          int offset_0 = tmp_0->getPointOffset(0,0);
2067          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2068          // Get the views
2069          DataArrayView view_1 = tmp_1->getDefaultValue();
2070          DataArrayView view_2 = tmp_2->getDefaultValue();
2071          // Get the pointers to the actual data
2072          double *ptr_1 = &((view_1.getData())[0]);
2073          double *ptr_2 = &((view_2.getData())[0]);
2074          // Compute a result for the default
2075          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2076          // Compute a result for each tag
2077          const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2078          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2079          for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2080            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2081            DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2082            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2083            double *ptr_1 = &view_1.getData(0);
2084            double *ptr_2 = &view_2.getData(0);
2085            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2086          }
2087    
2088        }
2089        else if (arg_0_Z.isConstant()   && arg_1_Z.isExpanded()) {
2090    
2091          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2092          DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2093          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2094          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2095    
2096          int sampleNo_1,dataPointNo_1;
2097          int numSamples_1 = arg_1_Z.getNumSamples();
2098          int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2099          int offset_0 = tmp_0->getPointOffset(0,0);
2100          #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2101          for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2102            for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2103              int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2104              int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2105              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2106              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2107              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2108              tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2109    
2110            }
2111          }
2112    
2113        }
2114        else if (arg_0_Z.isTagged()     && arg_1_Z.isConstant()) {
2115    
2116          // Borrow DataTagged input from Data object
2117          DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2118    
2119          // Prepare the DataConstant input
2120          DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2121    
2122          // Prepare a DataTagged output 2
2123          res = Data(0.0, shape1, arg_0_Z.getFunctionSpace());      // DataTagged output
2124          res.tag();
2125          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2126    
2127          // Prepare offset into DataConstant
2128          int offset_1 = tmp_1->getPointOffset(0,0);
2129          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2130          // Get the views
2131          DataArrayView view_0 = tmp_0->getDefaultValue();
2132          DataArrayView view_2 = tmp_2->getDefaultValue();
2133          // Get the pointers to the actual data
2134          double *ptr_0 = &((view_0.getData())[0]);
2135          double *ptr_2 = &((view_2.getData())[0]);
2136          // Compute a result for the default
2137          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2138          // Compute a result for each tag
2139          const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2140          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2141          for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2142            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2143            DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2144            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2145            double *ptr_0 = &view_0.getData(0);
2146            double *ptr_2 = &view_2.getData(0);
2147            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2148          }
2149    
2150        }
2151        else if (arg_0_Z.isTagged()     && arg_1_Z.isTagged()) {
2152    
2153          // Borrow DataTagged input from Data object
2154          DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2155    
2156          // Borrow DataTagged input from Data object
2157          DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2158    
2159          // Prepare a DataTagged output 2
2160          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());
2161          res.tag();        // DataTagged output
2162          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2163    
2164          // Get the views
2165          DataArrayView view_0 = tmp_0->getDefaultValue();
2166          DataArrayView view_1 = tmp_1->getDefaultValue();
2167          DataArrayView view_2 = tmp_2->getDefaultValue();
2168          // Get the pointers to the actual data
2169          double *ptr_0 = &((view_0.getData())[0]);
2170          double *ptr_1 = &((view_1.getData())[0]);
2171          double *ptr_2 = &((view_2.getData())[0]);
2172          // Compute a result for the default
2173          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2174          // Merge the tags
2175          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2176          const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2177          const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2178          for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2179            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
2180          }
2181          for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2182            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2183          }
2184          // Compute a result for each tag
2185          const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2186          for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2187            DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2188            DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2189            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2190            double *ptr_0 = &view_0.getData(0);
2191            double *ptr_1 = &view_1.getData(0);
2192            double *ptr_2 = &view_2.getData(0);
2193            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2194          }
2195    
2196        }
2197        else if (arg_0_Z.isTagged()     && arg_1_Z.isExpanded()) {
2198    
2199          // After finding a common function space above the two inputs have the same numSamples and num DPPS
2200          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2201          DataTagged*   tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2202          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2203          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2204    
2205          int sampleNo_0,dataPointNo_0;
2206          int numSamples_0 = arg_0_Z.getNumSamples();
2207          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2208          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2209          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2210            int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2211            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2212            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2213              int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2214              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2215              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2216              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2217              tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2218            }
2219          }
2220    
2221        }
2222        else if (arg_0_Z.isExpanded()   && arg_1_Z.isConstant()) {
2223    
2224          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2225          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2226          DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2227          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2228    
2229          int sampleNo_0,dataPointNo_0;
2230          int numSamples_0 = arg_0_Z.getNumSamples();
2231          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2232          int offset_1 = tmp_1->getPointOffset(0,0);
2233          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2234          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2235            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2236              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2237              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2238              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2239              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2240              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2241              tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2242            }
2243          }
2244    
2245    
2246        }
2247        else if (arg_0_Z.isExpanded()   && arg_1_Z.isTagged()) {
2248    
2249          // After finding a common function space above the two inputs have the same numSamples and num DPPS
2250          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2251          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2252          DataTagged*   tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2253          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2254    
2255          int sampleNo_0,dataPointNo_0;
2256          int numSamples_0 = arg_0_Z.getNumSamples();
2257          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2258          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2259          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2260            int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2261            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2262            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2263              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2264              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2265              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2266              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2267              tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2268            }
2269          }
2270    
2271        }
2272        else if (arg_0_Z.isExpanded()   && arg_1_Z.isExpanded()) {
2273    
2274          // After finding a common function space above the two inputs have the same numSamples and num DPPS
2275          res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2276          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2277          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2278          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2279    
2280          int sampleNo_0,dataPointNo_0;
2281          int numSamples_0 = arg_0_Z.getNumSamples();
2282          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2283          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2284          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2285            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2286              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2287              int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2288              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2289              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2290              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2291              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2292              tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2293            }
2294          }
2295    
2296        }
2297        else {
2298          throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2299        }
2300    
2301      } else if (0 == rank1) {
2302    
2303        if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2304          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
2305          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2306          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
2307          double *ptr_2 = &((res.getPointDataView().getData())[0]);
2308          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2309        }
2310        else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
2311    
2312          // Prepare the DataConstant input
2313          DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2314    
2315          // Borrow DataTagged input from Data object
2316          DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2317    
2318          // Prepare a DataTagged output 2
2319          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataTagged output
2320          res.tag();
2321          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2322    
2323          // Prepare offset into DataConstant
2324          int offset_0 = tmp_0->getPointOffset(0,0);
2325          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2326          // Get the views
2327          DataArrayView view_1 = tmp_1->getDefaultValue();
2328          DataArrayView view_2 = tmp_2->getDefaultValue();
2329          // Get the pointers to the actual data
2330          double *ptr_1 = &((view_1.getData())[0]);
2331          double *ptr_2 = &((view_2.getData())[0]);
2332          // Compute a result for the default
2333          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2334          // Compute a result for each tag
2335          const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2336          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2337          for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2338            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2339            DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2340            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2341            double *ptr_1 = &view_1.getData(0);
2342            double *ptr_2 = &view_2.getData(0);
2343            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2344          }
2345    
2346        }
2347        else if (arg_0_Z.isConstant()   && arg_1_Z.isExpanded()) {
2348    
2349          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2350          DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2351          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2352          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2353    
2354          int sampleNo_1,dataPointNo_1;
2355          int numSamples_1 = arg_1_Z.getNumSamples();
2356          int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2357          int offset_0 = tmp_0->getPointOffset(0,0);
2358          #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2359          for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2360            for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2361              int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2362              int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2363              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2364              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2365              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2366              tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2367            }
2368          }
2369    
2370        }
2371        else if (arg_0_Z.isTagged()     && arg_1_Z.isConstant()) {
2372    
2373          // Borrow DataTagged input from Data object
2374          DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2375    
2376          // Prepare the DataConstant input
2377          DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2378    
2379          // Prepare a DataTagged output 2
2380          res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataTagged output
2381          res.tag();
2382          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2383    
2384          // Prepare offset into DataConstant
2385          int offset_1 = tmp_1->getPointOffset(0,0);
2386          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2387          // Get the views
2388          DataArrayView view_0 = tmp_0->getDefaultValue();
2389          DataArrayView view_2 = tmp_2->getDefaultValue();
2390          // Get the pointers to the actual data
2391          double *ptr_0 = &((view_0.getData())[0]);
2392          double *ptr_2 = &((view_2.getData())[0]);
2393          // Compute a result for the default
2394          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2395          // Compute a result for each tag
2396          const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2397          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2398          for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2399            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2400            DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2401            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2402            double *ptr_0 = &view_0.getData(0);
2403            double *ptr_2 = &view_2.getData(0);
2404            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2405          }
2406    
2407        }
2408        else if (arg_0_Z.isTagged()     && arg_1_Z.isTagged()) {
2409    
2410          // Borrow DataTagged input from Data object
2411          DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2412    
2413          // Borrow DataTagged input from Data object
2414          DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2415    
2416          // Prepare a DataTagged output 2
2417          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
2418          res.tag();        // DataTagged output
2419          DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2420    
2421          // Get the views
2422          DataArrayView view_0 = tmp_0->getDefaultValue();
2423          DataArrayView view_1 = tmp_1->getDefaultValue();
2424          DataArrayView view_2 = tmp_2->getDefaultValue();
2425          // Get the pointers to the actual data
2426          double *ptr_0 = &((view_0.getData())[0]);
2427          double *ptr_1 = &((view_1.getData())[0]);
2428          double *ptr_2 = &((view_2.getData())[0]);
2429          // Compute a result for the default
2430          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2431          // Merge the tags
2432          DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2433          const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2434          const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2435          for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2436            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
2437          }
2438          for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2439            tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2440          }
2441          // Compute a result for each tag
2442          const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2443          for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2444            DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2445            DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2446            DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2447            double *ptr_0 = &view_0.getData(0);
2448            double *ptr_1 = &view_1.getData(0);
2449            double *ptr_2 = &view_2.getData(0);
2450            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2451          }
2452    
2453        }
2454        else if (arg_0_Z.isTagged()     && arg_1_Z.isExpanded()) {
2455    
2456          // After finding a common function space above the two inputs have the same numSamples and num DPPS
2457          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2458          DataTagged*   tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2459          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2460          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2461    
2462          int sampleNo_0,dataPointNo_0;
2463          int numSamples_0 = arg_0_Z.getNumSamples();
2464          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2465          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2466          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2467            int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2468            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2469            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2470              int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2471              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2472              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2473              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2474              tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2475            }
2476          }
2477    
2478        }
2479        else if (arg_0_Z.isExpanded()   && arg_1_Z.isConstant()) {
2480    
2481          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2482          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2483          DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2484          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2485    
2486          int sampleNo_0,dataPointNo_0;
2487          int numSamples_0 = arg_0_Z.getNumSamples();
2488          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2489          int offset_1 = tmp_1->getPointOffset(0,0);
2490          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2491          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2492            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2493              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2494              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2495              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2496              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2497              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2498              tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2499            }
2500          }
2501    
2502    
2503        }
2504        else if (arg_0_Z.isExpanded()   && arg_1_Z.isTagged()) {
2505    
2506          // After finding a common function space above the two inputs have the same numSamples and num DPPS
2507          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2508          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2509          DataTagged*   tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2510          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2511    
2512          int sampleNo_0,dataPointNo_0;
2513          int numSamples_0 = arg_0_Z.getNumSamples();
2514          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2515          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2516          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2517            int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2518            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2519            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2520              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2521              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2522              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2523              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2524              tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2525            }
2526          }
2527    
2528        }
2529        else if (arg_0_Z.isExpanded()   && arg_1_Z.isExpanded()) {
2530    
2531          // After finding a common function space above the two inputs have the same numSamples and num DPPS
2532          res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2533          DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2534          DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2535          DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2536    
2537          int sampleNo_0,dataPointNo_0;
2538          int numSamples_0 = arg_0_Z.getNumSamples();
2539          int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2540          #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2541          for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2542            for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2543              int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2544              int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2545              int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2546              double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2547              double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2548              double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2549              tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2550            }
2551          }
2552    
2553        }
2554        else {
2555          throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2556        }
2557    
2558      } else {
2559        throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible shapes");
2560      }
2561    
2562      return res;
2563    }
2564    
2565  }  }
2566  #endif  #endif

Legend:
Removed from v.1092  
changed lines
  Added in v.1332

  ViewVC Help
Powered by ViewVC 1.1.26