/[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 110 - (hide annotations)
Mon Feb 14 04:14:42 2005 UTC (14 years, 9 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 34143 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     this Data object and return the single double value result.
884     */
885     template <class UnaryFunction>
886     inline
887     double
888     algorithm(UnaryFunction operation) const;
889    
890 jgs 106 template <class UnaryFunction>
891     inline
892     Data
893     dp_algorithm(UnaryFunction operation) const;
894    
895 jgs 102 /**
896     \brief
897     Perform the given binary operation on all of the data's elements.
898     The underlying type of the right hand side (right) determines the final
899     type of *this after the operation. For example if the right hand side
900     is expanded *this will be expanded if necessary.
901     RHS is a Data object.
902     */
903     template <class BinaryFunction>
904     inline
905     void
906     binaryOp(const Data& right,
907     BinaryFunction operation);
908    
909     /**
910     \brief
911     Perform the given binary operation on all of the data's elements.
912     RHS is a boost::python object.
913     */
914     template <class BinaryFunction>
915     inline
916     void
917     binaryOp(const boost::python::object& right,
918     BinaryFunction operation);
919    
920     /**
921     \brief
922     Convert the data type of the RHS to match this.
923     \param right - Input - data type to match.
924     */
925     void
926     typeMatchLeft(Data& right) const;
927    
928     /**
929     \brief
930     Convert the data type of this to match the RHS.
931     \param right - Input - data type to match.
932     */
933     void
934     typeMatchRight(const Data& right);
935    
936     /**
937     \brief
938 jgs 94 Construct a Data object of the appropriate type.
939     */
940     template <class IValueType>
941     void
942     initialise(const IValueType& value,
943     const FunctionSpace& what,
944     bool expanded);
945    
946     /**
947     \brief
948     Reshape the data point if the data point is currently rank 0.
949     Will throw an exception if the data points are not rank 0.
950     The original data point value is used for all values of the new
951     data point.
952     */
953     void
954     reshapeDataPoint(const DataArrayView::ShapeType& shape);
955    
956     //
957 jgs 102 // pointer to the actual data object
958 jgs 94 boost::shared_ptr<DataAbstract> m_data;
959    
960     };
961    
962     template <class IValueType>
963     void
964     Data::initialise(const IValueType& value,
965     const FunctionSpace& what,
966     bool expanded)
967     {
968     //
969     // Construct a Data object of the appropriate type.
970     // Construct the object first as there seems to be a bug which causes
971     // undefined behaviour if an exception is thrown during construction
972     // within the shared_ptr constructor.
973     if (expanded) {
974     DataAbstract* temp=new DataExpanded(value,what);
975 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
976     m_data=temp_data;
977 jgs 94 } else {
978     DataAbstract* temp=new DataConstant(value,what);
979 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
980     m_data=temp_data;
981 jgs 94 }
982     }
983    
984 jgs 102 /**
985     Binary Data object operators.
986     */
987 jgs 94
988     /**
989     \brief
990     Operator+
991     Takes two Data objects.
992     */
993     Data operator+(const Data& left, const Data& right);
994    
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 LHS Data object and RHS python::object.
1020     python::object must be convertable to Data type.
1021     */
1022     Data operator+(const Data& left, const boost::python::object& right);
1023    
1024     /**
1025     \brief
1026     Operator-
1027     Takes LHS Data object and RHS python::object.
1028     python::object must be convertable to Data type.
1029     */
1030     Data operator-(const Data& left, const boost::python::object& right);
1031    
1032     /**
1033     \brief
1034     Operator*
1035     Takes LHS Data object and RHS python::object.
1036     python::object must be convertable to Data type.
1037     */
1038     Data operator*(const Data& left, const boost::python::object& right);
1039    
1040     /**
1041     \brief
1042     Operator/
1043     Takes LHS Data object and RHS python::object.
1044     python::object must be convertable to Data type.
1045     */
1046     Data operator/(const Data& left, const boost::python::object& right);
1047    
1048     /**
1049     \brief
1050     Operator+
1051     Takes LHS python::object and RHS Data object.
1052     python::object must be convertable to Data type.
1053     */
1054     Data operator+(const boost::python::object& left, const Data& right);
1055    
1056     /**
1057     \brief
1058     Operator-
1059     Takes LHS python::object and RHS Data object.
1060     python::object must be convertable to Data type.
1061     */
1062     Data operator-(const boost::python::object& left, const Data& right);
1063    
1064     /**
1065     \brief
1066     Operator*
1067     Takes LHS python::object and RHS Data object.
1068     python::object must be convertable to Data type.
1069     */
1070     Data operator*(const boost::python::object& left, const Data& right);
1071    
1072     /**
1073     \brief
1074     Operator/
1075     Takes LHS python::object and RHS Data object.
1076     python::object must be convertable to Data type.
1077     */
1078     Data operator/(const boost::python::object& left, const Data& right);
1079    
1080     /**
1081     \brief
1082     Output operator
1083     */
1084     std::ostream& operator<<(std::ostream& o, const Data& data);
1085    
1086     /**
1087     \brief
1088     Return true if operands are equivalent, else return false.
1089     NB: this operator does very little at this point, and isn't to
1090     be relied on. Requires further implementation.
1091     */
1092 jgs 102 //bool operator==(const Data& left, const Data& right);
1093 jgs 94
1094 jgs 102 /**
1095     \brief
1096     Perform the given binary operation with this and right as operands.
1097     Right is a Data object.
1098     */
1099 jgs 94 template <class BinaryFunction>
1100     inline
1101     void
1102     Data::binaryOp(const Data& right,
1103     BinaryFunction operation)
1104     {
1105     //
1106     // if this has a rank of zero promote it to the rank of the RHS
1107     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1108     reshapeDataPoint(right.getPointDataView().getShape());
1109     }
1110     //
1111     // initially make the temporary a shallow copy
1112     Data tempRight(right);
1113     if (getFunctionSpace()!=right.getFunctionSpace()) {
1114     if (right.probeInterpolation(getFunctionSpace())) {
1115     //
1116     // an interpolation is required so create a new Data
1117     tempRight=Data(right,this->getFunctionSpace());
1118     } else if (probeInterpolation(right.getFunctionSpace())) {
1119     //
1120     // interpolate onto the RHS function space
1121     Data tempLeft(*this,right.getFunctionSpace());
1122     m_data=tempLeft.m_data;
1123     }
1124     }
1125     operandCheck(tempRight);
1126     //
1127     // ensure this has the right type for the RHS
1128 jgs 102 typeMatchRight(tempRight);
1129 jgs 94 //
1130     // Need to cast to the concrete types so that the correct binaryOp
1131     // is called.
1132     if (isExpanded()) {
1133     //
1134     // Expanded data will be done in parallel, the right hand side can be
1135     // of any data type
1136     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1137     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1138     escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1139     } else if (isTagged()) {
1140     //
1141     // Tagged data is operated on serially, the right hand side can be
1142     // either DataConstant or DataTagged
1143     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1144     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1145     if (right.isTagged()) {
1146     DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1147     EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1148     escript::binaryOp(*leftC,*rightC,operation);
1149     } else {
1150     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1151     EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1152     escript::binaryOp(*leftC,*rightC,operation);
1153     }
1154 jgs 102 } else if (isConstant()) {
1155 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1156     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1157     EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1158     escript::binaryOp(*leftC,*rightC,operation);
1159     }
1160     }
1161    
1162 jgs 102 /**
1163     \brief
1164     Perform the given binary operation with this and right as operands.
1165     Right is a boost::python object.
1166     */
1167 jgs 94 template <class BinaryFunction>
1168     inline
1169     void
1170     Data::binaryOp(const boost::python::object& right,
1171     BinaryFunction operation)
1172     {
1173     DataArray temp(right);
1174     //
1175     // if this has a rank of zero promote it to the rank of the RHS.
1176     if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1177     reshapeDataPoint(temp.getView().getShape());
1178     }
1179     //
1180     // Always allow scalar values for the RHS but check other shapes
1181     if (temp.getView().getRank()!=0) {
1182     if (!getPointDataView().checkShape(temp.getView().getShape())) {
1183     throw DataException(getPointDataView().createShapeErrorMessage(
1184     "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1185     }
1186     }
1187     if (isExpanded()) {
1188     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1189     EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1190     escript::binaryOp(*leftC,temp.getView(),operation);
1191     } else if (isTagged()) {
1192     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1193     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1194     escript::binaryOp(*leftC,temp.getView(),operation);
1195 jgs 102 } else if (isConstant()) {
1196 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1197     EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1198     escript::binaryOp(*leftC,temp.getView(),operation);
1199     }
1200     }
1201    
1202 jgs 102 /**
1203     \brief
1204     Perform the given unary operation on other and return the result.
1205     Given operation is performed on each element of each data point, thus
1206     argument object is a rank n Data object, and returned object is a rank n
1207     Data object.
1208     Calls Data::unaryOp.
1209     */
1210 jgs 94 template <class UnaryFunction>
1211     inline
1212 jgs 102 Data
1213     unaryOp(const Data& other,
1214     UnaryFunction operation)
1215     {
1216     Data result;
1217     result.copy(other);
1218     result.unaryOp(operation);
1219     return result;
1220     }
1221    
1222     /**
1223     \brief
1224     Perform the given unary operation on this.
1225     Given operation is performed on each element of each data point.
1226     Calls escript::unaryOp.
1227     */
1228     template <class UnaryFunction>
1229     inline
1230 jgs 94 void
1231     Data::unaryOp(UnaryFunction operation)
1232     {
1233     if (isExpanded()) {
1234     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1235     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1236     escript::unaryOp(*leftC,operation);
1237     } else if (isTagged()) {
1238     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1239     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1240     escript::unaryOp(*leftC,operation);
1241 jgs 102 } else if (isConstant()) {
1242 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1243     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1244     escript::unaryOp(*leftC,operation);
1245     }
1246     }
1247    
1248 jgs 102 /**
1249     \brief
1250     Perform the given Data object reduction algorithm on this and return the result.
1251     Given operation combines each element of each data point, thus argument
1252     object (*this) is a rank n Data object, and returned object is a scalar.
1253     Calls escript::algorithm.
1254     */
1255 jgs 94 template <class UnaryFunction>
1256     inline
1257     double
1258     Data::algorithm(UnaryFunction operation) const
1259     {
1260     if (isExpanded()) {
1261     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1262     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1263     return escript::algorithm(*leftC,operation);
1264 jgs 102 } else if (isTagged()) {
1265 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1266     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1267     return escript::algorithm(*leftC,operation);
1268 jgs 102 } else if (isConstant()) {
1269 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1270     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1271     return escript::algorithm(*leftC,operation);
1272     }
1273 jgs 102 return 0;
1274 jgs 94 }
1275    
1276 jgs 102 /**
1277     \brief
1278     Perform the given data point reduction algorithm on data and return the result.
1279     Given operation combines each element within each data point into a scalar,
1280     thus argument object is a rank n Data object, and returned object is a
1281     rank 0 Data object.
1282     Calls escript::dp_algorithm.
1283     */
1284 jgs 94 template <class UnaryFunction>
1285     inline
1286     Data
1287 jgs 106 Data::dp_algorithm(UnaryFunction operation) const
1288 jgs 94 {
1289 jgs 106 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1290     if (isExpanded()) {
1291     DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1292 jgs 102 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1293     EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1294     EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1295     escript::dp_algorithm(*dataE,*resultE,operation);
1296 jgs 106 } else if (isTagged()) {
1297     DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1298 jgs 102 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1299     EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1300     EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1301     escript::dp_algorithm(*dataT,*resultT,operation);
1302 jgs 106 } else if (isConstant()) {
1303     DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1304 jgs 102 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1305     EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1306     EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1307     escript::dp_algorithm(*dataC,*resultC,operation);
1308     }
1309 jgs 94 return result;
1310     }
1311    
1312     }
1313     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26