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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 113 - (hide annotations)
Mon Feb 28 07:06:33 2005 UTC (14 years, 8 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 34482 byte(s)
*** empty log message ***

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26