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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (hide annotations)
Fri May 6 04:26:16 2005 UTC (13 years, 11 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 35766 byte(s)
Merge of development branch back to main trunk on 2005-05-06

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26