/[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

revision 1358 by gross, Wed Dec 5 03:41:06 2007 UTC revision 1811 by ksteube, Thu Sep 25 23:11:13 2008 UTC
# Line 1  Line 1 
1    
 /* $Id$ */  
   
2  /*******************************************************  /*******************************************************
3   *  *
4   *           Copyright 2003-2007 by ACceSS MNRF  * Copyright (c) 2003-2008 by University of Queensland
5   *       Copyright 2007 by University of Queensland  * Earth Systems Science Computational Center (ESSCC)
6   *  * http://www.uq.edu.au/esscc
7   *                http://esscc.uq.edu.au  *
8   *        Primary Business: Queensland, Australia  * Primary Business: Queensland, Australia
9   *  Licensed under the Open Software License version 3.0  * Licensed under the Open Software License version 3.0
10   *     http://www.opensource.org/licenses/osl-3.0.php  * http://www.opensource.org/licenses/osl-3.0.php
11   *  *
12   *******************************************************/  *******************************************************/
13    
14    
15  /** \file Data.h */  /** \file Data.h */
16    
# Line 25  Line 24 
24  #include "BinaryOp.h"  #include "BinaryOp.h"
25  #include "UnaryOp.h"  #include "UnaryOp.h"
26  #include "DataException.h"  #include "DataException.h"
27    #include "DataTypes.h"
28    
29  extern "C" {  extern "C" {
30  #include "DataC.h"  #include "DataC.h"
# Line 34  extern "C" { Line 34  extern "C" {
34  #include "esysmpi.h"  #include "esysmpi.h"
35  #include <string>  #include <string>
36  #include <algorithm>  #include <algorithm>
37    #include <sstream>
38    
39    
40  #include <boost/shared_ptr.hpp>  #include <boost/shared_ptr.hpp>
41  #include <boost/python/object.hpp>  #include <boost/python/object.hpp>
# Line 50  class DataExpanded; Line 52  class DataExpanded;
52    
53  /**  /**
54     \brief     \brief
55     Data creates the appropriate Data object for the given construction     Data represents a collection of datapoints.
    arguments.  
56    
57     Description:     Description:
58     Data is essentially a factory class which creates the appropriate Data     Internally, the datapoints are actually stored by a DataAbstract object.
59     object for the given construction arguments. It retains control over     The specific instance of DataAbstract used may vary over the lifetime
60     the object created for the lifetime of the object.     of the Data object.
61     The type of Data object referred to may change during the lifetime of     Some methods on this class return references (eg getShape()).
62     the Data object.     These references should not be used after an operation which changes the underlying DataAbstract object.
63       Doing so will lead to invalid memory access.
64       This should not affect any methods exposed via boost::python.
65  */  */
66  class Data {  class Data {
67    
# Line 101  class Data { Line 104  class Data {
104         const FunctionSpace& what);         const FunctionSpace& what);
105    
106    /**    /**
107       \brief      \brief Copy Data from an existing vector
108       Constructor which copies data from a DataArrayView.    */
109    
      \param value - Input - Data value for a single point.  
      \param what - Input - A description of what this data represents.  
      \param expanded - Input - Flag, if true fill the entire container with  
                        the value. Otherwise a more efficient storage  
                        mechanism will be used.  
   */  
110    ESCRIPT_DLL_API    ESCRIPT_DLL_API
111    Data(const DataArrayView& value,    Data(const DataTypes::ValueType& value,
112         const FunctionSpace& what=FunctionSpace(),           const DataTypes::ShapeType& shape,
113         bool expanded=false);                   const FunctionSpace& what=FunctionSpace(),
114                     bool expanded=false);
115    
116    /**    /**
117       \brief       \brief
# Line 128  class Data { Line 126  class Data {
126    */    */
127    ESCRIPT_DLL_API    ESCRIPT_DLL_API
128    Data(double value,    Data(double value,
129         const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),         const DataTypes::ShapeType& dataPointShape=DataTypes::ShapeType(),
130         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
131         bool expanded=false);         bool expanded=false);
132    
# Line 141  class Data { Line 139  class Data {
139    */    */
140    ESCRIPT_DLL_API    ESCRIPT_DLL_API
141    Data(const Data& inData,    Data(const Data& inData,
142         const DataArrayView::RegionType& region);         const DataTypes::RegionType& region);
   
   /**  
      \brief  
      Constructor which will create Tagged data if expanded is false.  
      No attempt is made to ensure the tag keys match the tag keys  
      within the function space.  
   
      \param tagKeys - Input - List of tag values.  
      \param values - Input - List of values, one for each tag.  
      \param defaultValue - Input - A default value, used if tag doesn't exist.  
      \param what - Input - A description of what this data represents.  
      \param expanded - Input - Flag, if true fill the entire container with  
                        the appropriate values.  
     ==>*  
   */  
   ESCRIPT_DLL_API  
   Data(const DataTagged::TagListType& tagKeys,  
        const DataTagged::ValueListType& values,  
        const DataArrayView& defaultValue,  
        const FunctionSpace& what=FunctionSpace(),  
        bool expanded=false);  
143    
144    /**    /**
145       \brief       \brief
# Line 217  class Data { Line 194  class Data {
194         const boost::python::tuple& shape=boost::python::make_tuple(),         const boost::python::tuple& shape=boost::python::make_tuple(),
195         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
196         bool expanded=false);         bool expanded=false);
197    
198    
199    
200      /**
201        \brief Create a Data using an existing DataAbstract. Warning: The new object assumes ownership of the pointer!
202        Once you have passed the pointer, do not delete it.
203      */
204      ESCRIPT_DLL_API
205      Data(DataAbstract* underlyingdata);
206    
207    
208    /**    /**
209       \brief       \brief
210       Destructor       Destructor
# Line 225  class Data { Line 213  class Data {
213    ~Data();    ~Data();
214    
215    /**    /**
216       \brief       \brief Make this object a deep copy of "other".
      Perform a deep copy.  
217    */    */
218    ESCRIPT_DLL_API    ESCRIPT_DLL_API
219    void    void
220    copy(const Data& other);    copy(const Data& other);
221    
222    /**    /**
223         \brief Return a pointer to a deep copy of this object.
224      */
225      ESCRIPT_DLL_API
226      Data*
227      copySelf();
228    
229    
230    
231    
232      /**
233       Member access methods.       Member access methods.
234    */    */
235    
# Line 298  class Data { Line 295  class Data {
295       \brief       \brief
296       Return the tag number associated with the given data-point.       Return the tag number associated with the given data-point.
297    
      The data-point number here corresponds to the data-point number in the  
      numarray returned by convertToNumArray.  
298    */    */
299    ESCRIPT_DLL_API    ESCRIPT_DLL_API
300    int    int
# Line 313  class Data { Line 308  class Data {
308    escriptDataC    escriptDataC
309    getDataC();    getDataC();
310    
311    
312    
313    
314    
315    
316    // REMOVE ME
317    // ESCRIPT_DLL_API
318    // void
319    // CompareDebug(const Data& rd);
320    
321    
322    /**    /**
323       \brief       \brief
324       Return the C wrapper for the Data object - const version.       Return the C wrapper for the Data object - const version.
# Line 323  class Data { Line 329  class Data {
329    
330    /**    /**
331       \brief       \brief
332       Write the data as a string.       Write the data as a string. For large amounts of data, a summary is printed.
333    */    */
334    ESCRIPT_DLL_API    ESCRIPT_DLL_API
   inline  
335    std::string    std::string
336    toString() const    toString() const;
   {  
     return m_data->toString();  
   }  
337    
338    /**  
339       \brief  //  /**
340    /*     \brief
341       Return the DataArrayView of the point data. This essentially contains       Return the DataArrayView of the point data. This essentially contains
342       the shape information for each data point although it also may be used       the shape information for each data point although it also may be used
343       to manipulate the point data.       to manipulate the point data.*/
344    */  //  */
345    ESCRIPT_DLL_API  //   ESCRIPT_DLL_API
346    inline  //   inline
347    const DataArrayView&  //   const DataArrayView&
348    getPointDataView() const  //   getPointDataView() const
349    {  //   {
350       return m_data->getPointDataView();  //      return m_data->getPointDataView();
351    }  //   }
352    
353    /**    /**
354       \brief       \brief
# Line 392  class Data { Line 395  class Data {
395    
396    /**    /**
397       \brief       \brief
398       Return true if this Data is empty.       Return true if this Data holds an instance of DataEmpty. This is _not_ the same as asking if the object
399    contains datapoints.
400    */    */
401    ESCRIPT_DLL_API    ESCRIPT_DLL_API
402    bool    bool
# Line 447  class Data { Line 451  class Data {
451    int    int
452    getDataPointRank() const    getDataPointRank() const
453    {    {
454      return m_data->getPointDataView().getRank();  //    return m_data->getPointDataView().getRank();
455        return m_data->getRank();
456    }    }
457    
458    /**    /**
# Line 484  class Data { Line 489  class Data {
489    {    {
490      return m_data->getNumDPPSample();      return m_data->getNumDPPSample();
491    }    }
492    
493    
494      /**
495        \brief
496        Return the number of values in the shape for this object.
497      */
498      ESCRIPT_DLL_API
499      int
500      getNoValues() const
501      {
502        return m_data->getNoValues();
503      }
504    
505    
506    /**    /**
507       \brief       \brief
508       dumps the object into a netCDF file       dumps the object into a netCDF file
# Line 519  class Data { Line 538  class Data {
538      return m_data->getSampleDataByTag(tag);      return m_data->getSampleDataByTag(tag);
539    }    }
540    
541    //  /**
542    /*     \brief
543         Return a view into the data for the data point specified.
544         NOTE: Construction of the DataArrayView is a relatively expensive
545         operation.
546         \param sampleNo - Input -
547         \param dataPointNo - Input -*/
548    //  */
549    //   ESCRIPT_DLL_API
550    //   inline
551    //   DataArrayView
552    //   getDataPoint(int sampleNo,
553    //                int dataPointNo)
554    //   {
555    //                 return m_data->getDataPoint(sampleNo,dataPointNo);
556    //   }
557    
558    
559    /**    /**
560       \brief       \brief
561       Return a view into the data for the data point specified.       Return a view into the data for the data point specified.
# Line 528  class Data { Line 565  class Data {
565       \param dataPointNo - Input -       \param dataPointNo - Input -
566    */    */
567    ESCRIPT_DLL_API    ESCRIPT_DLL_API
568      DataTypes::ValueType::const_reference
569      getDataPoint(int sampleNo, int dataPointNo) const;
570    
571    
572      ESCRIPT_DLL_API
573      DataTypes::ValueType::reference
574      getDataPoint(int sampleNo, int dataPointNo);
575    
576    
577    
578      /**
579         \brief
580         Return the offset for the given sample and point within the sample
581      */
582      ESCRIPT_DLL_API
583    inline    inline
584    DataArrayView    DataTypes::ValueType::size_type
585    getDataPoint(int sampleNo,    getDataOffset(int sampleNo,
586                 int dataPointNo)                 int dataPointNo)
587    {    {
588                  return m_data->getDataPoint(sampleNo,dataPointNo);                  return m_data->getPointOffset(sampleNo,dataPointNo);
589    }    }
590    
591    /**    /**
# Line 541  class Data { Line 593  class Data {
593       Return a reference to the data point shape.       Return a reference to the data point shape.
594    */    */
595    ESCRIPT_DLL_API    ESCRIPT_DLL_API
596    const DataArrayView::ShapeType&    inline
597    getDataPointShape() const;    const DataTypes::ShapeType&
598      getDataPointShape() const
599      {
600        return m_data->getShape();
601      }
602    
603    /**    /**
604       \brief       \brief
# Line 566  class Data { Line 622  class Data {
622       Return the number of doubles stored for this Data.       Return the number of doubles stored for this Data.
623    */    */
624    ESCRIPT_DLL_API    ESCRIPT_DLL_API
625    DataArrayView::ValueType::size_type    DataTypes::ValueType::size_type
626    getLength() const;    getLength() const;
627    
628    
# Line 599  class Data { Line 655  class Data {
655    setTaggedValue(int tagKey,    setTaggedValue(int tagKey,
656                   const boost::python::object& value);                   const boost::python::object& value);
657    
658    
659    //  /**
660    //     \brief
661    //     Assign the given value to the tag. Implicitly converts this
662    //     object to type DataTagged if it is constant.
663    //
664    //     \param tagKey - Input - Integer key.
665    //     \param value - Input - Value to associate with given key.
666    //    ==>*
667    //  */
668    //   ESCRIPT_DLL_API
669    //   void
670    //   setTaggedValueFromCPP(int tagKey,
671    //                         const DataArrayView& value);
672    
673    /**    /**
674       \brief       \brief
675       Assign the given value to the tag. Implicitly converts this       Assign the given value to the tag. Implicitly converts this
676       object to type DataTagged if it is constant.       object to type DataTagged if it is constant.
677    
678       \param tagKey - Input - Integer key.       \param tagKey - Input - Integer key.
679         \param pointshape - Input - The shape of the value parameter
680       \param value - Input - Value to associate with given key.       \param value - Input - Value to associate with given key.
681      ==>*       \param dataOffset - Input - Offset of the begining of the point within the value parameter
682    */    */
683    ESCRIPT_DLL_API    ESCRIPT_DLL_API
684    void    void
685    setTaggedValueFromCPP(int tagKey,    setTaggedValueFromCPP(int tagKey,
686                          const DataArrayView& value);              const DataTypes::ShapeType& pointshape,
687                            const DataTypes::ValueType& value,
688                int dataOffset=0);
689    
690    
691    
692    /**    /**
693      \brief      \brief
# Line 1212  class Data { Line 1288  class Data {
1288    */    */
1289    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1290    Data    Data
1291    getSlice(const DataArrayView::RegionType& region) const;    getSlice(const DataTypes::RegionType& region) const;
1292    
1293    /**    /**
1294       \brief       \brief
# Line 1225  class Data { Line 1301  class Data {
1301    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1302    void    void
1303    setSlice(const Data& value,    setSlice(const Data& value,
1304             const DataArrayView::RegionType& region);             const DataTypes::RegionType& region);
   
   /**  
      \brief  
      Archive the current Data object to the given file.  
      \param fileName - Input - file to archive to.  
   */  
   ESCRIPT_DLL_API  
   void  
   archiveData(const std::string fileName);  
   
   /**  
      \brief  
      Extract the Data object archived in the given file, overwriting  
      the current Data object.  
      Note - the current object must be of type DataEmpty.  
      \param fileName - Input - file to extract from.  
      \param fspace - Input - a suitable FunctionSpace descibing the data.  
   */  
   ESCRIPT_DLL_API  
   void  
   extractData(const std::string fileName,  
               const FunctionSpace& fspace);  
   
1305    
1306    /**    /**
1307       \brief       \brief
# Line 1290  class Data { Line 1343  class Data {
1343    /**    /**
1344       \brief       \brief
1345       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
1346        TODO Ownership of this object should be explained in doco.
1347    */    */
1348    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1349          DataAbstract*          DataAbstract*
1350          borrowData(void) const;          borrowData(void) const;
1351    
1352    
1353      /**
1354         \brief
1355         Return a pointer to the beginning of the datapoint at the specified offset.
1356         TODO Eventually these should be inlined.
1357         \param i - position(offset) in the underlying datastructure
1358      */
1359      ESCRIPT_DLL_API
1360            DataTypes::ValueType::const_reference
1361            getDataAtOffset(DataTypes::ValueType::size_type i) const;
1362    
1363    
1364      ESCRIPT_DLL_API
1365            DataTypes::ValueType::reference
1366            getDataAtOffset(DataTypes::ValueType::size_type i);
1367    
1368   protected:   protected:
1369    
1370   private:   private:
# Line 1370  class Data { Line 1440  class Data {
1440       \brief       \brief
1441       Construct a Data object of the appropriate type.       Construct a Data object of the appropriate type.
1442    */    */
1443    template <class IValueType>  
1444    void    void
1445    initialise(const IValueType& value,    initialise(const DataTypes::ValueType& value,
1446             const DataTypes::ShapeType& shape,
1447               const FunctionSpace& what,               const FunctionSpace& what,
1448               bool expanded);               bool expanded);
1449    
1450      void
1451      initialise(const boost::python::numeric::array& value,
1452                     const FunctionSpace& what,
1453                     bool expanded);
1454    
1455    //    //
1456    // flag to protect the data object against any update    // flag to protect the data object against any update
1457    bool m_protected;    bool m_protected;
# Line 1386  class Data { Line 1462  class Data {
1462    
1463  };  };
1464    
1465  template <class IValueType>  
1466  void  
1467  Data::initialise(const IValueType& value,  /**
1468                   const FunctionSpace& what,     Modify a filename for MPI parallel output to multiple files
1469                   bool expanded)  */
1470  {  char *Escript_MPI_appendRankToFileName(const char *, int, int);
   //  
   // Construct a Data object of the appropriate type.  
   // Construct the object first as there seems to be a bug which causes  
   // undefined behaviour if an exception is thrown during construction  
   // within the shared_ptr constructor.  
   if (expanded) {  
     DataAbstract* temp=new DataExpanded(value,what);  
     boost::shared_ptr<DataAbstract> temp_data(temp);  
     m_data=temp_data;  
   } else {  
     DataAbstract* temp=new DataConstant(value,what);  
     boost::shared_ptr<DataAbstract> temp_data(temp);  
     m_data=temp_data;  
   }  
 }  
1471    
1472  /**  /**
1473     Binary Data object operators.     Binary Data object operators.
# Line 1532  C_GeneralTensorProduct(Data& arg0, Line 1593  C_GeneralTensorProduct(Data& arg0,
1593                       int transpose=0);                       int transpose=0);
1594    
1595    
 /**  
   \brief  
   Compute a tensor operation with two Data objects  
   \param arg0 - Input - Data object  
   \param arg1 - Input - Data object  
   \param operation - Input - Binary op functor  
 */  
 template <typename BinaryFunction>  
 ESCRIPT_DLL_API  
 Data  
 C_TensorBinaryOperation(Data const &arg0,  
                         Data const &arg1,  
                         BinaryFunction operation);  
1596    
1597  /**  // /**
1598    \brief  /*  \brief
1599    Return true if operands are equivalent, else return false.    Return true if operands are equivalent, else return false.
1600    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
1601    be relied on. Requires further implementation.    be relied on. Requires further implementation.*/
1602  */  //*/
1603  // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);  // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);
1604    
1605  /**  /**
# Line 1567  Data::binaryOp(const Data& right, Line 1615  Data::binaryOp(const Data& right,
1615  {  {
1616     //     //
1617     // if this has a rank of zero promote it to the rank of the RHS     // if this has a rank of zero promote it to the rank of the RHS
1618     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {     if (getDataPointRank()==0 && right.getDataPointRank()!=0) {
1619       throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");       throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");
1620     }     }
1621     //     //
# Line 1646  Data::algorithm(BinaryFunction operation Line 1694  Data::algorithm(BinaryFunction operation
1694      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1695      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1696      return escript::algorithm(*leftC,operation,initial_value);      return escript::algorithm(*leftC,operation,initial_value);
1697      } else if (isEmpty()) {
1698        throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1699    }    }
1700    return 0;    return 0;
1701  }  }
# Line 1663  inline Line 1713  inline
1713  Data  Data
1714  Data::dp_algorithm(BinaryFunction operation, double initial_value) const  Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1715  {  {
1716    if (isExpanded()) {    if (isEmpty()) {
1717      Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());      throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1718      }
1719      else if (isExpanded()) {
1720        Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1721      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1722      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1723      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1724      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1725      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1726      return result;      return result;
1727    } else if (isTagged()) {    }
1728      else if (isTagged()) {
1729      DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
     DataArrayView::ShapeType viewShape;  
     DataArrayView::ValueType viewData(1);  
     viewData[0]=0;  
     DataArrayView defaultValue(viewData,viewShape);  
     DataTagged::TagListType keys;  
     DataTagged::ValueListType values;  
     DataTagged::DataMapType::const_iterator i;  
     for (i=dataT->getTagLookup().begin();i!=dataT->getTagLookup().end();i++) {  
       keys.push_back(i->first);  
       values.push_back(defaultValue);  
     }  
     Data result(keys,values,defaultValue,getFunctionSpace());  
     DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());  
1730      EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");      EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1731      EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");      DataTypes::ValueType defval(1);
1732        defval[0]=0;
1733        DataTagged* resultT=new DataTagged(getFunctionSpace(), DataTypes::scalarShape, defval, dataT);
1734      escript::dp_algorithm(*dataT,*resultT,operation,initial_value);      escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1735      return result;      return Data(resultT);   // note: the Data object now owns the resultT pointer
1736    } else if (isConstant()) {    }
1737      Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());    else if (isConstant()) {
1738        Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1739      DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1740      DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());      DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1741      EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");      EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
# Line 1703  Data::dp_algorithm(BinaryFunction operat Line 1747  Data::dp_algorithm(BinaryFunction operat
1747    return falseRetVal;    return falseRetVal;
1748  }  }
1749    
1750    /**
1751      \brief
1752      Compute a tensor operation with two Data objects
1753      \param arg0 - Input - Data object
1754      \param arg1 - Input - Data object
1755      \param operation - Input - Binary op functor
1756    */
1757  template <typename BinaryFunction>  template <typename BinaryFunction>
1758    inline
1759  Data  Data
1760  C_TensorBinaryOperation(Data const &arg_0,  C_TensorBinaryOperation(Data const &arg_0,
1761                          Data const &arg_1,                          Data const &arg_1,
1762                          BinaryFunction operation)                          BinaryFunction operation)
1763  {  {
1764      if (arg_0.isEmpty() || arg_1.isEmpty())
1765      {
1766         throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1767      }
1768    // Interpolate if necessary and find an appropriate function space    // Interpolate if necessary and find an appropriate function space
1769    Data arg_0_Z, arg_1_Z;    Data arg_0_Z, arg_1_Z;
1770    if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {    if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {
# Line 1730  C_TensorBinaryOperation(Data const &arg_ Line 1786  C_TensorBinaryOperation(Data const &arg_
1786    // Get rank and shape of inputs    // Get rank and shape of inputs
1787    int rank0 = arg_0_Z.getDataPointRank();    int rank0 = arg_0_Z.getDataPointRank();
1788    int rank1 = arg_1_Z.getDataPointRank();    int rank1 = arg_1_Z.getDataPointRank();
1789    DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();    DataTypes::ShapeType shape0 = arg_0_Z.getDataPointShape();
1790    DataArrayView::ShapeType shape1 = arg_1_Z.getDataPointShape();    DataTypes::ShapeType shape1 = arg_1_Z.getDataPointShape();
1791    int size0 = arg_0_Z.getDataPointSize();    int size0 = arg_0_Z.getDataPointSize();
1792    int size1 = arg_1_Z.getDataPointSize();    int size1 = arg_1_Z.getDataPointSize();
1793    
# Line 1742  C_TensorBinaryOperation(Data const &arg_ Line 1798  C_TensorBinaryOperation(Data const &arg_
1798    
1799      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
1800        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
1801        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);  /*      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1802        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1803        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &((res.getPointDataView().getData())[0]);*/
1804          double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
1805          double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
1806          double *ptr_2 = &(res.getDataAtOffset(0));
1807    
1808        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1809      }      }
1810      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 1762  C_TensorBinaryOperation(Data const &arg_ Line 1822  C_TensorBinaryOperation(Data const &arg_
1822    
1823        // Prepare offset into DataConstant        // Prepare offset into DataConstant
1824        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
1825        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1826        // Get the views        // Get the views
1827        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
1828        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1829    //       // Get the pointers to the actual data
1830    //       double *ptr_1 = &((view_1.getData())[0]);
1831    //       double *ptr_2 = &((view_2.getData())[0]);
1832    
1833        // Get the pointers to the actual data        // Get the pointers to the actual data
1834        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
1835        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1836    
1837        // Compute a result for the default        // Compute a result for the default
1838        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1839        // Compute a result for each tag        // Compute a result for each tag
1840        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1841        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1842        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1843          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1844          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  /*        DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1845          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1846          double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
1847          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
1848            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1849            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1850    
1851          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1852        }        }
1853    
# Line 1800  C_TensorBinaryOperation(Data const &arg_ Line 1868  C_TensorBinaryOperation(Data const &arg_
1868          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1869            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1870            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1871            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);  //           double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1872            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1873            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1874    
1875              double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1876              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1877              double *ptr_2 = &(res.getDataAtOffset(offset_2));
1878            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1879          }          }
1880        }        }
# Line 1823  C_TensorBinaryOperation(Data const &arg_ Line 1895  C_TensorBinaryOperation(Data const &arg_
1895    
1896        // Prepare offset into DataConstant        // Prepare offset into DataConstant
1897        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
1898        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //       double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1899          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1900        // Get the views        // Get the views
1901        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
1902        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1903    //       // Get the pointers to the actual data
1904    //       double *ptr_0 = &((view_0.getData())[0]);
1905    //       double *ptr_2 = &((view_2.getData())[0]);
1906        // Get the pointers to the actual data        // Get the pointers to the actual data
1907        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
1908        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1909        // Compute a result for the default        // Compute a result for the default
1910        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1911        // Compute a result for each tag        // Compute a result for each tag
1912        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1913        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1914        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1915          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1916          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1917          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1918          double *ptr_0 = &view_0.getData(0);  //         double *ptr_0 = &view_0.getData(0);
1919          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
1920            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1921            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1922          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1923        }        }
1924    
# Line 1858  C_TensorBinaryOperation(Data const &arg_ Line 1936  C_TensorBinaryOperation(Data const &arg_
1936        res.tag();        // DataTagged output        res.tag();        // DataTagged output
1937        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1938    
1939        // Get the views  //       // Get the views
1940        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
1941        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
1942        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1943    //       // Get the pointers to the actual data
1944    //       double *ptr_0 = &((view_0.getData())[0]);
1945    //       double *ptr_1 = &((view_1.getData())[0]);
1946    //       double *ptr_2 = &((view_2.getData())[0]);
1947    
1948        // Get the pointers to the actual data        // Get the pointers to the actual data
1949        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
1950        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
1951        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1952    
1953        // Compute a result for the default        // Compute a result for the default
1954        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1955        // Merge the tags        // Merge the tags
# Line 1873  C_TensorBinaryOperation(Data const &arg_ Line 1957  C_TensorBinaryOperation(Data const &arg_
1957        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1958        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1959        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1960          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
1961        }        }
1962        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1963          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1964        }        }
1965        // Compute a result for each tag        // Compute a result for each tag
1966        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1967        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1968          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  
1969          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1970          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1971          double *ptr_0 = &view_0.getData(0);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1972          double *ptr_1 = &view_1.getData(0);  //         double *ptr_0 = &view_0.getData(0);
1973          double *ptr_2 = &view_2.getData(0);  //         double *ptr_1 = &view_1.getData(0);
1974    //         double *ptr_2 = &view_2.getData(0);
1975    
1976            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1977            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1978            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1979    
1980          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1981        }        }
1982    
# Line 1905  C_TensorBinaryOperation(Data const &arg_ Line 1995  C_TensorBinaryOperation(Data const &arg_
1995        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1996        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1997          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
1998          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1999          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2000            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2001            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2002            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  
2003            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2004    //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2005              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2006              double *ptr_2 = &(res.getDataAtOffset(offset_2));
2007    
2008    
2009            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2010          }          }
2011        }        }
# Line 1932  C_TensorBinaryOperation(Data const &arg_ Line 2027  C_TensorBinaryOperation(Data const &arg_
2027          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2028            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2029            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2030            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);  
2031            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //           double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2032            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2033    //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2034    
2035              double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2036              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2037              double *ptr_2 = &(res.getDataAtOffset(offset_2));
2038    
2039    
2040            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2041          }          }
2042        }        }
# Line 1954  C_TensorBinaryOperation(Data const &arg_ Line 2056  C_TensorBinaryOperation(Data const &arg_
2056        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2057        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2058          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2059          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2060          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2061            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2062            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2063            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2064            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2065            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2066          }          }
2067        }        }
# Line 1982  C_TensorBinaryOperation(Data const &arg_ Line 2084  C_TensorBinaryOperation(Data const &arg_
2084            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2085            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2086            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2087            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2088            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2089            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2090            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2091          }          }
2092        }        }
# Line 1998  C_TensorBinaryOperation(Data const &arg_ Line 2100  C_TensorBinaryOperation(Data const &arg_
2100    
2101      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2102        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output
2103        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2104        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2105        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &(res.getDataAtOffset(0));
2106        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2107      }      }
2108      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 2018  C_TensorBinaryOperation(Data const &arg_ Line 2120  C_TensorBinaryOperation(Data const &arg_
2120    
2121        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2122        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2123        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2124        // Get the views        // Get the views
2125        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
2126        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2127        // Get the pointers to the actual data  //       // Get the pointers to the actual data
2128        double *ptr_1 = &((view_1.getData())[0]);  //       double *ptr_1 = &((view_1.getData())[0]);
2129        double *ptr_2 = &((view_2.getData())[0]);  //       double *ptr_2 = &((view_2.getData())[0]);
2130           double *ptr_1 = &(tmp_1->getDefaultValue(0));
2131           double *ptr_2 = &(tmp_2->getDefaultValue(0));
2132    
2133        // Compute a result for the default        // Compute a result for the default
2134        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2135        // Compute a result for each tag        // Compute a result for each tag
2136        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2137        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2138        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2139          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2140          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2141          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2142          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2143          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2144            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2145            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2146          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2147        }        }
2148    
# Line 2056  C_TensorBinaryOperation(Data const &arg_ Line 2163  C_TensorBinaryOperation(Data const &arg_
2163          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2164            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2165            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2166            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2167            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2168            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2169            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2170    
2171          }          }
# Line 2080  C_TensorBinaryOperation(Data const &arg_ Line 2187  C_TensorBinaryOperation(Data const &arg_
2187    
2188        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2189        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2190        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //       double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2191          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2192        // Get the views        // Get the views
2193        DataArrayView view_0 = tmp_0->getDefaultValue();  /*      DataArrayView view_0 = tmp_0->getDefaultValue();
2194        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2195        // Get the pointers to the actual data        // Get the pointers to the actual data
2196        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &((view_0.getData())[0]);
2197        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2198    
2199          // Get the pointers to the actual data
2200          double *ptr_0 = &(tmp_0->getDefaultValue(0));
2201          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2202    
2203    
2204        // Compute a result for the default        // Compute a result for the default
2205        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2206        // Compute a result for each tag        // Compute a result for each tag
2207        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2208        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2209        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2210          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2211          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2212          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2213          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2214          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2215            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2216            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2217    
2218          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2219        }        }
2220    
# Line 2116  C_TensorBinaryOperation(Data const &arg_ Line 2233  C_TensorBinaryOperation(Data const &arg_
2233        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2234    
2235        // Get the views        // Get the views
2236        DataArrayView view_0 = tmp_0->getDefaultValue();  /*      DataArrayView view_0 = tmp_0->getDefaultValue();
2237        DataArrayView view_1 = tmp_1->getDefaultValue();        DataArrayView view_1 = tmp_1->getDefaultValue();
2238        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2239        // Get the pointers to the actual data        // Get the pointers to the actual data
2240        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &((view_0.getData())[0]);
2241        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &((view_1.getData())[0]);
2242        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2243    
2244          // Get the pointers to the actual data
2245          double *ptr_0 = &(tmp_0->getDefaultValue(0));
2246          double *ptr_1 = &(tmp_1->getDefaultValue(0));
2247          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2248    
2249    
2250        // Compute a result for the default        // Compute a result for the default
2251        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2252        // Merge the tags        // Merge the tags
# Line 2130  C_TensorBinaryOperation(Data const &arg_ Line 2254  C_TensorBinaryOperation(Data const &arg_
2254        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2255        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2256        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2257          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2258        }        }
2259        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2260          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2261        }        }
2262        // Compute a result for each tag        // Compute a result for each tag
2263        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2264        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2265          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  
2266    /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2267          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2268          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2269          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2270          double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
2271          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2272    
2273            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2274            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2275            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2276    
2277          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2278        }        }
2279    
# Line 2162  C_TensorBinaryOperation(Data const &arg_ Line 2292  C_TensorBinaryOperation(Data const &arg_
2292        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2293        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2294          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2295          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2296          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2297            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2298            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2299            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2300            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2301            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2302          }          }
2303        }        }
# Line 2189  C_TensorBinaryOperation(Data const &arg_ Line 2319  C_TensorBinaryOperation(Data const &arg_
2319          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2320            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2321            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2322            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2323            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2324            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2325            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2326          }          }
2327        }        }
# Line 2212  C_TensorBinaryOperation(Data const &arg_ Line 2342  C_TensorBinaryOperation(Data const &arg_
2342        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2343        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2344          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2345          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2346          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2347            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2348            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2349            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2350            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2351            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2352          }          }
2353        }        }
# Line 2240  C_TensorBinaryOperation(Data const &arg_ Line 2370  C_TensorBinaryOperation(Data const &arg_
2370            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2371            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2372            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2373            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2374            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2375            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2376            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2377          }          }
2378        }        }
# Line 2256  C_TensorBinaryOperation(Data const &arg_ Line 2386  C_TensorBinaryOperation(Data const &arg_
2386    
2387      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2388        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
2389        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2390        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2391        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &(res.getDataAtOffset(0));
2392        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2393      }      }
2394      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 2276  C_TensorBinaryOperation(Data const &arg_ Line 2406  C_TensorBinaryOperation(Data const &arg_
2406    
2407        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2408        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2409        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2410        // Get the views        // Get the views
2411        DataArrayView view_1 = tmp_1->getDefaultValue();  /*      DataArrayView view_1 = tmp_1->getDefaultValue();
2412        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2413        // Get the pointers to the actual data        // Get the pointers to the actual data
2414        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &((view_1.getData())[0]);
2415        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2416          //Get the pointers to the actual data
2417          double *ptr_1 = &(tmp_1->getDefaultValue(0));
2418          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2419    
2420        // Compute a result for the default        // Compute a result for the default
2421        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2422        // Compute a result for each tag        // Compute a result for each tag
2423        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2424        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2425        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2426          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2427          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2428          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2429          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2430          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2431            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2432            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2433    
2434    
2435          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2436        }        }
2437    
# Line 2314  C_TensorBinaryOperation(Data const &arg_ Line 2452  C_TensorBinaryOperation(Data const &arg_
2452          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2453            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2454            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2455            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2456            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2457            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2458            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2459          }          }
2460        }        }
# Line 2337  C_TensorBinaryOperation(Data const &arg_ Line 2475  C_TensorBinaryOperation(Data const &arg_
2475    
2476        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2477        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2478        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2479        // Get the views        // Get the views
2480        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
2481        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2482    //       // Get the pointers to the actual data
2483    //       double *ptr_0 = &((view_0.getData())[0]);
2484    //       double *ptr_2 = &((view_2.getData())[0]);
2485        // Get the pointers to the actual data        // Get the pointers to the actual data
2486        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
2487        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
2488        // Compute a result for the default        // Compute a result for the default
2489        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2490        // Compute a result for each tag        // Compute a result for each tag
2491        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2492        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2493        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2494          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2495          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2496          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2497          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2498          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2499            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2500            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2501          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2502        }        }
2503    
# Line 2373  C_TensorBinaryOperation(Data const &arg_ Line 2516  C_TensorBinaryOperation(Data const &arg_
2516        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2517    
2518        // Get the views        // Get the views
2519        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
2520        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
2521        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2522    //       // Get the pointers to the actual data
2523    //       double *ptr_0 = &((view_0.getData())[0]);
2524    //       double *ptr_1 = &((view_1.getData())[0]);
2525    //       double *ptr_2 = &((view_2.getData())[0]);
2526    
2527        // Get the pointers to the actual data        // Get the pointers to the actual data
2528        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
2529        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
2530        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
2531    
2532        // Compute a result for the default        // Compute a result for the default
2533        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2534        // Merge the tags        // Merge the tags
# Line 2387  C_TensorBinaryOperation(Data const &arg_ Line 2536  C_TensorBinaryOperation(Data const &arg_
2536        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2537        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2538        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2539          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2540        }        }
2541        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2542          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2543        }        }
2544        // Compute a result for each tag        // Compute a result for each tag
2545        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2546        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2547          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2548          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2549          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2550          double *ptr_0 = &view_0.getData(0);  //         double *ptr_0 = &view_0.getData(0);
2551          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2552          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2553    
2554            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2555            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2556            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2557          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2558        }        }
2559    
# Line 2419  C_TensorBinaryOperation(Data const &arg_ Line 2572  C_TensorBinaryOperation(Data const &arg_
2572        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2573        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2574          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2575          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2576          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2577            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2578            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2579            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2580            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2581            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2582          }          }
2583        }        }
# Line 2446  C_TensorBinaryOperation(Data const &arg_ Line 2599  C_TensorBinaryOperation(Data const &arg_
2599          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2600            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2601            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2602            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2603            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2604            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2605            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2606          }          }
2607        }        }
# Line 2469  C_TensorBinaryOperation(Data const &arg_ Line 2622  C_TensorBinaryOperation(Data const &arg_
2622        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2623        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2624          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2625          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2626          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2627            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2628            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2629            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2630            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2631            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2632          }          }
2633        }        }
# Line 2497  C_TensorBinaryOperation(Data const &arg_ Line 2650  C_TensorBinaryOperation(Data const &arg_
2650            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2651            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2652            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2653            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2654            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2655            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2656            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2657          }          }
2658        }        }
# Line 2521  Data Line 2674  Data
2674  C_TensorUnaryOperation(Data const &arg_0,  C_TensorUnaryOperation(Data const &arg_0,
2675                         UnaryFunction operation)                         UnaryFunction operation)
2676  {  {
2677      if (arg_0.isEmpty())  // do this before we attempt to interpolate
2678      {
2679         throw DataException("Error - Operations not permitted on instances of DataEmpty.");
2680      }
2681    
2682    // Interpolate if necessary and find an appropriate function space    // Interpolate if necessary and find an appropriate function space
2683    Data arg_0_Z = Data(arg_0);    Data arg_0_Z = Data(arg_0);
2684    
2685    // Get rank and shape of inputs    // Get rank and shape of inputs
2686    int rank0 = arg_0_Z.getDataPointRank();    int rank0 = arg_0_Z.getDataPointRank();
2687    DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();    const DataTypes::ShapeType& shape0 = arg_0_Z.getDataPointShape();
2688    int size0 = arg_0_Z.getDataPointSize();    int size0 = arg_0_Z.getDataPointSize();
2689    
2690    // Declare output Data object    // Declare output Data object
# Line 2534  C_TensorUnaryOperation(Data const &arg_0 Line 2692  C_TensorUnaryOperation(Data const &arg_0
2692    
2693    if (arg_0_Z.isConstant()) {    if (arg_0_Z.isConstant()) {
2694      res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataConstant output      res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataConstant output
2695      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);  //     double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2696      double *ptr_2 = &((res.getPointDataView().getData())[0]);  //     double *ptr_2 = &((res.getPointDataView().getData())[0]);
2697        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2698        double *ptr_2 = &(res.getDataAtOffset(0));
2699      tensor_unary_operation(size0, ptr_0, ptr_2, operation);      tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2700    }    }
2701    else if (arg_0_Z.isTagged()) {    else if (arg_0_Z.isTagged()) {
# Line 2548  C_TensorUnaryOperation(Data const &arg_0 Line 2708  C_TensorUnaryOperation(Data const &arg_0
2708      res.tag();      res.tag();
2709      DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());      DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2710    
2711      // Get the views  //     // Get the views
2712      DataArrayView view_0 = tmp_0->getDefaultValue();  //     DataArrayView view_0 = tmp_0->getDefaultValue();
2713      DataArrayView view_2 = tmp_2->getDefaultValue();  //     DataArrayView view_2 = tmp_2->getDefaultValue();
2714    //     // Get the pointers to the actual data
2715    //     double *ptr_0 = &((view_0.getData())[0]);
2716    //     double *ptr_2 = &((view_2.getData())[0]);
2717      // Get the pointers to the actual data      // Get the pointers to the actual data
2718      double *ptr_0 = &((view_0.getData())[0]);      double *ptr_0 = &(tmp_0->getDefaultValue(0));
2719      double *ptr_2 = &((view_2.getData())[0]);      double *ptr_2 = &(tmp_2->getDefaultValue(0));
2720      // Compute a result for the default      // Compute a result for the default
2721      tensor_unary_operation(size0, ptr_0, ptr_2, operation);      tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2722      // Compute a result for each tag      // Compute a result for each tag
2723      const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();      const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2724      DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory      DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2725      for (i=lookup_0.begin();i!=lookup_0.end();i++) {      for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2726        tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());        tmp_2->addTag(i->first);
2727        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //       DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2728        DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //       DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2729        double *ptr_0 = &view_0.getData(0);  //       double *ptr_0 = &view_0.getData(0);
2730        double *ptr_2 = &view_2.getData(0);  //       double *ptr_2 = &view_2.getData(0);
2731          double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2732          double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2733        tensor_unary_operation(size0, ptr_0, ptr_2, operation);        tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2734      }      }
2735    
# Line 2581  C_TensorUnaryOperation(Data const &arg_0 Line 2746  C_TensorUnaryOperation(Data const &arg_0
2746      #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)      #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2747      for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {      for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2748        for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {        for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2749    //         int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2750    //         int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2751    //         double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2752    //         double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2753          int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);          int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2754          int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);          int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2755          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2756          double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);          double *ptr_2 = &(res.getDataAtOffset(offset_2));
2757          tensor_unary_operation(size0, ptr_0, ptr_2, operation);          tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2758        }        }
2759      }      }
   
2760    }    }
2761    else {    else {
2762      throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");      throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");

Legend:
Removed from v.1358  
changed lines
  Added in v.1811

  ViewVC Help
Powered by ViewVC 1.1.26