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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 150 - (hide annotations)
Thu Sep 15 03:44:45 2005 UTC (13 years, 9 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 37898 byte(s)
Merge of development branch dev-02 back to main trunk on 2005-09-15

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26