/[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 82 - (hide annotations)
Tue Oct 26 06:53:54 2004 UTC (17 years, 1 month ago) by jgs
File MIME type: text/plain
File size: 26712 byte(s)
Initial revision

1 jgs 82 // $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     function space of inData the inData are tried to be interpolated to what
92     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     Perform the specified algorithm on the Data and return result.
209     */
210     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     void
220     unaryOp(UnaryFunction operation);
221    
222     /**
223     \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     */
229     template <class BinaryFunction>
230     void
231     binaryOp(const Data& right,
232     BinaryFunction operation);
233    
234     /**
235     \brief
236     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     Return the C wrapper for the Data object.
285     */
286     escriptDataC getDataC();
287    
288     /**
289     \brief
290     Return the C wrapper for the Data object - const version.
291     */
292     escriptDataC getDataC() const;
293    
294     /**
295     \brief
296     Write the data as a string.
297     */
298     std::string toString() const;
299    
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     Perform a deep copy.
316     */
317     void
318     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     expand();
334    
335     /**
336     \brief
337     If possible convert the Data type to tagged. This will only allow
338     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     Return true if this Data is empty.
361     */
362     bool
363     isEmpty() const;
364    
365     /**
366     \brief
367     Return true if this Data is constant.
368     */
369     bool
370     isConstant() const;
371    
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     Return the number of data points per sample.
422     */
423     inline
424     int
425     getNumDataPointsPerSample() const
426     {
427     return m_data->getNumDPPSample();
428     }
429    
430     /**
431     \brief
432     Return the number of samples.
433     */
434     int
435     getNumSamples() const;
436    
437     /**
438     \brief
439     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     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     getSampleData(DataAbstract::ShapeType::size_type sampleNo);
454    
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     getSampleDataByTag(int tag);
463    
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     Return data point shape as a tuple of integers:
490     */
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     Return the number of doubles stored for Data.
505     */
506     DataArrayView::ValueType::size_type
507     getLength() const;
508    
509     /**
510     \brief
511     Interpolates this onto the given functionspace and returns the result as a Data object.
512     */
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     Return a Data with a 1 for +ive values and a 0 for -ive values.
544     */
545     Data
546     whereNonNegative() const;
547    
548     /**
549     \brief
550     Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
551     */
552     Data
553     whereNegative() const;
554    
555     /**
556     \brief
557     Return a Data with a 1 for 0 values a 0 for +ive or -ive.
558     */
559     Data
560     whereZero() const;
561    
562     /**
563     \brief
564     Return the sin of Data.
565     */
566     Data
567     sin() const;
568    
569     /**
570     \brief
571     Return the cos of Data.
572     */
573     Data
574     cos() const;
575    
576     /**
577     \brief
578     Return the tan of Data.
579     */
580     Data
581     tan() const;
582    
583     /**
584     \brief
585     Return the log to base 10 of Data.
586     */
587     Data
588     log() const;
589    
590     /**
591     \brief
592     Return the natural log of Data.
593     */
594     Data
595     ln() const;
596    
597     /**
598     \brief
599     Return a Data containing a slice of this Data.
600     */
601     Data
602     getSlice(const DataArrayView::RegionType& region) const;
603    
604     /**
605     \brief
606     Copy the specified region from the given value.
607     \param value - Input - Data to copy from.
608     \param region - Input - Region to copy.
609     */
610     void
611     setSlice(const Data& value,
612     const DataArrayView::RegionType& region);
613    
614     /**
615     \brief
616     Return the maximum absolute value.
617     */
618     double
619     Lsup() const;
620    
621     /**
622     \brief
623     Return the maximum value.
624     */
625     double
626     sup() const;
627    
628     /**
629     \brief
630     Return the minimum value.
631     */
632     double
633     inf() const;
634    
635     /**
636     \brief
637     Returns a slice from this.
638     */
639     Data
640     getItem(const boost::python::object& key) const;
641    
642     /**
643     \brief
644     Copies slice from value into this.
645     */
646     void
647     setItem(const boost::python::object& key,
648     const Data& value);
649    
650     /**
651     \brief
652     Convert the underlying data type to match the RHS.
653     \param right - Input - data type to match.
654     */
655     void
656     typeMatch(const Data& right);
657    
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     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     */
673     void
674     setTaggedValue(int tagKey,
675     const boost::python::object& value);
676    
677     /**
678     \brief
679     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     */
685     void
686     setTaggedValue(int tagKey,
687     const DataArrayView& value);
688    
689     private:
690    
691     /**
692     \brief
693     Construct a Data object of the appropriate type.
694     */
695     template <class IValueType>
696     void
697     initialise(const IValueType& value,
698     const FunctionSpace& what,
699     bool expanded);
700    
701     /**
702     \brief
703     Reshape the data point if the data point is currently rank 0.
704     Will throw an exception if the data points are not rank 0.
705     The original data point value is used for all values of the new
706     data point.
707     */
708     void
709     reshapeDataPoint(const DataArrayView::ShapeType& shape);
710    
711     //
712     // pointer to the actual data
713     boost::shared_ptr<DataAbstract> m_data;
714    
715     };
716    
717     template <class IValueType>
718     void
719     Data::initialise(const IValueType& value,
720     const FunctionSpace& what,
721     bool expanded)
722     {
723     //
724     // Construct a Data object of the appropriate type.
725     // Construct the object first as there seems to be a bug which causes
726     // undefined behaviour if an exception is thrown during construction
727     // within the shared_ptr constructor.
728     if (expanded) {
729     DataAbstract* temp=new DataExpanded(value,what);
730     m_data=boost::shared_ptr<DataAbstract>(temp);
731     } else {
732     DataAbstract* temp=new DataConstant(value,what);
733     m_data=boost::shared_ptr<DataAbstract>(temp);
734     }
735     }
736    
737     inline
738     DataAbstract::ValueType::value_type*
739     Data::getSampleData(DataAbstract::ValueType::size_type sampleNo)
740     {
741     return m_data->getSampleData(sampleNo);
742     }
743    
744     inline
745     DataAbstract::ValueType::value_type*
746     Data::getSampleDataByTag(int tag)
747     {
748     return m_data->getSampleDataByTag(tag);
749     }
750    
751     inline
752     void
753     Data::operandCheck(const Data& right) const
754     {
755     return m_data->operandCheck(*(right.m_data.get()));
756     }
757    
758     inline
759     int
760     Data::getNumSamples() const
761     {
762     return m_data->getNumSamples();
763     }
764    
765     inline
766     std::string
767     Data::toString() const
768     {
769     return m_data->toString();
770     }
771    
772     /**
773     \brief
774     Operator+
775     Takes two Data objects.
776     */
777     Data operator+(const Data& left, const Data& right);
778    
779     /**
780     \brief
781     Operator-
782     Takes two Data objects.
783     */
784     Data operator-(const Data& left, const Data& right);
785    
786     /**
787     \brief
788     Operator*
789     Takes two Data objects.
790     */
791     Data operator*(const Data& left, const Data& right);
792    
793     /**
794     \brief
795     Operator/
796     Takes two Data objects.
797     */
798     Data operator/(const Data& left, const Data& right);
799    
800     /**
801     \brief
802     Operator+
803     Takes LHS Data object and RHS python::object.
804     python::object must be convertable to Data type.
805     */
806     Data operator+(const Data& left, const boost::python::object& right);
807    
808     /**
809     \brief
810     Operator-
811     Takes LHS Data object and RHS python::object.
812     python::object must be convertable to Data type.
813     */
814     Data operator-(const Data& left, const boost::python::object& right);
815    
816     /**
817     \brief
818     Operator*
819     Takes LHS Data object and RHS python::object.
820     python::object must be convertable to Data type.
821     */
822     Data operator*(const Data& left, const boost::python::object& right);
823    
824     /**
825     \brief
826     Operator/
827     Takes LHS Data object and RHS python::object.
828     python::object must be convertable to Data type.
829     */
830     Data operator/(const Data& left, const boost::python::object& right);
831    
832     /**
833     \brief
834     Operator+
835     Takes LHS python::object and RHS Data object.
836     python::object must be convertable to Data type.
837     */
838     Data operator+(const boost::python::object& left, const Data& right);
839    
840     /**
841     \brief
842     Operator-
843     Takes LHS python::object and RHS Data object.
844     python::object must be convertable to Data type.
845     */
846     Data operator-(const boost::python::object& left, const Data& right);
847    
848     /**
849     \brief
850     Operator*
851     Takes LHS python::object and RHS Data object.
852     python::object must be convertable to Data type.
853     */
854     Data operator*(const boost::python::object& left, const Data& right);
855    
856     /**
857     \brief
858     Operator/
859     Takes LHS python::object and RHS Data object.
860     python::object must be convertable to Data type.
861     */
862     Data operator/(const boost::python::object& left, const Data& right);
863    
864     /**
865     \brief
866     Output operator
867     */
868     std::ostream& operator<<(std::ostream& o, const Data& data);
869    
870     /**
871     \brief
872     Return true if operands are equivalent, else return false.
873     NB: this operator does very little at this point, and isn't to
874     be relied on. Requires further implementation.
875     */
876     bool operator==(const Data& left, const Data& right);
877    
878     template <class BinaryFunction>
879     inline
880     void
881     Data::binaryOp(const Data& right,
882     BinaryFunction operation)
883     {
884     //
885     // if this has a rank of zero promote it to the rank of the RHS
886     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
887     reshapeDataPoint(right.getPointDataView().getShape());
888     }
889     //
890     // initially make the temporary a shallow copy
891     Data tempRight(right);
892     if (getFunctionSpace()!=right.getFunctionSpace()) {
893     if (right.probeInterpolation(getFunctionSpace())) {
894     //
895     // an interpolation is required so create a new Data
896     tempRight=Data(right,this->getFunctionSpace());
897     } else if (probeInterpolation(right.getFunctionSpace())) {
898     //
899     // interpolate onto the RHS function space
900     Data tempLeft(*this,right.getFunctionSpace());
901     m_data=tempLeft.m_data;
902     }
903     }
904     operandCheck(tempRight);
905     //
906     // ensure this has the right type for the RHS
907     typeMatch(tempRight);
908     //
909     // Need to cast to the concrete types so that the correct binaryOp
910     // is called.
911     if (isExpanded()) {
912     //
913     // Expanded data will be done in parallel, the right hand side can be
914     // of any data type
915     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
916     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
917     escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
918     } else if (isTagged()) {
919     //
920     // Tagged data is operated on serially, the right hand side can be
921     // either DataConstant or DataTagged
922     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
923     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
924     if (right.isTagged()) {
925     DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
926     EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
927     escript::binaryOp(*leftC,*rightC,operation);
928     } else {
929     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
930     EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
931     escript::binaryOp(*leftC,*rightC,operation);
932     }
933     } else {
934     //
935     // can only be DataConstant
936     DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
937     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
938     EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
939     escript::binaryOp(*leftC,*rightC,operation);
940     }
941     }
942    
943     template <class BinaryFunction>
944     inline
945     void
946     Data::binaryOp(const boost::python::object& right,
947     BinaryFunction operation)
948     {
949     DataArray temp(right);
950     //
951     // if this has a rank of zero promote it to the rank of the RHS.
952     if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
953     reshapeDataPoint(temp.getView().getShape());
954     }
955     //
956     // Always allow scalar values for the RHS but check other shapes
957     if (temp.getView().getRank()!=0) {
958     if (!getPointDataView().checkShape(temp.getView().getShape())) {
959     throw DataException(getPointDataView().createShapeErrorMessage(
960     "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
961     }
962     }
963    
964     if (isExpanded()) {
965     //
966     // Expanded data will be done in parallel
967     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
968     EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
969     escript::binaryOp(*leftC,temp.getView(),operation);
970     } else if (isTagged()) {
971     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
972     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
973     escript::binaryOp(*leftC,temp.getView(),operation);
974     } else {
975     //
976     // can only be DataConstant
977     DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
978     EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
979     escript::binaryOp(*leftC,temp.getView(),operation);
980     }
981     }
982    
983     template <class UnaryFunction>
984     inline
985     void
986     Data::unaryOp(UnaryFunction operation)
987     {
988     if (isExpanded()) {
989     //
990     // Expanded data will be done in parallel
991     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
992     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
993     escript::unaryOp(*leftC,operation);
994     } else if (isTagged()) {
995     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
996     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
997     escript::unaryOp(*leftC,operation);
998     } else {
999     DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1000     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1001     escript::unaryOp(*leftC,operation);
1002     }
1003     }
1004    
1005     template <class UnaryFunction>
1006     inline
1007     double
1008     Data::algorithm(UnaryFunction operation) const
1009     {
1010     if (isExpanded()) {
1011     //
1012     // Expanded data will be done in parallel
1013     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1014     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1015     return escript::algorithm(*leftC,operation);
1016     }
1017     else if (isTagged()) {
1018     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1019     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1020     return escript::algorithm(*leftC,operation);
1021     } else {
1022     DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1023     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1024     return escript::algorithm(*leftC,operation);
1025     }
1026     }
1027    
1028     template <class UnaryFunction>
1029     inline
1030     Data
1031     unaryOp(const Data& other,
1032     UnaryFunction operation)
1033     {
1034     //
1035     // Perform the given operation on a copy of the input data and return the result
1036     Data result;
1037     //
1038     // perform a deep copy
1039     result.copy(other);
1040     result.unaryOp(operation);
1041     return result;
1042     }
1043    
1044     }
1045    
1046     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26