/[escript]/trunk/escript/src/Data.h
ViewVC logotype

Contents of /trunk/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1946 - (show annotations)
Wed Oct 29 05:48:53 2008 UTC (10 years, 10 months ago) by jfenwick
File MIME type: text/plain
File size: 88619 byte(s)
A cleanup of some of the problems I found doing a Wall compile.

Removed some commented out lines.
Swapped some member initialisers.
Removed virtual qualifiers from some methods in FunctionSpace.
Fixed some unused or (possibly) uninitialised variables.


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26