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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 97 - (hide annotations)
Tue Dec 14 05:39:33 2004 UTC (14 years, 11 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.cpp
File size: 23417 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     #include "escript/Data/Data.h"
19    
20     #include <iostream>
21     #include <algorithm>
22     #include <vector>
23     #include <exception>
24     #include <functional>
25     #include <math.h>
26    
27     #include <boost/python/str.hpp>
28     #include <boost/python/extract.hpp>
29     #include <boost/python/long.hpp>
30    
31     #include "escript/Data/DataException.h"
32    
33     #include "escript/Data/DataExpanded.h"
34     #include "escript/Data/DataConstant.h"
35     #include "escript/Data/DataTagged.h"
36     #include "escript/Data/DataEmpty.h"
37     #include "escript/Data/DataArray.h"
38     #include "escript/Data/DataAlgorithm.h"
39     #include "escript/Data/FunctionSpaceFactory.h"
40     #include "escript/Data/AbstractContinuousDomain.h"
41 jgs 97 #include "escript/Data/UnaryFuncs.h"
42 jgs 94
43     using namespace std;
44     using namespace boost::python;
45     using namespace boost;
46     using namespace escript;
47    
48     Data::Data()
49     {
50     //
51     // Default data is type DataEmpty
52     DataAbstract* temp=new DataEmpty();
53 jgs 97 shared_ptr<DataAbstract> temp_data(temp);
54     m_data=temp_data;
55 jgs 94 }
56    
57     Data::Data(double value,
58     const tuple& shape,
59     const FunctionSpace& what,
60     bool expanded)
61     {
62     DataArrayView::ShapeType dataPointShape;
63     for (int i = 0; i < shape.attr("__len__")(); ++i) {
64     dataPointShape.push_back(extract<const int>(shape[i]));
65     }
66     DataArray temp(dataPointShape,value);
67     initialise(temp.getView(),what,expanded);
68     }
69    
70     Data::Data(double value,
71     const DataArrayView::ShapeType& dataPointShape,
72     const FunctionSpace& what,
73     bool expanded)
74     {
75     DataArray temp(dataPointShape,value);
76     pair<int,int> dataShape=what.getDataShape();
77     initialise(temp.getView(),what,expanded);
78     }
79    
80 jgs 97 Data::Data(const Data& inData)
81 jgs 94 {
82 jgs 97 m_data=inData.m_data;
83 jgs 94 }
84    
85     Data::Data(const Data& inData,
86     const DataArrayView::RegionType& region)
87     {
88     //
89 jgs 97 // Create Data which is a slice of another Data
90     DataAbstract* tmp = inData.m_data->getSlice(region);
91     shared_ptr<DataAbstract> temp_data(tmp);
92     m_data=temp_data;
93 jgs 94 }
94    
95     Data::Data(const Data& inData,
96     const FunctionSpace& functionspace)
97     {
98     if (inData.getFunctionSpace()==functionspace) {
99     m_data=inData.m_data;
100     } else {
101     Data tmp(0,inData.getPointDataView().getShape(),functionspace,true);
102     // Note for Lutz, Must use a reference or pointer to a derived object
103     // in order to get polymorphic behaviour. Shouldn't really
104     // be able to create an instance of AbstractDomain but that was done
105     // as a boost python work around which may no longer be required.
106     const AbstractDomain& inDataDomain=inData.getDomain();
107     if (inDataDomain==functionspace.getDomain()) {
108     inDataDomain.interpolateOnDomain(tmp,inData);
109     } else {
110     inDataDomain.interpolateACross(tmp,inData);
111     }
112     m_data=tmp.m_data;
113     }
114     }
115    
116     Data::Data(const DataTagged::TagListType& tagKeys,
117     const DataTagged::ValueListType & values,
118     const DataArrayView& defaultValue,
119     const FunctionSpace& what,
120     bool expanded)
121     {
122     DataAbstract* temp=new DataTagged(tagKeys,values,defaultValue,what);
123 jgs 97 shared_ptr<DataAbstract> temp_data(temp);
124     m_data=temp_data;
125 jgs 94 if (expanded) {
126     expand();
127     }
128     }
129    
130     Data::Data(const numeric::array& value,
131     const FunctionSpace& what,
132     bool expanded)
133     {
134     initialise(value,what,expanded);
135     }
136    
137     Data::Data(const DataArrayView& value,
138     const FunctionSpace& what,
139     bool expanded)
140     {
141     initialise(value,what,expanded);
142     }
143    
144     Data::Data(const object& value,
145     const FunctionSpace& what,
146     bool expanded)
147     {
148     numeric::array asNumArray(value);
149     initialise(asNumArray,what,expanded);
150     }
151    
152     Data::Data(const object& value,
153     const Data& other)
154     {
155     //
156     // Create DataConstant using the given value and all other parameters
157     // copied from other. If value is a rank 0 object this Data
158     // will assume the point data shape of other.
159     DataArray temp(value);
160     if (temp.getView().getRank()==0) {
161     //
162     // Create a DataArray with the scalar value for all elements
163     DataArray temp2(other.getPointDataView().getShape(),temp.getView()());
164     initialise(temp2.getView(),other.getFunctionSpace(),false);
165     } else {
166     //
167     // Create a DataConstant with the same sample shape as other
168     initialise(temp.getView(),other.getFunctionSpace(),false);
169     }
170     }
171    
172     escriptDataC
173     Data::getDataC()
174     {
175     escriptDataC temp;
176     temp.m_dataPtr=(void*)this;
177     return temp;
178     }
179    
180     escriptDataC
181     Data::getDataC() const
182     {
183     escriptDataC temp;
184     temp.m_dataPtr=(void*)this;
185     return temp;
186     }
187    
188     tuple
189     Data::getShapeTuple() const
190     {
191     const DataArrayView::ShapeType& shape=getDataPointShape();
192     switch(getDataPointRank()) {
193     case 0:
194     return make_tuple();
195     case 1:
196     return make_tuple(long_(shape[0]));
197     case 2:
198     return make_tuple(long_(shape[0]),long_(shape[1]));
199     case 3:
200     return make_tuple(long_(shape[0]),long_(shape[1]),long_(shape[2]));
201     case 4:
202     return make_tuple(long_(shape[0]),long_(shape[1]),long_(shape[2]),long_(shape[3]));
203     default:
204     throw DataException("Error - illegal Data rank.");
205     }
206     }
207    
208     void
209     Data::copy(const Data& other)
210     {
211     //
212     // Perform a deep copy
213     {
214     DataExpanded* temp=dynamic_cast<DataExpanded*>(other.m_data.get());
215     if (temp!=0) {
216     //
217     // Construct a DataExpanded copy
218     DataAbstract* newData=new DataExpanded(*temp);
219 jgs 97 shared_ptr<DataAbstract> temp_data(newData);
220     m_data=temp_data;
221 jgs 94 return;
222     }
223     }
224     {
225     DataTagged* temp=dynamic_cast<DataTagged*>(other.m_data.get());
226     if (temp!=0) {
227     //
228 jgs 97 // Construct a DataTagged copy
229 jgs 94 DataAbstract* newData=new DataTagged(*temp);
230 jgs 97 shared_ptr<DataAbstract> temp_data(newData);
231     m_data=temp_data;
232 jgs 94 return;
233     }
234     }
235     {
236     DataConstant* temp=dynamic_cast<DataConstant*>(other.m_data.get());
237     if (temp!=0) {
238     //
239     // Construct a DataConstant copy
240     DataAbstract* newData=new DataConstant(*temp);
241 jgs 97 shared_ptr<DataAbstract> temp_data(newData);
242     m_data=temp_data;
243 jgs 94 return;
244     }
245     }
246 jgs 97 {
247     DataEmpty* temp=dynamic_cast<DataEmpty*>(other.m_data.get());
248     if (temp!=0) {
249     //
250     // Construct a DataEmpty copy
251     DataAbstract* newData=new DataEmpty();
252     shared_ptr<DataAbstract> temp_data(newData);
253     m_data=temp_data;
254     return;
255     }
256     }
257 jgs 94 throw DataException("Error - Copy not implemented for this Data type.");
258     }
259    
260     void
261     Data::copyWithMask(const Data& other,
262     const Data& mask)
263     {
264     Data mask1;
265     Data mask2;
266    
267     mask1 = mask.wherePositive();
268     mask2.copy(mask1);
269    
270     mask1 *= other;
271     mask2 *= *this;
272     mask2 = *this - mask2;
273    
274     *this = mask1 + mask2;
275     }
276    
277     bool
278     Data::isExpanded() const
279     {
280     DataExpanded* temp=dynamic_cast<DataExpanded*>(m_data.get());
281     return (temp!=0);
282     }
283    
284     bool
285     Data::isTagged() const
286     {
287     DataTagged* temp=dynamic_cast<DataTagged*>(m_data.get());
288     return (temp!=0);
289     }
290    
291     bool
292     Data::isEmpty() const
293     {
294     DataEmpty* temp=dynamic_cast<DataEmpty*>(m_data.get());
295     return (temp!=0);
296     }
297    
298     bool
299     Data::isConstant() const
300     {
301     DataConstant* temp=dynamic_cast<DataConstant*>(m_data.get());
302     return (temp!=0);
303     }
304    
305     void
306     Data::expand()
307     {
308     if (isConstant()) {
309     DataConstant* tempDataConst=dynamic_cast<DataConstant*>(m_data.get());
310     DataAbstract* temp=new DataExpanded(*tempDataConst);
311 jgs 97 shared_ptr<DataAbstract> temp_data(temp);
312     m_data=temp_data;
313 jgs 94 } else if (isTagged()) {
314     DataTagged* tempDataTag=dynamic_cast<DataTagged*>(m_data.get());
315     DataAbstract* temp=new DataExpanded(*tempDataTag);
316 jgs 97 shared_ptr<DataAbstract> temp_data(temp);
317     m_data=temp_data;
318 jgs 94 } else if (isExpanded()) {
319     //
320     // do nothing
321     } else if (isEmpty()) {
322     throw DataException("Error - Expansion of DataEmpty not possible.");
323     } else {
324     throw DataException("Error - Expansion not implemented for this Data type.");
325     }
326     }
327    
328     void
329     Data::tag()
330     {
331     if (isConstant()) {
332     DataConstant* tempDataConst=dynamic_cast<DataConstant*>(m_data.get());
333     DataAbstract* temp=new DataTagged(*tempDataConst);
334 jgs 97 shared_ptr<DataAbstract> temp_data(temp);
335     m_data=temp_data;
336 jgs 94 } else if (isTagged()) {
337     // do nothing
338     } else if (isExpanded()) {
339     throw DataException("Error - Creating tag data from DataExpanded not possible.");
340     } else if (isEmpty()) {
341     throw DataException("Error - Creating tag data from DataEmpty not possible.");
342     } else {
343     throw DataException("Error - Tagging not implemented for this Data type.");
344     }
345     }
346    
347 jgs 97 void
348     Data::reshapeDataPoint(const DataArrayView::ShapeType& shape)
349     {
350     m_data->reshapeDataPoint(shape);
351     }
352    
353 jgs 94 Data
354     Data::wherePositive() const
355     {
356     return escript::unaryOp(*this,bind2nd(greater<double>(),0.0));
357     }
358    
359     Data
360 jgs 97 Data::whereNegative() const
361     {
362     return escript::unaryOp(*this,bind2nd(less<double>(),0.0));
363     }
364    
365     Data
366 jgs 94 Data::whereNonNegative() const
367     {
368     return escript::unaryOp(*this,bind2nd(greater_equal<double>(),0.0));
369     }
370    
371     Data
372 jgs 97 Data::whereNonPositive() const
373 jgs 94 {
374 jgs 97 return escript::unaryOp(*this,bind2nd(less_equal<double>(),0.0));
375 jgs 94 }
376    
377     Data
378     Data::whereZero() const
379     {
380     return escript::unaryOp(*this,bind2nd(equal_to<double>(),0.0));
381     }
382    
383     Data
384 jgs 97 Data::whereNonZero() const
385     {
386     return escript::unaryOp(*this,bind2nd(not_equal_to<double>(),0.0));
387     }
388    
389     Data
390 jgs 94 Data::interpolate(const FunctionSpace& functionspace) const
391     {
392     return Data(*this,functionspace);
393     }
394    
395     bool
396     Data::probeInterpolation(const FunctionSpace& functionspace) const
397     {
398     if (getFunctionSpace()==functionspace) {
399     return true;
400     } else {
401     const AbstractDomain& domain=getDomain();
402     if (domain==functionspace.getDomain()) {
403     return domain.probeInterpolationOnDomain(getFunctionSpace().getTypeCode(),functionspace.getTypeCode());
404     } else {
405     return domain.probeInterpolationACross(getFunctionSpace().getTypeCode(),functionspace.getDomain(),functionspace.getTypeCode());
406     }
407     }
408     }
409    
410     Data
411     Data::gradOn(const FunctionSpace& functionspace) const
412     {
413     if (functionspace.getDomain()!=getDomain())
414     throw DataException("Error - gradient cannot be calculated on different domains.");
415     DataArrayView::ShapeType grad_shape=getPointDataView().getShape();
416     grad_shape.push_back(functionspace.getDim());
417     Data out(0.0,grad_shape,functionspace,true);
418     getDomain().setToGradient(out,*this);
419     return out;
420     }
421    
422     Data
423     Data::grad() const
424     {
425     return gradOn(escript::function(getDomain()));
426     }
427    
428     int
429     Data::getDataPointSize() const
430     {
431     return getPointDataView().noValues();
432     }
433    
434     DataArrayView::ValueType::size_type
435     Data::getLength() const
436     {
437     return m_data->getLength();
438     }
439    
440     const DataArrayView::ShapeType&
441     Data::getDataPointShape() const
442     {
443     return getPointDataView().getShape();
444     }
445    
446     boost::python::numeric::array
447     Data::integrate() const
448     {
449     int index;
450     int rank = getDataPointRank();
451     DataArrayView::ShapeType shape = getDataPointShape();
452    
453     //
454     // calculate the integral values
455     vector<double> integrals(getDataPointSize());
456     AbstractContinuousDomain::asAbstractContinuousDomain(getDomain()).setToIntegrals(integrals,*this);
457    
458     //
459     // create the numeric array to be returned
460     // and load the array with the integral values
461     boost::python::numeric::array bp_array(1.0);
462     if (rank==0) {
463     index = 0;
464     bp_array[0] = integrals[index];
465     }
466     if (rank==1) {
467     bp_array.resize(shape[0]);
468     for (int i=0; i<shape[0]; i++) {
469     index = i;
470     bp_array[i] = integrals[index];
471     }
472     }
473     if (rank==2) {
474     bp_array.resize(shape[0],shape[1]);
475     for (int i=0; i<shape[0]; i++) {
476     for (int j=0; j<shape[1]; j++) {
477     index = i + shape[0] * j;
478     bp_array[i,j] = integrals[index];
479     }
480     }
481     }
482     if (rank==3) {
483     bp_array.resize(shape[0],shape[1],shape[2]);
484     for (int i=0; i<shape[0]; i++) {
485     for (int j=0; j<shape[1]; j++) {
486     for (int k=0; k<shape[2]; k++) {
487     index = i + shape[0] * ( j + shape[1] * k );
488     bp_array[i,j,k] = integrals[index];
489     }
490     }
491     }
492     }
493     if (rank==4) {
494     bp_array.resize(shape[0],shape[1],shape[2],shape[3]);
495     for (int i=0; i<shape[0]; i++) {
496     for (int j=0; j<shape[1]; j++) {
497     for (int k=0; k<shape[2]; k++) {
498     for (int l=0; l<shape[3]; l++) {
499     index = i + shape[0] * ( j + shape[1] * ( k + shape[2] * l ) );
500     bp_array[i,j,k,l] = integrals[index];
501     }
502     }
503     }
504     }
505     }
506    
507     //
508     // return the loaded array
509     return bp_array;
510     }
511    
512     Data
513     Data::sin() const
514     {
515     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::sin);
516     }
517    
518     Data
519     Data::cos() const
520     {
521     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::cos);
522     }
523    
524     Data
525     Data::tan() const
526     {
527     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::tan);
528     }
529    
530     Data
531     Data::log() const
532     {
533     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::log10);
534     }
535    
536     Data
537     Data::ln() const
538     {
539     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::log);
540     }
541    
542     double
543     Data::Lsup() const
544     {
545     //
546 jgs 97 // set the initial absolute maximum value to zero
547     return algorithm(DataAlgorithmAdapter<AbsMax>(0));
548 jgs 94 }
549    
550     double
551     Data::sup() const
552     {
553     //
554 jgs 97 // set the initial maximum value to min possible double
555 jgs 94 return algorithm(DataAlgorithmAdapter<FMax>(numeric_limits<double>::min()));
556     }
557    
558     double
559     Data::inf() const
560     {
561     //
562 jgs 97 // set the initial minimum value to max possible double
563 jgs 94 return algorithm(DataAlgorithmAdapter<FMin>(numeric_limits<double>::max()));
564     }
565    
566 jgs 97 Data
567     Data::maxval() const
568 jgs 94 {
569 jgs 97 // not implemented - will use dp_algorithm
570     return (*this);
571     }
572    
573     Data
574     Data::minval() const
575     {
576     // not implemented - will use dp_algorithm
577     return (*this);
578     }
579    
580     Data
581     Data::length() const
582     {
583     // not implemented - will use dp_algorithm
584     return (*this);
585     }
586    
587     Data
588     Data::trace() const
589     {
590     // not implemented - will use dp_algorithm
591     return (*this);
592     }
593    
594     Data
595     Data::transpose(int axis) const
596     {
597     // not implemented
598     return (*this);
599     }
600    
601     Data
602     Data::sign() const
603     {
604     return escript::unaryOp(*this,escript::fsign);
605     }
606    
607     Data
608     Data::abs() const
609     {
610     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::fabs);
611     }
612    
613     Data
614     Data::neg() const
615     {
616     return escript::unaryOp(*this,negate<double>());
617     }
618    
619     Data
620     Data::pos() const
621     {
622     return (*this);
623     }
624    
625     Data
626     Data::exp() const
627     {
628     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::exp);
629     }
630    
631     Data
632     Data::sqrt() const
633     {
634     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::sqrt);
635     }
636    
637     Data&
638     Data::operator+=(const Data& right)
639     {
640 jgs 94 binaryOp(right,plus<double>());
641     return (*this);
642     }
643    
644 jgs 97 Data&
645     Data::operator+=(const boost::python::object& right)
646 jgs 94 {
647     binaryOp(right,plus<double>());
648     return (*this);
649     }
650    
651 jgs 97 Data&
652     Data::operator-=(const Data& right)
653 jgs 94 {
654     binaryOp(right,minus<double>());
655     return (*this);
656     }
657    
658 jgs 97 Data&
659     Data::operator-=(const boost::python::object& right)
660 jgs 94 {
661     binaryOp(right,minus<double>());
662     return (*this);
663     }
664    
665 jgs 97 Data&
666     Data::operator*=(const Data& right)
667 jgs 94 {
668     binaryOp(right,multiplies<double>());
669     return (*this);
670     }
671    
672 jgs 97 Data&
673     Data::operator*=(const boost::python::object& right)
674 jgs 94 {
675     binaryOp(right,multiplies<double>());
676     return (*this);
677     }
678    
679 jgs 97 Data&
680     Data::operator/=(const Data& right)
681 jgs 94 {
682     binaryOp(right,divides<double>());
683     return (*this);
684     }
685    
686 jgs 97 Data&
687     Data::operator/=(const boost::python::object& right)
688 jgs 94 {
689     binaryOp(right,divides<double>());
690     return (*this);
691     }
692    
693 jgs 97 Data
694     Data::powO(const boost::python::object& right) const
695 jgs 94 {
696     Data result;
697     result.copy(*this);
698     result.binaryOp(right,(Data::BinaryDFunPtr)::pow);
699     return result;
700     }
701    
702 jgs 97 Data
703     Data::powD(const Data& right) const
704 jgs 94 {
705     Data result;
706     result.copy(*this);
707     result.binaryOp(right,(Data::BinaryDFunPtr)::pow);
708     return result;
709     }
710    
711     //
712     // NOTE: It is essential to specify the namepsace this operator belongs to
713 jgs 97 Data
714     escript::operator+(const Data& left, const Data& right)
715 jgs 94 {
716     Data result;
717     //
718     // perform a deep copy
719     result.copy(left);
720     result+=right;
721     return result;
722     }
723    
724     //
725     // NOTE: It is essential to specify the namepsace this operator belongs to
726 jgs 97 Data
727     escript::operator-(const Data& left, const Data& right)
728 jgs 94 {
729     Data result;
730     //
731     // perform a deep copy
732     result.copy(left);
733     result-=right;
734     return result;
735     }
736    
737     //
738     // NOTE: It is essential to specify the namepsace this operator belongs to
739 jgs 97 Data
740     escript::operator*(const Data& left, const Data& right)
741 jgs 94 {
742     Data result;
743     //
744     // perform a deep copy
745     result.copy(left);
746     result*=right;
747     return result;
748     }
749    
750     //
751     // NOTE: It is essential to specify the namepsace this operator belongs to
752 jgs 97 Data
753     escript::operator/(const Data& left, const Data& right)
754 jgs 94 {
755     Data result;
756     //
757     // perform a deep copy
758     result.copy(left);
759     result/=right;
760     return result;
761     }
762    
763     //
764     // NOTE: It is essential to specify the namepsace this operator belongs to
765 jgs 97 Data
766     escript::operator+(const Data& left, const boost::python::object& right)
767 jgs 94 {
768     //
769     // Convert to DataArray format if possible
770     DataArray temp(right);
771     Data result;
772     //
773     // perform a deep copy
774     result.copy(left);
775     result+=right;
776     return result;
777     }
778    
779     //
780     // NOTE: It is essential to specify the namepsace this operator belongs to
781 jgs 97 Data
782     escript::operator-(const Data& left, const boost::python::object& right)
783 jgs 94 {
784     //
785     // Convert to DataArray format if possible
786     DataArray temp(right);
787     Data result;
788     //
789     // perform a deep copy
790     result.copy(left);
791     result-=right;
792     return result;
793     }
794    
795     //
796     // NOTE: It is essential to specify the namepsace this operator belongs to
797 jgs 97 Data
798     escript::operator*(const Data& left, const boost::python::object& right)
799 jgs 94 {
800     //
801     // Convert to DataArray format if possible
802     DataArray temp(right);
803     Data result;
804     //
805     // perform a deep copy
806     result.copy(left);
807     result*=right;
808     return result;
809     }
810    
811     //
812     // NOTE: It is essential to specify the namepsace this operator belongs to
813 jgs 97 Data
814     escript::operator/(const Data& left, const boost::python::object& right)
815 jgs 94 {
816     //
817     // Convert to DataArray format if possible
818     DataArray temp(right);
819     Data result;
820     //
821     // perform a deep copy
822     result.copy(left);
823     result/=right;
824     return result;
825     }
826    
827     //
828     // NOTE: It is essential to specify the namepsace this operator belongs to
829 jgs 97 Data
830     escript::operator+(const boost::python::object& left, const Data& right)
831 jgs 94 {
832     //
833     // Construct the result using the given value and the other parameters
834     // from right
835     Data result(left,right);
836     result+=right;
837     return result;
838     }
839    
840     //
841     // NOTE: It is essential to specify the namepsace this operator belongs to
842 jgs 97 Data
843     escript::operator-(const boost::python::object& left, const Data& right)
844 jgs 94 {
845     //
846     // Construct the result using the given value and the other parameters
847     // from right
848     Data result(left,right);
849     result-=right;
850     return result;
851     }
852    
853     //
854     // NOTE: It is essential to specify the namepsace this operator belongs to
855 jgs 97 Data
856     escript::operator*(const boost::python::object& left, const Data& right)
857 jgs 94 {
858     //
859     // Construct the result using the given value and the other parameters
860     // from right
861     Data result(left,right);
862     result*=right;
863     return result;
864     }
865    
866     //
867     // NOTE: It is essential to specify the namepsace this operator belongs to
868 jgs 97 Data
869     escript::operator/(const boost::python::object& left, const Data& right)
870 jgs 94 {
871     //
872     // Construct the result using the given value and the other parameters
873     // from right
874     Data result(left,right);
875     result/=right;
876     return result;
877     }
878    
879     //
880     // NOTE: It is essential to specify the namepsace this operator belongs to
881 jgs 97 //bool escript::operator==(const Data& left, const Data& right)
882     //{
883     // /*
884     // NB: this operator does very little at this point, and isn't to
885     // be relied on. Requires further implementation.
886     // */
887     //
888     // bool ret;
889     //
890     // if (left.isEmpty()) {
891     // if(!right.isEmpty()) {
892     // ret = false;
893     // } else {
894     // ret = true;
895     // }
896     // }
897     //
898     // if (left.isConstant()) {
899     // if(!right.isConstant()) {
900     // ret = false;
901     // } else {
902     // ret = true;
903     // }
904     // }
905     //
906     // if (left.isTagged()) {
907     // if(!right.isTagged()) {
908     // ret = false;
909     // } else {
910     // ret = true;
911     // }
912     // }
913     //
914     // if (left.isExpanded()) {
915     // if(!right.isExpanded()) {
916     // ret = false;
917     // } else {
918     // ret = true;
919     // }
920     // }
921     //
922     // return ret;
923     //}
924    
925     Data
926     Data::getItem(const boost::python::object& key) const
927 jgs 94 {
928 jgs 97 const DataArrayView& view=getPointDataView();
929 jgs 94
930 jgs 97 DataArrayView::RegionType slice_region=view.getSliceRegion(key);
931 jgs 94
932 jgs 97 if (slice_region.size()!=view.getRank()) {
933     throw DataException("Error - slice size does not match Data rank.");
934 jgs 94 }
935    
936 jgs 97 return getSlice(slice_region);
937 jgs 94 }
938    
939     Data
940 jgs 97 Data::getSlice(const DataArrayView::RegionType& region) const
941 jgs 94 {
942 jgs 97 return Data(*this,region);
943 jgs 94 }
944    
945     void
946 jgs 97 Data::setItemO(const boost::python::object& key,
947     const boost::python::object& value)
948 jgs 94 {
949 jgs 97 Data tempData(value,getFunctionSpace());
950     setItemD(key,tempData);
951     }
952    
953     void
954     Data::setItemD(const boost::python::object& key,
955     const Data& value)
956     {
957 jgs 94 const DataArrayView& view=getPointDataView();
958     DataArrayView::RegionType slice_region=view.getSliceRegion(key);
959     if (slice_region.size()!=view.getRank()) {
960     throw DataException("Error - slice size does not match Data rank.");
961     }
962     setSlice(value,slice_region);
963     }
964    
965     void
966 jgs 97 Data::setSlice(const Data& value,
967     const DataArrayView::RegionType& region)
968 jgs 94 {
969 jgs 97 Data tempValue(value);
970     typeMatchLeft(tempValue);
971     typeMatchRight(tempValue);
972     m_data->setSlice(tempValue.m_data.get(),region);
973     }
974    
975     void
976     Data::typeMatchLeft(Data& right) const
977     {
978     if (isExpanded()){
979     right.expand();
980     } else if (isTagged()) {
981     if (right.isConstant()) {
982     right.tag();
983     }
984     }
985     }
986    
987     void
988     Data::typeMatchRight(const Data& right)
989     {
990 jgs 94 if (isTagged()) {
991     if (right.isExpanded()) {
992     expand();
993     }
994     } else if (isConstant()) {
995     if (right.isExpanded()) {
996     expand();
997     } else if (right.isTagged()) {
998     tag();
999     }
1000     }
1001     }
1002    
1003     void
1004     Data::setTaggedValue(int tagKey,
1005     const boost::python::object& value)
1006     {
1007     //
1008     // Ensure underlying data object is of type DataTagged
1009     tag();
1010    
1011     if (!isTagged()) {
1012     throw DataException("Error - DataTagged conversion failed!!");
1013     }
1014    
1015     //
1016     // Construct DataArray from boost::python::object input value
1017     DataArray valueDataArray(value);
1018    
1019     //
1020     // Call DataAbstract::setTaggedValue
1021     m_data->setTaggedValue(tagKey,valueDataArray.getView());
1022     }
1023    
1024     /*
1025     Note: this version removed for now. Not needed, and breaks escript.cpp
1026     void
1027     Data::setTaggedValue(int tagKey,
1028     const DataArrayView& value)
1029     {
1030     //
1031     // Ensure underlying data object is of type DataTagged
1032     tag();
1033    
1034     if (!isTagged()) {
1035     throw DataException("Error - DataTagged conversion failed!!");
1036     }
1037    
1038     //
1039     // Call DataAbstract::setTaggedValue
1040     m_data->setTaggedValue(tagKey,value);
1041     }
1042     */
1043    
1044     ostream& escript::operator<<(ostream& o, const Data& data)
1045     {
1046     o << data.toString();
1047     return o;
1048     }

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26