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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 100 - (hide annotations)
Wed Dec 15 03:48:48 2004 UTC (15 years ago) by jgs
File MIME type: text/plain
File size: 26799 byte(s)
*** empty log message ***

1 jgs 94 // $Id$
2     /*=============================================================================
3    
4     ******************************************************************************
5     * *
6     * COPYRIGHT ACcESS 2004 - All Rights Reserved *
7     * *
8     * This software is the property of ACcESS. No part of this code *
9     * may be copied in any form or by any means without the expressed written *
10     * consent of ACcESS. Copying, use or modification of this software *
11     * by any unauthorised person is illegal unless that *
12     * person has a software license agreement with ACcESS. *
13     * *
14     ******************************************************************************
15    
16     ******************************************************************************/
17    
18     #ifndef DATA_H
19     #define DATA_H
20    
21     #include "escript/Data/DataAbstract.h"
22     #include "escript/Data/DataTagged.h"
23     #include "escript/Data/FunctionSpace.h"
24     #include "escript/Data/BinaryOp.h"
25     #include "escript/Data/UnaryOp.h"
26    
27     extern "C" {
28     #include "escript/Data/DataC.h"
29     }
30    
31     #include <iostream>
32     #include <string>
33     #include <memory>
34     #include <algorithm>
35    
36     #include <boost/shared_ptr.hpp>
37     #include <boost/python/object.hpp>
38     #include <boost/python/list.hpp>
39     #include <boost/python/tuple.hpp>
40     #include <boost/python/numeric.hpp>
41    
42     /**
43     \brief
44     Data is essentially a factory class which creates the appropriate Data
45     object for the given construction arguments. It retains control over
46     the object created for the lifetime of the object.
47     The type of Data object referred to may change during the lifetime of
48     the Data object.
49    
50     Description:
51     Data is essentially a factory class which creates the appropriate Data
52     object for the given construction arguments. It retains control over
53     the object created for the lifetime of the object.
54     The type of Data object referred to may change during the lifetime of
55     the Data object.
56     */
57    
58     namespace escript {
59    
60     //
61     // Forward declaration for various implimentations of Data.
62     class DataEmpty;
63     class DataConstant;
64     class DataTagged;
65     class DataExpanded;
66    
67     class Data {
68    
69     public:
70    
71     typedef double (*UnaryDFunPtr)(double);
72     typedef double (*BinaryDFunPtr)(double,double);
73    
74     /**
75     \brief
76     Default constructor.
77     Creates a DataEmpty object.
78     */
79     Data();
80    
81     /**
82     \brief
83     Copy constructor.
84     WARNING: Only performs a shallow copy.
85     */
86     Data(const Data& inData);
87    
88     /**
89     \brief
90     Constructor from another Data object. If "what" is different from the
91 jgs 100 function space of inData the inData are tried to be interpolated to what
92 jgs 94 otherwise a shallow copy of inData is returned.
93     */
94     Data(const Data& inData,
95     const FunctionSpace& what);
96    
97     /**
98     \brief
99     Constructor which copies data from a DataArrayView.
100    
101     \param value - Input - Data value for a single point.
102     \param what - Input - A description of what this data represents.
103     \param expanded - Input - Flag, if true fill the entire container with
104     the value. Otherwise a more efficient storage
105     mechanism will be used.
106     */
107     Data(const DataArrayView& value,
108     const FunctionSpace& what=FunctionSpace(),
109     bool expanded=false);
110    
111     /**
112     \brief
113     Constructor which creates a Data from a DataArrayView shape.
114    
115     \param value - Input - Single value applied to all Data.
116     \param dataPointShape - Input - The shape of each data point.
117     \param what - Input - A description of what this data represents.
118     \param expanded - Input - Flag, if true fill the entire container with
119     the given value. Otherwise a more efficient storage
120     mechanism will be used.
121     */
122     Data(double value,
123     const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),
124     const FunctionSpace& what=FunctionSpace(),
125     bool expanded=false);
126    
127     /**
128     \brief
129     Constructor which performs a deep copy of a region from another Data object.
130    
131     \param inData - Input - Input Data object.
132     \param region - Input - Region to copy.
133     */
134     Data(const Data& inData,
135     const DataArrayView::RegionType& region);
136    
137     /**
138     \brief
139     Constructor which will create Tagged data if expanded is false.
140     No attempt is made to ensure the tag keys match the tag keys
141     within the function space.
142    
143     \param tagKeys - Input - List of tag values.
144     \param values - Input - List of values, one for each tag.
145     \param defaultValue - Input - A default value, used if tag doesn't exist.
146     \param what - Input - A description of what this data represents.
147     \param expanded - Input - Flag, if true fill the entire container with
148     the appropriate values.
149     */
150     Data(const DataTagged::TagListType& tagKeys,
151     const DataTagged::ValueListType& values,
152     const DataArrayView& defaultValue,
153     const FunctionSpace& what=FunctionSpace(),
154     bool expanded=false);
155    
156     /**
157     \brief
158     Constructor which copies data from a python numarray.
159    
160     \param value - Input - Data value for a single point.
161     \param what - Input - A description of what this data represents.
162     \param expanded - Input - Flag, if true fill the entire container with
163     the value. Otherwise a more efficient storage
164     mechanism will be used.
165     */
166     Data(const boost::python::numeric::array& value,
167     const FunctionSpace& what=FunctionSpace(),
168     bool expanded=false);
169    
170     /**
171     \brief
172     Constructor which copies data from any object that can be converted into
173     a python numarray.
174    
175     \param value - Input - Input data.
176     \param what - Input - A description of what this data represents.
177     \param expanded - Input - Flag, if true fill the entire container with
178     the value. Otherwise a more efficient storage
179     mechanism will be used.
180     */
181     Data(const boost::python::object& value,
182     const FunctionSpace& what=FunctionSpace(),
183     bool expanded=false);
184    
185     /**
186     \brief
187     Constructor which creates a DataConstant.
188     Copies data from any object that can be converted
189     into a numarray. All other parameters are copied from other.
190    
191     \param value - Input - Input data.
192     \param other - Input - contains all other parameters.
193     */
194     Data(const boost::python::object& value,
195     const Data& other);
196    
197     /**
198     \brief
199     Constructor which creates a DataConstant of "shape" with constant value.
200     */
201     Data(double value,
202     const boost::python::tuple& shape=boost::python::make_tuple(),
203     const FunctionSpace& what=FunctionSpace(),
204     bool expanded=false);
205    
206     /**
207     \brief
208 jgs 100 Perform the specified algorithm on the Data and return result.
209 jgs 94 */
210 jgs 100 template <class UnaryFunction>
211     inline double
212     algorithm(UnaryFunction operation) const;
213    
214     /**
215     \brief
216     Perform the given unary operation on all of the data's elements.
217     */
218     template <class UnaryFunction>
219 jgs 94 void
220 jgs 100 unaryOp(UnaryFunction operation);
221 jgs 94
222     /**
223 jgs 100 \brief
224     Perform the given binary operation on all of the data's elements.
225     The underlying type of the right hand side (right) determines the final
226     type of *this after the operation. For example if the right hand side
227     is expanded *this will be expanded if necessary.
228 jgs 94 */
229 jgs 100 template <class BinaryFunction>
230     void
231     binaryOp(const Data& right,
232     BinaryFunction operation);
233 jgs 94
234     /**
235     \brief
236 jgs 100 Perform the given binary operation on all of the data's elements.
237     */
238     template <class BinaryFunction>
239     void
240     binaryOp(const boost::python::object& right,
241     BinaryFunction operation);
242    
243     /**
244     \brief
245     Overloaded operator +=
246     \param right - Input - The right hand side.
247     */
248     Data& operator+=(const Data& right);
249     Data& operator+=(const boost::python::object& right);
250    
251     /**
252     \brief
253     Overloaded operator -=
254     \param right - Input - The right hand side.
255     */
256     Data& operator-=(const Data& right);
257     Data& operator-=(const boost::python::object& right);
258    
259     /**
260     \brief
261     Overloaded operator *=
262     \param right - Input - The right hand side.
263     */
264     Data& operator*=(const Data& right);
265     Data& operator*=(const boost::python::object& right);
266    
267     /**
268     \brief
269     Overloaded operator /=
270     \param right - Input - The right hand side.
271     */
272     Data& operator/=(const Data& right);
273     Data& operator/=(const boost::python::object& right);
274    
275     /**
276     \brief
277     Return the power of Data.
278     */
279     Data powD(const Data& right) const;
280     Data powO(const boost::python::object& right) const;
281    
282     /**
283     \brief
284 jgs 94 Return the C wrapper for the Data object.
285     */
286 jgs 100 escriptDataC getDataC();
287 jgs 94
288     /**
289     \brief
290     Return the C wrapper for the Data object - const version.
291     */
292 jgs 100 escriptDataC getDataC() const;
293 jgs 94
294     /**
295     \brief
296     Write the data as a string.
297     */
298 jgs 100 std::string toString() const;
299 jgs 94
300     /**
301     \brief
302     Return the DataArrayView of the point data. This essentially contains
303     the shape information for each data point although it also may be used
304     to manipulate the point data.
305     */
306     inline
307     const DataArrayView&
308     getPointDataView() const
309     {
310     return m_data->getPointDataView();
311     }
312    
313     /**
314     \brief
315 jgs 100 Perform a deep copy.
316 jgs 94 */
317     void
318 jgs 100 copy(const Data& other);
319    
320     /**
321     \brief
322     Copy other Data object into this Data object where mask is positive.
323     */
324     void
325     copyWithMask(const Data& other,
326     const Data& mask);
327    
328     /**
329     \brief
330     Whatever the current Data type make it expanded.
331     */
332     void
333 jgs 94 expand();
334    
335     /**
336     \brief
337 jgs 100 If possible convert the Data type to tagged. This will only allow
338 jgs 94 Constant data to be converted to tagged. An attempt to convert
339     Expanded data to tagged will throw an exception.
340     */
341     void
342     tag();
343    
344     /**
345     \brief
346     Return true if this Data is expanded.
347     */
348     bool
349     isExpanded() const;
350    
351     /**
352     \brief
353     Return true if this Data is tagged.
354     */
355     bool
356     isTagged() const;
357    
358     /**
359     \brief
360 jgs 100 Return true if this Data is empty.
361 jgs 94 */
362     bool
363 jgs 100 isEmpty() const;
364 jgs 94
365     /**
366     \brief
367 jgs 100 Return true if this Data is constant.
368 jgs 94 */
369     bool
370 jgs 100 isConstant() const;
371 jgs 94
372     /**
373     \brief
374     Return the function space.
375     */
376     inline
377     const FunctionSpace&
378     getFunctionSpace() const
379     {
380     return m_data->getFunctionSpace();
381     }
382    
383     /**
384     \brief
385     Return a copy of the function space.
386     */
387     const FunctionSpace
388     getCopyOfFunctionSpace() const;
389    
390     /**
391     \brief
392     Return the domain.
393     */
394     inline
395     const AbstractDomain&
396     getDomain() const
397     {
398     return getFunctionSpace().getDomain();
399     }
400    
401     /**
402     \brief
403     Return a copy of the domain.
404     */
405     const AbstractDomain
406     getCopyOfDomain() const;
407    
408     /**
409     \brief
410     Return the rank of the point data.
411     */
412     inline
413     int
414     getDataPointRank() const
415     {
416     return m_data->getPointDataView().getRank();
417     }
418    
419     /**
420     \brief
421 jgs 100 Return the number of data points per sample.
422 jgs 94 */
423     inline
424     int
425 jgs 100 getNumDataPointsPerSample() const
426 jgs 94 {
427 jgs 100 return m_data->getNumDPPSample();
428 jgs 94 }
429    
430     /**
431     \brief
432 jgs 100 Return the number of samples.
433 jgs 94 */
434     int
435 jgs 100 getNumSamples() const;
436 jgs 94
437     /**
438     \brief
439 jgs 100 Check *this and the right operand are compatible. Throws
440     an exception if they aren't.
441     \param right - Input - The right hand side.
442     */
443     void
444     operandCheck(const Data& right) const;
445    
446     /**
447     \brief
448 jgs 94 Return the sample data for the given sample no. This is not the
449     preferred interface but is provided for use by C code.
450     \param sampleNo - Input - the given sample no.
451     */
452     DataAbstract::ValueType::value_type*
453 jgs 100 getSampleData(DataAbstract::ShapeType::size_type sampleNo);
454 jgs 94
455     /**
456     \brief
457     Return the sample data for the given tag. If an attempt is made to
458     access data that isn't tagged an exception will be thrown.
459     \param tag - Input - the tag key.
460     */
461     DataAbstract::ValueType::value_type*
462 jgs 100 getSampleDataByTag(int tag);
463 jgs 94
464     /**
465     \brief
466     Return a view into the data for the data point specified.
467     NOTE: Construction of the DataArrayView is a relatively expensive
468     operation.
469     \param sampleNo - Input -
470     \param dataPointNo - Input -
471     */
472     inline
473     DataArrayView
474     getDataPoint(int sampleNo,
475     int dataPointNo)
476     {
477     return m_data->getDataPoint(sampleNo,dataPointNo);
478     }
479    
480     /**
481     \brief
482     Return a reference to the data point shape.
483     */
484     const DataArrayView::ShapeType&
485     getDataPointShape() const;
486    
487     /**
488     \brief
489 jgs 100 Return data point shape as a tuple of integers:
490 jgs 94 */
491     boost::python::tuple
492     getShapeTuple() const;
493    
494     /**
495     \brief
496     Return the size of the data point. It is the product of the
497     data point shape dimensions.
498     */
499     int
500     getDataPointSize() const;
501    
502     /**
503     \brief
504 jgs 100 Return the number of doubles stored for Data.
505 jgs 94 */
506     DataArrayView::ValueType::size_type
507     getLength() const;
508    
509     /**
510     \brief
511 jgs 100 Interpolates this onto the given functionspace and returns the result as a Data object.
512 jgs 94 */
513     Data
514     interpolate(const FunctionSpace& functionspace) const;
515    
516     /**
517     \brief
518     Calculates the gradient of the data at the data points of functionspace.
519     If functionspace is not present the function space of Function(getDomain()) is used.
520     */
521     Data
522     gradOn(const FunctionSpace& functionspace) const;
523    
524     Data
525     grad() const;
526    
527     /**
528     \brief
529     Calculate the integral over the function space domain.
530     */
531     boost::python::numeric::array
532     integrate() const;
533    
534     /**
535     \brief
536     Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
537     */
538     Data
539     wherePositive() const;
540    
541     /**
542     \brief
543 jgs 100 Return a Data with a 1 for +ive values and a 0 for -ive values.
544 jgs 94 */
545     Data
546     whereNonNegative() const;
547    
548     /**
549     \brief
550 jgs 100 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
551 jgs 94 */
552     Data
553 jgs 100 whereNegative() const;
554 jgs 94
555     /**
556     \brief
557 jgs 100 Return a Data with a 1 for 0 values a 0 for +ive or -ive.
558 jgs 94 */
559     Data
560     whereZero() const;
561    
562     /**
563     \brief
564 jgs 100 Return the sin of Data.
565 jgs 94 */
566     Data
567     sin() const;
568    
569     /**
570     \brief
571 jgs 100 Return the cos of Data.
572 jgs 94 */
573     Data
574     cos() const;
575    
576     /**
577     \brief
578 jgs 100 Return the tan of Data.
579 jgs 94 */
580     Data
581     tan() const;
582    
583     /**
584     \brief
585 jgs 100 Return the log to base 10 of Data.
586 jgs 94 */
587     Data
588     log() const;
589    
590     /**
591     \brief
592 jgs 100 Return the natural log of Data.
593 jgs 94 */
594     Data
595     ln() const;
596    
597     /**
598     \brief
599 jgs 100 Return a Data containing a slice of this Data.
600 jgs 94 */
601 jgs 100 Data
602     getSlice(const DataArrayView::RegionType& region) const;
603 jgs 94
604     /**
605     \brief
606 jgs 100 Copy the specified region from the given value.
607     \param value - Input - Data to copy from.
608     \param region - Input - Region to copy.
609 jgs 94 */
610 jgs 100 void
611     setSlice(const Data& value,
612     const DataArrayView::RegionType& region);
613 jgs 94
614     /**
615     \brief
616 jgs 100 Return the maximum absolute value.
617 jgs 94 */
618     double
619 jgs 100 Lsup() const;
620 jgs 94
621     /**
622     \brief
623 jgs 100 Return the maximum value.
624 jgs 94 */
625 jgs 100 double
626     sup() const;
627 jgs 94
628     /**
629     \brief
630 jgs 100 Return the minimum value.
631 jgs 94 */
632 jgs 100 double
633     inf() const;
634 jgs 94
635     /**
636     \brief
637 jgs 100 Returns a slice from this.
638 jgs 94 */
639     Data
640 jgs 100 getItem(const boost::python::object& key) const;
641 jgs 94
642     /**
643     \brief
644 jgs 100 Copies slice from value into this.
645 jgs 94 */
646 jgs 100 void
647     setItem(const boost::python::object& key,
648     const Data& value);
649 jgs 94
650     /**
651     \brief
652 jgs 100 Convert the underlying data type to match the RHS.
653     \param right - Input - data type to match.
654 jgs 94 */
655 jgs 100 void
656     typeMatch(const Data& right);
657 jgs 94
658     /**
659     \brief
660     Returns true if this can be interpolated to functionspace.
661     */
662     bool
663     probeInterpolation(const FunctionSpace& functionspace) const;
664    
665     /**
666     \brief
667 jgs 100 Assign the given value to the tag. Implicitly converts this
668     object to type DataTagged. Throws an exception if this object
669     cannot be converted to a DataTagged object.
670     \param tagKey - Input - Integer key.
671     \param value - Input - Value to associate with given key.
672 jgs 94 */
673     void
674 jgs 100 setTaggedValue(int tagKey,
675     const boost::python::object& value);
676 jgs 94
677     /**
678     \brief
679 jgs 100 Assign the given value to the tag. Implicitly converts this
680     object to type DataTagged. Throws an exception if this object
681     cannot be converted to a DataTagged object.
682     \param tagKey - Input - Integer key.
683     \param value - Input - Value to associate with given key.
684     Note: removed for now - this version not needed, and breaks escript.cpp
685 jgs 94 */
686 jgs 100 /*
687 jgs 94 void
688 jgs 100 setTaggedValue(int tagKey,
689     const DataArrayView& value);
690 jgs 94 */
691    
692     private:
693    
694     /**
695     \brief
696     Construct a Data object of the appropriate type.
697     */
698     template <class IValueType>
699     void
700     initialise(const IValueType& value,
701     const FunctionSpace& what,
702     bool expanded);
703    
704     /**
705     \brief
706     Reshape the data point if the data point is currently rank 0.
707     Will throw an exception if the data points are not rank 0.
708     The original data point value is used for all values of the new
709     data point.
710     */
711     void
712     reshapeDataPoint(const DataArrayView::ShapeType& shape);
713    
714     //
715 jgs 100 // pointer to the actual data
716 jgs 94 boost::shared_ptr<DataAbstract> m_data;
717    
718     };
719    
720     template <class IValueType>
721     void
722     Data::initialise(const IValueType& value,
723     const FunctionSpace& what,
724     bool expanded)
725     {
726     //
727     // Construct a Data object of the appropriate type.
728     // Construct the object first as there seems to be a bug which causes
729     // undefined behaviour if an exception is thrown during construction
730     // within the shared_ptr constructor.
731     if (expanded) {
732     DataAbstract* temp=new DataExpanded(value,what);
733 jgs 100 m_data=boost::shared_ptr<DataAbstract>(temp);
734 jgs 94 } else {
735     DataAbstract* temp=new DataConstant(value,what);
736 jgs 100 m_data=boost::shared_ptr<DataAbstract>(temp);
737 jgs 94 }
738     }
739    
740 jgs 100 inline
741     DataAbstract::ValueType::value_type*
742     Data::getSampleData(DataAbstract::ValueType::size_type sampleNo)
743     {
744     return m_data->getSampleData(sampleNo);
745     }
746 jgs 94
747 jgs 100 inline
748     DataAbstract::ValueType::value_type*
749     Data::getSampleDataByTag(int tag)
750     {
751     return m_data->getSampleDataByTag(tag);
752     }
753    
754     inline
755     void
756     Data::operandCheck(const Data& right) const
757     {
758     return m_data->operandCheck(*(right.m_data.get()));
759     }
760    
761     inline
762     int
763     Data::getNumSamples() const
764     {
765     return m_data->getNumSamples();
766     }
767    
768     inline
769     std::string
770     Data::toString() const
771     {
772     return m_data->toString();
773     }
774    
775 jgs 94 /**
776     \brief
777     Operator+
778     Takes two Data objects.
779     */
780     Data operator+(const Data& left, const Data& right);
781    
782     /**
783     \brief
784     Operator-
785     Takes two Data objects.
786     */
787     Data operator-(const Data& left, const Data& right);
788    
789     /**
790     \brief
791     Operator*
792     Takes two Data objects.
793     */
794     Data operator*(const Data& left, const Data& right);
795    
796     /**
797     \brief
798     Operator/
799     Takes two Data objects.
800     */
801     Data operator/(const Data& left, const Data& right);
802    
803     /**
804     \brief
805     Operator+
806     Takes LHS Data object and RHS python::object.
807     python::object must be convertable to Data type.
808     */
809     Data operator+(const Data& left, const boost::python::object& right);
810    
811     /**
812     \brief
813     Operator-
814     Takes LHS Data object and RHS python::object.
815     python::object must be convertable to Data type.
816     */
817     Data operator-(const Data& left, const boost::python::object& right);
818    
819     /**
820     \brief
821     Operator*
822     Takes LHS Data object and RHS python::object.
823     python::object must be convertable to Data type.
824     */
825     Data operator*(const Data& left, const boost::python::object& right);
826    
827     /**
828     \brief
829     Operator/
830     Takes LHS Data object and RHS python::object.
831     python::object must be convertable to Data type.
832     */
833     Data operator/(const Data& left, const boost::python::object& right);
834    
835     /**
836     \brief
837     Operator+
838     Takes LHS python::object and RHS Data object.
839     python::object must be convertable to Data type.
840     */
841     Data operator+(const boost::python::object& left, const Data& right);
842    
843     /**
844     \brief
845     Operator-
846     Takes LHS python::object and RHS Data object.
847     python::object must be convertable to Data type.
848     */
849     Data operator-(const boost::python::object& left, const Data& right);
850    
851     /**
852     \brief
853     Operator*
854     Takes LHS python::object and RHS Data object.
855     python::object must be convertable to Data type.
856     */
857     Data operator*(const boost::python::object& left, const Data& right);
858    
859     /**
860     \brief
861     Operator/
862     Takes LHS python::object and RHS Data object.
863     python::object must be convertable to Data type.
864     */
865     Data operator/(const boost::python::object& left, const Data& right);
866    
867     /**
868     \brief
869     Output operator
870     */
871     std::ostream& operator<<(std::ostream& o, const Data& data);
872    
873     /**
874     \brief
875     Return true if operands are equivalent, else return false.
876     NB: this operator does very little at this point, and isn't to
877     be relied on. Requires further implementation.
878     */
879 jgs 100 bool operator==(const Data& left, const Data& right);
880 jgs 94
881     template <class BinaryFunction>
882     inline
883     void
884     Data::binaryOp(const Data& right,
885     BinaryFunction operation)
886     {
887     //
888     // if this has a rank of zero promote it to the rank of the RHS
889     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
890     reshapeDataPoint(right.getPointDataView().getShape());
891     }
892     //
893     // initially make the temporary a shallow copy
894     Data tempRight(right);
895     if (getFunctionSpace()!=right.getFunctionSpace()) {
896     if (right.probeInterpolation(getFunctionSpace())) {
897     //
898     // an interpolation is required so create a new Data
899     tempRight=Data(right,this->getFunctionSpace());
900     } else if (probeInterpolation(right.getFunctionSpace())) {
901     //
902     // interpolate onto the RHS function space
903     Data tempLeft(*this,right.getFunctionSpace());
904     m_data=tempLeft.m_data;
905     }
906     }
907     operandCheck(tempRight);
908     //
909     // ensure this has the right type for the RHS
910 jgs 100 typeMatch(tempRight);
911 jgs 94 //
912     // Need to cast to the concrete types so that the correct binaryOp
913     // is called.
914     if (isExpanded()) {
915     //
916     // Expanded data will be done in parallel, the right hand side can be
917     // of any data type
918     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
919     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
920     escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
921     } else if (isTagged()) {
922     //
923     // Tagged data is operated on serially, the right hand side can be
924     // either DataConstant or DataTagged
925     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
926     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
927     if (right.isTagged()) {
928     DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
929     EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
930     escript::binaryOp(*leftC,*rightC,operation);
931     } else {
932     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
933     EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
934     escript::binaryOp(*leftC,*rightC,operation);
935     }
936 jgs 100 } else {
937     //
938     // can only be DataConstant
939 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
940     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
941     EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
942     escript::binaryOp(*leftC,*rightC,operation);
943     }
944     }
945    
946     template <class BinaryFunction>
947     inline
948     void
949     Data::binaryOp(const boost::python::object& right,
950     BinaryFunction operation)
951     {
952     DataArray temp(right);
953     //
954     // if this has a rank of zero promote it to the rank of the RHS.
955     if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
956     reshapeDataPoint(temp.getView().getShape());
957     }
958     //
959     // Always allow scalar values for the RHS but check other shapes
960     if (temp.getView().getRank()!=0) {
961     if (!getPointDataView().checkShape(temp.getView().getShape())) {
962     throw DataException(getPointDataView().createShapeErrorMessage(
963     "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
964     }
965     }
966 jgs 100
967 jgs 94 if (isExpanded()) {
968 jgs 100 //
969     // Expanded data will be done in parallel
970 jgs 94 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
971     EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
972     escript::binaryOp(*leftC,temp.getView(),operation);
973     } else if (isTagged()) {
974     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
975     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
976     escript::binaryOp(*leftC,temp.getView(),operation);
977 jgs 100 } else {
978     //
979     // can only be DataConstant
980 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
981     EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
982     escript::binaryOp(*leftC,temp.getView(),operation);
983     }
984     }
985    
986     template <class UnaryFunction>
987     inline
988     void
989     Data::unaryOp(UnaryFunction operation)
990     {
991     if (isExpanded()) {
992 jgs 100 //
993     // Expanded data will be done in parallel
994 jgs 94 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
995     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
996     escript::unaryOp(*leftC,operation);
997     } else if (isTagged()) {
998     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
999     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1000     escript::unaryOp(*leftC,operation);
1001 jgs 100 } else {
1002 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1003     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1004     escript::unaryOp(*leftC,operation);
1005     }
1006     }
1007    
1008     template <class UnaryFunction>
1009     inline
1010     double
1011     Data::algorithm(UnaryFunction operation) const
1012     {
1013     if (isExpanded()) {
1014 jgs 100 //
1015     // Expanded data will be done in parallel
1016 jgs 94 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1017     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1018     return escript::algorithm(*leftC,operation);
1019 jgs 100 }
1020     else if (isTagged()) {
1021 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1022     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1023     return escript::algorithm(*leftC,operation);
1024 jgs 100 } else {
1025 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1026     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1027     return escript::algorithm(*leftC,operation);
1028     }
1029     }
1030    
1031     template <class UnaryFunction>
1032     inline
1033     Data
1034 jgs 100 unaryOp(const Data& other,
1035     UnaryFunction operation)
1036 jgs 94 {
1037 jgs 100 //
1038     // Perform the given operation on a copy of the input data and return the result
1039     Data result;
1040     //
1041     // perform a deep copy
1042     result.copy(other);
1043     result.unaryOp(operation);
1044 jgs 94 return result;
1045     }
1046    
1047     }
1048 jgs 100
1049 jgs 94 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26