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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 147 - (hide annotations)
Fri Aug 12 01:45:47 2005 UTC (14 years ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 36537 byte(s)
erge of development branch dev-02 back to main trunk on 2005-08-12

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26