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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 155 - (hide annotations)
Wed Nov 9 02:02:19 2005 UTC (13 years, 9 months ago) by jgs
File MIME type: text/plain
File size: 37948 byte(s)
move all directories from trunk/esys2 into trunk and remove esys2

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26