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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1796 - (show annotations)
Wed Sep 17 01:45:46 2008 UTC (11 years, 1 month ago) by jfenwick
Original Path: trunk/escript/src/Data.h
File MIME type: text/plain
File size: 87757 byte(s)
Merged noarrayview branch onto trunk.


1
2 /* $Id$ */
3
4 /*******************************************************
5 *
6 * Copyright 2003-2007 by ACceSS MNRF
7 * Copyright 2007 by University of Queensland
8 *
9 * 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 */
17
18 #ifndef DATA_H
19 #define DATA_H
20 #include "system_dep.h"
21
22 #include "DataAbstract.h"
23 #include "DataAlgorithm.h"
24 #include "FunctionSpace.h"
25 #include "BinaryOp.h"
26 #include "UnaryOp.h"
27 #include "DataException.h"
28 #include "DataTypes.h"
29
30 extern "C" {
31 #include "DataC.h"
32 /* #include "paso/Paso.h" doesn't belong in this file...causes trouble for BruceFactory.cpp */
33 }
34
35 #include "esysmpi.h"
36 #include <string>
37 #include <algorithm>
38 #include <sstream>
39
40
41 #include <boost/shared_ptr.hpp>
42 #include <boost/python/object.hpp>
43 #include <boost/python/tuple.hpp>
44 #include <boost/python/numeric.hpp>
45
46 namespace escript {
47
48 //
49 // Forward declaration for various implementations of Data.
50 class DataConstant;
51 class DataTagged;
52 class DataExpanded;
53
54 /**
55 \brief
56 Data creates the appropriate Data object for the given construction
57 arguments.
58
59 Description:
60 Data is essentially a factory class which creates the appropriate Data
61 object for the given construction arguments. It retains control over
62 the object created for the lifetime of the object.
63 The type of Data object referred to may change during the lifetime of
64 the Data object.
65 */
66 class Data {
67
68 public:
69
70 // These typedefs allow function names to be cast to pointers
71 // to functions of the appropriate type when calling unaryOp etc.
72 typedef double (*UnaryDFunPtr)(double);
73 typedef double (*BinaryDFunPtr)(double,double);
74
75
76 /**
77 Constructors.
78 */
79
80 /**
81 \brief
82 Default constructor.
83 Creates a DataEmpty object.
84 */
85 ESCRIPT_DLL_API
86 Data();
87
88 /**
89 \brief
90 Copy constructor.
91 WARNING: Only performs a shallow copy.
92 */
93 ESCRIPT_DLL_API
94 Data(const Data& inData);
95
96 /**
97 \brief
98 Constructor from another Data object. If "what" is different from the
99 function space of inData the inData are tried to be interpolated to what,
100 otherwise a shallow copy of inData is returned.
101 */
102 ESCRIPT_DLL_API
103 Data(const Data& inData,
104 const FunctionSpace& what);
105
106 /**
107 \brief Copy Data from an existing vector
108 */
109
110 ESCRIPT_DLL_API
111 Data(const DataTypes::ValueType& value,
112 const DataTypes::ShapeType& shape,
113 const FunctionSpace& what=FunctionSpace(),
114 bool expanded=false);
115
116 /**
117 \brief
118 Constructor which creates a Data from a DataArrayView shape.
119
120 \param value - Input - Single value applied to all Data.
121 \param dataPointShape - Input - The shape of each data point.
122 \param what - Input - A description of what this data represents.
123 \param expanded - Input - Flag, if true fill the entire container with
124 the given value. Otherwise a more efficient storage
125 mechanism will be used.
126 */
127 ESCRIPT_DLL_API
128 Data(double value,
129 const DataTypes::ShapeType& dataPointShape=DataTypes::ShapeType(),
130 const FunctionSpace& what=FunctionSpace(),
131 bool expanded=false);
132
133 /**
134 \brief
135 Constructor which performs a deep copy of a region from another Data object.
136
137 \param inData - Input - Input Data object.
138 \param region - Input - Region to copy.
139 */
140 ESCRIPT_DLL_API
141 Data(const Data& inData,
142 const DataTypes::RegionType& region);
143
144 /**
145 \brief
146 Constructor which copies data from a python numarray.
147
148 \param value - Input - Data value for a single point.
149 \param what - Input - A description of what this data represents.
150 \param expanded - Input - Flag, if true fill the entire container with
151 the value. Otherwise a more efficient storage
152 mechanism will be used.
153 */
154 ESCRIPT_DLL_API
155 Data(const boost::python::numeric::array& value,
156 const FunctionSpace& what=FunctionSpace(),
157 bool expanded=false);
158
159 /**
160 \brief
161 Constructor which copies data from any object that can be converted into
162 a python numarray.
163
164 \param value - Input - Input data.
165 \param what - Input - A description of what this data represents.
166 \param expanded - Input - Flag, if true fill the entire container with
167 the value. Otherwise a more efficient storage
168 mechanism will be used.
169 */
170 ESCRIPT_DLL_API
171 Data(const boost::python::object& value,
172 const FunctionSpace& what=FunctionSpace(),
173 bool expanded=false);
174
175 /**
176 \brief
177 Constructor which creates a DataConstant.
178 Copies data from any object that can be converted
179 into a numarray. All other parameters are copied from other.
180
181 \param value - Input - Input data.
182 \param other - Input - contains all other parameters.
183 */
184 ESCRIPT_DLL_API
185 Data(const boost::python::object& value,
186 const Data& other);
187
188 /**
189 \brief
190 Constructor which creates a DataConstant of "shape" with constant value.
191 */
192 ESCRIPT_DLL_API
193 Data(double value,
194 const boost::python::tuple& shape=boost::python::make_tuple(),
195 const FunctionSpace& what=FunctionSpace(),
196 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
210 Destructor
211 */
212 ESCRIPT_DLL_API
213 ~Data();
214
215 /**
216 \brief
217 Perform a deep copy.
218 */
219 ESCRIPT_DLL_API
220 void
221 copy(const Data& other);
222
223 /**
224 Member access methods.
225 */
226
227 /**
228 \brief
229 switches on update protection
230
231 */
232 ESCRIPT_DLL_API
233 void
234 setProtection();
235
236 /**
237 \brief
238 Returns trueif the data object is protected against update
239
240 */
241 ESCRIPT_DLL_API
242 bool
243 isProtected() const;
244
245 /**
246 \brief
247 Return the values of a data point on this process
248 */
249 ESCRIPT_DLL_API
250 const boost::python::numeric::array
251 getValueOfDataPoint(int dataPointNo);
252
253 /**
254 \brief
255 sets the values of a data-point from a python object on this process
256 */
257 ESCRIPT_DLL_API
258 void
259 setValueOfDataPointToPyObject(int dataPointNo, const boost::python::object& py_object);
260
261 /**
262 \brief
263 sets the values of a data-point from a numarray object on this process
264 */
265 ESCRIPT_DLL_API
266 void
267 setValueOfDataPointToArray(int dataPointNo, const boost::python::numeric::array&);
268
269 /**
270 \brief
271 sets the values of a data-point on this process
272 */
273 ESCRIPT_DLL_API
274 void
275 setValueOfDataPoint(int dataPointNo, const double);
276
277 /**
278 \brief
279 Return the value of the specified data-point across all processors
280 */
281 ESCRIPT_DLL_API
282 const boost::python::numeric::array
283 getValueOfGlobalDataPoint(int procNo, int dataPointNo);
284
285 /**
286 \brief
287 Return the tag number associated with the given data-point.
288
289 */
290 ESCRIPT_DLL_API
291 int
292 getTagNumber(int dpno);
293
294 /**
295 \brief
296 Return the C wrapper for the Data object.
297 */
298 ESCRIPT_DLL_API
299 escriptDataC
300 getDataC();
301
302
303
304
305
306
307 // REMOVE ME
308 // ESCRIPT_DLL_API
309 // void
310 // CompareDebug(const Data& rd);
311
312
313 /**
314 \brief
315 Return the C wrapper for the Data object - const version.
316 */
317 ESCRIPT_DLL_API
318 escriptDataC
319 getDataC() const;
320
321 /**
322 \brief
323 Write the data as a string. For large amounts of data, a summary is printed.
324 */
325 ESCRIPT_DLL_API
326 std::string
327 toString() const;
328
329
330 // /**
331 /* \brief
332 Return the DataArrayView of the point data. This essentially contains
333 the shape information for each data point although it also may be used
334 to manipulate the point data.*/
335 // */
336 // ESCRIPT_DLL_API
337 // inline
338 // const DataArrayView&
339 // getPointDataView() const
340 // {
341 // return m_data->getPointDataView();
342 // }
343
344 /**
345 \brief
346 Whatever the current Data type make this into a DataExpanded.
347 */
348 ESCRIPT_DLL_API
349 void
350 expand();
351
352 /**
353 \brief
354 If possible convert this Data to DataTagged. This will only allow
355 Constant data to be converted to tagged. An attempt to convert
356 Expanded data to tagged will throw an exception.
357 ==>*
358 */
359 ESCRIPT_DLL_API
360 void
361 tag();
362
363 /**
364 \brief
365 Return true if this Data is expanded.
366 */
367 ESCRIPT_DLL_API
368 bool
369 isExpanded() const;
370
371 /**
372 \brief
373 Return true if this Data is tagged.
374 */
375 ESCRIPT_DLL_API
376 bool
377 isTagged() const;
378
379 /**
380 \brief
381 Return true if this Data is constant.
382 */
383 ESCRIPT_DLL_API
384 bool
385 isConstant() const;
386
387 /**
388 \brief
389 Return true if this Data is empty.
390 */
391 ESCRIPT_DLL_API
392 bool
393 isEmpty() const;
394
395 /**
396 \brief
397 Return the function space.
398 */
399 ESCRIPT_DLL_API
400 inline
401 const FunctionSpace&
402 getFunctionSpace() const
403 {
404 return m_data->getFunctionSpace();
405 }
406
407 /**
408 \brief
409 Return a copy of the function space.
410 */
411 ESCRIPT_DLL_API
412 const FunctionSpace
413 getCopyOfFunctionSpace() const;
414
415 /**
416 \brief
417 Return the domain.
418 */
419 ESCRIPT_DLL_API
420 inline
421 const AbstractDomain&
422 getDomain() const
423 {
424 return getFunctionSpace().getDomain();
425 }
426
427 /**
428 \brief
429 Return a copy of the domain.
430 */
431 ESCRIPT_DLL_API
432 const AbstractDomain
433 getCopyOfDomain() const;
434
435 /**
436 \brief
437 Return the rank of the point data.
438 */
439 ESCRIPT_DLL_API
440 inline
441 int
442 getDataPointRank() const
443 {
444 // return m_data->getPointDataView().getRank();
445 return m_data->getRank();
446 }
447
448 /**
449 \brief
450 Return the number of data points
451 */
452 ESCRIPT_DLL_API
453 inline
454 int
455 getNumDataPoints() const
456 {
457 return getNumSamples() * getNumDataPointsPerSample();
458 }
459 /**
460 \brief
461 Return the number of samples.
462 */
463 ESCRIPT_DLL_API
464 inline
465 int
466 getNumSamples() const
467 {
468 return m_data->getNumSamples();
469 }
470
471 /**
472 \brief
473 Return the number of data points per sample.
474 */
475 ESCRIPT_DLL_API
476 inline
477 int
478 getNumDataPointsPerSample() const
479 {
480 return m_data->getNumDPPSample();
481 }
482
483
484 /**
485 \brief
486 Return the number of values in the shape for this object.
487 */
488 ESCRIPT_DLL_API
489 int
490 getNoValues() const
491 {
492 return m_data->getNoValues();
493 }
494
495
496 /**
497 \brief
498 dumps the object into a netCDF file
499 */
500 ESCRIPT_DLL_API
501 void
502 dump(const std::string fileName) const;
503 /**
504 \brief
505 Return the sample data for the given sample no. This is not the
506 preferred interface but is provided for use by C code.
507 \param sampleNo - Input - the given sample no.
508 */
509 ESCRIPT_DLL_API
510 inline
511 DataAbstract::ValueType::value_type*
512 getSampleData(DataAbstract::ValueType::size_type sampleNo)
513 {
514 return m_data->getSampleData(sampleNo);
515 }
516
517 /**
518 \brief
519 Return the sample data for the given tag. If an attempt is made to
520 access data that isn't tagged an exception will be thrown.
521 \param tag - Input - the tag key.
522 */
523 ESCRIPT_DLL_API
524 inline
525 DataAbstract::ValueType::value_type*
526 getSampleDataByTag(int tag)
527 {
528 return m_data->getSampleDataByTag(tag);
529 }
530
531 // /**
532 /* \brief
533 Return a view into the data for the data point specified.
534 NOTE: Construction of the DataArrayView is a relatively expensive
535 operation.
536 \param sampleNo - Input -
537 \param dataPointNo - Input -*/
538 // */
539 // ESCRIPT_DLL_API
540 // inline
541 // DataArrayView
542 // getDataPoint(int sampleNo,
543 // int dataPointNo)
544 // {
545 // return m_data->getDataPoint(sampleNo,dataPointNo);
546 // }
547
548
549 /**
550 \brief
551 Return a view into the data for the data point specified.
552 NOTE: Construction of the DataArrayView is a relatively expensive
553 operation.
554 \param sampleNo - Input -
555 \param dataPointNo - Input -
556 */
557 ESCRIPT_DLL_API
558 DataTypes::ValueType::const_reference
559 getDataPoint(int sampleNo, int dataPointNo) const;
560
561
562 ESCRIPT_DLL_API
563 DataTypes::ValueType::reference
564 getDataPoint(int sampleNo, int dataPointNo);
565
566
567
568 /**
569 \brief
570 Return the offset for the given sample and point within the sample
571 */
572 ESCRIPT_DLL_API
573 inline
574 DataTypes::ValueType::size_type
575 getDataOffset(int sampleNo,
576 int dataPointNo)
577 {
578 return m_data->getPointOffset(sampleNo,dataPointNo);
579 }
580
581 /**
582 \brief
583 Return a reference to the data point shape.
584 */
585 ESCRIPT_DLL_API
586 inline
587 const DataTypes::ShapeType&
588 getDataPointShape() const
589 {
590 return m_data->getShape();
591 }
592
593 /**
594 \brief
595 Return the data point shape as a tuple of integers.
596 */
597 ESCRIPT_DLL_API
598 const boost::python::tuple
599 getShapeTuple() const;
600
601 /**
602 \brief
603 Return the size of the data point. It is the product of the
604 data point shape dimensions.
605 */
606 ESCRIPT_DLL_API
607 int
608 getDataPointSize() const;
609
610 /**
611 \brief
612 Return the number of doubles stored for this Data.
613 */
614 ESCRIPT_DLL_API
615 DataTypes::ValueType::size_type
616 getLength() const;
617
618
619
620 /**
621 \brief
622 Assign the given value to the tag assocciated with name. Implicitly converts this
623 object to type DataTagged. Throws an exception if this object
624 cannot be converted to a DataTagged object or name cannot be mapped onto a tag key.
625 \param tagKey - Input - Integer key.
626 \param value - Input - Value to associate with given key.
627 ==>*
628 */
629 ESCRIPT_DLL_API
630 void
631 setTaggedValueByName(std::string name,
632 const boost::python::object& value);
633
634 /**
635 \brief
636 Assign the given value to the tag. Implicitly converts this
637 object to type DataTagged if it is constant.
638
639 \param tagKey - Input - Integer key.
640 \param value - Input - Value to associate with given key.
641 ==>*
642 */
643 ESCRIPT_DLL_API
644 void
645 setTaggedValue(int tagKey,
646 const boost::python::object& value);
647
648
649 // /**
650 // \brief
651 // Assign the given value to the tag. Implicitly converts this
652 // object to type DataTagged if it is constant.
653 //
654 // \param tagKey - Input - Integer key.
655 // \param value - Input - Value to associate with given key.
656 // ==>*
657 // */
658 // ESCRIPT_DLL_API
659 // void
660 // setTaggedValueFromCPP(int tagKey,
661 // const DataArrayView& value);
662
663 /**
664 \brief
665 Assign the given value to the tag. Implicitly converts this
666 object to type DataTagged if it is constant.
667
668 \param tagKey - Input - Integer key.
669 \param pointshape - Input - The shape of the value parameter
670 \param value - Input - Value to associate with given key.
671 \param dataOffset - Input - Offset of the begining of the point within the value parameter
672 */
673 ESCRIPT_DLL_API
674 void
675 setTaggedValueFromCPP(int tagKey,
676 const DataTypes::ShapeType& pointshape,
677 const DataTypes::ValueType& value,
678 int dataOffset=0);
679
680
681
682 /**
683 \brief
684 Copy other Data object into this Data object where mask is positive.
685 */
686 ESCRIPT_DLL_API
687 void
688 copyWithMask(const Data& other,
689 const Data& mask);
690
691 /**
692 Data object operation methods and operators.
693 */
694
695 /**
696 \brief
697 set all values to zero
698 *
699 */
700 ESCRIPT_DLL_API
701 void
702 setToZero();
703
704 /**
705 \brief
706 Interpolates this onto the given functionspace and returns
707 the result as a Data object.
708 *
709 */
710 ESCRIPT_DLL_API
711 Data
712 interpolate(const FunctionSpace& functionspace) const;
713 /**
714 \brief
715 Calculates the gradient of the data at the data points of functionspace.
716 If functionspace is not present the function space of Function(getDomain()) is used.
717 *
718 */
719 ESCRIPT_DLL_API
720 Data
721 gradOn(const FunctionSpace& functionspace) const;
722
723 ESCRIPT_DLL_API
724 Data
725 grad() const;
726
727 /**
728 \brief
729 Calculate the integral over the function space domain.
730 *
731 */
732 ESCRIPT_DLL_API
733 boost::python::numeric::array
734 integrate() const;
735
736 /**
737 \brief
738 Returns 1./ Data object
739 *
740 */
741 ESCRIPT_DLL_API
742 Data
743 oneOver() const;
744 /**
745 \brief
746 Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
747 *
748 */
749 ESCRIPT_DLL_API
750 Data
751 wherePositive() const;
752
753 /**
754 \brief
755 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
756 *
757 */
758 ESCRIPT_DLL_API
759 Data
760 whereNegative() const;
761
762 /**
763 \brief
764 Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
765 *
766 */
767 ESCRIPT_DLL_API
768 Data
769 whereNonNegative() const;
770
771 /**
772 \brief
773 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
774 *
775 */
776 ESCRIPT_DLL_API
777 Data
778 whereNonPositive() const;
779
780 /**
781 \brief
782 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
783 *
784 */
785 ESCRIPT_DLL_API
786 Data
787 whereZero(double tol=0.0) const;
788
789 /**
790 \brief
791 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
792 *
793 */
794 ESCRIPT_DLL_API
795 Data
796 whereNonZero(double tol=0.0) const;
797
798 /**
799 \brief
800 Return the maximum absolute value of this Data object.
801 *
802 */
803 ESCRIPT_DLL_API
804 double
805 Lsup() const;
806
807 /**
808 \brief
809 Return the maximum value of this Data object.
810 *
811 */
812 ESCRIPT_DLL_API
813 double
814 sup() const;
815
816 /**
817 \brief
818 Return the minimum value of this Data object.
819 *
820 */
821 ESCRIPT_DLL_API
822 double
823 inf() const;
824
825 /**
826 \brief
827 Return the absolute value of each data point of this Data object.
828 *
829 */
830 ESCRIPT_DLL_API
831 Data
832 abs() const;
833
834 /**
835 \brief
836 Return the maximum value of each data point of this Data object.
837 *
838 */
839 ESCRIPT_DLL_API
840 Data
841 maxval() const;
842
843 /**
844 \brief
845 Return the minimum value of each data point of this Data object.
846 *
847 */
848 ESCRIPT_DLL_API
849 Data
850 minval() const;
851
852 /**
853 \brief
854 Return the (sample number, data-point number) of the data point with
855 the minimum value in this Data object.
856 */
857 ESCRIPT_DLL_API
858 const boost::python::tuple
859 minGlobalDataPoint() const;
860
861 ESCRIPT_DLL_API
862 void
863 calc_minGlobalDataPoint(int& ProcNo, int& DataPointNo) const;
864 /**
865 \brief
866 Return the sign of each data point of this Data object.
867 -1 for negative values, zero for zero values, 1 for positive values.
868 *
869 */
870 ESCRIPT_DLL_API
871 Data
872 sign() const;
873
874 /**
875 \brief
876 Return the symmetric part of a matrix which is half the matrix plus its transpose.
877 *
878 */
879 ESCRIPT_DLL_API
880 Data
881 symmetric() const;
882
883 /**
884 \brief
885 Return the nonsymmetric part of a matrix which is half the matrix minus its transpose.
886 *
887 */
888 ESCRIPT_DLL_API
889 Data
890 nonsymmetric() const;
891
892 /**
893 \brief
894 Return the trace of a matrix
895 *
896 */
897 ESCRIPT_DLL_API
898 Data
899 trace(int axis_offset) const;
900
901 /**
902 \brief
903 Transpose each data point of this Data object around the given axis.
904 *
905 */
906 ESCRIPT_DLL_API
907 Data
908 transpose(int axis_offset) const;
909
910 /**
911 \brief
912 Return the eigenvalues of the symmetric part at each data point of this Data object in increasing values.
913 Currently this function is restricted to rank 2, square shape, and dimension 3.
914 *
915 */
916 ESCRIPT_DLL_API
917 Data
918 eigenvalues() const;
919
920 /**
921 \brief
922 Return the eigenvalues and corresponding eigenvcetors of the symmetric part at each data point of this Data object.
923 the eigenvalues are ordered in increasing size where eigenvalues with relative difference less than
924 tol are treated as equal. The eigenvectors are orthogonal, normalized and the sclaed such that the
925 first non-zero entry is positive.
926 Currently this function is restricted to rank 2, square shape, and dimension 3
927 *
928 */
929 ESCRIPT_DLL_API
930 const boost::python::tuple
931 eigenvalues_and_eigenvectors(const double tol=1.e-12) const;
932
933 /**
934 \brief
935 swaps the components axis0 and axis1
936 *
937 */
938 ESCRIPT_DLL_API
939 Data
940 swapaxes(const int axis0, const int axis1) const;
941
942 /**
943 \brief
944 Return the error function erf of each data point of this Data object.
945 *
946 */
947 ESCRIPT_DLL_API
948 Data
949 erf() const;
950
951 /**
952 \brief
953 Return the sin of each data point of this Data object.
954 *
955 */
956 ESCRIPT_DLL_API
957 Data
958 sin() const;
959
960 /**
961 \brief
962 Return the cos of each data point of this Data object.
963 *
964 */
965 ESCRIPT_DLL_API
966 Data
967 cos() const;
968
969 /**
970 \brief
971 Return the tan of each data point of this Data object.
972 *
973 */
974 ESCRIPT_DLL_API
975 Data
976 tan() const;
977
978 /**
979 \brief
980 Return the asin of each data point of this Data object.
981 *
982 */
983 ESCRIPT_DLL_API
984 Data
985 asin() const;
986
987 /**
988 \brief
989 Return the acos of each data point of this Data object.
990 *
991 */
992 ESCRIPT_DLL_API
993 Data
994 acos() const;
995
996 /**
997 \brief
998 Return the atan of each data point of this Data object.
999 *
1000 */
1001 ESCRIPT_DLL_API
1002 Data
1003 atan() const;
1004
1005 /**
1006 \brief
1007 Return the sinh of each data point of this Data object.
1008 *
1009 */
1010 ESCRIPT_DLL_API
1011 Data
1012 sinh() const;
1013
1014 /**
1015 \brief
1016 Return the cosh of each data point of this Data object.
1017 *
1018 */
1019 ESCRIPT_DLL_API
1020 Data
1021 cosh() const;
1022
1023 /**
1024 \brief
1025 Return the tanh of each data point of this Data object.
1026 *
1027 */
1028 ESCRIPT_DLL_API
1029 Data
1030 tanh() const;
1031
1032 /**
1033 \brief
1034 Return the asinh of each data point of this Data object.
1035 *
1036 */
1037 ESCRIPT_DLL_API
1038 Data
1039 asinh() const;
1040
1041 /**
1042 \brief
1043 Return the acosh of each data point of this Data object.
1044 *
1045 */
1046 ESCRIPT_DLL_API
1047 Data
1048 acosh() const;
1049
1050 /**
1051 \brief
1052 Return the atanh of each data point of this Data object.
1053 *
1054 */
1055 ESCRIPT_DLL_API
1056 Data
1057 atanh() const;
1058
1059 /**
1060 \brief
1061 Return the log to base 10 of each data point of this Data object.
1062 *
1063 */
1064 ESCRIPT_DLL_API
1065 Data
1066 log10() const;
1067
1068 /**
1069 \brief
1070 Return the natural log of each data point of this Data object.
1071 *
1072 */
1073 ESCRIPT_DLL_API
1074 Data
1075 log() const;
1076
1077 /**
1078 \brief
1079 Return the exponential function of each data point of this Data object.
1080 *
1081 */
1082 ESCRIPT_DLL_API
1083 Data
1084 exp() const;
1085
1086 /**
1087 \brief
1088 Return the square root of each data point of this Data object.
1089 *
1090 */
1091 ESCRIPT_DLL_API
1092 Data
1093 sqrt() const;
1094
1095 /**
1096 \brief
1097 Return the negation of each data point of this Data object.
1098 *
1099 */
1100 ESCRIPT_DLL_API
1101 Data
1102 neg() const;
1103
1104 /**
1105 \brief
1106 Return the identity of each data point of this Data object.
1107 Simply returns this object unmodified.
1108 *
1109 */
1110 ESCRIPT_DLL_API
1111 Data
1112 pos() const;
1113
1114 /**
1115 \brief
1116 Return the given power of each data point of this Data object.
1117
1118 \param right Input - the power to raise the object to.
1119 *
1120 */
1121 ESCRIPT_DLL_API
1122 Data
1123 powD(const Data& right) const;
1124
1125 /**
1126 \brief
1127 Return the given power of each data point of this boost python object.
1128
1129 \param right Input - the power to raise the object to.
1130 *
1131 */
1132 ESCRIPT_DLL_API
1133 Data
1134 powO(const boost::python::object& right) const;
1135
1136 /**
1137 \brief
1138 Return the given power of each data point of this boost python object.
1139
1140 \param left Input - the bases
1141 *
1142 */
1143
1144 ESCRIPT_DLL_API
1145 Data
1146 rpowO(const boost::python::object& left) const;
1147
1148 /**
1149 \brief
1150 writes the object to a file in the DX file format
1151 */
1152 ESCRIPT_DLL_API
1153 void
1154 saveDX(std::string fileName) const;
1155
1156 /**
1157 \brief
1158 writes the object to a file in the VTK file format
1159 */
1160 ESCRIPT_DLL_API
1161 void
1162 saveVTK(std::string fileName) const;
1163
1164 /**
1165 \brief
1166 Overloaded operator +=
1167 \param right - Input - The right hand side.
1168 *
1169 */
1170 ESCRIPT_DLL_API
1171 Data& operator+=(const Data& right);
1172 ESCRIPT_DLL_API
1173 Data& operator+=(const boost::python::object& right);
1174
1175 ESCRIPT_DLL_API
1176 Data& operator=(const Data& other);
1177
1178 /**
1179 \brief
1180 Overloaded operator -=
1181 \param right - Input - The right hand side.
1182 *
1183 */
1184 ESCRIPT_DLL_API
1185 Data& operator-=(const Data& right);
1186 ESCRIPT_DLL_API
1187 Data& operator-=(const boost::python::object& right);
1188
1189 /**
1190 \brief
1191 Overloaded operator *=
1192 \param right - Input - The right hand side.
1193 *
1194 */
1195 ESCRIPT_DLL_API
1196 Data& operator*=(const Data& right);
1197 ESCRIPT_DLL_API
1198 Data& operator*=(const boost::python::object& right);
1199
1200 /**
1201 \brief
1202 Overloaded operator /=
1203 \param right - Input - The right hand side.
1204 *
1205 */
1206 ESCRIPT_DLL_API
1207 Data& operator/=(const Data& right);
1208 ESCRIPT_DLL_API
1209 Data& operator/=(const boost::python::object& right);
1210
1211 /**
1212 \brief
1213 Returns true if this can be interpolated to functionspace.
1214 */
1215 ESCRIPT_DLL_API
1216 bool
1217 probeInterpolation(const FunctionSpace& functionspace) const;
1218
1219 /**
1220 Data object slicing methods.
1221 */
1222
1223 /**
1224 \brief
1225 Returns a slice from this Data object.
1226
1227 /description
1228 Implements the [] get operator in python.
1229 Calls getSlice.
1230
1231 \param key - Input - python slice tuple specifying
1232 slice to return.
1233 */
1234 ESCRIPT_DLL_API
1235 Data
1236 getItem(const boost::python::object& key) const;
1237
1238 /**
1239 \brief
1240 Copies slice from value into this Data object.
1241
1242 Implements the [] set operator in python.
1243 Calls setSlice.
1244
1245 \param key - Input - python slice tuple specifying
1246 slice to copy from value.
1247 \param value - Input - Data object to copy from.
1248 */
1249 ESCRIPT_DLL_API
1250 void
1251 setItemD(const boost::python::object& key,
1252 const Data& value);
1253
1254 ESCRIPT_DLL_API
1255 void
1256 setItemO(const boost::python::object& key,
1257 const boost::python::object& value);
1258
1259 // These following public methods should be treated as private.
1260
1261 /**
1262 \brief
1263 Perform the given unary operation on every element of every data point in
1264 this Data object.
1265 */
1266 template <class UnaryFunction>
1267 ESCRIPT_DLL_API
1268 inline
1269 void
1270 unaryOp2(UnaryFunction operation);
1271
1272 /**
1273 \brief
1274 Return a Data object containing the specified slice of
1275 this Data object.
1276 \param region - Input - Region to copy.
1277 *
1278 */
1279 ESCRIPT_DLL_API
1280 Data
1281 getSlice(const DataTypes::RegionType& region) const;
1282
1283 /**
1284 \brief
1285 Copy the specified slice from the given value into this
1286 Data object.
1287 \param value - Input - Data to copy from.
1288 \param region - Input - Region to copy.
1289 *
1290 */
1291 ESCRIPT_DLL_API
1292 void
1293 setSlice(const Data& value,
1294 const DataTypes::RegionType& region);
1295
1296 /**
1297 \brief
1298 print the data values to stdout. Used for debugging
1299 */
1300 ESCRIPT_DLL_API
1301 void
1302 print(void);
1303
1304 /**
1305 \brief
1306 return the MPI rank number of the local data
1307 MPI_COMM_WORLD is assumed and the result of MPI_Comm_size()
1308 is returned
1309 */
1310 ESCRIPT_DLL_API
1311 int
1312 get_MPIRank(void) const;
1313
1314 /**
1315 \brief
1316 return the MPI rank number of the local data
1317 MPI_COMM_WORLD is assumed and the result of MPI_Comm_rank()
1318 is returned
1319 */
1320 ESCRIPT_DLL_API
1321 int
1322 get_MPISize(void) const;
1323
1324 /**
1325 \brief
1326 return the MPI rank number of the local data
1327 MPI_COMM_WORLD is assumed and returned.
1328 */
1329 ESCRIPT_DLL_API
1330 MPI_Comm
1331 get_MPIComm(void) const;
1332
1333 /**
1334 \brief
1335 return the object produced by the factory, which is a DataConstant or DataExpanded
1336 TODO Ownership of this object should be explained in doco.
1337 */
1338 ESCRIPT_DLL_API
1339 DataAbstract*
1340 borrowData(void) const;
1341
1342
1343 /**
1344 \brief
1345 Return a pointer to the beginning of the datapoint at the specified offset.
1346 TODO Eventually these should be inlined.
1347 \param i - position(offset) in the underlying datastructure
1348 */
1349 ESCRIPT_DLL_API
1350 DataTypes::ValueType::const_reference
1351 getDataAtOffset(DataTypes::ValueType::size_type i) const;
1352
1353
1354 ESCRIPT_DLL_API
1355 DataTypes::ValueType::reference
1356 getDataAtOffset(DataTypes::ValueType::size_type i);
1357
1358 protected:
1359
1360 private:
1361
1362 /**
1363 \brief
1364 Check *this and the right operand are compatible. Throws
1365 an exception if they aren't.
1366 \param right - Input - The right hand side.
1367 */
1368 inline
1369 void
1370 operandCheck(const Data& right) const
1371 {
1372 return m_data->operandCheck(*(right.m_data.get()));
1373 }
1374
1375 /**
1376 \brief
1377 Perform the specified reduction algorithm on every element of every data point in
1378 this Data object according to the given function and return the single value result.
1379 */
1380 template <class BinaryFunction>
1381 inline
1382 double
1383 algorithm(BinaryFunction operation,
1384 double initial_value) const;
1385
1386 /**
1387 \brief
1388 Reduce each data-point in this Data object using the given operation. Return a Data
1389 object with the same number of data-points, but with each data-point containing only
1390 one value - the result of the reduction operation on the corresponding data-point in
1391 this Data object
1392 */
1393 template <class BinaryFunction>
1394 inline
1395 Data
1396 dp_algorithm(BinaryFunction operation,
1397 double initial_value) const;
1398
1399 /**
1400 \brief
1401 Perform the given binary operation on all of the data's elements.
1402 The underlying type of the right hand side (right) determines the final
1403 type of *this after the operation. For example if the right hand side
1404 is expanded *this will be expanded if necessary.
1405 RHS is a Data object.
1406 */
1407 template <class BinaryFunction>
1408 inline
1409 void
1410 binaryOp(const Data& right,
1411 BinaryFunction operation);
1412
1413 /**
1414 \brief
1415 Convert the data type of the RHS to match this.
1416 \param right - Input - data type to match.
1417 */
1418 void
1419 typeMatchLeft(Data& right) const;
1420
1421 /**
1422 \brief
1423 Convert the data type of this to match the RHS.
1424 \param right - Input - data type to match.
1425 */
1426 void
1427 typeMatchRight(const Data& right);
1428
1429 /**
1430 \brief
1431 Construct a Data object of the appropriate type.
1432 */
1433
1434 void
1435 initialise(const DataTypes::ValueType& value,
1436 const DataTypes::ShapeType& shape,
1437 const FunctionSpace& what,
1438 bool expanded);
1439
1440 void
1441 initialise(const boost::python::numeric::array& value,
1442 const FunctionSpace& what,
1443 bool expanded);
1444
1445 //
1446 // flag to protect the data object against any update
1447 bool m_protected;
1448
1449 //
1450 // pointer to the actual data object
1451 boost::shared_ptr<DataAbstract> m_data;
1452
1453 };
1454
1455
1456
1457 /**
1458 Modify a filename for MPI parallel output to multiple files
1459 */
1460 char *Escript_MPI_appendRankToFileName(const char *, int, int);
1461
1462 /**
1463 Binary Data object operators.
1464 */
1465 inline double rpow(double x,double y)
1466 {
1467 return pow(y,x);
1468 }
1469
1470 /**
1471 \brief
1472 Operator+
1473 Takes two Data objects.
1474 */
1475 ESCRIPT_DLL_API Data operator+(const Data& left, const Data& right);
1476
1477 /**
1478 \brief
1479 Operator-
1480 Takes two Data objects.
1481 */
1482 ESCRIPT_DLL_API Data operator-(const Data& left, const Data& right);
1483
1484 /**
1485 \brief
1486 Operator*
1487 Takes two Data objects.
1488 */
1489 ESCRIPT_DLL_API Data operator*(const Data& left, const Data& right);
1490
1491 /**
1492 \brief
1493 Operator/
1494 Takes two Data objects.
1495 */
1496 ESCRIPT_DLL_API Data operator/(const Data& left, const Data& right);
1497
1498 /**
1499 \brief
1500 Operator+
1501 Takes LHS Data object and RHS python::object.
1502 python::object must be convertable to Data type.
1503 */
1504 ESCRIPT_DLL_API Data operator+(const Data& left, const boost::python::object& right);
1505
1506 /**
1507 \brief
1508 Operator-
1509 Takes LHS Data object and RHS python::object.
1510 python::object must be convertable to Data type.
1511 */
1512 ESCRIPT_DLL_API Data operator-(const Data& left, const boost::python::object& right);
1513
1514 /**
1515 \brief
1516 Operator*
1517 Takes LHS Data object and RHS python::object.
1518 python::object must be convertable to Data type.
1519 */
1520 ESCRIPT_DLL_API Data operator*(const Data& left, const boost::python::object& right);
1521
1522 /**
1523 \brief
1524 Operator/
1525 Takes LHS Data object and RHS python::object.
1526 python::object must be convertable to Data type.
1527 */
1528 ESCRIPT_DLL_API Data operator/(const Data& left, const boost::python::object& right);
1529
1530 /**
1531 \brief
1532 Operator+
1533 Takes LHS python::object and RHS Data object.
1534 python::object must be convertable to Data type.
1535 */
1536 ESCRIPT_DLL_API Data operator+(const boost::python::object& left, const Data& right);
1537
1538 /**
1539 \brief
1540 Operator-
1541 Takes LHS python::object and RHS Data object.
1542 python::object must be convertable to Data type.
1543 */
1544 ESCRIPT_DLL_API Data operator-(const boost::python::object& left, const Data& right);
1545
1546 /**
1547 \brief
1548 Operator*
1549 Takes LHS python::object and RHS Data object.
1550 python::object must be convertable to Data type.
1551 */
1552 ESCRIPT_DLL_API Data operator*(const boost::python::object& left, const Data& right);
1553
1554 /**
1555 \brief
1556 Operator/
1557 Takes LHS python::object and RHS Data object.
1558 python::object must be convertable to Data type.
1559 */
1560 ESCRIPT_DLL_API Data operator/(const boost::python::object& left, const Data& right);
1561
1562
1563
1564 /**
1565 \brief
1566 Output operator
1567 */
1568 ESCRIPT_DLL_API std::ostream& operator<<(std::ostream& o, const Data& data);
1569
1570 /**
1571 \brief
1572 Compute a tensor product of two Data objects
1573 \param arg0 - Input - Data object
1574 \param arg1 - Input - Data object
1575 \param axis_offset - Input - axis offset
1576 \param transpose - Input - 0: transpose neither, 1: transpose arg0, 2: transpose arg1
1577 */
1578 ESCRIPT_DLL_API
1579 Data
1580 C_GeneralTensorProduct(Data& arg0,
1581 Data& arg1,
1582 int axis_offset=0,
1583 int transpose=0);
1584
1585
1586
1587 // /**
1588 /* \brief
1589 Return true if operands are equivalent, else return false.
1590 NB: this operator does very little at this point, and isn't to
1591 be relied on. Requires further implementation.*/
1592 //*/
1593 // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);
1594
1595 /**
1596 \brief
1597 Perform the given binary operation with this and right as operands.
1598 Right is a Data object.
1599 */
1600 template <class BinaryFunction>
1601 inline
1602 void
1603 Data::binaryOp(const Data& right,
1604 BinaryFunction operation)
1605 {
1606 //
1607 // if this has a rank of zero promote it to the rank of the RHS
1608 if (getDataPointRank()==0 && right.getDataPointRank()!=0) {
1609 throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");
1610 }
1611 //
1612 // initially make the temporary a shallow copy
1613 Data tempRight(right);
1614 if (getFunctionSpace()!=right.getFunctionSpace()) {
1615 if (right.probeInterpolation(getFunctionSpace())) {
1616 //
1617 // an interpolation is required so create a new Data
1618 tempRight=Data(right,this->getFunctionSpace());
1619 } else if (probeInterpolation(right.getFunctionSpace())) {
1620 //
1621 // interpolate onto the RHS function space
1622 Data tempLeft(*this,right.getFunctionSpace());
1623 m_data=tempLeft.m_data;
1624 }
1625 }
1626 operandCheck(tempRight);
1627 //
1628 // ensure this has the right type for the RHS
1629 typeMatchRight(tempRight);
1630 //
1631 // Need to cast to the concrete types so that the correct binaryOp
1632 // is called.
1633 if (isExpanded()) {
1634 //
1635 // Expanded data will be done in parallel, the right hand side can be
1636 // of any data type
1637 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1638 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1639 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1640 } else if (isTagged()) {
1641 //
1642 // Tagged data is operated on serially, the right hand side can be
1643 // either DataConstant or DataTagged
1644 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1645 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1646 if (right.isTagged()) {
1647 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1648 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1649 escript::binaryOp(*leftC,*rightC,operation);
1650 } else {
1651 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1652 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1653 escript::binaryOp(*leftC,*rightC,operation);
1654 }
1655 } else if (isConstant()) {
1656 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1657 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1658 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1659 escript::binaryOp(*leftC,*rightC,operation);
1660 }
1661 }
1662
1663 /**
1664 \brief
1665 Perform the given Data object reduction algorithm on this and return the result.
1666 Given operation combines each element of each data point, thus argument
1667 object (*this) is a rank n Data object, and returned object is a scalar.
1668 Calls escript::algorithm.
1669 */
1670 template <class BinaryFunction>
1671 inline
1672 double
1673 Data::algorithm(BinaryFunction operation, double initial_value) const
1674 {
1675 if (isExpanded()) {
1676 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1677 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1678 return escript::algorithm(*leftC,operation,initial_value);
1679 } else if (isTagged()) {
1680 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1681 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1682 return escript::algorithm(*leftC,operation,initial_value);
1683 } else if (isConstant()) {
1684 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1685 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1686 return escript::algorithm(*leftC,operation,initial_value);
1687 }
1688 return 0;
1689 }
1690
1691 /**
1692 \brief
1693 Perform the given data point reduction algorithm on data and return the result.
1694 Given operation combines each element within each data point into a scalar,
1695 thus argument object is a rank n Data object, and returned object is a
1696 rank 0 Data object.
1697 Calls escript::dp_algorithm.
1698 */
1699 template <class BinaryFunction>
1700 inline
1701 Data
1702 Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1703 {
1704 if (isExpanded()) {
1705 Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1706 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1707 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1708 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1709 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1710 escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1711 return result;
1712 } else if (isTagged()) {
1713 DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1714 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1715
1716 // DataTypes::ShapeType viewShape;
1717 // DataTypes::ValueType viewData(1);
1718 // viewData[0]=0;
1719 // DataArrayView defaultValue(viewData,viewShape);
1720 // DataTagged::TagListType keys;
1721 // DataTagged::ValueListType values;
1722 // DataTagged::DataMapType::const_iterator i;
1723 // for (i=dataT->getTagLookup().begin();i!=dataT->getTagLookup().end();i++) {
1724 // keys.push_back(i->first);
1725 // values.push_back(defaultValue);
1726 // }
1727 // Data result(keys,values,defaultValue,getFunctionSpace());
1728 // DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1729 // EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1730
1731
1732
1733
1734 DataTypes::ValueType defval(1);
1735 defval[0]=0;
1736 DataTagged* resultT=new DataTagged(getFunctionSpace(), DataTypes::scalarShape, defval, dataT);
1737 escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1738 return Data(resultT); // note: the Data object now owns the resultT pointer
1739
1740 } else if (isConstant()) {
1741 Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1742 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1743 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1744 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1745 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1746 escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1747 return result;
1748 }
1749 Data falseRetVal; // to keep compiler quiet
1750 return falseRetVal;
1751 }
1752
1753 /**
1754 \brief
1755 Compute a tensor operation with two Data objects
1756 \param arg0 - Input - Data object
1757 \param arg1 - Input - Data object
1758 \param operation - Input - Binary op functor
1759 */
1760 template <typename BinaryFunction>
1761 inline
1762 Data
1763 C_TensorBinaryOperation(Data const &arg_0,
1764 Data const &arg_1,
1765 BinaryFunction operation)
1766 {
1767 // Interpolate if necessary and find an appropriate function space
1768 Data arg_0_Z, arg_1_Z;
1769 if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {
1770 if (arg_0.probeInterpolation(arg_1.getFunctionSpace())) {
1771 arg_0_Z = arg_0.interpolate(arg_1.getFunctionSpace());
1772 arg_1_Z = Data(arg_1);
1773 }
1774 else if (arg_1.probeInterpolation(arg_0.getFunctionSpace())) {
1775 arg_1_Z=arg_1.interpolate(arg_0.getFunctionSpace());
1776 arg_0_Z =Data(arg_0);
1777 }
1778 else {
1779 throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible function spaces.");
1780 }
1781 } else {
1782 arg_0_Z = Data(arg_0);
1783 arg_1_Z = Data(arg_1);
1784 }
1785 // Get rank and shape of inputs
1786 int rank0 = arg_0_Z.getDataPointRank();
1787 int rank1 = arg_1_Z.getDataPointRank();
1788 DataTypes::ShapeType shape0 = arg_0_Z.getDataPointShape();
1789 DataTypes::ShapeType shape1 = arg_1_Z.getDataPointShape();
1790 int size0 = arg_0_Z.getDataPointSize();
1791 int size1 = arg_1_Z.getDataPointSize();
1792
1793 // Declare output Data object
1794 Data res;
1795
1796 if (shape0 == shape1) {
1797
1798 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
1799 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataConstant output
1800 /* double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1801 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1802 double *ptr_2 = &((res.getPointDataView().getData())[0]);*/
1803 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
1804 double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
1805 double *ptr_2 = &(res.getDataAtOffset(0));
1806
1807 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1808 }
1809 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
1810
1811 // Prepare the DataConstant input
1812 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1813
1814 // Borrow DataTagged input from Data object
1815 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1816
1817 // Prepare a DataTagged output 2
1818 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataTagged output
1819 res.tag();
1820 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1821
1822 // Prepare offset into DataConstant
1823 int offset_0 = tmp_0->getPointOffset(0,0);
1824 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1825 // Get the views
1826 // DataArrayView view_1 = tmp_1->getDefaultValue();
1827 // DataArrayView view_2 = tmp_2->getDefaultValue();
1828 // // Get the pointers to the actual data
1829 // double *ptr_1 = &((view_1.getData())[0]);
1830 // double *ptr_2 = &((view_2.getData())[0]);
1831
1832 // Get the pointers to the actual data
1833 double *ptr_1 = &(tmp_1->getDefaultValue(0));
1834 double *ptr_2 = &(tmp_2->getDefaultValue(0));
1835
1836 // Compute a result for the default
1837 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1838 // Compute a result for each tag
1839 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1840 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1841 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1842 tmp_2->addTag(i->first);
1843 /* DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1844 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1845 double *ptr_1 = &view_1.getData(0);
1846 double *ptr_2 = &view_2.getData(0);*/
1847 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1848 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1849
1850 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1851 }
1852
1853 }
1854 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
1855
1856 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1857 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1858 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1859 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1860
1861 int sampleNo_1,dataPointNo_1;
1862 int numSamples_1 = arg_1_Z.getNumSamples();
1863 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
1864 int offset_0 = tmp_0->getPointOffset(0,0);
1865 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
1866 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
1867 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1868 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1869 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1870 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1871 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1872 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1873
1874 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1875 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1876 double *ptr_2 = &(res.getDataAtOffset(offset_2));
1877 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1878 }
1879 }
1880
1881 }
1882 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
1883
1884 // Borrow DataTagged input from Data object
1885 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1886
1887 // Prepare the DataConstant input
1888 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
1889
1890 // Prepare a DataTagged output 2
1891 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
1892 res.tag();
1893 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1894
1895 // Prepare offset into DataConstant
1896 int offset_1 = tmp_1->getPointOffset(0,0);
1897 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1898 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1899 // Get the views
1900 // DataArrayView view_0 = tmp_0->getDefaultValue();
1901 // DataArrayView view_2 = tmp_2->getDefaultValue();
1902 // // Get the pointers to the actual data
1903 // double *ptr_0 = &((view_0.getData())[0]);
1904 // double *ptr_2 = &((view_2.getData())[0]);
1905 // Get the pointers to the actual data
1906 double *ptr_0 = &(tmp_0->getDefaultValue(0));
1907 double *ptr_2 = &(tmp_2->getDefaultValue(0));
1908 // Compute a result for the default
1909 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1910 // Compute a result for each tag
1911 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1912 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1913 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1914 tmp_2->addTag(i->first);
1915 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1916 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1917 // double *ptr_0 = &view_0.getData(0);
1918 // double *ptr_2 = &view_2.getData(0);
1919 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1920 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1921 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1922 }
1923
1924 }
1925 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
1926
1927 // Borrow DataTagged input from Data object
1928 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1929
1930 // Borrow DataTagged input from Data object
1931 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1932
1933 // Prepare a DataTagged output 2
1934 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
1935 res.tag(); // DataTagged output
1936 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1937
1938 // // Get the views
1939 // DataArrayView view_0 = tmp_0->getDefaultValue();
1940 // DataArrayView view_1 = tmp_1->getDefaultValue();
1941 // DataArrayView view_2 = tmp_2->getDefaultValue();
1942 // // Get the pointers to the actual data
1943 // double *ptr_0 = &((view_0.getData())[0]);
1944 // double *ptr_1 = &((view_1.getData())[0]);
1945 // double *ptr_2 = &((view_2.getData())[0]);
1946
1947 // Get the pointers to the actual data
1948 double *ptr_0 = &(tmp_0->getDefaultValue(0));
1949 double *ptr_1 = &(tmp_1->getDefaultValue(0));
1950 double *ptr_2 = &(tmp_2->getDefaultValue(0));
1951
1952 // Compute a result for the default
1953 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1954 // Merge the tags
1955 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1956 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1957 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1958 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1959 tmp_2->addTag(i->first); // use tmp_2 to get correct shape
1960 }
1961 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1962 tmp_2->addTag(i->first);
1963 }
1964 // Compute a result for each tag
1965 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1966 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1967
1968 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1969 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1970 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1971 // double *ptr_0 = &view_0.getData(0);
1972 // double *ptr_1 = &view_1.getData(0);
1973 // double *ptr_2 = &view_2.getData(0);
1974
1975 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1976 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1977 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1978
1979 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1980 }
1981
1982 }
1983 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
1984
1985 // After finding a common function space above the two inputs have the same numSamples and num DPPS
1986 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1987 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1988 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1989 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1990
1991 int sampleNo_0,dataPointNo_0;
1992 int numSamples_0 = arg_0_Z.getNumSamples();
1993 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1994 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1995 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1996 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
1997 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1998 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1999 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2000 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2001
2002 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2003 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2004 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2005 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2006
2007
2008 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2009 }
2010 }
2011
2012 }
2013 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2014
2015 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2016 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2017 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2018 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2019
2020 int sampleNo_0,dataPointNo_0;
2021 int numSamples_0 = arg_0_Z.getNumSamples();
2022 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2023 int offset_1 = tmp_1->getPointOffset(0,0);
2024 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2025 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2026 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2027 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2028 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2029
2030 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2031 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2032 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2033
2034 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2035 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2036 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2037
2038
2039 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2040 }
2041 }
2042
2043 }
2044 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2045
2046 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2047 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2048 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2049 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2050 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2051
2052 int sampleNo_0,dataPointNo_0;
2053 int numSamples_0 = arg_0_Z.getNumSamples();
2054 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2055 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2056 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2057 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2058 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2059 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2060 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2061 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2062 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2063 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2064 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2065 }
2066 }
2067
2068 }
2069 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2070
2071 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2072 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2073 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2074 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2075 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2076
2077 int sampleNo_0,dataPointNo_0;
2078 int numSamples_0 = arg_0_Z.getNumSamples();
2079 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2080 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2081 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2082 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2083 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2084 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2085 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2086 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2087 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2088 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2089 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2090 }
2091 }
2092
2093 }
2094 else {
2095 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2096 }
2097
2098 } else if (0 == rank0) {
2099
2100 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
2101 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace()); // DataConstant output
2102 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2103 double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2104 double *ptr_2 = &(res.getDataAtOffset(0));
2105 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2106 }
2107 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
2108
2109 // Prepare the DataConstant input
2110 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2111
2112 // Borrow DataTagged input from Data object
2113 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2114
2115 // Prepare a DataTagged output 2
2116 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace()); // DataTagged output
2117 res.tag();
2118 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2119
2120 // Prepare offset into DataConstant
2121 int offset_0 = tmp_0->getPointOffset(0,0);
2122 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2123 // Get the views
2124 // DataArrayView view_1 = tmp_1->getDefaultValue();
2125 // DataArrayView view_2 = tmp_2->getDefaultValue();
2126 // // Get the pointers to the actual data
2127 // double *ptr_1 = &((view_1.getData())[0]);
2128 // double *ptr_2 = &((view_2.getData())[0]);
2129 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2130 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2131
2132 // Compute a result for the default
2133 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2134 // Compute a result for each tag
2135 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2136 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2137 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2138 tmp_2->addTag(i->first);
2139 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2140 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2141 // double *ptr_1 = &view_1.getData(0);
2142 // double *ptr_2 = &view_2.getData(0);
2143 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2144 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2145 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2146 }
2147
2148 }
2149 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
2150
2151 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2152 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2153 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2154 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2155
2156 int sampleNo_1,dataPointNo_1;
2157 int numSamples_1 = arg_1_Z.getNumSamples();
2158 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2159 int offset_0 = tmp_0->getPointOffset(0,0);
2160 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2161 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2162 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2163 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2164 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2165 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2166 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2167 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2168 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2169
2170 }
2171 }
2172
2173 }
2174 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
2175
2176 // Borrow DataTagged input from Data object
2177 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2178
2179 // Prepare the DataConstant input
2180 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2181
2182 // Prepare a DataTagged output 2
2183 res = Data(0.0, shape1, arg_0_Z.getFunctionSpace()); // DataTagged output
2184 res.tag();
2185 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2186
2187 // Prepare offset into DataConstant
2188 int offset_1 = tmp_1->getPointOffset(0,0);
2189 // double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2190 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2191 // Get the views
2192 /* DataArrayView view_0 = tmp_0->getDefaultValue();
2193 DataArrayView view_2 = tmp_2->getDefaultValue();
2194 // Get the pointers to the actual data
2195 double *ptr_0 = &((view_0.getData())[0]);
2196 double *ptr_2 = &((view_2.getData())[0]);*/
2197
2198 // Get the pointers to the actual data
2199 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2200 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2201
2202
2203 // Compute a result for the default
2204 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2205 // Compute a result for each tag
2206 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2207 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2208 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2209 tmp_2->addTag(i->first);
2210 /* DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2211 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2212 double *ptr_0 = &view_0.getData(0);
2213 double *ptr_2 = &view_2.getData(0);*/
2214 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2215 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2216
2217 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2218 }
2219
2220 }
2221 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
2222
2223 // Borrow DataTagged input from Data object
2224 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2225
2226 // Borrow DataTagged input from Data object
2227 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2228
2229 // Prepare a DataTagged output 2
2230 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());
2231 res.tag(); // DataTagged output
2232 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2233
2234 // Get the views
2235 /* DataArrayView view_0 = tmp_0->getDefaultValue();
2236 DataArrayView view_1 = tmp_1->getDefaultValue();
2237 DataArrayView view_2 = tmp_2->getDefaultValue();
2238 // Get the pointers to the actual data
2239 double *ptr_0 = &((view_0.getData())[0]);
2240 double *ptr_1 = &((view_1.getData())[0]);
2241 double *ptr_2 = &((view_2.getData())[0]);*/
2242
2243 // Get the pointers to the actual data
2244 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2245 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2246 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2247
2248
2249 // Compute a result for the default
2250 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2251 // Merge the tags
2252 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2253 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2254 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2255 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2256 tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2257 }
2258 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2259 tmp_2->addTag(i->first);
2260 }
2261 // Compute a result for each tag
2262 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2263 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2264
2265 /* DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2266 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2267 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2268 double *ptr_0 = &view_0.getData(0);
2269 double *ptr_1 = &view_1.getData(0);
2270 double *ptr_2 = &view_2.getData(0);*/
2271
2272 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2273 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2274 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2275
2276 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2277 }
2278
2279 }
2280 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
2281
2282 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2283 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2284 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2285 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2286 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2287
2288 int sampleNo_0,dataPointNo_0;
2289 int numSamples_0 = arg_0_Z.getNumSamples();
2290 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2291 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2292 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2293 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2294 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2295 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2296 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2297 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2298 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2299 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2300 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2301 }
2302 }
2303
2304 }
2305 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2306
2307 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2308 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2309 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2310 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2311
2312 int sampleNo_0,dataPointNo_0;
2313 int numSamples_0 = arg_0_Z.getNumSamples();
2314 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2315 int offset_1 = tmp_1->getPointOffset(0,0);
2316 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2317 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2318 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2319 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2320 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2321 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2322 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2323 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2324 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2325 }
2326 }
2327
2328
2329 }
2330 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2331
2332 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2333 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2334 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2335 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2336 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2337
2338 int sampleNo_0,dataPointNo_0;
2339 int numSamples_0 = arg_0_Z.getNumSamples();
2340 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2341 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2342 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2343 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2344 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2345 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2346 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2347 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2348 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2349 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2350 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2351 }
2352 }
2353
2354 }
2355 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2356
2357 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2358 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2359 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2360 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2361 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2362
2363 int sampleNo_0,dataPointNo_0;
2364 int numSamples_0 = arg_0_Z.getNumSamples();
2365 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2366 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2367 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2368 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2369 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2370 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2371 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2372 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2373 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2374 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2375 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2376 }
2377 }
2378
2379 }
2380 else {
2381 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2382 }
2383
2384 } else if (0 == rank1) {
2385
2386 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
2387 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataConstant output
2388 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2389 double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2390 double *ptr_2 = &(res.getDataAtOffset(0));
2391 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2392 }
2393 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
2394
2395 // Prepare the DataConstant input
2396 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2397
2398 // Borrow DataTagged input from Data object
2399 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2400
2401 // Prepare a DataTagged output 2
2402 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataTagged output
2403 res.tag();
2404 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2405
2406 // Prepare offset into DataConstant
2407 int offset_0 = tmp_0->getPointOffset(0,0);
2408 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2409 // Get the views
2410 /* DataArrayView view_1 = tmp_1->getDefaultValue();
2411 DataArrayView view_2 = tmp_2->getDefaultValue();
2412 // Get the pointers to the actual data
2413 double *ptr_1 = &((view_1.getData())[0]);
2414 double *ptr_2 = &((view_2.getData())[0]);*/
2415 //Get the pointers to the actual data
2416 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2417 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2418
2419 // Compute a result for the default
2420 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2421 // Compute a result for each tag
2422 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2423 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2424 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2425 tmp_2->addTag(i->first);
2426 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2427 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2428 // double *ptr_1 = &view_1.getData(0);
2429 // double *ptr_2 = &view_2.getData(0);
2430 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2431 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2432
2433
2434 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2435 }
2436
2437 }
2438 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
2439
2440 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2441 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2442 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2443 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2444
2445 int sampleNo_1,dataPointNo_1;
2446 int numSamples_1 = arg_1_Z.getNumSamples();
2447 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2448 int offset_0 = tmp_0->getPointOffset(0,0);
2449 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2450 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2451 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2452 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2453 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2454 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2455 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2456 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2457 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2458 }
2459 }
2460
2461 }
2462 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
2463
2464 // Borrow DataTagged input from Data object
2465 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2466
2467 // Prepare the DataConstant input
2468 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2469
2470 // Prepare a DataTagged output 2
2471 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
2472 res.tag();
2473 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2474
2475 // Prepare offset into DataConstant
2476 int offset_1 = tmp_1->getPointOffset(0,0);
2477 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2478 // Get the views
2479 // DataArrayView view_0 = tmp_0->getDefaultValue();
2480 // DataArrayView view_2 = tmp_2->getDefaultValue();
2481 // // Get the pointers to the actual data
2482 // double *ptr_0 = &((view_0.getData())[0]);
2483 // double *ptr_2 = &((view_2.getData())[0]);
2484 // Get the pointers to the actual data
2485 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2486 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2487 // Compute a result for the default
2488 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2489 // Compute a result for each tag
2490 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2491 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2492 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2493 tmp_2->addTag(i->first);
2494 /* DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2495 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2496 double *ptr_0 = &view_0.getData(0);
2497 double *ptr_2 = &view_2.getData(0);*/
2498 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2499 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2500 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2501 }
2502
2503 }
2504 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
2505
2506 // Borrow DataTagged input from Data object
2507 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2508
2509 // Borrow DataTagged input from Data object
2510 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2511
2512 // Prepare a DataTagged output 2
2513 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
2514 res.tag(); // DataTagged output
2515 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2516
2517 // Get the views
2518 // DataArrayView view_0 = tmp_0->getDefaultValue();
2519 // DataArrayView view_1 = tmp_1->getDefaultValue();
2520 // DataArrayView view_2 = tmp_2->getDefaultValue();
2521 // // Get the pointers to the actual data
2522 // double *ptr_0 = &((view_0.getData())[0]);
2523 // double *ptr_1 = &((view_1.getData())[0]);
2524 // double *ptr_2 = &((view_2.getData())[0]);
2525
2526 // Get the pointers to the actual data
2527 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2528 double *ptr_1 = &(tmp_1->getDefaultValue(0));
2529 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2530
2531 // Compute a result for the default
2532 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2533 // Merge the tags
2534 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2535 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2536 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2537 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2538 tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2539 }
2540 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2541 tmp_2->addTag(i->first);
2542 }
2543 // Compute a result for each tag
2544 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2545 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2546 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2547 // DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2548 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2549 // double *ptr_0 = &view_0.getData(0);
2550 // double *ptr_1 = &view_1.getData(0);
2551 // double *ptr_2 = &view_2.getData(0);
2552
2553 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2554 double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2555 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2556 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2557 }
2558
2559 }
2560 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
2561
2562 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2563 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2564 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2565 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2566 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2567
2568 int sampleNo_0,dataPointNo_0;
2569 int numSamples_0 = arg_0_Z.getNumSamples();
2570 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2571 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2572 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2573 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2574 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2575 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2576 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2577 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2578 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2579 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2580 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2581 }
2582 }
2583
2584 }
2585 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2586
2587 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2588 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2589 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2590 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2591
2592 int sampleNo_0,dataPointNo_0;
2593 int numSamples_0 = arg_0_Z.getNumSamples();
2594 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2595 int offset_1 = tmp_1->getPointOffset(0,0);
2596 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2597 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2598 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2599 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2600 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2601 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2602 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2603 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2604 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2605 }
2606 }
2607
2608
2609 }
2610 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2611
2612 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2613 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2614 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2615 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2616 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2617
2618 int sampleNo_0,dataPointNo_0;
2619 int numSamples_0 = arg_0_Z.getNumSamples();
2620 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2621 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2622 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2623 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2624 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2625 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2626 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2627 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2628 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2629 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2630 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2631 }
2632 }
2633
2634 }
2635 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2636
2637 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2638 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2639 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2640 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2641 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2642
2643 int sampleNo_0,dataPointNo_0;
2644 int numSamples_0 = arg_0_Z.getNumSamples();
2645 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2646 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2647 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2648 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2649 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2650 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2651 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2652 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2653 double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2654 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2655 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2656 }
2657 }
2658
2659 }
2660 else {
2661 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2662 }
2663
2664 } else {
2665 throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible shapes");
2666 }
2667
2668 return res;
2669 }
2670
2671 template <typename UnaryFunction>
2672 Data
2673 C_TensorUnaryOperation(Data const &arg_0,
2674 UnaryFunction operation)
2675 {
2676 // Interpolate if necessary and find an appropriate function space
2677 Data arg_0_Z = Data(arg_0);
2678
2679 // Get rank and shape of inputs
2680 int rank0 = arg_0_Z.getDataPointRank();
2681 const DataTypes::ShapeType& shape0 = arg_0_Z.getDataPointShape();
2682 int size0 = arg_0_Z.getDataPointSize();
2683
2684 // Declare output Data object
2685 Data res;
2686
2687 if (arg_0_Z.isConstant()) {
2688 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataConstant output
2689 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2690 // double *ptr_2 = &((res.getPointDataView().getData())[0]);
2691 double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2692 double *ptr_2 = &(res.getDataAtOffset(0));
2693 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2694 }
2695 else if (arg_0_Z.isTagged()) {
2696
2697 // Borrow DataTagged input from Data object
2698 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2699
2700 // Prepare a DataTagged output 2
2701 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
2702 res.tag();
2703 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2704
2705 // // Get the views
2706 // DataArrayView view_0 = tmp_0->getDefaultValue();
2707 // DataArrayView view_2 = tmp_2->getDefaultValue();
2708 // // Get the pointers to the actual data
2709 // double *ptr_0 = &((view_0.getData())[0]);
2710 // double *ptr_2 = &((view_2.getData())[0]);
2711 // Get the pointers to the actual data
2712 double *ptr_0 = &(tmp_0->getDefaultValue(0));
2713 double *ptr_2 = &(tmp_2->getDefaultValue(0));
2714 // Compute a result for the default
2715 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2716 // Compute a result for each tag
2717 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2718 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2719 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2720 tmp_2->addTag(i->first);
2721 // DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2722 // DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2723 // double *ptr_0 = &view_0.getData(0);
2724 // double *ptr_2 = &view_2.getData(0);
2725 double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2726 double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2727 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2728 }
2729
2730 }
2731 else if (arg_0_Z.isExpanded()) {
2732
2733 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace(),true); // DataExpanded output
2734 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2735 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2736
2737 int sampleNo_0,dataPointNo_0;
2738 int numSamples_0 = arg_0_Z.getNumSamples();
2739 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2740 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2741 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2742 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2743 // int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2744 // int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2745 // double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2746 // double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2747 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2748 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2749 double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2750 double *ptr_2 = &(res.getDataAtOffset(offset_2));
2751 tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2752 }
2753 }
2754
2755 }
2756 else {
2757 throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");
2758 }
2759
2760 return res;
2761 }
2762
2763 }
2764 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26