/[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 149 - (hide annotations)
Thu Sep 1 03:31:39 2005 UTC (14 years, 1 month ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 36857 byte(s)
Merge of development branch dev-02 back to main trunk on 2005-09-01

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     Return the log to base 10 of each data point of this Data object.
765     *
766     */
767     Data
768     log() const;
769    
770     /**
771     \brief
772     Return the natural log of each data point of this Data object.
773     *
774     */
775     Data
776     ln() const;
777    
778     /**
779     \brief
780     Return the exponential function of each data point of this Data object.
781     *
782     */
783     Data
784 jgs 102 exp() const;
785    
786     /**
787 jgs 123 \brief
788     Return the square root of each data point of this Data object.
789     *
790 jgs 102 */
791     Data
792     sqrt() const;
793    
794     /**
795 jgs 123 \brief
796     Return the negation of each data point of this Data object.
797     *
798 jgs 121 */
799     Data
800     neg() const;
801    
802     /**
803 jgs 123 \brief
804     Return the identity of each data point of this Data object.
805     Simply returns this object unmodified.
806     *
807 jgs 121 */
808     Data
809     pos() const;
810    
811     /**
812 jgs 94 \brief
813 jgs 102 Return the given power of each data point of this Data object.
814 jgs 121
815     \param right Input - the power to raise the object to.
816 jgs 123 *
817 jgs 102 */
818     Data
819     powD(const Data& right) const;
820    
821 jgs 121 /**
822 jgs 123 \brief
823     Return the given power of each data point of this boost python object.
824    
825     \param right Input - the power to raise the object to.
826     *
827 jgs 121 */
828 jgs 102 Data
829     powO(const boost::python::object& right) const;
830    
831     /**
832 jgs 123 \brief
833     writes the object to a file in the DX file format
834 jgs 104 */
835     void
836     saveDX(std::string fileName) const;
837    
838     /**
839 jgs 123 \brief
840     writes the object to a file in the VTK file format
841 jgs 110 */
842     void
843     saveVTK(std::string fileName) const;
844    
845     /**
846 jgs 102 \brief
847     Overloaded operator +=
848     \param right - Input - The right hand side.
849 jgs 123 *
850 jgs 102 */
851     Data& operator+=(const Data& right);
852     Data& operator+=(const boost::python::object& right);
853    
854     /**
855     \brief
856     Overloaded operator -=
857     \param right - Input - The right hand side.
858 jgs 123 *
859 jgs 102 */
860     Data& operator-=(const Data& right);
861     Data& operator-=(const boost::python::object& right);
862    
863     /**
864     \brief
865     Overloaded operator *=
866     \param right - Input - The right hand side.
867 jgs 123 *
868 jgs 102 */
869     Data& operator*=(const Data& right);
870     Data& operator*=(const boost::python::object& right);
871    
872     /**
873     \brief
874     Overloaded operator /=
875     \param right - Input - The right hand side.
876 jgs 123 *
877 jgs 102 */
878     Data& operator/=(const Data& right);
879     Data& operator/=(const boost::python::object& right);
880    
881     /**
882     \brief
883 jgs 94 Returns true if this can be interpolated to functionspace.
884     */
885     bool
886     probeInterpolation(const FunctionSpace& functionspace) const;
887    
888     /**
889 jgs 102 Data object slicing methods.
890     */
891    
892     /**
893 jgs 94 \brief
894 jgs 102 Returns a slice from this Data object.
895    
896     /description
897     Implements the [] get operator in python.
898     Calls getSlice.
899    
900     \param key - Input - python slice tuple specifying
901     slice to return.
902 jgs 94 */
903 jgs 102 Data
904     getItem(const boost::python::object& key) const;
905    
906     /**
907     \brief
908     Copies slice from value into this Data object.
909    
910     Implements the [] set operator in python.
911     Calls setSlice.
912    
913     \param key - Input - python slice tuple specifying
914     slice to copy from value.
915     \param value - Input - Data object to copy from.
916     */
917 jgs 94 void
918 jgs 102 setItemD(const boost::python::object& key,
919     const Data& value);
920 jgs 94
921 jgs 102 void
922     setItemO(const boost::python::object& key,
923     const boost::python::object& value);
924    
925     // These following public methods should be treated as private.
926    
927 jgs 94 /**
928     \brief
929 jgs 102 Perform the given unary operation on every element of every data point in
930     this Data object.
931 jgs 94 */
932 jgs 102 template <class UnaryFunction>
933     inline
934 jgs 94 void
935 jgs 102 unaryOp(UnaryFunction operation);
936    
937     /**
938     \brief
939     Return a Data object containing the specified slice of
940     this Data object.
941     \param region - Input - Region to copy.
942 jgs 123 *
943 jgs 94 */
944 jgs 102 Data
945     getSlice(const DataArrayView::RegionType& region) const;
946 jgs 94
947 jgs 102 /**
948     \brief
949     Copy the specified slice from the given value into this
950     Data object.
951     \param value - Input - Data to copy from.
952     \param region - Input - Region to copy.
953 jgs 123 *
954 jgs 102 */
955     void
956     setSlice(const Data& value,
957     const DataArrayView::RegionType& region);
958    
959 jgs 119 /**
960     \brief
961     Archive the current Data object to the given file.
962     \param fileName - Input - file to archive to.
963     */
964     void
965     archiveData(const std::string fileName);
966    
967     /**
968     \brief
969     Extract the Data object archived in the given file, overwriting
970     the current Data object.
971     Note - the current object must be of type DataEmpty.
972     \param fileName - Input - file to extract from.
973 jgs 121 \param fspace - Input - a suitable FunctionSpace descibing the data.
974 jgs 119 */
975     void
976     extractData(const std::string fileName,
977     const FunctionSpace& fspace);
978    
979 jgs 102 protected:
980    
981 jgs 94 private:
982    
983     /**
984     \brief
985 jgs 102 Check *this and the right operand are compatible. Throws
986     an exception if they aren't.
987     \param right - Input - The right hand side.
988     */
989     inline
990     void
991     operandCheck(const Data& right) const
992     {
993     return m_data->operandCheck(*(right.m_data.get()));
994     }
995    
996     /**
997     \brief
998     Perform the specified reduction algorithm on every element of every data point in
999 jgs 113 this Data object according to the given function and return the single value result.
1000 jgs 102 */
1001 jgs 147 template <class BinaryFunction>
1002 jgs 102 inline
1003     double
1004 jgs 147 algorithm(BinaryFunction operation,
1005     double initial_value) const;
1006 jgs 102
1007 jgs 113 /**
1008     \brief
1009     Reduce each data-point in this Data object using the given operation. Return a Data
1010     object with the same number of data-points, but with each data-point containing only
1011     one value - the result of the reduction operation on the corresponding data-point in
1012     this Data object
1013     */
1014 jgs 147 template <class BinaryFunction>
1015 jgs 106 inline
1016     Data
1017 jgs 147 dp_algorithm(BinaryFunction operation,
1018     double initial_value) const;
1019 jgs 106
1020 jgs 102 /**
1021     \brief
1022     Perform the given binary operation on all of the data's elements.
1023     The underlying type of the right hand side (right) determines the final
1024     type of *this after the operation. For example if the right hand side
1025     is expanded *this will be expanded if necessary.
1026     RHS is a Data object.
1027     */
1028     template <class BinaryFunction>
1029     inline
1030     void
1031     binaryOp(const Data& right,
1032     BinaryFunction operation);
1033    
1034     /**
1035     \brief
1036     Perform the given binary operation on all of the data's elements.
1037     RHS is a boost::python object.
1038     */
1039     template <class BinaryFunction>
1040     inline
1041     void
1042     binaryOp(const boost::python::object& right,
1043     BinaryFunction operation);
1044    
1045     /**
1046     \brief
1047     Convert the data type of the RHS to match this.
1048     \param right - Input - data type to match.
1049     */
1050     void
1051     typeMatchLeft(Data& right) const;
1052    
1053     /**
1054     \brief
1055     Convert the data type of this to match the RHS.
1056     \param right - Input - data type to match.
1057     */
1058     void
1059     typeMatchRight(const Data& right);
1060    
1061     /**
1062     \brief
1063 jgs 94 Construct a Data object of the appropriate type.
1064     */
1065     template <class IValueType>
1066     void
1067     initialise(const IValueType& value,
1068     const FunctionSpace& what,
1069     bool expanded);
1070    
1071     /**
1072     \brief
1073     Reshape the data point if the data point is currently rank 0.
1074     Will throw an exception if the data points are not rank 0.
1075     The original data point value is used for all values of the new
1076     data point.
1077     */
1078     void
1079     reshapeDataPoint(const DataArrayView::ShapeType& shape);
1080    
1081     //
1082 jgs 102 // pointer to the actual data object
1083 jgs 94 boost::shared_ptr<DataAbstract> m_data;
1084    
1085 jgs 123 //
1086     // pointer to the internal profiling data
1087     struct profDataEntry *profData;
1088    
1089 jgs 94 };
1090    
1091     template <class IValueType>
1092     void
1093     Data::initialise(const IValueType& value,
1094     const FunctionSpace& what,
1095     bool expanded)
1096     {
1097     //
1098     // Construct a Data object of the appropriate type.
1099     // Construct the object first as there seems to be a bug which causes
1100     // undefined behaviour if an exception is thrown during construction
1101     // within the shared_ptr constructor.
1102     if (expanded) {
1103     DataAbstract* temp=new DataExpanded(value,what);
1104 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1105     m_data=temp_data;
1106 jgs 94 } else {
1107     DataAbstract* temp=new DataConstant(value,what);
1108 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1109     m_data=temp_data;
1110 jgs 94 }
1111     }
1112    
1113 jgs 102 /**
1114     Binary Data object operators.
1115     */
1116 jgs 94
1117     /**
1118     \brief
1119     Operator+
1120     Takes two Data objects.
1121     */
1122     Data operator+(const Data& left, const Data& right);
1123    
1124     /**
1125     \brief
1126     Operator-
1127     Takes two Data objects.
1128     */
1129     Data operator-(const Data& left, const Data& right);
1130    
1131     /**
1132     \brief
1133     Operator*
1134     Takes two Data objects.
1135     */
1136     Data operator*(const Data& left, const Data& right);
1137    
1138     /**
1139     \brief
1140     Operator/
1141     Takes two Data objects.
1142     */
1143     Data operator/(const Data& left, const Data& right);
1144    
1145     /**
1146     \brief
1147     Operator+
1148     Takes LHS Data object and RHS python::object.
1149     python::object must be convertable to Data type.
1150     */
1151     Data operator+(const Data& left, const boost::python::object& right);
1152    
1153     /**
1154     \brief
1155     Operator-
1156     Takes LHS Data object and RHS python::object.
1157     python::object must be convertable to Data type.
1158     */
1159     Data operator-(const Data& left, const boost::python::object& right);
1160    
1161     /**
1162     \brief
1163     Operator*
1164     Takes LHS Data object and RHS python::object.
1165     python::object must be convertable to Data type.
1166     */
1167     Data operator*(const Data& left, const boost::python::object& right);
1168    
1169     /**
1170     \brief
1171     Operator/
1172     Takes LHS Data object and RHS python::object.
1173     python::object must be convertable to Data type.
1174     */
1175     Data operator/(const Data& left, const boost::python::object& right);
1176    
1177     /**
1178     \brief
1179     Operator+
1180     Takes LHS python::object and RHS Data object.
1181     python::object must be convertable to Data type.
1182     */
1183     Data operator+(const boost::python::object& left, const Data& right);
1184    
1185     /**
1186     \brief
1187     Operator-
1188     Takes LHS python::object and RHS Data object.
1189     python::object must be convertable to Data type.
1190     */
1191     Data operator-(const boost::python::object& left, const Data& right);
1192    
1193     /**
1194     \brief
1195     Operator*
1196     Takes LHS python::object and RHS Data object.
1197     python::object must be convertable to Data type.
1198     */
1199     Data operator*(const boost::python::object& left, const Data& right);
1200    
1201     /**
1202     \brief
1203     Operator/
1204     Takes LHS python::object and RHS Data object.
1205     python::object must be convertable to Data type.
1206     */
1207     Data operator/(const boost::python::object& left, const Data& right);
1208    
1209     /**
1210     \brief
1211     Output operator
1212     */
1213     std::ostream& operator<<(std::ostream& o, const Data& data);
1214    
1215     /**
1216     \brief
1217     Return true if operands are equivalent, else return false.
1218     NB: this operator does very little at this point, and isn't to
1219     be relied on. Requires further implementation.
1220     */
1221 jgs 102 //bool operator==(const Data& left, const Data& right);
1222 jgs 94
1223 jgs 102 /**
1224     \brief
1225     Perform the given binary operation with this and right as operands.
1226     Right is a Data object.
1227     */
1228 jgs 94 template <class BinaryFunction>
1229     inline
1230     void
1231     Data::binaryOp(const Data& right,
1232     BinaryFunction operation)
1233     {
1234     //
1235     // if this has a rank of zero promote it to the rank of the RHS
1236     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1237     reshapeDataPoint(right.getPointDataView().getShape());
1238     }
1239     //
1240     // initially make the temporary a shallow copy
1241     Data tempRight(right);
1242     if (getFunctionSpace()!=right.getFunctionSpace()) {
1243     if (right.probeInterpolation(getFunctionSpace())) {
1244     //
1245     // an interpolation is required so create a new Data
1246     tempRight=Data(right,this->getFunctionSpace());
1247     } else if (probeInterpolation(right.getFunctionSpace())) {
1248     //
1249     // interpolate onto the RHS function space
1250     Data tempLeft(*this,right.getFunctionSpace());
1251     m_data=tempLeft.m_data;
1252     }
1253     }
1254     operandCheck(tempRight);
1255     //
1256     // ensure this has the right type for the RHS
1257 jgs 102 typeMatchRight(tempRight);
1258 jgs 94 //
1259     // Need to cast to the concrete types so that the correct binaryOp
1260     // is called.
1261     if (isExpanded()) {
1262     //
1263     // Expanded data will be done in parallel, the right hand side can be
1264     // of any data type
1265     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1266     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1267     escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1268     } else if (isTagged()) {
1269     //
1270     // Tagged data is operated on serially, the right hand side can be
1271     // either DataConstant or DataTagged
1272     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1273     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1274     if (right.isTagged()) {
1275     DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1276     EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1277     escript::binaryOp(*leftC,*rightC,operation);
1278     } else {
1279     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1280     EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1281     escript::binaryOp(*leftC,*rightC,operation);
1282     }
1283 jgs 102 } else if (isConstant()) {
1284 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1285     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1286     EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1287     escript::binaryOp(*leftC,*rightC,operation);
1288     }
1289     }
1290    
1291 jgs 102 /**
1292     \brief
1293     Perform the given binary operation with this and right as operands.
1294     Right is a boost::python object.
1295     */
1296 jgs 94 template <class BinaryFunction>
1297     inline
1298     void
1299     Data::binaryOp(const boost::python::object& right,
1300     BinaryFunction operation)
1301     {
1302     DataArray temp(right);
1303     //
1304     // if this has a rank of zero promote it to the rank of the RHS.
1305     if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1306     reshapeDataPoint(temp.getView().getShape());
1307     }
1308     //
1309     // Always allow scalar values for the RHS but check other shapes
1310     if (temp.getView().getRank()!=0) {
1311     if (!getPointDataView().checkShape(temp.getView().getShape())) {
1312     throw DataException(getPointDataView().createShapeErrorMessage(
1313     "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1314     }
1315     }
1316     if (isExpanded()) {
1317     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1318     EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1319     escript::binaryOp(*leftC,temp.getView(),operation);
1320     } else if (isTagged()) {
1321     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1322     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1323     escript::binaryOp(*leftC,temp.getView(),operation);
1324 jgs 102 } else if (isConstant()) {
1325 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1326     EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1327     escript::binaryOp(*leftC,temp.getView(),operation);
1328     }
1329     }
1330    
1331 jgs 102 /**
1332     \brief
1333     Perform the given unary operation on other and return the result.
1334     Given operation is performed on each element of each data point, thus
1335     argument object is a rank n Data object, and returned object is a rank n
1336     Data object.
1337     Calls Data::unaryOp.
1338     */
1339 jgs 94 template <class UnaryFunction>
1340     inline
1341 jgs 102 Data
1342     unaryOp(const Data& other,
1343     UnaryFunction operation)
1344     {
1345     Data result;
1346     result.copy(other);
1347     result.unaryOp(operation);
1348     return result;
1349     }
1350    
1351     /**
1352     \brief
1353     Perform the given unary operation on this.
1354     Given operation is performed on each element of each data point.
1355     Calls escript::unaryOp.
1356     */
1357     template <class UnaryFunction>
1358     inline
1359 jgs 94 void
1360     Data::unaryOp(UnaryFunction operation)
1361     {
1362     if (isExpanded()) {
1363     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1364     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1365     escript::unaryOp(*leftC,operation);
1366     } else if (isTagged()) {
1367     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1368     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1369     escript::unaryOp(*leftC,operation);
1370 jgs 102 } else if (isConstant()) {
1371 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1372     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1373     escript::unaryOp(*leftC,operation);
1374     }
1375     }
1376    
1377 jgs 102 /**
1378     \brief
1379     Perform the given Data object reduction algorithm on this and return the result.
1380     Given operation combines each element of each data point, thus argument
1381     object (*this) is a rank n Data object, and returned object is a scalar.
1382     Calls escript::algorithm.
1383     */
1384 jgs 147 template <class BinaryFunction>
1385 jgs 94 inline
1386     double
1387 jgs 147 Data::algorithm(BinaryFunction operation, double initial_value) const
1388 jgs 94 {
1389     if (isExpanded()) {
1390     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1391     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1392 jgs 147 return escript::algorithm(*leftC,operation,initial_value);
1393 jgs 102 } else if (isTagged()) {
1394 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1395     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1396 jgs 147 return escript::algorithm(*leftC,operation,initial_value);
1397 jgs 102 } else if (isConstant()) {
1398 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1399     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1400 jgs 147 return escript::algorithm(*leftC,operation,initial_value);
1401 jgs 94 }
1402 jgs 102 return 0;
1403 jgs 94 }
1404    
1405 jgs 102 /**
1406     \brief
1407     Perform the given data point reduction algorithm on data and return the result.
1408     Given operation combines each element within each data point into a scalar,
1409     thus argument object is a rank n Data object, and returned object is a
1410     rank 0 Data object.
1411     Calls escript::dp_algorithm.
1412     */
1413 jgs 147 template <class BinaryFunction>
1414 jgs 94 inline
1415     Data
1416 jgs 147 Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1417 jgs 94 {
1418 jgs 106 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1419     if (isExpanded()) {
1420     DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1421 jgs 102 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1422     EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1423     EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1424 jgs 147 escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1425 jgs 106 } else if (isTagged()) {
1426     DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1427 jgs 102 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1428     EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1429     EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1430 jgs 147 escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1431 jgs 106 } else if (isConstant()) {
1432     DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1433 jgs 102 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1434     EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1435     EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1436 jgs 147 escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1437 jgs 102 }
1438 jgs 94 return result;
1439     }
1440    
1441     }
1442     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26