/[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 126 - (show annotations)
Fri Jul 22 03:53:08 2005 UTC (14 years, 3 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 36330 byte(s)
Merge of development branch back to main trunk on 2005-07-22

1 // $Id$
2 /*
3 ******************************************************************************
4 * *
5 * COPYRIGHT ACcESS 2004 - All Rights Reserved *
6 * *
7 * This software is the property of ACcESS. No part of this code *
8 * may be copied in any form or by any means without the expressed written *
9 * consent of ACcESS. Copying, use or modification of this software *
10 * by any unauthorised person is illegal unless that *
11 * person has a software license agreement with ACcESS. *
12 * *
13 ******************************************************************************
14 */
15
16 /** \file Data.h */
17
18 #ifndef DATA_H
19 #define DATA_H
20
21 #include "escript/Data/DataAbstract.h"
22 #include "escript/Data/DataTagged.h"
23 #include "escript/Data/DataAlgorithm.h"
24 #include "escript/Data/FunctionSpace.h"
25 #include "escript/Data/BinaryOp.h"
26 #include "escript/Data/UnaryOp.h"
27 #include "escript/Data/DataException.h"
28
29 extern "C" {
30 #include "escript/Data/DataC.h"
31 }
32
33 #include <iostream>
34 #include <string>
35 #include <memory>
36 #include <algorithm>
37
38 #include <boost/shared_ptr.hpp>
39 #include <boost/python/object.hpp>
40 #include <boost/python/list.hpp>
41 #include <boost/python/tuple.hpp>
42 #include <boost/python/numeric.hpp>
43
44 namespace escript {
45
46 //
47 // Forward declaration for various implimentations of Data.
48 class DataEmpty;
49 class DataConstant;
50 class DataTagged;
51 class DataExpanded;
52
53 /**
54 \brief
55 Data creates the appropriate Data object for the given construction
56 arguments.
57
58 Description:
59 Data is essentially a factory class which creates the appropriate Data
60 object for the given construction arguments. It retains control over
61 the object created for the lifetime of the object.
62 The type of Data object referred to may change during the lifetime of
63 the Data object.
64 */
65 class Data {
66
67 public:
68
69 // These typedefs allow function names to be cast to pointers
70 // to functions of the appropriate type when calling unaryOp etc.
71 typedef double (*UnaryDFunPtr)(double);
72 typedef double (*BinaryDFunPtr)(double,double);
73
74 /**
75 Constructors.
76 */
77
78 /**
79 \brief
80 Default constructor.
81 Creates a DataEmpty object.
82 */
83 Data();
84
85 /**
86 \brief
87 Copy constructor.
88 WARNING: Only performs a shallow copy.
89 */
90 Data(const Data& inData);
91
92 /**
93 \brief
94 Constructor from another Data object. If "what" is different from the
95 function space of inData the inData are tried to be interpolated to what,
96 otherwise a shallow copy of inData is returned.
97 */
98 Data(const Data& inData,
99 const FunctionSpace& what);
100
101 /**
102 \brief
103 Constructor which copies data from a DataArrayView.
104
105 \param value - Input - Data value for a single point.
106 \param what - Input - A description of what this data represents.
107 \param expanded - Input - Flag, if true fill the entire container with
108 the value. Otherwise a more efficient storage
109 mechanism will be used.
110 */
111 Data(const DataArrayView& value,
112 const FunctionSpace& what=FunctionSpace(),
113 bool expanded=false);
114
115 /**
116 \brief
117 Constructor which creates a Data from a DataArrayView shape.
118
119 \param value - Input - Single value applied to all Data.
120 \param dataPointShape - Input - The shape of each data point.
121 \param what - Input - A description of what this data represents.
122 \param expanded - Input - Flag, if true fill the entire container with
123 the given value. Otherwise a more efficient storage
124 mechanism will be used.
125 */
126 Data(double value,
127 const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),
128 const FunctionSpace& what=FunctionSpace(),
129 bool expanded=false);
130
131 /**
132 \brief
133 Constructor which performs a deep copy of a region from another Data object.
134
135 \param inData - Input - Input Data object.
136 \param region - Input - Region to copy.
137 */
138 Data(const Data& inData,
139 const DataArrayView::RegionType& region);
140
141 /**
142 \brief
143 Constructor which will create Tagged data if expanded is false.
144 No attempt is made to ensure the tag keys match the tag keys
145 within the function space.
146
147 \param tagKeys - Input - List of tag values.
148 \param values - Input - List of values, one for each tag.
149 \param defaultValue - Input - A default value, used if tag doesn't exist.
150 \param what - Input - A description of what this data represents.
151 \param expanded - Input - Flag, if true fill the entire container with
152 the appropriate values.
153 */
154 Data(const DataTagged::TagListType& tagKeys,
155 const DataTagged::ValueListType& values,
156 const DataArrayView& defaultValue,
157 const FunctionSpace& what=FunctionSpace(),
158 bool expanded=false);
159
160 /**
161 \brief
162 Constructor which copies data from a python numarray.
163
164 \param value - Input - Data value for a single point.
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 Data(const boost::python::numeric::array& value,
171 const FunctionSpace& what=FunctionSpace(),
172 bool expanded=false);
173
174 /**
175 \brief
176 Constructor which copies data from any object that can be converted into
177 a python numarray.
178
179 \param value - Input - Input data.
180 \param what - Input - A description of what this data represents.
181 \param expanded - Input - Flag, if true fill the entire container with
182 the value. Otherwise a more efficient storage
183 mechanism will be used.
184 */
185 Data(const boost::python::object& value,
186 const FunctionSpace& what=FunctionSpace(),
187 bool expanded=false);
188
189 /**
190 \brief
191 Constructor which creates a DataConstant.
192 Copies data from any object that can be converted
193 into a numarray. All other parameters are copied from other.
194
195 \param value - Input - Input data.
196 \param other - Input - contains all other parameters.
197 */
198 Data(const boost::python::object& value,
199 const Data& other);
200
201 /**
202 \brief
203 Constructor which creates a DataConstant of "shape" with constant value.
204 */
205 Data(double value,
206 const boost::python::tuple& shape=boost::python::make_tuple(),
207 const FunctionSpace& what=FunctionSpace(),
208 bool expanded=false);
209
210 /**
211 \brief
212 Perform a deep copy.
213 */
214 void
215 copy(const Data& other);
216
217 /**
218 Member access methods.
219 */
220
221 /**
222 \brief
223 Return the values of all data-points as a single python numarray object.
224 */
225 const boost::python::numeric::array
226 convertToNumArray();
227
228 /**
229 \brief fills the expanded Data object from values of a python numarray object.
230
231 */
232 void
233 fillFromNumArray(const boost::python::numeric::array);
234 /**
235 \brief
236 Return the values of all data-points for the given sample as a single python numarray object.
237 */
238 const boost::python::numeric::array
239 convertToNumArrayFromSampleNo(int sampleNo);
240
241 /**
242 \brief
243 Return the value of the specified data-point as a single python numarray object.
244 */
245 const boost::python::numeric::array
246 convertToNumArrayFromDPNo(int sampleNo,
247 int dataPointNo);
248
249 /**
250 \brief
251 Return the C wrapper for the Data object.
252 */
253 escriptDataC
254 getDataC();
255
256 /**
257 \brief
258 Return the C wrapper for the Data object - const version.
259 */
260 escriptDataC
261 getDataC() const;
262
263 /**
264 \brief
265 Write the data as a string.
266 */
267 inline
268 std::string
269 toString() const
270 {
271 return m_data->toString();
272 }
273
274 /**
275 \brief
276 Return the DataArrayView of the point data. This essentially contains
277 the shape information for each data point although it also may be used
278 to manipulate the point data.
279 */
280 inline
281 const DataArrayView&
282 getPointDataView() const
283 {
284 return m_data->getPointDataView();
285 }
286
287 /**
288 \brief
289 Whatever the current Data type make this into a DataExpanded.
290 */
291 void
292 expand();
293
294 /**
295 \brief
296 If possible convert this Data to DataTagged. This will only allow
297 Constant data to be converted to tagged. An attempt to convert
298 Expanded data to tagged will throw an exception.
299 */
300 void
301 tag();
302
303 /**
304 \brief
305 Return true if this Data is expanded.
306 */
307 bool
308 isExpanded() const;
309
310 /**
311 \brief
312 Return true if this Data is tagged.
313 */
314 bool
315 isTagged() const;
316
317 /**
318 \brief
319 Return true if this Data is constant.
320 */
321 bool
322 isConstant() const;
323
324 /**
325 \brief
326 Return true if this Data is empty.
327 */
328 bool
329 isEmpty() const;
330
331 /**
332 \brief
333 Return the function space.
334 */
335 inline
336 const FunctionSpace&
337 getFunctionSpace() const
338 {
339 return m_data->getFunctionSpace();
340 }
341
342 /**
343 \brief
344 Return a copy of the function space.
345 */
346 const FunctionSpace
347 getCopyOfFunctionSpace() const;
348
349 /**
350 \brief
351 Return the domain.
352 */
353 inline
354 const AbstractDomain&
355 getDomain() const
356 {
357 return getFunctionSpace().getDomain();
358 }
359
360 /**
361 \brief
362 Return a copy of the domain.
363 */
364 const AbstractDomain
365 getCopyOfDomain() const;
366
367 /**
368 \brief
369 Return the rank of the point data.
370 */
371 inline
372 int
373 getDataPointRank() const
374 {
375 return m_data->getPointDataView().getRank();
376 }
377
378 /**
379 \brief
380 Return the number of samples.
381 */
382 inline
383 int
384 getNumSamples() const
385 {
386 return m_data->getNumSamples();
387 }
388
389 /**
390 \brief
391 Return the number of data points per sample.
392 */
393 inline
394 int
395 getNumDataPointsPerSample() const
396 {
397 return m_data->getNumDPPSample();
398 }
399
400 /**
401 \brief
402 Return the sample data for the given sample no. This is not the
403 preferred interface but is provided for use by C code.
404 \param sampleNo - Input - the given sample no.
405 */
406 inline
407 DataAbstract::ValueType::value_type*
408 getSampleData(DataAbstract::ValueType::size_type sampleNo)
409 {
410 return m_data->getSampleData(sampleNo);
411 }
412
413 /**
414 \brief
415 Return the sample data for the given tag. If an attempt is made to
416 access data that isn't tagged an exception will be thrown.
417 \param tag - Input - the tag key.
418 */
419 inline
420 DataAbstract::ValueType::value_type*
421 getSampleDataByTag(int tag)
422 {
423 return m_data->getSampleDataByTag(tag);
424 }
425
426 /**
427 \brief
428 Assign the given value to the data-points referenced by the given
429 reference number.
430
431 The value supplied is a python numarray object. The data from this numarray
432 is unpacked into a DataArray, and this is used to set the corresponding
433 data-points in the underlying Data object.
434
435 If the underlying Data object cannot be accessed via reference numbers, an
436 exception will be thrown.
437
438 \param ref - Input - reference number.
439 \param value - Input - value to assign to data-points associated with
440 the given reference number.
441 */
442 void
443 setRefValue(int ref,
444 const boost::python::numeric::array& value);
445
446 /**
447 \brief
448 Return the values associated with the data-points referenced by the given
449 reference number.
450
451 The value supplied is a python numarray object. The data from the corresponding
452 data-points in this Data object are packed into the given numarray object.
453
454 If the underlying Data object cannot be accessed via reference numbers, an
455 exception will be thrown.
456
457 \param ref - Input - reference number.
458 \param value - Output - object to receive values from data-points
459 associated with the given reference number.
460 */
461 void
462 getRefValue(int ref,
463 boost::python::numeric::array& value);
464
465 /**
466 \brief
467 Return a view into the data for the data point specified.
468 NOTE: Construction of the DataArrayView is a relatively expensive
469 operation.
470 \param sampleNo - Input -
471 \param dataPointNo - Input -
472 */
473 inline
474 DataArrayView
475 getDataPoint(int sampleNo,
476 int dataPointNo)
477 {
478 return m_data->getDataPoint(sampleNo,dataPointNo);
479 }
480
481 /**
482 \brief
483 Return a reference to the data point shape.
484 */
485 const DataArrayView::ShapeType&
486 getDataPointShape() const;
487
488 /**
489 \brief
490 Return the data point shape as a tuple of integers.
491 */
492 const boost::python::tuple
493 getShapeTuple() const;
494
495 /**
496 \brief
497 Return the size of the data point. It is the product of the
498 data point shape dimensions.
499 */
500 int
501 getDataPointSize() const;
502
503 /**
504 \brief
505 Return the number of doubles stored for this Data.
506 */
507 DataArrayView::ValueType::size_type
508 getLength() const;
509
510 /**
511 \brief
512 Assign the given value to the tag. Implicitly converts this
513 object to type DataTagged. Throws an exception if this object
514 cannot be converted to a DataTagged object.
515 \param tagKey - Input - Integer key.
516 \param value - Input - Value to associate with given key.
517 */
518 void
519 setTaggedValue(int tagKey,
520 const boost::python::object& value);
521
522 /**
523 \brief
524 Assign the given value to the tag. Implicitly converts this
525 object to type DataTagged. Throws an exception if this object
526 cannot be converted to a DataTagged object.
527 \param tagKey - Input - Integer key.
528 \param value - Input - Value to associate with given key.
529 */
530 void
531 setTaggedValueFromCPP(int tagKey,
532 const DataArrayView& value);
533
534 /**
535 \brief
536 Copy other Data object into this Data object where mask is positive.
537 */
538 void
539 copyWithMask(const Data& other,
540 const Data& mask);
541
542 /**
543 Data object operation methods and operators.
544 */
545
546 /**
547 \brief
548 Interpolates this onto the given functionspace and returns
549 the result as a Data object.
550 *
551 */
552 Data
553 interpolate(const FunctionSpace& functionspace) const;
554
555 /**
556 \brief
557 Calculates the gradient of the data at the data points of functionspace.
558 If functionspace is not present the function space of Function(getDomain()) is used.
559 *
560 */
561 Data
562 gradOn(const FunctionSpace& functionspace) const;
563
564 Data
565 grad() const;
566
567 /**
568 \brief
569 Calculate the integral over the function space domain.
570 *
571 */
572 boost::python::numeric::array
573 integrate() const;
574
575 /**
576 \brief
577 Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
578 *
579 */
580 Data
581 wherePositive() const;
582
583 /**
584 \brief
585 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
586 *
587 */
588 Data
589 whereNegative() const;
590
591 /**
592 \brief
593 Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
594 *
595 */
596 Data
597 whereNonNegative() const;
598
599 /**
600 \brief
601 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
602 *
603 */
604 Data
605 whereNonPositive() const;
606
607 /**
608 \brief
609 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
610 *
611 */
612 Data
613 whereZero() const;
614
615 /**
616 \brief
617 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
618 *
619 */
620 Data
621 whereNonZero() const;
622
623 /**
624 \brief
625 Return the maximum absolute value of this Data object.
626 *
627 */
628 double
629 Lsup() const;
630
631 /**
632 \brief
633 Return the minimum absolute value of this Data object.
634 *
635 */
636 double
637 Linf() const;
638
639 /**
640 \brief
641 Return the maximum value of this Data object.
642 *
643 */
644 double
645 sup() const;
646
647 /**
648 \brief
649 Return the minimum value of this Data object.
650 *
651 */
652 double
653 inf() const;
654
655 /**
656 \brief
657 Return the absolute value of each data point of this Data object.
658 *
659 */
660 Data
661 abs() const;
662
663 /**
664 \brief
665 Return the maximum value of each data point of this Data object.
666 *
667 */
668 Data
669 maxval() const;
670
671 /**
672 \brief
673 Return the minimum value of each data point of this Data object.
674 *
675 */
676 Data
677 minval() const;
678
679 /**
680 \brief
681 Return the (sample number, data-point number) of the data point with
682 the minimum value in this Data object.
683 */
684 const boost::python::tuple
685 mindp() const;
686
687 /**
688 \brief
689 Return the length of each data point of this Data object.
690 sqrt(sum(A[i,j,k,l]^2))
691 *
692 */
693 Data
694 length() const;
695
696 /**
697 \brief
698 Return the sign of each data point of this Data object.
699 -1 for negative values, zero for zero values, 1 for positive values.
700 *
701 */
702 Data
703 sign() const;
704
705 /**
706 \brief
707 Transpose each data point of this Data object around the given axis.
708 --* not implemented yet *--
709 *
710 */
711 Data
712 transpose(int axis) const;
713
714 /**
715 \brief
716 Calculate the trace of each data point of this Data object.
717 sum(A[i,i,i,i])
718 *
719 */
720 Data
721 trace() const;
722
723 /**
724 \brief
725 Return the sin of each data point of this Data object.
726 *
727 */
728 Data
729 sin() const;
730
731 /**
732 \brief
733 Return the cos of each data point of this Data object.
734 *
735 */
736 Data
737 cos() const;
738
739 /**
740 \brief
741 Return the tan of each data point of this Data object.
742 *
743 */
744 Data
745 tan() const;
746
747 /**
748 \brief
749 Return the log to base 10 of each data point of this Data object.
750 *
751 */
752 Data
753 log() const;
754
755 /**
756 \brief
757 Return the natural log of each data point of this Data object.
758 *
759 */
760 Data
761 ln() const;
762
763 /**
764 \brief
765 Return the exponential function of each data point of this Data object.
766 *
767 */
768 Data
769 exp() const;
770
771 /**
772 \brief
773 Return the square root of each data point of this Data object.
774 *
775 */
776 Data
777 sqrt() const;
778
779 /**
780 \brief
781 Return the negation of each data point of this Data object.
782 *
783 */
784 Data
785 neg() const;
786
787 /**
788 \brief
789 Return the identity of each data point of this Data object.
790 Simply returns this object unmodified.
791 *
792 */
793 Data
794 pos() const;
795
796 /**
797 \brief
798 Return the given power of each data point of this Data object.
799
800 \param right Input - the power to raise the object to.
801 *
802 */
803 Data
804 powD(const Data& right) const;
805
806 /**
807 \brief
808 Return the given power of each data point of this boost python object.
809
810 \param right Input - the power to raise the object to.
811 *
812 */
813 Data
814 powO(const boost::python::object& right) const;
815
816 /**
817 \brief
818 writes the object to a file in the DX file format
819 */
820 void
821 saveDX(std::string fileName) const;
822
823 /**
824 \brief
825 writes the object to a file in the VTK file format
826 */
827 void
828 saveVTK(std::string fileName) const;
829
830 /**
831 \brief
832 Overloaded operator +=
833 \param right - Input - The right hand side.
834 *
835 */
836 Data& operator+=(const Data& right);
837 Data& operator+=(const boost::python::object& right);
838
839 /**
840 \brief
841 Overloaded operator -=
842 \param right - Input - The right hand side.
843 *
844 */
845 Data& operator-=(const Data& right);
846 Data& operator-=(const boost::python::object& right);
847
848 /**
849 \brief
850 Overloaded operator *=
851 \param right - Input - The right hand side.
852 *
853 */
854 Data& operator*=(const Data& right);
855 Data& operator*=(const boost::python::object& right);
856
857 /**
858 \brief
859 Overloaded operator /=
860 \param right - Input - The right hand side.
861 *
862 */
863 Data& operator/=(const Data& right);
864 Data& operator/=(const boost::python::object& right);
865
866 /**
867 \brief
868 Returns true if this can be interpolated to functionspace.
869 */
870 bool
871 probeInterpolation(const FunctionSpace& functionspace) const;
872
873 /**
874 Data object slicing methods.
875 */
876
877 /**
878 \brief
879 Returns a slice from this Data object.
880
881 /description
882 Implements the [] get operator in python.
883 Calls getSlice.
884
885 \param key - Input - python slice tuple specifying
886 slice to return.
887 */
888 Data
889 getItem(const boost::python::object& key) const;
890
891 /**
892 \brief
893 Copies slice from value into this Data object.
894
895 Implements the [] set operator in python.
896 Calls setSlice.
897
898 \param key - Input - python slice tuple specifying
899 slice to copy from value.
900 \param value - Input - Data object to copy from.
901 */
902 void
903 setItemD(const boost::python::object& key,
904 const Data& value);
905
906 void
907 setItemO(const boost::python::object& key,
908 const boost::python::object& value);
909
910 // These following public methods should be treated as private.
911
912 /**
913 \brief
914 Perform the given unary operation on every element of every data point in
915 this Data object.
916 */
917 template <class UnaryFunction>
918 inline
919 void
920 unaryOp(UnaryFunction operation);
921
922 /**
923 \brief
924 Return a Data object containing the specified slice of
925 this Data object.
926 \param region - Input - Region to copy.
927 *
928 */
929 Data
930 getSlice(const DataArrayView::RegionType& region) const;
931
932 /**
933 \brief
934 Copy the specified slice from the given value into this
935 Data object.
936 \param value - Input - Data to copy from.
937 \param region - Input - Region to copy.
938 *
939 */
940 void
941 setSlice(const Data& value,
942 const DataArrayView::RegionType& region);
943
944 /**
945 \brief
946 Archive the current Data object to the given file.
947 \param fileName - Input - file to archive to.
948 */
949 void
950 archiveData(const std::string fileName);
951
952 /**
953 \brief
954 Extract the Data object archived in the given file, overwriting
955 the current Data object.
956 Note - the current object must be of type DataEmpty.
957 \param fileName - Input - file to extract from.
958 \param fspace - Input - a suitable FunctionSpace descibing the data.
959 */
960 void
961 extractData(const std::string fileName,
962 const FunctionSpace& fspace);
963
964 protected:
965
966 private:
967
968 /**
969 \brief
970 Check *this and the right operand are compatible. Throws
971 an exception if they aren't.
972 \param right - Input - The right hand side.
973 */
974 inline
975 void
976 operandCheck(const Data& right) const
977 {
978 return m_data->operandCheck(*(right.m_data.get()));
979 }
980
981 /**
982 \brief
983 Perform the specified reduction algorithm on every element of every data point in
984 this Data object according to the given function and return the single value result.
985 */
986 template <class UnaryFunction>
987 inline
988 double
989 algorithm(UnaryFunction operation) const;
990
991 /**
992 \brief
993 Reduce each data-point in this Data object using the given operation. Return a Data
994 object with the same number of data-points, but with each data-point containing only
995 one value - the result of the reduction operation on the corresponding data-point in
996 this Data object
997 */
998 template <class UnaryFunction>
999 inline
1000 Data
1001 dp_algorithm(UnaryFunction operation) const;
1002
1003 /**
1004 \brief
1005 Perform the given binary operation on all of the data's elements.
1006 The underlying type of the right hand side (right) determines the final
1007 type of *this after the operation. For example if the right hand side
1008 is expanded *this will be expanded if necessary.
1009 RHS is a Data object.
1010 */
1011 template <class BinaryFunction>
1012 inline
1013 void
1014 binaryOp(const Data& right,
1015 BinaryFunction operation);
1016
1017 /**
1018 \brief
1019 Perform the given binary operation on all of the data's elements.
1020 RHS is a boost::python object.
1021 */
1022 template <class BinaryFunction>
1023 inline
1024 void
1025 binaryOp(const boost::python::object& right,
1026 BinaryFunction operation);
1027
1028 /**
1029 \brief
1030 Convert the data type of the RHS to match this.
1031 \param right - Input - data type to match.
1032 */
1033 void
1034 typeMatchLeft(Data& right) const;
1035
1036 /**
1037 \brief
1038 Convert the data type of this to match the RHS.
1039 \param right - Input - data type to match.
1040 */
1041 void
1042 typeMatchRight(const Data& right);
1043
1044 /**
1045 \brief
1046 Construct a Data object of the appropriate type.
1047 */
1048 template <class IValueType>
1049 void
1050 initialise(const IValueType& value,
1051 const FunctionSpace& what,
1052 bool expanded);
1053
1054 /**
1055 \brief
1056 Reshape the data point if the data point is currently rank 0.
1057 Will throw an exception if the data points are not rank 0.
1058 The original data point value is used for all values of the new
1059 data point.
1060 */
1061 void
1062 reshapeDataPoint(const DataArrayView::ShapeType& shape);
1063
1064 //
1065 // pointer to the actual data object
1066 boost::shared_ptr<DataAbstract> m_data;
1067
1068 //
1069 // pointer to the internal profiling data
1070 struct profDataEntry *profData;
1071
1072 };
1073
1074 template <class IValueType>
1075 void
1076 Data::initialise(const IValueType& value,
1077 const FunctionSpace& what,
1078 bool expanded)
1079 {
1080 //
1081 // Construct a Data object of the appropriate type.
1082 // Construct the object first as there seems to be a bug which causes
1083 // undefined behaviour if an exception is thrown during construction
1084 // within the shared_ptr constructor.
1085 if (expanded) {
1086 DataAbstract* temp=new DataExpanded(value,what);
1087 boost::shared_ptr<DataAbstract> temp_data(temp);
1088 m_data=temp_data;
1089 } else {
1090 DataAbstract* temp=new DataConstant(value,what);
1091 boost::shared_ptr<DataAbstract> temp_data(temp);
1092 m_data=temp_data;
1093 }
1094 }
1095
1096 /**
1097 Binary Data object operators.
1098 */
1099
1100 /**
1101 \brief
1102 Operator+
1103 Takes two Data objects.
1104 */
1105 Data operator+(const Data& left, const Data& right);
1106
1107 /**
1108 \brief
1109 Operator-
1110 Takes two Data objects.
1111 */
1112 Data operator-(const Data& left, const Data& right);
1113
1114 /**
1115 \brief
1116 Operator*
1117 Takes two Data objects.
1118 */
1119 Data operator*(const Data& left, const Data& right);
1120
1121 /**
1122 \brief
1123 Operator/
1124 Takes two Data objects.
1125 */
1126 Data operator/(const Data& left, const Data& right);
1127
1128 /**
1129 \brief
1130 Operator+
1131 Takes LHS Data object and RHS python::object.
1132 python::object must be convertable to Data type.
1133 */
1134 Data operator+(const Data& left, const boost::python::object& right);
1135
1136 /**
1137 \brief
1138 Operator-
1139 Takes LHS Data object and RHS python::object.
1140 python::object must be convertable to Data type.
1141 */
1142 Data operator-(const Data& left, const boost::python::object& right);
1143
1144 /**
1145 \brief
1146 Operator*
1147 Takes LHS Data object and RHS python::object.
1148 python::object must be convertable to Data type.
1149 */
1150 Data operator*(const Data& left, const boost::python::object& right);
1151
1152 /**
1153 \brief
1154 Operator/
1155 Takes LHS Data object and RHS python::object.
1156 python::object must be convertable to Data type.
1157 */
1158 Data operator/(const Data& left, const boost::python::object& right);
1159
1160 /**
1161 \brief
1162 Operator+
1163 Takes LHS python::object and RHS Data object.
1164 python::object must be convertable to Data type.
1165 */
1166 Data operator+(const boost::python::object& left, const Data& right);
1167
1168 /**
1169 \brief
1170 Operator-
1171 Takes LHS python::object and RHS Data object.
1172 python::object must be convertable to Data type.
1173 */
1174 Data operator-(const boost::python::object& left, const Data& right);
1175
1176 /**
1177 \brief
1178 Operator*
1179 Takes LHS python::object and RHS Data object.
1180 python::object must be convertable to Data type.
1181 */
1182 Data operator*(const boost::python::object& left, const Data& right);
1183
1184 /**
1185 \brief
1186 Operator/
1187 Takes LHS python::object and RHS Data object.
1188 python::object must be convertable to Data type.
1189 */
1190 Data operator/(const boost::python::object& left, const Data& right);
1191
1192 /**
1193 \brief
1194 Output operator
1195 */
1196 std::ostream& operator<<(std::ostream& o, const Data& data);
1197
1198 /**
1199 \brief
1200 Return true if operands are equivalent, else return false.
1201 NB: this operator does very little at this point, and isn't to
1202 be relied on. Requires further implementation.
1203 */
1204 //bool operator==(const Data& left, const Data& right);
1205
1206 /**
1207 \brief
1208 Perform the given binary operation with this and right as operands.
1209 Right is a Data object.
1210 */
1211 template <class BinaryFunction>
1212 inline
1213 void
1214 Data::binaryOp(const Data& right,
1215 BinaryFunction operation)
1216 {
1217 //
1218 // if this has a rank of zero promote it to the rank of the RHS
1219 if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1220 reshapeDataPoint(right.getPointDataView().getShape());
1221 }
1222 //
1223 // initially make the temporary a shallow copy
1224 Data tempRight(right);
1225 if (getFunctionSpace()!=right.getFunctionSpace()) {
1226 if (right.probeInterpolation(getFunctionSpace())) {
1227 //
1228 // an interpolation is required so create a new Data
1229 tempRight=Data(right,this->getFunctionSpace());
1230 } else if (probeInterpolation(right.getFunctionSpace())) {
1231 //
1232 // interpolate onto the RHS function space
1233 Data tempLeft(*this,right.getFunctionSpace());
1234 m_data=tempLeft.m_data;
1235 }
1236 }
1237 operandCheck(tempRight);
1238 //
1239 // ensure this has the right type for the RHS
1240 typeMatchRight(tempRight);
1241 //
1242 // Need to cast to the concrete types so that the correct binaryOp
1243 // is called.
1244 if (isExpanded()) {
1245 //
1246 // Expanded data will be done in parallel, the right hand side can be
1247 // of any data type
1248 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1249 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1250 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1251 } else if (isTagged()) {
1252 //
1253 // Tagged data is operated on serially, the right hand side can be
1254 // either DataConstant or DataTagged
1255 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1256 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1257 if (right.isTagged()) {
1258 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1259 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1260 escript::binaryOp(*leftC,*rightC,operation);
1261 } else {
1262 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1263 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1264 escript::binaryOp(*leftC,*rightC,operation);
1265 }
1266 } else if (isConstant()) {
1267 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1268 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1269 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1270 escript::binaryOp(*leftC,*rightC,operation);
1271 }
1272 }
1273
1274 /**
1275 \brief
1276 Perform the given binary operation with this and right as operands.
1277 Right is a boost::python object.
1278 */
1279 template <class BinaryFunction>
1280 inline
1281 void
1282 Data::binaryOp(const boost::python::object& right,
1283 BinaryFunction operation)
1284 {
1285 DataArray temp(right);
1286 //
1287 // if this has a rank of zero promote it to the rank of the RHS.
1288 if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1289 reshapeDataPoint(temp.getView().getShape());
1290 }
1291 //
1292 // Always allow scalar values for the RHS but check other shapes
1293 if (temp.getView().getRank()!=0) {
1294 if (!getPointDataView().checkShape(temp.getView().getShape())) {
1295 throw DataException(getPointDataView().createShapeErrorMessage(
1296 "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1297 }
1298 }
1299 if (isExpanded()) {
1300 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1301 EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1302 escript::binaryOp(*leftC,temp.getView(),operation);
1303 } else if (isTagged()) {
1304 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1305 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1306 escript::binaryOp(*leftC,temp.getView(),operation);
1307 } else if (isConstant()) {
1308 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1309 EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1310 escript::binaryOp(*leftC,temp.getView(),operation);
1311 }
1312 }
1313
1314 /**
1315 \brief
1316 Perform the given unary operation on other and return the result.
1317 Given operation is performed on each element of each data point, thus
1318 argument object is a rank n Data object, and returned object is a rank n
1319 Data object.
1320 Calls Data::unaryOp.
1321 */
1322 template <class UnaryFunction>
1323 inline
1324 Data
1325 unaryOp(const Data& other,
1326 UnaryFunction operation)
1327 {
1328 Data result;
1329 result.copy(other);
1330 result.unaryOp(operation);
1331 return result;
1332 }
1333
1334 /**
1335 \brief
1336 Perform the given unary operation on this.
1337 Given operation is performed on each element of each data point.
1338 Calls escript::unaryOp.
1339 */
1340 template <class UnaryFunction>
1341 inline
1342 void
1343 Data::unaryOp(UnaryFunction operation)
1344 {
1345 if (isExpanded()) {
1346 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1347 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1348 escript::unaryOp(*leftC,operation);
1349 } else if (isTagged()) {
1350 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1351 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1352 escript::unaryOp(*leftC,operation);
1353 } else if (isConstant()) {
1354 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1355 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1356 escript::unaryOp(*leftC,operation);
1357 }
1358 }
1359
1360 /**
1361 \brief
1362 Perform the given Data object reduction algorithm on this and return the result.
1363 Given operation combines each element of each data point, thus argument
1364 object (*this) is a rank n Data object, and returned object is a scalar.
1365 Calls escript::algorithm.
1366 */
1367 template <class UnaryFunction>
1368 inline
1369 double
1370 Data::algorithm(UnaryFunction operation) const
1371 {
1372 if (isExpanded()) {
1373 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1374 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1375 return escript::algorithm(*leftC,operation);
1376 } else if (isTagged()) {
1377 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1378 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1379 return escript::algorithm(*leftC,operation);
1380 } else if (isConstant()) {
1381 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1382 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1383 return escript::algorithm(*leftC,operation);
1384 }
1385 return 0;
1386 }
1387
1388 /**
1389 \brief
1390 Perform the given data point reduction algorithm on data and return the result.
1391 Given operation combines each element within each data point into a scalar,
1392 thus argument object is a rank n Data object, and returned object is a
1393 rank 0 Data object.
1394 Calls escript::dp_algorithm.
1395 */
1396 template <class UnaryFunction>
1397 inline
1398 Data
1399 Data::dp_algorithm(UnaryFunction operation) const
1400 {
1401 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1402 if (isExpanded()) {
1403 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1404 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1405 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1406 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1407 escript::dp_algorithm(*dataE,*resultE,operation);
1408 } else if (isTagged()) {
1409 DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1410 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1411 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1412 EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1413 escript::dp_algorithm(*dataT,*resultT,operation);
1414 } else if (isConstant()) {
1415 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1416 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1417 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1418 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1419 escript::dp_algorithm(*dataC,*resultC,operation);
1420 }
1421 return result;
1422 }
1423
1424 }
1425 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26