/[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 148 - (hide annotations)
Tue Aug 23 01:24:31 2005 UTC (14 years, 1 month ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 36611 byte(s)
Merge of development branch dev-02 back to main trunk on 2005-08-23

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26