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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 751 - (show annotations)
Mon Jun 26 01:46:34 2006 UTC (12 years, 11 months ago) by bcumming
File MIME type: text/plain
File size: 39151 byte(s)
Changes relating to the MPI version of escript
The standard OpenMP version of escript is unchanged

- updated data types (Finley_Mesh, Finley_NodeFile, etc) to store meshes
  over multiple MPI processes.
- added CommBuffer code in Paso for communication of Data associated
  with distributed meshes
- updates in Finley and Escript to support distributed data and operations
  on distributed data (such as interpolation).
- construction of RHS in MPI, so that simple explicit schemes (such as
  /docs/examples/wave.py without IO and the Locator) can run in MPI.
- updated mesh generation for first order line, rectangle and brick
  meshes and second order line meshes in MPI.        
- small changes to trunk/SConstruct and trunk/scons/ess_options.py to
  build the MPI version, these changes are turned off by default.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26