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

Contents of /trunk/esys2/escript/src/Data/Data.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 110 - (show annotations)
Mon Feb 14 04:14:42 2005 UTC (14 years, 4 months ago) by jgs
File size: 25379 byte(s)
*** empty log message ***

1 // $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 #include "escript/Data/UnaryFuncs.h"
42
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 shared_ptr<DataAbstract> temp_data(temp);
54 m_data=temp_data;
55 }
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 Data::Data(const Data& inData)
81 {
82 m_data=inData.m_data;
83 }
84
85 Data::Data(const Data& inData,
86 const DataArrayView::RegionType& region)
87 {
88 //
89 // 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 }
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 shared_ptr<DataAbstract> temp_data(temp);
124 m_data=temp_data;
125 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 shared_ptr<DataAbstract> temp_data(newData);
220 m_data=temp_data;
221 return;
222 }
223 }
224 {
225 DataTagged* temp=dynamic_cast<DataTagged*>(other.m_data.get());
226 if (temp!=0) {
227 //
228 // Construct a DataTagged copy
229 DataAbstract* newData=new DataTagged(*temp);
230 shared_ptr<DataAbstract> temp_data(newData);
231 m_data=temp_data;
232 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 shared_ptr<DataAbstract> temp_data(newData);
242 m_data=temp_data;
243 return;
244 }
245 }
246 {
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 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 shared_ptr<DataAbstract> temp_data(temp);
312 m_data=temp_data;
313 } else if (isTagged()) {
314 DataTagged* tempDataTag=dynamic_cast<DataTagged*>(m_data.get());
315 DataAbstract* temp=new DataExpanded(*tempDataTag);
316 shared_ptr<DataAbstract> temp_data(temp);
317 m_data=temp_data;
318 } 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 shared_ptr<DataAbstract> temp_data(temp);
335 m_data=temp_data;
336 } 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 void
348 Data::reshapeDataPoint(const DataArrayView::ShapeType& shape)
349 {
350 m_data->reshapeDataPoint(shape);
351 }
352
353 Data
354 Data::wherePositive() const
355 {
356 return escript::unaryOp(*this,bind2nd(greater<double>(),0.0));
357 }
358
359 Data
360 Data::whereNegative() const
361 {
362 return escript::unaryOp(*this,bind2nd(less<double>(),0.0));
363 }
364
365 Data
366 Data::whereNonNegative() const
367 {
368 return escript::unaryOp(*this,bind2nd(greater_equal<double>(),0.0));
369 }
370
371 Data
372 Data::whereNonPositive() const
373 {
374 return escript::unaryOp(*this,bind2nd(less_equal<double>(),0.0));
375 }
376
377 Data
378 Data::whereZero() const
379 {
380 return escript::unaryOp(*this,bind2nd(equal_to<double>(),0.0));
381 }
382
383 Data
384 Data::whereNonZero() const
385 {
386 return escript::unaryOp(*this,bind2nd(not_equal_to<double>(),0.0));
387 }
388
389 Data
390 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 bp_array.resize(1);
464 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 Data
544 Data::sign() const
545 {
546 return escript::unaryOp(*this,escript::fsign);
547 }
548
549 Data
550 Data::abs() const
551 {
552 return escript::unaryOp(*this,(Data::UnaryDFunPtr)::fabs);
553 }
554
555 Data
556 Data::neg() const
557 {
558 return escript::unaryOp(*this,negate<double>());
559 }
560
561 Data
562 Data::pos() const
563 {
564 return (*this);
565 }
566
567 Data
568 Data::exp() const
569 {
570 return escript::unaryOp(*this,(Data::UnaryDFunPtr)::exp);
571 }
572
573 Data
574 Data::sqrt() const
575 {
576 return escript::unaryOp(*this,(Data::UnaryDFunPtr)::sqrt);
577 }
578
579 double
580 Data::Lsup() const
581 {
582 //
583 // set the initial absolute maximum value to zero
584 return algorithm(DataAlgorithmAdapter<AbsMax>(0));
585 }
586
587 double
588 Data::sup() const
589 {
590 //
591 // set the initial maximum value to min possible double
592 return algorithm(DataAlgorithmAdapter<FMax>(numeric_limits<double>::max()*-1));
593 }
594
595 double
596 Data::inf() const
597 {
598 //
599 // set the initial minimum value to max possible double
600 return algorithm(DataAlgorithmAdapter<FMin>(numeric_limits<double>::max()));
601 }
602
603 Data
604 Data::maxval() const
605 {
606 return dp_algorithm(DataAlgorithmAdapter<FMax>(numeric_limits<double>::max()*-1));
607 }
608
609 Data
610 Data::minval() const
611 {
612 return dp_algorithm(DataAlgorithmAdapter<FMin>(numeric_limits<double>::max()));
613 }
614
615 Data
616 Data::length() const
617 {
618 return dp_algorithm(DataAlgorithmAdapter<Length>(0));
619 }
620
621 Data
622 Data::trace() const
623 {
624 return dp_algorithm(DataAlgorithmAdapter<Trace>(0));
625 }
626
627 Data
628 Data::transpose(int axis) const
629 {
630 // not implemented
631 throw DataException("Error - Data::transpose not implemented yet.");
632 return Data();
633 }
634
635 void
636 Data::saveDX(std::string fileName) const
637 {
638 getDomain().saveDX(fileName,*this);
639 return;
640 }
641
642 void
643 Data::saveVTK(std::string fileName) const
644 {
645 getDomain().saveVTK(fileName,*this);
646 return;
647 }
648
649 Data&
650 Data::operator+=(const Data& right)
651 {
652 binaryOp(right,plus<double>());
653 return (*this);
654 }
655
656 Data&
657 Data::operator+=(const boost::python::object& right)
658 {
659 binaryOp(right,plus<double>());
660 return (*this);
661 }
662
663 Data&
664 Data::operator-=(const Data& right)
665 {
666 binaryOp(right,minus<double>());
667 return (*this);
668 }
669
670 Data&
671 Data::operator-=(const boost::python::object& right)
672 {
673 binaryOp(right,minus<double>());
674 return (*this);
675 }
676
677 Data&
678 Data::operator*=(const Data& right)
679 {
680 binaryOp(right,multiplies<double>());
681 return (*this);
682 }
683
684 Data&
685 Data::operator*=(const boost::python::object& right)
686 {
687 binaryOp(right,multiplies<double>());
688 return (*this);
689 }
690
691 Data&
692 Data::operator/=(const Data& right)
693 {
694 binaryOp(right,divides<double>());
695 return (*this);
696 }
697
698 Data&
699 Data::operator/=(const boost::python::object& right)
700 {
701 binaryOp(right,divides<double>());
702 return (*this);
703 }
704
705 Data
706 Data::powO(const boost::python::object& right) const
707 {
708 Data result;
709 result.copy(*this);
710 result.binaryOp(right,(Data::BinaryDFunPtr)::pow);
711 return result;
712 }
713
714 Data
715 Data::powD(const Data& right) const
716 {
717 Data result;
718 result.copy(*this);
719 result.binaryOp(right,(Data::BinaryDFunPtr)::pow);
720 return result;
721 }
722
723 //
724 // NOTE: It is essential to specify the namepsace this operator belongs to
725 Data
726 escript::operator+(const Data& left, const Data& right)
727 {
728 Data result;
729 //
730 // perform a deep copy
731 result.copy(left);
732 result+=right;
733 return result;
734 }
735
736 //
737 // NOTE: It is essential to specify the namepsace this operator belongs to
738 Data
739 escript::operator-(const Data& left, const Data& right)
740 {
741 Data result;
742 //
743 // perform a deep copy
744 result.copy(left);
745 result-=right;
746 return result;
747 }
748
749 //
750 // NOTE: It is essential to specify the namepsace this operator belongs to
751 Data
752 escript::operator*(const Data& left, const Data& right)
753 {
754 Data result;
755 //
756 // perform a deep copy
757 result.copy(left);
758 result*=right;
759 return result;
760 }
761
762 //
763 // NOTE: It is essential to specify the namepsace this operator belongs to
764 Data
765 escript::operator/(const Data& left, const Data& right)
766 {
767 Data result;
768 //
769 // perform a deep copy
770 result.copy(left);
771 result/=right;
772 return result;
773 }
774
775 //
776 // NOTE: It is essential to specify the namepsace this operator belongs to
777 Data
778 escript::operator+(const Data& left, const boost::python::object& right)
779 {
780 //
781 // Convert to DataArray format if possible
782 DataArray temp(right);
783 Data result;
784 //
785 // perform a deep copy
786 result.copy(left);
787 result+=right;
788 return result;
789 }
790
791 //
792 // NOTE: It is essential to specify the namepsace this operator belongs to
793 Data
794 escript::operator-(const Data& left, const boost::python::object& right)
795 {
796 //
797 // Convert to DataArray format if possible
798 DataArray temp(right);
799 Data result;
800 //
801 // perform a deep copy
802 result.copy(left);
803 result-=right;
804 return result;
805 }
806
807 //
808 // NOTE: It is essential to specify the namepsace this operator belongs to
809 Data
810 escript::operator*(const Data& left, const boost::python::object& right)
811 {
812 //
813 // Convert to DataArray format if possible
814 DataArray temp(right);
815 Data result;
816 //
817 // perform a deep copy
818 result.copy(left);
819 result*=right;
820 return result;
821 }
822
823 //
824 // NOTE: It is essential to specify the namepsace this operator belongs to
825 Data
826 escript::operator/(const Data& left, const boost::python::object& right)
827 {
828 //
829 // Convert to DataArray format if possible
830 DataArray temp(right);
831 Data result;
832 //
833 // perform a deep copy
834 result.copy(left);
835 result/=right;
836 return result;
837 }
838
839 //
840 // NOTE: It is essential to specify the namepsace this operator belongs to
841 Data
842 escript::operator+(const boost::python::object& left, const Data& right)
843 {
844 //
845 // Construct the result using the given value and the other parameters
846 // from right
847 Data result(left,right);
848 result+=right;
849 return result;
850 }
851
852 //
853 // NOTE: It is essential to specify the namepsace this operator belongs to
854 Data
855 escript::operator-(const boost::python::object& left, const Data& right)
856 {
857 //
858 // Construct the result using the given value and the other parameters
859 // from right
860 Data result(left,right);
861 result-=right;
862 return result;
863 }
864
865 //
866 // NOTE: It is essential to specify the namepsace this operator belongs to
867 Data
868 escript::operator*(const boost::python::object& left, const Data& right)
869 {
870 //
871 // Construct the result using the given value and the other parameters
872 // from right
873 Data result(left,right);
874 result*=right;
875 return result;
876 }
877
878 //
879 // NOTE: It is essential to specify the namepsace this operator belongs to
880 Data
881 escript::operator/(const boost::python::object& left, const Data& right)
882 {
883 //
884 // Construct the result using the given value and the other parameters
885 // from right
886 Data result(left,right);
887 result/=right;
888 return result;
889 }
890
891 //
892 // NOTE: It is essential to specify the namepsace this operator belongs to
893 //bool escript::operator==(const Data& left, const Data& right)
894 //{
895 // /*
896 // NB: this operator does very little at this point, and isn't to
897 // be relied on. Requires further implementation.
898 // */
899 //
900 // bool ret;
901 //
902 // if (left.isEmpty()) {
903 // if(!right.isEmpty()) {
904 // ret = false;
905 // } else {
906 // ret = true;
907 // }
908 // }
909 //
910 // if (left.isConstant()) {
911 // if(!right.isConstant()) {
912 // ret = false;
913 // } else {
914 // ret = true;
915 // }
916 // }
917 //
918 // if (left.isTagged()) {
919 // if(!right.isTagged()) {
920 // ret = false;
921 // } else {
922 // ret = true;
923 // }
924 // }
925 //
926 // if (left.isExpanded()) {
927 // if(!right.isExpanded()) {
928 // ret = false;
929 // } else {
930 // ret = true;
931 // }
932 // }
933 //
934 // return ret;
935 //}
936
937 Data
938 Data::getItem(const boost::python::object& key) const
939 {
940 const DataArrayView& view=getPointDataView();
941
942 DataArrayView::RegionType slice_region=view.getSliceRegion(key);
943
944 if (slice_region.size()!=view.getRank()) {
945 throw DataException("Error - slice size does not match Data rank.");
946 }
947
948 return getSlice(slice_region);
949 }
950
951 Data
952 Data::getSlice(const DataArrayView::RegionType& region) const
953 {
954 return Data(*this,region);
955 }
956
957 void
958 Data::setItemO(const boost::python::object& key,
959 const boost::python::object& value)
960 {
961 Data tempData(value,getFunctionSpace());
962 setItemD(key,tempData);
963 }
964
965 void
966 Data::setItemD(const boost::python::object& key,
967 const Data& value)
968 {
969 const DataArrayView& view=getPointDataView();
970 DataArrayView::RegionType slice_region=view.getSliceRegion(key);
971 if (slice_region.size()!=view.getRank()) {
972 throw DataException("Error - slice size does not match Data rank.");
973 }
974 if (getFunctionSpace()!=value.getFunctionSpace()) {
975 setSlice(Data(value,getFunctionSpace()),slice_region);
976 } else {
977 setSlice(value,slice_region);
978 }
979 }
980
981 void
982 Data::setSlice(const Data& value,
983 const DataArrayView::RegionType& region)
984 {
985 Data tempValue(value);
986 typeMatchLeft(tempValue);
987 typeMatchRight(tempValue);
988 m_data->setSlice(tempValue.m_data.get(),region);
989 }
990
991 void
992 Data::typeMatchLeft(Data& right) const
993 {
994 if (isExpanded()){
995 right.expand();
996 } else if (isTagged()) {
997 if (right.isConstant()) {
998 right.tag();
999 }
1000 }
1001 }
1002
1003 void
1004 Data::typeMatchRight(const Data& right)
1005 {
1006 if (isTagged()) {
1007 if (right.isExpanded()) {
1008 expand();
1009 }
1010 } else if (isConstant()) {
1011 if (right.isExpanded()) {
1012 expand();
1013 } else if (right.isTagged()) {
1014 tag();
1015 }
1016 }
1017 }
1018
1019 void
1020 Data::setTaggedValue(int tagKey,
1021 const boost::python::object& value)
1022 {
1023 //
1024 // Ensure underlying data object is of type DataTagged
1025 tag();
1026
1027 if (!isTagged()) {
1028 throw DataException("Error - DataTagged conversion failed!!");
1029 }
1030
1031 //
1032 // Construct DataArray from boost::python::object input value
1033 DataArray valueDataArray(value);
1034
1035 //
1036 // Call DataAbstract::setTaggedValue
1037 m_data->setTaggedValue(tagKey,valueDataArray.getView());
1038 }
1039
1040 void
1041 Data::setRefValue(int ref,
1042 const boost::python::numeric::array& value)
1043 {
1044 //
1045 // Construct DataArray from boost::python::object input value
1046 DataArray valueDataArray(value);
1047
1048 //
1049 // Call DataAbstract::setRefValue
1050 m_data->setRefValue(ref,valueDataArray);
1051 }
1052
1053 void
1054 Data::getRefValue(int ref,
1055 boost::python::numeric::array& value)
1056 {
1057 //
1058 // Construct DataArray for boost::python::object return value
1059 DataArray valueDataArray(value);
1060
1061 //
1062 // Load DataArray with values from data-points specified by ref
1063 m_data->getRefValue(ref,valueDataArray);
1064
1065 //
1066 // Load values from valueDataArray into return numarray
1067
1068 // extract the shape of the numarray
1069 int rank = value.getrank();
1070 DataArrayView::ShapeType shape;
1071 for (int i=0; i < rank; i++) {
1072 shape.push_back(extract<int>(value.getshape()[i]));
1073 }
1074
1075 // and load the numarray with the data from the DataArray
1076 DataArrayView valueView = valueDataArray.getView();
1077
1078 if (rank==0) {
1079 throw DataException("Data::getRefValue error: only rank 1 data handled for now.");
1080 }
1081 if (rank==1) {
1082 for (int i=0; i < shape[0]; i++) {
1083 value[i] = valueView(i);
1084 }
1085 }
1086 if (rank==2) {
1087 throw DataException("Data::getRefValue error: only rank 1 data handled for now.");
1088 }
1089 if (rank==3) {
1090 throw DataException("Data::getRefValue error: only rank 1 data handled for now.");
1091 }
1092 if (rank==4) {
1093 throw DataException("Data::getRefValue error: only rank 1 data handled for now.");
1094 }
1095
1096 }
1097
1098 /*
1099 Note: this version removed for now. Not needed, and breaks escript.cpp
1100 void
1101 Data::setTaggedValue(int tagKey,
1102 const DataArrayView& value)
1103 {
1104 //
1105 // Ensure underlying data object is of type DataTagged
1106 tag();
1107
1108 if (!isTagged()) {
1109 throw DataException("Error - DataTagged conversion failed!!");
1110 }
1111
1112 //
1113 // Call DataAbstract::setTaggedValue
1114 m_data->setTaggedValue(tagKey,value);
1115 }
1116 */
1117
1118 ostream& escript::operator<<(ostream& o, const Data& data)
1119 {
1120 o << data.toString();
1121 return o;
1122 }

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26