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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 108 - (hide annotations)
Thu Jan 27 06:21:59 2005 UTC (14 years, 4 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.cpp
File size: 23771 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 102 #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 102 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 102 Data::Data(const Data& inData)
81 jgs 94 {
82 jgs 102 m_data=inData.m_data;
83 jgs 94 }
84    
85     Data::Data(const Data& inData,
86     const DataArrayView::RegionType& region)
87     {
88     //
89 jgs 102 // 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 102 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 102 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 102 // Construct a DataTagged copy
229 jgs 94 DataAbstract* newData=new DataTagged(*temp);
230 jgs 102 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 102 shared_ptr<DataAbstract> temp_data(newData);
242     m_data=temp_data;
243 jgs 94 return;
244     }
245     }
246 jgs 102 {
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 102 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 102 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 102 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 102 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 102 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 102 Data::whereNonPositive() const
373 jgs 94 {
374 jgs 102 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 102 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 jgs 108 bp_array.resize(1);
464 jgs 94 index = 0;
465     bp_array[0] = integrals[index];
466     }
467     if (rank==1) {
468     bp_array.resize(shape[0]);
469     for (int i=0; i<shape[0]; i++) {
470     index = i;
471     bp_array[i] = integrals[index];
472     }
473     }
474     if (rank==2) {
475     bp_array.resize(shape[0],shape[1]);
476     for (int i=0; i<shape[0]; i++) {
477     for (int j=0; j<shape[1]; j++) {
478     index = i + shape[0] * j;
479     bp_array[i,j] = integrals[index];
480     }
481     }
482     }
483     if (rank==3) {
484     bp_array.resize(shape[0],shape[1],shape[2]);
485     for (int i=0; i<shape[0]; i++) {
486     for (int j=0; j<shape[1]; j++) {
487     for (int k=0; k<shape[2]; k++) {
488     index = i + shape[0] * ( j + shape[1] * k );
489     bp_array[i,j,k] = integrals[index];
490     }
491     }
492     }
493     }
494     if (rank==4) {
495     bp_array.resize(shape[0],shape[1],shape[2],shape[3]);
496     for (int i=0; i<shape[0]; i++) {
497     for (int j=0; j<shape[1]; j++) {
498     for (int k=0; k<shape[2]; k++) {
499     for (int l=0; l<shape[3]; l++) {
500     index = i + shape[0] * ( j + shape[1] * ( k + shape[2] * l ) );
501     bp_array[i,j,k,l] = integrals[index];
502     }
503     }
504     }
505     }
506     }
507    
508     //
509     // return the loaded array
510     return bp_array;
511     }
512    
513     Data
514     Data::sin() const
515     {
516     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::sin);
517     }
518    
519     Data
520     Data::cos() const
521     {
522     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::cos);
523     }
524    
525     Data
526     Data::tan() const
527     {
528     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::tan);
529     }
530    
531     Data
532     Data::log() const
533     {
534     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::log10);
535     }
536    
537     Data
538     Data::ln() const
539     {
540     return escript::unaryOp(*this,(Data::UnaryDFunPtr)::log);
541     }
542    
543 jgs 106 Data
544     Data::sign() const
545 jgs 94 {
546 jgs 106 return escript::unaryOp(*this,escript::fsign);
547 jgs 94 }
548    
549 jgs 106 Data
550     Data::abs() const
551 jgs 94 {
552 jgs 106 return escript::unaryOp(*this,(Data::UnaryDFunPtr)::fabs);
553 jgs 94 }
554    
555 jgs 106 Data
556     Data::neg() const
557 jgs 94 {
558 jgs 106 return escript::unaryOp(*this,negate<double>());
559 jgs 94 }
560    
561 jgs 102 Data
562 jgs 106 Data::pos() const
563 jgs 94 {
564 jgs 102 return (*this);
565     }
566    
567     Data
568 jgs 106 Data::exp() const
569 jgs 102 {
570 jgs 106 return escript::unaryOp(*this,(Data::UnaryDFunPtr)::exp);
571 jgs 102 }
572    
573     Data
574 jgs 106 Data::sqrt() const
575 jgs 102 {
576 jgs 106 return escript::unaryOp(*this,(Data::UnaryDFunPtr)::sqrt);
577 jgs 102 }
578    
579 jgs 106 double
580     Data::Lsup() const
581 jgs 102 {
582 jgs 106 //
583     // set the initial absolute maximum value to zero
584     return algorithm(DataAlgorithmAdapter<AbsMax>(0));
585 jgs 102 }
586    
587 jgs 106 double
588     Data::sup() const
589 jgs 102 {
590 jgs 106 //
591     // set the initial maximum value to min possible double
592 jgs 108 return algorithm(DataAlgorithmAdapter<FMax>(numeric_limits<double>::max()*-1));
593 jgs 102 }
594    
595 jgs 106 double
596     Data::inf() const
597 jgs 102 {
598 jgs 106 //
599     // set the initial minimum value to max possible double
600     return algorithm(DataAlgorithmAdapter<FMin>(numeric_limits<double>::max()));
601 jgs 102 }
602    
603     Data
604 jgs 106 Data::maxval() const
605 jgs 102 {
606 jgs 108 return dp_algorithm(DataAlgorithmAdapter<FMax>(numeric_limits<double>::max()*-1));
607 jgs 102 }
608    
609     Data
610 jgs 106 Data::minval() const
611 jgs 102 {
612 jgs 106 return dp_algorithm(DataAlgorithmAdapter<FMin>(numeric_limits<double>::max()));
613 jgs 102 }
614    
615     Data
616 jgs 106 Data::length() const
617 jgs 102 {
618 jgs 106 return dp_algorithm(DataAlgorithmAdapter<Length>(0));
619 jgs 102 }
620    
621     Data
622 jgs 106 Data::trace() const
623 jgs 102 {
624 jgs 106 return dp_algorithm(DataAlgorithmAdapter<Trace>(0));
625 jgs 102 }
626    
627     Data
628 jgs 106 Data::transpose(int axis) const
629 jgs 102 {
630 jgs 106 // not implemented
631     throw DataException("Error - Data::transpose not implemented yet.");
632     return Data();
633 jgs 102 }
634    
635 jgs 104 void
636     Data::saveDX(std::string fileName) const
637     {
638     getDomain().saveDX(fileName,*this);
639     return;
640     }
641    
642 jgs 102 Data&
643     Data::operator+=(const Data& right)
644     {
645 jgs 94 binaryOp(right,plus<double>());
646     return (*this);
647     }
648    
649 jgs 102 Data&
650     Data::operator+=(const boost::python::object& right)
651 jgs 94 {
652     binaryOp(right,plus<double>());
653     return (*this);
654     }
655    
656 jgs 102 Data&
657     Data::operator-=(const Data& right)
658 jgs 94 {
659     binaryOp(right,minus<double>());
660     return (*this);
661     }
662    
663 jgs 102 Data&
664     Data::operator-=(const boost::python::object& right)
665 jgs 94 {
666     binaryOp(right,minus<double>());
667     return (*this);
668     }
669    
670 jgs 102 Data&
671     Data::operator*=(const Data& right)
672 jgs 94 {
673     binaryOp(right,multiplies<double>());
674     return (*this);
675     }
676    
677 jgs 102 Data&
678     Data::operator*=(const boost::python::object& right)
679 jgs 94 {
680     binaryOp(right,multiplies<double>());
681     return (*this);
682     }
683    
684 jgs 102 Data&
685     Data::operator/=(const Data& right)
686 jgs 94 {
687     binaryOp(right,divides<double>());
688     return (*this);
689     }
690    
691 jgs 102 Data&
692     Data::operator/=(const boost::python::object& right)
693 jgs 94 {
694     binaryOp(right,divides<double>());
695     return (*this);
696     }
697    
698 jgs 102 Data
699     Data::powO(const boost::python::object& right) const
700 jgs 94 {
701     Data result;
702     result.copy(*this);
703     result.binaryOp(right,(Data::BinaryDFunPtr)::pow);
704     return result;
705     }
706    
707 jgs 102 Data
708     Data::powD(const Data& right) const
709 jgs 94 {
710     Data result;
711     result.copy(*this);
712     result.binaryOp(right,(Data::BinaryDFunPtr)::pow);
713     return result;
714     }
715    
716     //
717     // NOTE: It is essential to specify the namepsace this operator belongs to
718 jgs 102 Data
719     escript::operator+(const Data& left, const Data& right)
720 jgs 94 {
721     Data result;
722     //
723     // perform a deep copy
724     result.copy(left);
725     result+=right;
726     return result;
727     }
728    
729     //
730     // NOTE: It is essential to specify the namepsace this operator belongs to
731 jgs 102 Data
732     escript::operator-(const Data& left, const Data& right)
733 jgs 94 {
734     Data result;
735     //
736     // perform a deep copy
737     result.copy(left);
738     result-=right;
739     return result;
740     }
741    
742     //
743     // NOTE: It is essential to specify the namepsace this operator belongs to
744 jgs 102 Data
745     escript::operator*(const Data& left, const Data& right)
746 jgs 94 {
747     Data result;
748     //
749     // perform a deep copy
750     result.copy(left);
751     result*=right;
752     return result;
753     }
754    
755     //
756     // NOTE: It is essential to specify the namepsace this operator belongs to
757 jgs 102 Data
758     escript::operator/(const Data& left, const Data& right)
759 jgs 94 {
760     Data result;
761     //
762     // perform a deep copy
763     result.copy(left);
764     result/=right;
765     return result;
766     }
767    
768     //
769     // NOTE: It is essential to specify the namepsace this operator belongs to
770 jgs 102 Data
771     escript::operator+(const Data& left, const boost::python::object& right)
772 jgs 94 {
773     //
774     // Convert to DataArray format if possible
775     DataArray temp(right);
776     Data result;
777     //
778     // perform a deep copy
779     result.copy(left);
780     result+=right;
781     return result;
782     }
783    
784     //
785     // NOTE: It is essential to specify the namepsace this operator belongs to
786 jgs 102 Data
787     escript::operator-(const Data& left, const boost::python::object& right)
788 jgs 94 {
789     //
790     // Convert to DataArray format if possible
791     DataArray temp(right);
792     Data result;
793     //
794     // perform a deep copy
795     result.copy(left);
796     result-=right;
797     return result;
798     }
799    
800     //
801     // NOTE: It is essential to specify the namepsace this operator belongs to
802 jgs 102 Data
803     escript::operator*(const Data& left, const boost::python::object& right)
804 jgs 94 {
805     //
806     // Convert to DataArray format if possible
807     DataArray temp(right);
808     Data result;
809     //
810     // perform a deep copy
811     result.copy(left);
812     result*=right;
813     return result;
814     }
815    
816     //
817     // NOTE: It is essential to specify the namepsace this operator belongs to
818 jgs 102 Data
819     escript::operator/(const Data& left, const boost::python::object& right)
820 jgs 94 {
821     //
822     // Convert to DataArray format if possible
823     DataArray temp(right);
824     Data result;
825     //
826     // perform a deep copy
827     result.copy(left);
828     result/=right;
829     return result;
830     }
831    
832     //
833     // NOTE: It is essential to specify the namepsace this operator belongs to
834 jgs 102 Data
835     escript::operator+(const boost::python::object& left, const Data& right)
836 jgs 94 {
837     //
838     // Construct the result using the given value and the other parameters
839     // from right
840     Data result(left,right);
841     result+=right;
842     return result;
843     }
844    
845     //
846     // NOTE: It is essential to specify the namepsace this operator belongs to
847 jgs 102 Data
848     escript::operator-(const boost::python::object& left, const Data& right)
849 jgs 94 {
850     //
851     // Construct the result using the given value and the other parameters
852     // from right
853     Data result(left,right);
854     result-=right;
855     return result;
856     }
857    
858     //
859     // NOTE: It is essential to specify the namepsace this operator belongs to
860 jgs 102 Data
861     escript::operator*(const boost::python::object& left, const Data& right)
862 jgs 94 {
863     //
864     // Construct the result using the given value and the other parameters
865     // from right
866     Data result(left,right);
867     result*=right;
868     return result;
869     }
870    
871     //
872     // NOTE: It is essential to specify the namepsace this operator belongs to
873 jgs 102 Data
874     escript::operator/(const boost::python::object& left, const Data& right)
875 jgs 94 {
876     //
877     // Construct the result using the given value and the other parameters
878     // from right
879     Data result(left,right);
880     result/=right;
881     return result;
882     }
883    
884     //
885     // NOTE: It is essential to specify the namepsace this operator belongs to
886 jgs 102 //bool escript::operator==(const Data& left, const Data& right)
887     //{
888     // /*
889     // NB: this operator does very little at this point, and isn't to
890     // be relied on. Requires further implementation.
891     // */
892     //
893     // bool ret;
894     //
895     // if (left.isEmpty()) {
896     // if(!right.isEmpty()) {
897     // ret = false;
898     // } else {
899     // ret = true;
900     // }
901     // }
902     //
903     // if (left.isConstant()) {
904     // if(!right.isConstant()) {
905     // ret = false;
906     // } else {
907     // ret = true;
908     // }
909     // }
910     //
911     // if (left.isTagged()) {
912     // if(!right.isTagged()) {
913     // ret = false;
914     // } else {
915     // ret = true;
916     // }
917     // }
918     //
919     // if (left.isExpanded()) {
920     // if(!right.isExpanded()) {
921     // ret = false;
922     // } else {
923     // ret = true;
924     // }
925     // }
926     //
927     // return ret;
928     //}
929    
930     Data
931     Data::getItem(const boost::python::object& key) const
932 jgs 94 {
933 jgs 102 const DataArrayView& view=getPointDataView();
934 jgs 94
935 jgs 102 DataArrayView::RegionType slice_region=view.getSliceRegion(key);
936 jgs 94
937 jgs 102 if (slice_region.size()!=view.getRank()) {
938     throw DataException("Error - slice size does not match Data rank.");
939 jgs 94 }
940    
941 jgs 102 return getSlice(slice_region);
942 jgs 94 }
943    
944     Data
945 jgs 102 Data::getSlice(const DataArrayView::RegionType& region) const
946 jgs 94 {
947 jgs 102 return Data(*this,region);
948 jgs 94 }
949    
950     void
951 jgs 102 Data::setItemO(const boost::python::object& key,
952     const boost::python::object& value)
953 jgs 94 {
954 jgs 102 Data tempData(value,getFunctionSpace());
955     setItemD(key,tempData);
956     }
957    
958     void
959     Data::setItemD(const boost::python::object& key,
960     const Data& value)
961     {
962 jgs 94 const DataArrayView& view=getPointDataView();
963     DataArrayView::RegionType slice_region=view.getSliceRegion(key);
964     if (slice_region.size()!=view.getRank()) {
965     throw DataException("Error - slice size does not match Data rank.");
966     }
967 jgs 108 if (getFunctionSpace()!=value.getFunctionSpace()) {
968     setSlice(Data(value,getFunctionSpace()),slice_region);
969     } else {
970     setSlice(value,slice_region);
971     }
972 jgs 94 }
973    
974     void
975 jgs 102 Data::setSlice(const Data& value,
976     const DataArrayView::RegionType& region)
977 jgs 94 {
978 jgs 102 Data tempValue(value);
979     typeMatchLeft(tempValue);
980     typeMatchRight(tempValue);
981     m_data->setSlice(tempValue.m_data.get(),region);
982     }
983    
984     void
985     Data::typeMatchLeft(Data& right) const
986     {
987     if (isExpanded()){
988     right.expand();
989     } else if (isTagged()) {
990     if (right.isConstant()) {
991     right.tag();
992     }
993     }
994     }
995    
996     void
997     Data::typeMatchRight(const Data& right)
998     {
999 jgs 94 if (isTagged()) {
1000     if (right.isExpanded()) {
1001     expand();
1002     }
1003     } else if (isConstant()) {
1004     if (right.isExpanded()) {
1005     expand();
1006     } else if (right.isTagged()) {
1007     tag();
1008     }
1009     }
1010     }
1011    
1012     void
1013     Data::setTaggedValue(int tagKey,
1014     const boost::python::object& value)
1015     {
1016     //
1017     // Ensure underlying data object is of type DataTagged
1018     tag();
1019    
1020     if (!isTagged()) {
1021     throw DataException("Error - DataTagged conversion failed!!");
1022     }
1023    
1024     //
1025     // Construct DataArray from boost::python::object input value
1026     DataArray valueDataArray(value);
1027    
1028     //
1029     // Call DataAbstract::setTaggedValue
1030     m_data->setTaggedValue(tagKey,valueDataArray.getView());
1031     }
1032    
1033     /*
1034     Note: this version removed for now. Not needed, and breaks escript.cpp
1035     void
1036     Data::setTaggedValue(int tagKey,
1037     const DataArrayView& value)
1038     {
1039     //
1040     // Ensure underlying data object is of type DataTagged
1041     tag();
1042    
1043     if (!isTagged()) {
1044     throw DataException("Error - DataTagged conversion failed!!");
1045     }
1046    
1047     //
1048     // Call DataAbstract::setTaggedValue
1049     m_data->setTaggedValue(tagKey,value);
1050     }
1051     */
1052    
1053     ostream& escript::operator<<(ostream& o, const Data& data)
1054     {
1055     o << data.toString();
1056     return o;
1057     }

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26