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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 123 - (show annotations)
Fri Jul 8 04:08:13 2005 UTC (14 years, 5 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 36168 byte(s)
Merge of development branch back to main trunk on 2005-07-08

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26