/[escript]/branches/schroedinger/escript/src/Data.h
ViewVC logotype

Annotation of /branches/schroedinger/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 123 - (hide annotations)
Fri Jul 8 04:08:13 2005 UTC (14 years, 4 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 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     // Forward declaration for various implimentations of Data.
48     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    
210     /**
211     \brief
212 jgs 102 Perform a deep copy.
213 jgs 94 */
214     void
215 jgs 102 copy(const Data& other);
216 jgs 94
217     /**
218 jgs 102 Member access methods.
219 jgs 94 */
220    
221     /**
222     \brief
223 jgs 121 Return the values of all data-points as a single python numarray object.
224 jgs 117 */
225 jgs 121 const boost::python::numeric::array
226 jgs 117 convertToNumArray();
227    
228     /**
229     \brief
230 jgs 121 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 jgs 94 Return the C wrapper for the Data object.
246     */
247 jgs 102 escriptDataC
248     getDataC();
249 jgs 94
250     /**
251     \brief
252     Return the C wrapper for the Data object - const version.
253     */
254 jgs 102 escriptDataC
255     getDataC() const;
256 jgs 94
257     /**
258     \brief
259     Write the data as a string.
260     */
261 jgs 102 inline
262     std::string
263     toString() const
264     {
265     return m_data->toString();
266     }
267 jgs 94
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 jgs 102 Whatever the current Data type make this into a DataExpanded.
284 jgs 94 */
285     void
286     expand();
287    
288     /**
289     \brief
290 jgs 102 If possible convert this Data to DataTagged. This will only allow
291 jgs 94 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 jgs 102 Return true if this Data is constant.
314 jgs 94 */
315     bool
316 jgs 102 isConstant() const;
317 jgs 94
318     /**
319     \brief
320 jgs 102 Return true if this Data is empty.
321 jgs 94 */
322     bool
323 jgs 102 isEmpty() const;
324 jgs 94
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 jgs 102 Return the number of samples.
375 jgs 94 */
376     inline
377     int
378 jgs 102 getNumSamples() const
379 jgs 94 {
380 jgs 102 return m_data->getNumSamples();
381 jgs 94 }
382    
383     /**
384     \brief
385 jgs 102 Return the number of data points per sample.
386 jgs 94 */
387 jgs 102 inline
388 jgs 94 int
389 jgs 102 getNumDataPointsPerSample() const
390     {
391     return m_data->getNumDPPSample();
392     }
393 jgs 94
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 jgs 102 inline
401 jgs 94 DataAbstract::ValueType::value_type*
402 jgs 102 getSampleData(DataAbstract::ValueType::size_type sampleNo)
403     {
404     return m_data->getSampleData(sampleNo);
405     }
406 jgs 94
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 jgs 102 inline
414 jgs 94 DataAbstract::ValueType::value_type*
415 jgs 102 getSampleDataByTag(int tag)
416     {
417     return m_data->getSampleDataByTag(tag);
418     }
419 jgs 94
420     /**
421     \brief
422 jgs 110 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 jgs 94 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 jgs 102 Return the data point shape as a tuple of integers.
485 jgs 94 */
486 jgs 121 const boost::python::tuple
487 jgs 94 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 jgs 102 Return the number of doubles stored for this Data.
500 jgs 94 */
501     DataArrayView::ValueType::size_type
502     getLength() const;
503    
504     /**
505     \brief
506 jgs 102 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 jgs 94 */
512 jgs 102 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 jgs 121 setTaggedValueFromCPP(int tagKey,
526     const DataArrayView& value);
527 jgs 102
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 jgs 123 *
545 jgs 102 */
546 jgs 94 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 jgs 123 *
554 jgs 94 */
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 jgs 123 *
565 jgs 94 */
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 jgs 123 *
573 jgs 94 */
574     Data
575     wherePositive() const;
576    
577     /**
578     \brief
579 jgs 102 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
580 jgs 123 *
581 jgs 94 */
582     Data
583 jgs 102 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 jgs 123 *
589 jgs 102 */
590     Data
591 jgs 94 whereNonNegative() const;
592    
593     /**
594     \brief
595 jgs 102 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
596 jgs 123 *
597 jgs 94 */
598     Data
599 jgs 102 whereNonPositive() const;
600 jgs 94
601     /**
602     \brief
603 jgs 102 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
604 jgs 123 *
605 jgs 94 */
606     Data
607     whereZero() const;
608    
609     /**
610     \brief
611 jgs 102 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
612 jgs 123 *
613 jgs 94 */
614     Data
615 jgs 102 whereNonZero() const;
616    
617     /**
618     \brief
619     Return the maximum absolute value of this Data object.
620 jgs 123 *
621 jgs 94 */
622 jgs 102 double
623     Lsup() const;
624 jgs 94
625     /**
626     \brief
627 jgs 117 Return the minimum absolute value of this Data object.
628 jgs 123 *
629 jgs 117 */
630     double
631     Linf() const;
632    
633     /**
634     \brief
635 jgs 102 Return the maximum value of this Data object.
636 jgs 123 *
637 jgs 94 */
638 jgs 102 double
639     sup() const;
640 jgs 94
641     /**
642     \brief
643 jgs 102 Return the minimum value of this Data object.
644 jgs 123 *
645 jgs 94 */
646     double
647 jgs 102 inf() const;
648 jgs 94
649     /**
650     \brief
651 jgs 102 Return the absolute value of each data point of this Data object.
652 jgs 123 *
653 jgs 94 */
654 jgs 102 Data
655     abs() const;
656 jgs 94
657     /**
658     \brief
659 jgs 102 Return the maximum value of each data point of this Data object.
660 jgs 123 *
661 jgs 94 */
662 jgs 102 Data
663     maxval() const;
664 jgs 94
665     /**
666     \brief
667 jgs 102 Return the minimum value of each data point of this Data object.
668 jgs 123 *
669 jgs 94 */
670     Data
671 jgs 102 minval() const;
672 jgs 94
673     /**
674     \brief
675 jgs 121 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 jgs 102 Return the length of each data point of this Data object.
684     sqrt(sum(A[i,j,k,l]^2))
685 jgs 123 *
686 jgs 94 */
687 jgs 102 Data
688     length() const;
689 jgs 94
690     /**
691     \brief
692 jgs 102 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 jgs 123 *
695 jgs 94 */
696 jgs 102 Data
697     sign() const;
698 jgs 94
699     /**
700 jgs 123 \brief
701     Transpose each data point of this Data object around the given axis.
702     --* not implemented yet *--
703     *
704 jgs 102 */
705     Data
706     transpose(int axis) const;
707    
708     /**
709 jgs 123 \brief
710     Calculate the trace of each data point of this Data object.
711     sum(A[i,i,i,i])
712     *
713 jgs 102 */
714     Data
715     trace() const;
716    
717     /**
718 jgs 123 \brief
719     Return the sin of each data point of this Data object.
720     *
721 jgs 102 */
722     Data
723 jgs 123 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 jgs 102 exp() const;
764    
765     /**
766 jgs 123 \brief
767     Return the square root of each data point of this Data object.
768     *
769 jgs 102 */
770     Data
771     sqrt() const;
772    
773     /**
774 jgs 123 \brief
775     Return the negation of each data point of this Data object.
776     *
777 jgs 121 */
778     Data
779     neg() const;
780    
781     /**
782 jgs 123 \brief
783     Return the identity of each data point of this Data object.
784     Simply returns this object unmodified.
785     *
786 jgs 121 */
787     Data
788     pos() const;
789    
790     /**
791 jgs 94 \brief
792 jgs 102 Return the given power of each data point of this Data object.
793 jgs 121
794     \param right Input - the power to raise the object to.
795 jgs 123 *
796 jgs 102 */
797     Data
798     powD(const Data& right) const;
799    
800 jgs 121 /**
801 jgs 123 \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 jgs 121 */
807 jgs 102 Data
808     powO(const boost::python::object& right) const;
809    
810     /**
811 jgs 123 \brief
812     writes the object to a file in the DX file format
813 jgs 104 */
814     void
815     saveDX(std::string fileName) const;
816    
817     /**
818 jgs 123 \brief
819     writes the object to a file in the VTK file format
820 jgs 110 */
821     void
822     saveVTK(std::string fileName) const;
823    
824     /**
825 jgs 102 \brief
826     Overloaded operator +=
827     \param right - Input - The right hand side.
828 jgs 123 *
829 jgs 102 */
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 jgs 123 *
838 jgs 102 */
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 jgs 123 *
847 jgs 102 */
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 jgs 123 *
856 jgs 102 */
857     Data& operator/=(const Data& right);
858     Data& operator/=(const boost::python::object& right);
859    
860     /**
861     \brief
862 jgs 94 Returns true if this can be interpolated to functionspace.
863     */
864     bool
865     probeInterpolation(const FunctionSpace& functionspace) const;
866    
867     /**
868 jgs 102 Data object slicing methods.
869     */
870    
871     /**
872 jgs 94 \brief
873 jgs 102 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 jgs 94 */
882 jgs 102 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 jgs 94 void
897 jgs 102 setItemD(const boost::python::object& key,
898     const Data& value);
899 jgs 94
900 jgs 102 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 jgs 94 /**
907     \brief
908 jgs 102 Perform the given unary operation on every element of every data point in
909     this Data object.
910 jgs 94 */
911 jgs 102 template <class UnaryFunction>
912     inline
913 jgs 94 void
914 jgs 102 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 jgs 123 *
922 jgs 94 */
923 jgs 102 Data
924     getSlice(const DataArrayView::RegionType& region) const;
925 jgs 94
926 jgs 102 /**
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 jgs 123 *
933 jgs 102 */
934     void
935     setSlice(const Data& value,
936     const DataArrayView::RegionType& region);
937    
938 jgs 119 /**
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 jgs 121 \param fspace - Input - a suitable FunctionSpace descibing the data.
953 jgs 119 */
954     void
955     extractData(const std::string fileName,
956     const FunctionSpace& fspace);
957    
958 jgs 102 protected:
959    
960 jgs 94 private:
961    
962     /**
963     \brief
964 jgs 102 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 jgs 113 this Data object according to the given function and return the single value result.
979 jgs 102 */
980     template <class UnaryFunction>
981     inline
982     double
983     algorithm(UnaryFunction operation) const;
984    
985 jgs 113 /**
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 jgs 106 template <class UnaryFunction>
993     inline
994     Data
995     dp_algorithm(UnaryFunction operation) const;
996    
997 jgs 102 /**
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 jgs 94 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 jgs 102 // pointer to the actual data object
1060 jgs 94 boost::shared_ptr<DataAbstract> m_data;
1061    
1062 jgs 123 //
1063     // pointer to the internal profiling data
1064     struct profDataEntry *profData;
1065    
1066 jgs 94 };
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 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1082     m_data=temp_data;
1083 jgs 94 } else {
1084     DataAbstract* temp=new DataConstant(value,what);
1085 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1086     m_data=temp_data;
1087 jgs 94 }
1088     }
1089    
1090 jgs 102 /**
1091     Binary Data object operators.
1092     */
1093 jgs 94
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 jgs 102 //bool operator==(const Data& left, const Data& right);
1199 jgs 94
1200 jgs 102 /**
1201     \brief
1202     Perform the given binary operation with this and right as operands.
1203     Right is a Data object.
1204     */
1205 jgs 94 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 jgs 102 typeMatchRight(tempRight);
1235 jgs 94 //
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 jgs 102 } else if (isConstant()) {
1261 jgs 94 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 jgs 102 /**
1269     \brief
1270     Perform the given binary operation with this and right as operands.
1271     Right is a boost::python object.
1272     */
1273 jgs 94 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 jgs 102 } else if (isConstant()) {
1302 jgs 94 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 jgs 102 /**
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 jgs 94 template <class UnaryFunction>
1317     inline
1318 jgs 102 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 jgs 94 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 jgs 102 } else if (isConstant()) {
1348 jgs 94 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 jgs 102 /**
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 jgs 94 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 jgs 102 } else if (isTagged()) {
1371 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1372     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1373     return escript::algorithm(*leftC,operation);
1374 jgs 102 } else if (isConstant()) {
1375 jgs 94 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 jgs 102 return 0;
1380 jgs 94 }
1381    
1382 jgs 102 /**
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 jgs 94 template <class UnaryFunction>
1391     inline
1392     Data
1393 jgs 106 Data::dp_algorithm(UnaryFunction operation) const
1394 jgs 94 {
1395 jgs 106 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1396     if (isExpanded()) {
1397     DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1398 jgs 102 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 jgs 106 } else if (isTagged()) {
1403     DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1404 jgs 102 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 jgs 106 } else if (isConstant()) {
1409     DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1410 jgs 102 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 jgs 94 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