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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 126 - (hide annotations)
Fri Jul 22 03:53:08 2005 UTC (14 years, 4 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 36330 byte(s)
Merge of development branch back to main trunk on 2005-07-22

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26