1 |
// $Id$ |
// $Id$ |
2 |
|
|
3 |
/* |
/* |
4 |
****************************************************************************** |
****************************************************************************** |
5 |
* * |
* * |
16 |
|
|
17 |
#include "escript/Data/DataTagged.h" |
#include "escript/Data/DataTagged.h" |
18 |
#include "escript/Data/DataConstant.h" |
#include "escript/Data/DataConstant.h" |
19 |
|
#include "escript/Data/DataExpanded.h" |
20 |
|
#include "escript/Data/DataException.h" |
21 |
|
|
22 |
#include <sstream> |
#include <sstream> |
23 |
|
|
25 |
|
|
26 |
namespace escript { |
namespace escript { |
27 |
|
|
28 |
DataTagged::DataTagged(): |
DataTagged::DataTagged() |
29 |
DataAbstract(FunctionSpace()) |
: DataAbstract(FunctionSpace()) |
30 |
{ |
{ |
|
// |
|
31 |
// create a scalar default value |
// create a scalar default value |
32 |
m_data.push_back(0.0); |
m_data.resize(1); |
33 |
DataArrayView temp(m_data,DataArrayView::ShapeType()); |
DataArrayView temp(m_data,DataArrayView::ShapeType()); |
34 |
setPointDataView(temp); |
setPointDataView(temp); |
35 |
} |
} |
37 |
DataTagged::DataTagged(const TagListType& tagKeys, |
DataTagged::DataTagged(const TagListType& tagKeys, |
38 |
const ValueListType& values, |
const ValueListType& values, |
39 |
const DataArrayView& defaultValue, |
const DataArrayView& defaultValue, |
40 |
const FunctionSpace& what): |
const FunctionSpace& what) |
41 |
DataAbstract(what) |
: DataAbstract(what) |
42 |
{ |
{ |
43 |
// |
// initialise the array of data values |
44 |
// The default value is always the first item in the values list |
// the default value is always the first item in the values list |
45 |
m_data.insert(m_data.end(), &defaultValue.getData(0), &defaultValue.getData(defaultValue.noValues()) ); |
m_data.resize(defaultValue.noValues()); |
46 |
|
for (int i=0; i<defaultValue.noValues(); i++) { |
47 |
|
m_data[i]=defaultValue.getData(i); |
48 |
|
} |
49 |
|
|
50 |
|
// create the data view |
51 |
DataArrayView temp(m_data,defaultValue.getShape()); |
DataArrayView temp(m_data,defaultValue.getShape()); |
52 |
setPointDataView(temp); |
setPointDataView(temp); |
53 |
|
|
54 |
// add remaining tags and values |
// add remaining tags and values |
55 |
addTaggedValues(tagKeys,values); |
addTaggedValues(tagKeys,values); |
56 |
} |
} |
57 |
|
|
58 |
DataTagged::DataTagged(const DataTagged& other): |
DataTagged::DataTagged(const FunctionSpace& what, |
59 |
DataAbstract(other.getFunctionSpace()), |
const DataArrayView::ShapeType &shape, |
60 |
|
const int tags[], |
61 |
|
const ValueType &data) |
62 |
|
: DataAbstract(what) |
63 |
|
{ |
64 |
|
// copy the data |
65 |
|
m_data=data; |
66 |
|
|
67 |
|
// create the view of the data |
68 |
|
DataArrayView tempView(m_data,shape); |
69 |
|
setPointDataView(tempView); |
70 |
|
|
71 |
|
// create the tag lookup map |
72 |
|
for (int sampleNo=0; sampleNo<getNumSamples(); sampleNo++) { |
73 |
|
m_offsetLookup.insert(DataMapType::value_type(sampleNo,tags[sampleNo])); |
74 |
|
} |
75 |
|
} |
76 |
|
|
77 |
|
DataTagged::DataTagged(const DataTagged& other) |
78 |
|
: DataAbstract(other.getFunctionSpace()), |
79 |
m_data(other.m_data), |
m_data(other.m_data), |
80 |
m_offsetLookup(other.m_offsetLookup) |
m_offsetLookup(other.m_offsetLookup) |
81 |
{ |
{ |
82 |
|
// create the data view |
83 |
DataArrayView temp(m_data,other.getPointDataView().getShape()); |
DataArrayView temp(m_data,other.getPointDataView().getShape()); |
84 |
setPointDataView(temp); |
setPointDataView(temp); |
85 |
} |
} |
86 |
|
|
87 |
DataTagged::DataTagged(const DataConstant& other): |
DataTagged::DataTagged(const DataConstant& other) |
88 |
DataAbstract(other.getFunctionSpace()) |
: DataAbstract(other.getFunctionSpace()) |
89 |
{ |
{ |
90 |
// |
// fill the default value with the constant value item from "other" |
|
// Fill the default value with the constant value item from other |
|
91 |
const DataArrayView& value=other.getPointDataView(); |
const DataArrayView& value=other.getPointDataView(); |
92 |
m_data.insert(m_data.end(), &value.getData(0), &value.getData(value.noValues()) ); |
m_data.resize(value.noValues()); |
93 |
|
for (int i=0; i<value.noValues(); i++) { |
94 |
|
m_data[i]=value.getData(i); |
95 |
|
} |
96 |
|
|
97 |
|
// create the data view |
98 |
DataArrayView temp(m_data,value.getShape()); |
DataArrayView temp(m_data,value.getShape()); |
99 |
setPointDataView(temp); |
setPointDataView(temp); |
100 |
} |
} |
101 |
|
|
102 |
DataTagged::DataTagged(const DataTagged& other, |
DataTagged::DataTagged(const DataTagged& other, |
103 |
const DataArrayView::RegionType& region): |
const DataArrayView::RegionType& region) |
104 |
DataAbstract(other.getFunctionSpace()) |
: DataAbstract(other.getFunctionSpace()) |
105 |
{ |
{ |
|
// |
|
106 |
// get the shape of the slice to copy from other |
// get the shape of the slice to copy from other |
107 |
DataArrayView::ShapeType shape(DataArrayView::getResultSliceShape(region)); |
DataArrayView::ShapeType shape(DataArrayView::getResultSliceShape(region)); |
108 |
// |
DataArrayView::RegionLoopRangeType region_loop_range=getSliceRegionLoopRange(region); |
109 |
|
|
110 |
// allocate enough space for all values |
// allocate enough space for all values |
111 |
m_data.resize(DataArrayView::noValues(shape)*(other.m_offsetLookup.size()+1)); |
m_data.resize(DataArrayView::noValues(shape)*(other.m_offsetLookup.size()+1)); |
112 |
|
|
113 |
|
// create the data view |
114 |
DataArrayView temp(m_data,shape); |
DataArrayView temp(m_data,shape); |
115 |
setPointDataView(temp); |
setPointDataView(temp); |
116 |
getDefaultValue().copySlice(other.getDefaultValue(),region); |
|
117 |
// |
// copy the default value |
118 |
// Loop through the tag values |
getDefaultValue().copySlice(other.getDefaultValue(),region_loop_range); |
119 |
|
|
120 |
|
// loop through the tag values copying these |
121 |
DataMapType::const_iterator pos; |
DataMapType::const_iterator pos; |
122 |
DataArrayView::ValueType::size_type tagOffset=getPointDataView().noValues(); |
DataArrayView::ValueType::size_type tagOffset=getPointDataView().noValues(); |
123 |
for (pos=other.m_offsetLookup.begin();pos!=other.m_offsetLookup.end();++pos){ |
for (pos=other.m_offsetLookup.begin();pos!=other.m_offsetLookup.end();pos++){ |
124 |
getPointDataView().copySlice(tagOffset,other.getPointDataView(), pos->second,region); |
getPointDataView().copySlice(tagOffset,other.getPointDataView(),pos->second,region_loop_range); |
125 |
m_offsetLookup.insert(DataMapType::value_type(pos->first,tagOffset)); |
m_offsetLookup.insert(DataMapType::value_type(pos->first,tagOffset)); |
126 |
tagOffset+=getPointDataView().noValues(); |
tagOffset+=getPointDataView().noValues(); |
127 |
} |
} |
128 |
} |
} |
129 |
|
|
130 |
void |
void |
131 |
DataTagged::reshapeDataPoint(const DataArrayView::ShapeType& shape) |
DataTagged::reshapeDataPoint(const DataArrayView::ShapeType& shape) |
132 |
{ |
{ |
|
// |
|
133 |
// can only reshape a rank zero data point |
// can only reshape a rank zero data point |
134 |
if (getPointDataView().getRank()!=0) { |
if (getPointDataView().getRank()!=0) { |
135 |
stringstream temp; |
stringstream temp; |
138 |
<< getPointDataView().getRank(); |
<< getPointDataView().getRank(); |
139 |
throw DataException(temp.str()); |
throw DataException(temp.str()); |
140 |
} |
} |
141 |
// |
|
142 |
// allocate enough space for all values |
// allocate enough space for all values |
143 |
DataArrayView::ValueType newData(DataArrayView::noValues(shape)*(m_offsetLookup.size()+1)); |
DataArrayView::ValueType newData(DataArrayView::noValues(shape)*(m_offsetLookup.size()+1)); |
144 |
DataArrayView newView(newData,shape); |
DataArrayView newView(newData,shape); |
145 |
newView.copy(0,getDefaultValue()()); |
newView.copy(0,getDefaultValue()()); |
146 |
// |
|
147 |
// Loop through the tag values |
// loop through the tag values |
148 |
DataMapType::iterator pos; |
DataMapType::iterator pos; |
149 |
DataArrayView::ValueType::size_type tagOffset=DataArrayView::noValues(shape); |
DataArrayView::ValueType::size_type tagOffset=DataArrayView::noValues(shape); |
150 |
for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();++pos){ |
for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();pos++){ |
151 |
newView.copy(tagOffset,m_data[pos->second]); |
newView.copy(tagOffset,m_data[pos->second]); |
152 |
pos->second=tagOffset; |
pos->second=tagOffset; |
153 |
tagOffset+=DataArrayView::noValues(shape); |
tagOffset+=DataArrayView::noValues(shape); |
171 |
if (tempDataTag==0) { |
if (tempDataTag==0) { |
172 |
throw DataException("Programming error - casting to DataTagged."); |
throw DataException("Programming error - casting to DataTagged."); |
173 |
} |
} |
174 |
|
|
175 |
|
DataArrayView::ShapeType shape(DataArrayView::getResultSliceShape(region)); |
176 |
|
DataArrayView::RegionLoopRangeType region_loop_range=getSliceRegionLoopRange(region); |
177 |
if (getPointDataView().getRank()!=region.size()) { |
if (getPointDataView().getRank()!=region.size()) { |
178 |
throw DataException("Error - Invalid slice region."); |
throw DataException("Error - Invalid slice region."); |
179 |
} |
} |
180 |
// |
if (tempDataTag->getPointDataView().getRank()>0 && !value->getPointDataView().checkShape(shape)) { |
|
// get the shape of the slice |
|
|
DataArrayView::ShapeType shape(DataArrayView::getResultSliceShape(region)); |
|
|
if (!value->getPointDataView().checkShape(shape)) { |
|
181 |
throw DataException (value->getPointDataView().createShapeErrorMessage( |
throw DataException (value->getPointDataView().createShapeErrorMessage( |
182 |
"Error - Couldn't copy slice due to shape mismatch.",shape)); |
"Error - Couldn't copy slice due to shape mismatch.",shape)); |
183 |
} |
} |
184 |
getDefaultValue().copySliceFrom(tempDataTag->getDefaultValue(),region); |
|
185 |
// |
getDefaultValue().copySliceFrom(tempDataTag->getDefaultValue(),region_loop_range); |
186 |
// Loop through the tag values |
|
187 |
|
// loop through the tag values |
188 |
DataMapType::const_iterator pos; |
DataMapType::const_iterator pos; |
189 |
for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();++pos){ |
for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();pos++) { |
190 |
getDataPointByTag(pos->first).copySliceFrom(tempDataTag->getDataPointByTag(pos->first),region); |
getDataPointByTag(pos->first).copySliceFrom(tempDataTag->getDataPointByTag(pos->first),region_loop_range); |
191 |
} |
} |
192 |
|
} |
193 |
|
|
194 |
|
int |
195 |
|
DataTagged::getTagNumber(int dpno) |
196 |
|
{ |
197 |
|
// |
198 |
|
// Get the number of samples and data-points per sample |
199 |
|
int numSamples = getNumSamples(); |
200 |
|
int numDataPointsPerSample = getNumDPPSample(); |
201 |
|
int numDataPoints = numSamples * numDataPointsPerSample; |
202 |
|
|
203 |
|
if (numDataPointsPerSample==0) { |
204 |
|
throw DataException("DataTagged::getTagNumber error: no data-points associated with this object."); |
205 |
|
} |
206 |
|
|
207 |
|
if (dpno<0 || dpno>numDataPoints) { |
208 |
|
throw DataException("DataTagged::getTagNumber error: invalid data-point number supplied."); |
209 |
|
} |
210 |
|
|
211 |
|
// |
212 |
|
// Determine the sample number which corresponds to this data-point number |
213 |
|
int sampleNo = dpno / numDataPointsPerSample; |
214 |
|
|
215 |
|
// |
216 |
|
// Determine the tag number which corresponds to this sample number |
217 |
|
int tagNo = getFunctionSpace().getTagFromSampleNo(sampleNo); |
218 |
|
|
219 |
|
// |
220 |
|
// return the tag number |
221 |
|
return(tagNo); |
222 |
} |
} |
223 |
|
|
224 |
void |
void |
225 |
DataTagged::setTaggedValue(int tagKey, |
DataTagged::setTaggedValue(int tagKey, |
226 |
const DataArrayView& value) |
const DataArrayView& value) |
227 |
{ |
{ |
228 |
|
if (!getPointDataView().checkShape(value.getShape())) { |
229 |
|
throw DataException(getPointDataView().createShapeErrorMessage( |
230 |
|
"Error - Cannot setTaggedValue due to shape mismatch.", value.getShape())); |
231 |
|
} |
232 |
DataMapType::iterator pos(m_offsetLookup.find(tagKey)); |
DataMapType::iterator pos(m_offsetLookup.find(tagKey)); |
233 |
if (pos==m_offsetLookup.end()) { |
if (pos==m_offsetLookup.end()) { |
234 |
// |
// tag couldn't be found so use addTaggedValue |
|
// tag couldn't be found so add as a new tag |
|
235 |
addTaggedValue(tagKey,value); |
addTaggedValue(tagKey,value); |
236 |
} else { |
} else { |
237 |
if (!getPointDataView().checkShape(value.getShape())) { |
// copy the values into the data array at the offset determined by m_offsetLookup |
238 |
throw DataException(getPointDataView().createShapeErrorMessage( |
int offset=pos->second; |
239 |
"Error - Cannot setTaggedValue due to shape mismatch.", value.getShape())); |
for (int i=0; i<getPointDataView().noValues(); i++) { |
240 |
|
m_data[offset+i]=value.getData(i); |
241 |
} |
} |
|
// |
|
|
// copy the values into tagged data storage |
|
|
copy(&value.getData(0), &value.getData(getPointDataView().noValues()), &m_data[pos->second]); |
|
|
} |
|
|
} |
|
|
|
|
|
void |
|
|
DataTagged::setTaggedValues(const TagListType& tagKeys, |
|
|
const ValueListType& values) |
|
|
{ |
|
|
for (int i=0;i<tagKeys.size();++i) { |
|
|
setTaggedValue(tagKeys[i],values[i]); |
|
242 |
} |
} |
243 |
} |
} |
244 |
|
|
248 |
{ |
{ |
249 |
if (!getPointDataView().checkShape(value.getShape())) { |
if (!getPointDataView().checkShape(value.getShape())) { |
250 |
throw DataException(getPointDataView().createShapeErrorMessage( |
throw DataException(getPointDataView().createShapeErrorMessage( |
251 |
"Error - Cannot addTaggedValue due to shape mismatch.", value.getShape())); |
"Error - Cannot addTaggedValue due to shape mismatch.", value.getShape())); |
252 |
} |
} |
253 |
// |
DataMapType::iterator pos(m_offsetLookup.find(tagKey)); |
254 |
// save the key and the location of its data |
if (pos!=m_offsetLookup.end()) { |
255 |
m_offsetLookup.insert( DataMapType::value_type(tagKey,m_data.size()) ); |
// tag already exists so use setTaggedValue |
256 |
// |
setTaggedValue(tagKey,value); |
257 |
// insert the data given in value at the end of m_data |
} else { |
258 |
m_data.insert( m_data.end(), &(value.getData(0)), &(value.getData(value.noValues())) ); |
// save the key and the location of its data in the lookup tab |
259 |
|
m_offsetLookup.insert(DataMapType::value_type(tagKey,m_data.size())); |
260 |
|
// add the data given in "value" at the end of m_data |
261 |
|
// need to make a temp copy of m_data, resize m_data, then copy |
262 |
|
// all the old values plus the value to be added back into m_data |
263 |
|
ValueType m_data_temp(m_data); |
264 |
|
int oldSize=m_data.size(); |
265 |
|
int newSize=m_data.size()+value.noValues(); |
266 |
|
m_data.resize(newSize); |
267 |
|
for (int i=0;i<oldSize;i++) { |
268 |
|
m_data[i]=m_data_temp[i]; |
269 |
|
} |
270 |
|
for (int i=0;i<value.noValues();i++) { |
271 |
|
m_data[oldSize+i]=value.getData(i); |
272 |
|
} |
273 |
|
} |
274 |
|
} |
275 |
|
|
276 |
|
void |
277 |
|
DataTagged::setTaggedValues(const TagListType& tagKeys, |
278 |
|
const ValueListType& values) |
279 |
|
{ |
280 |
|
addTaggedValues(tagKeys,values); |
281 |
} |
} |
282 |
|
|
283 |
void |
void |
285 |
const ValueListType& values) |
const ValueListType& values) |
286 |
{ |
{ |
287 |
if (values.size()==0) { |
if (values.size()==0) { |
288 |
// |
// copy the default value for each of the tags |
|
// Copy the default value for each of the tags |
|
289 |
TagListType::const_iterator iT; |
TagListType::const_iterator iT; |
290 |
for (iT=tagKeys.begin();iT!=tagKeys.end();++iT) { |
for (iT=tagKeys.begin();iT!=tagKeys.end();iT++) { |
|
// |
|
291 |
// the point data view for DataTagged points at the default value |
// the point data view for DataTagged points at the default value |
292 |
addTaggedValue(*iT,getPointDataView()); |
addTaggedValue(*iT,getPointDataView()); |
293 |
} |
} |
294 |
} else if (values.size()==1 && tagKeys.size()>1) { |
} else if (values.size()==1 && tagKeys.size()>1) { |
|
// |
|
295 |
// assume the one value will be used for all tag values |
// assume the one value will be used for all tag values |
|
// Copy the input data |
|
296 |
TagListType::const_iterator iT; |
TagListType::const_iterator iT; |
297 |
for (iT=tagKeys.begin();iT!=tagKeys.end();++iT) { |
for (iT=tagKeys.begin();iT!=tagKeys.end();iT++) { |
298 |
addTaggedValue(*iT,values[0]); |
addTaggedValue(*iT,values[0]); |
299 |
} |
} |
300 |
} else { |
} else { |
304 |
<< " doesn't match the number of values: " << values.size(); |
<< " doesn't match the number of values: " << values.size(); |
305 |
throw DataException(temp.str()); |
throw DataException(temp.str()); |
306 |
} else { |
} else { |
307 |
for (int i=0;i<tagKeys.size();++i) { |
for (int i=0;i<tagKeys.size();i++) { |
308 |
addTaggedValue(tagKeys[i],values[i]); |
addTaggedValue(tagKeys[i],values[i]); |
309 |
} |
} |
310 |
} |
} |
316 |
{ |
{ |
317 |
DataMapType::iterator pos(m_offsetLookup.find(tag)); |
DataMapType::iterator pos(m_offsetLookup.find(tag)); |
318 |
if (pos==m_offsetLookup.end()) { |
if (pos==m_offsetLookup.end()) { |
|
// |
|
319 |
// tag couldn't be found so return the default value |
// tag couldn't be found so return the default value |
320 |
return &(m_data[0]); |
return &(m_data[0]); |
321 |
} else { |
} else { |
|
// |
|
322 |
// return the data-point corresponding to the given tag |
// return the data-point corresponding to the given tag |
323 |
return &(m_data[pos->second]); |
return &(m_data[pos->second]); |
324 |
} |
} |
331 |
DataMapType::const_iterator i; |
DataMapType::const_iterator i; |
332 |
temp << "Tag(Default)" << endl; |
temp << "Tag(Default)" << endl; |
333 |
temp << getDefaultValue().toString() << endl; |
temp << getDefaultValue().toString() << endl; |
|
// |
|
334 |
// create a temporary view as the offset will be changed |
// create a temporary view as the offset will be changed |
335 |
DataArrayView tempView(getPointDataView().getData(), getPointDataView().getShape()); |
DataArrayView tempView(getPointDataView().getData(), getPointDataView().getShape()); |
336 |
for (i=m_offsetLookup.begin();i!=m_offsetLookup.end();++i) { |
for (i=m_offsetLookup.begin();i!=m_offsetLookup.end();++i) { |
388 |
return m_data.size(); |
return m_data.size(); |
389 |
} |
} |
390 |
|
|
391 |
|
int |
392 |
|
DataTagged::archiveData(ofstream& archiveFile, |
393 |
|
const DataArrayView::ValueType::size_type noValues) const |
394 |
|
{ |
395 |
|
return(m_data.archiveData(archiveFile, noValues)); |
396 |
|
} |
397 |
|
|
398 |
|
int |
399 |
|
DataTagged::extractData(ifstream& archiveFile, |
400 |
|
const DataArrayView::ValueType::size_type noValues) |
401 |
|
{ |
402 |
|
return(m_data.extractData(archiveFile, noValues)); |
403 |
|
} |
404 |
|
|
405 |
} // end of namespace |
} // end of namespace |