1 /*******************************************************************/
2 /* XDMF */
3 /* eXtensible Data Model and Format */
4 /* */
5 /* Id : Id */
6 /* Date : $Date$ */
7 /* Version : $Revision$ */
8 /* */
9 /* Author: */
10 /* Jerry A. Clarke */
11 /* clarke@arl.army.mil */
12 /* US Army Research Laboratory */
13 /* Aberdeen Proving Ground, MD */
14 /* */
15 /* Copyright @ 2002 US Army Research Laboratory */
16 /* All Rights Reserved */
17 /* See Copyright.txt or http://www.arl.hpc.mil/ice for details */
18 /* */
19 /* This software is distributed WITHOUT ANY WARRANTY; without */
20 /* even the implied warranty of MERCHANTABILITY or FITNESS */
21 /* FOR A PARTICULAR PURPOSE. See the above copyright notice */
22 /* for more information. */
23 /* */
24 /*******************************************************************/
25 #include "XdmfDataItem.h"
26 #include "XdmfDataDesc.h"
27 #include "XdmfExpression.h"
28 #include "XdmfArray.h"
29 #include "XdmfDOM.h"
30 #include "XdmfHDF.h"
31
32 // Supported Xdmf Formats
33 #include "XdmfValuesXML.h"
34 #include "XdmfValuesHDF.h"
35 #ifdef XDMF_USE_MYSQL
36 #include "XdmfValuesMySQL.h"
37 #endif
38 #include "XdmfValuesBinary.h"
39
40 #include <libxml/tree.h>
41
42 namespace xdmf2
43 {
44
XdmfDataItem()45 XdmfDataItem::XdmfDataItem() {
46 this->SetElementName("DataItem");
47 this->Values = NULL;
48 this->DataDesc = new XdmfDataDesc();
49 this->DataDescIsMine = 1;
50 this->Array = new XdmfArray();
51 this->ArrayIsMine = 1;
52 this->Array->SetNumberType(XDMF_FLOAT32_TYPE);
53 this->Array->SetNumberOfElements(3);
54 this->Format = XDMF_FORMAT_XML;
55 this->HeavyDataSetName = NULL;
56 this->ItemType = XDMF_ITEM_UNIFORM;
57 this->Function = NULL;
58 this->ColumnMajor = 0;
59 this->TransposeInMemory = 1;
60 }
61
~XdmfDataItem()62 XdmfDataItem::~XdmfDataItem() {
63 XdmfDebug(".... Deleteing DataItem " << this);
64 if(this->Array && this->ArrayIsMine ){
65 XdmfDebug("Deleting array " << this->Array);
66 delete this->Array;
67 XdmfDebug("Done Deleteing array");
68 }
69 if(this->DataDesc && this->DataDescIsMine) delete this->DataDesc;
70 if(this->Values) delete this->Values;
71 delete [] this->HeavyDataSetName;
72 }
73
74 XdmfInt32
Release()75 XdmfDataItem::Release(){
76 // Don't Delete it.
77 if(this->Array) this->Array->SetNumberOfElements(3);
78 return(XDMF_SUCCESS);
79 }
80
81 XdmfInt32
Insert(XdmfElement * Child)82 XdmfDataItem::Insert( XdmfElement *Child){
83 if(Child && (
84 XDMF_WORD_CMP(Child->GetElementName(), "DataItem") ||
85 XDMF_WORD_CMP(Child->GetElementName(), "Information")
86 )){
87 return(XdmfElement::Insert(Child));
88 }else{
89 XdmfErrorMessage("DataItem can only Insert DataItem or Information elements");
90 }
91 return(XDMF_FAIL);
92 }
93
94 XdmfArray *
GetArray(XdmfInt32 Create)95 XdmfDataItem::GetArray(XdmfInt32 Create){
96 if(!this->Array && Create){
97 this->Array = new XdmfArray;
98 this->ArrayIsMine = 1;
99 }
100 return(this->Array);
101 }
102
103 XdmfInt32
SetArray(XdmfArray * anArray)104 XdmfDataItem::SetArray(XdmfArray *anArray){
105 if(this->Array && this->ArrayIsMine) delete this->Array;
106 this->ArrayIsMine = 0;
107 this->Array = anArray;
108 return(XDMF_SUCCESS);
109 }
110
111 XdmfInt32
SetDataDesc(XdmfDataDesc * aDataDesc)112 XdmfDataItem::SetDataDesc(XdmfDataDesc *aDataDesc){
113 if(this->DataDesc && this->DataDescIsMine) delete this->DataDesc;
114 this->DataDescIsMine = 0;
115 this->DataDesc = aDataDesc;
116 return(XDMF_SUCCESS);
117 }
118
119 // Derived version
120 XdmfInt32
Copy(XdmfElement * Source)121 XdmfDataItem::Copy(XdmfElement *Source){
122 XdmfDataItem *ds;
123
124 XdmfDebug("XdmfDataItem::Copy(XdmfElement *Source)");
125 ds = (XdmfDataItem *)Source;
126 // this->SetDOM(ds->GetDOM());
127 this->SetFormat(ds->GetFormat());
128 this->SetHeavyDataSetName(ds->GetHeavyDataSetName());
129 this->SetDsmBuffer(ds->GetDsmBuffer());
130 this->DataDesc->CopyType(ds->GetDataDesc());
131 this->DataDesc->CopyShape(ds->GetDataDesc());
132 this->DataDesc->CopySelection(ds->GetDataDesc());
133 if(CopyReferenceData){
134 XdmfDebug("Copying Data From Array");
135 this->SetArray(ds->GetArray()->Clone());
136 if(!this->Array){
137 XdmfErrorMessage("Error Cloning Array");
138 return(XDMF_FAIL);
139 }
140 // Allow for future deletion
141 this->ArrayIsMine = 1;
142 }else{
143 XdmfDebug("Referenceing Data From Array");
144 // Problem if owner deletes
145 this->SetArray(ds->GetArray());
146 }
147 return(XDMF_SUCCESS);
148 }
149
UpdateInformationFunction()150 XdmfInt32 XdmfDataItem::UpdateInformationFunction(){
151 switch(this->ItemType){
152 case XDMF_ITEM_FUNCTION :
153 XdmfConstString Value;
154 Value = this->Get("Function");
155 this->SetFunction(Value);
156 delete Value;
157 break;
158 case XDMF_ITEM_HYPERSLAB :
159 break;
160 case XDMF_ITEM_COORDINATES :
161 break;
162 }
163 return(XDMF_SUCCESS);
164 }
165
UpdateInformationCollection()166 XdmfInt32 XdmfDataItem::UpdateInformationCollection(){
167 return(XDMF_SUCCESS);
168 }
169
UpdateInformationTree()170 XdmfInt32 XdmfDataItem::UpdateInformationTree(){
171 return(XDMF_SUCCESS);
172 }
173
UpdateInformationUniform()174 XdmfInt32 XdmfDataItem::UpdateInformationUniform(){
175 XdmfConstString Value = 0;
176 XdmfInt32 Precision = 4;
177
178 Value = this->Get("Precision");
179 if(Value) Precision = atoi(Value);
180 free((void*)Value);
181 Value = this->Get("NumberType");
182 // Try DataType
183 if(!Value) Value = this->Get("DataType");
184 //! Try Old Style
185 if(!Value) Value = this->Get("Type");
186 // Only allow Simple for now.
187 if(XDMF_WORD_CMP(Value, "Char")){
188 this->DataDesc->SetNumberType(XDMF_INT8_TYPE);
189 } else if(XDMF_WORD_CMP(Value, "UChar")){
190 this->DataDesc->SetNumberType(XDMF_UINT8_TYPE);
191 } else if(XDMF_WORD_CMP(Value, "Short")){
192 this->DataDesc->SetNumberType(XDMF_INT16_TYPE);
193 } else if(XDMF_WORD_CMP(Value, "UShort")){
194 this->DataDesc->SetNumberType(XDMF_UINT16_TYPE);
195 } else if(XDMF_WORD_CMP(Value, "Int")){
196 if(Precision == 8){
197 this->DataDesc->SetNumberType(XDMF_INT64_TYPE);
198 }else{
199 this->DataDesc->SetNumberType(XDMF_INT32_TYPE);
200 }
201 } else if(XDMF_WORD_CMP(Value, "UInt")){
202 this->DataDesc->SetNumberType(XDMF_UINT32_TYPE);
203 } else {
204 if(Precision == 8){
205 this->DataDesc->SetNumberType(XDMF_FLOAT64_TYPE);
206 }else{
207 this->DataDesc->SetNumberType(XDMF_FLOAT32_TYPE);
208 }
209 }
210 free((void*)Value);;
211 Value = this->Get("Format");
212 // Currently XML or HDF5
213 if(XDMF_WORD_CMP(Value, "HDF")){
214 this->SetFormat(XDMF_FORMAT_HDF);
215 } else if(XDMF_WORD_CMP(Value, "HDF5")){
216 this->SetFormat(XDMF_FORMAT_HDF);
217 } else if(XDMF_WORD_CMP(Value, "H5")){
218 this->SetFormat(XDMF_FORMAT_HDF);
219 } else if(XDMF_WORD_CMP(Value, "XML")){
220 this->SetFormat(XDMF_FORMAT_XML);
221 } else if(XDMF_WORD_CMP(Value, "MYSQL")){
222 this->SetFormat(XDMF_FORMAT_MYSQL);
223 } else if(XDMF_WORD_CMP(Value, "BINARY")){
224 this->SetFormat(XDMF_FORMAT_BINARY);
225 }else if(Value){
226 XdmfErrorMessage("Unsupported DataItem Format :" << Value);
227 free((void*)Value);
228 return(XDMF_FAIL);
229 }
230 free((void*)Value);
231 return(XDMF_SUCCESS);
232 }
233
UpdateInformation()234 XdmfInt32 XdmfDataItem::UpdateInformation(){
235 XdmfConstString Value;
236
237 Value = this->Get("Major");
238 if(Value)
239 {
240 if(XDMF_WORD_CMP(Value,"Column"))
241 this->ColumnMajor = 1;
242 else if(XDMF_WORD_CMP(Value,"Row"))
243 this->ColumnMajor = 0;
244 else
245 {
246 XdmfErrorMessage("invalid major");
247 free((void*)Value);
248 return(XDMF_FAIL);
249 }
250 }
251 free((void*)Value);
252 XdmfDebug("Major = " << this->ColumnMajor);
253
254 XdmfDebug("XdmfDataItem::UpdateInformation()");
255 if(XdmfElement::UpdateInformation() != XDMF_SUCCESS) return(XDMF_FAIL);
256 // If this is a Reference, this->Element now points to the end of the chain. Continue?
257 XdmfDebug("Back from XdmfElement::UpdateInformation() IsReference = " << this->GetIsReference());
258 // XdmfDebug("o = " << this->GetReferenceObject(this->Element) << " this = " << this);
259 // XdmfDebug("r = " << this->ReferenceElement << " e = " << this->Element);
260 // XdmfDebug(this->DOM->Serialize(this->ReferenceElement));
261 // Dtetermine type : Uniform, Collection, or Tree
262 Value = this->Get("ItemType");
263 if(!Value){
264 // Try Old "Type=XX" Style from Xdmf Version 1.0
265 Value = this->Get("Type");
266 }
267 if(!Value){
268 this->SetItemType(XDMF_ITEM_UNIFORM);
269 }else{
270 // Allow for "break";
271 do {
272 if(XDMF_WORD_CMP(Value, "Uniform")){
273 this->SetItemType(XDMF_ITEM_UNIFORM);
274 break;
275 }
276 if(XDMF_WORD_CMP(Value, "Collection")){
277 this->SetItemType(XDMF_ITEM_COLLECTION);
278 break;
279 }
280 if(XDMF_WORD_CMP(Value, "Tree")){
281 this->SetItemType(XDMF_ITEM_TREE);
282 break;
283 }
284 if(XDMF_WORD_CMP(Value, "HyperSlab")){
285 this->SetItemType(XDMF_ITEM_HYPERSLAB);
286 break;
287 }
288 if(XDMF_WORD_CMP(Value, "Coordinates")){
289 this->SetItemType(XDMF_ITEM_COORDINATES);
290 break;
291 }
292 if(XDMF_WORD_CMP(Value, "Function")){
293 this->SetItemType(XDMF_ITEM_FUNCTION);
294 break;
295 }
296 XdmfErrorMessage("Unknown DataItem Type = " << Value);
297 free((void*)Value);
298 return(XDMF_FAIL);
299 } while(0);
300 }
301 free((void*)Value);
302 if(this->GetIsReference() &&
303 (this->ReferenceElement != this->Element) &&
304 (this->GetReferenceObject(this->Element) != this)){
305 XdmfDebug("Reference DataItem Copied Info from another ReferenceObject");
306 return(XDMF_SUCCESS);
307 }
308 Value = this->Get("Dimensions");
309 if(!Value) {
310 XdmfErrorMessage("Dimensions are not set in XML Element");
311 XdmfErrorMessage(this->DOM->Serialize(this->Element));
312 return(XDMF_FAIL);
313 }
314 if(!this->DataDesc) this->DataDesc = new XdmfDataDesc();
315 this->DataDesc->SetShapeFromString(Value);
316 free((void*)Value);;
317 switch(this->ItemType){
318 case XDMF_ITEM_UNIFORM :
319 return(this->UpdateInformationUniform());
320 break;
321 case XDMF_ITEM_COLLECTION:
322 return(this->UpdateInformationCollection());
323 break;
324 case XDMF_ITEM_TREE:
325 return(this->UpdateInformationTree());
326 break;
327 case XDMF_ITEM_HYPERSLAB :
328 case XDMF_ITEM_COORDINATES :
329 case XDMF_ITEM_FUNCTION :
330 return(this->UpdateInformationFunction());
331 break;
332 default :
333 // Should Never get Here
334 XdmfErrorMessage("Unknown ItemType");
335 return(XDMF_FAIL);
336 break;
337 }
338 // Should Never get Here
339 return(XDMF_SUCCESS);
340 }
341
UpdateFunction()342 XdmfInt32 XdmfDataItem::UpdateFunction(){
343 XdmfConstString Value;
344 XdmfArray *ReturnArray;
345 XdmfDataItem *ItemToDelete[100];
346 XdmfInt32 Id, NTmp = 0;
347
348 if(this->ItemType == XDMF_ITEM_COORDINATES){
349 // $0 is Selection $1 is Data Source
350 XdmfXmlNode Argument;
351 XdmfArray *TmpArray;
352 XdmfDataItem *TmpItem, *SrcItem;
353 XdmfInt64 NCoordinates, *Coordinates;
354
355 XdmfDebug("Updating Coordinate Selection");
356 Argument = this->DOM->FindDataElement(0, this->Element);
357 TmpItem = new XdmfDataItem();
358 TmpItem->SetDOM(this->DOM);
359 TmpItem->SetElement(Argument);
360 TmpItem->UpdateInformation();
361 TmpItem->Update();
362 TmpArray = TmpItem->GetArray();
363 NCoordinates = TmpArray->GetNumberOfElements();
364 Coordinates = new XdmfInt64[NCoordinates];
365 TmpArray->GetValues( 0, Coordinates, NCoordinates );
366 // Now Access the Source Data
367 SrcItem = new XdmfDataItem();
368 Argument = this->DOM->FindDataElement(1, this->Element);
369 SrcItem->SetDOM(this->DOM);
370 SrcItem->SetElement(Argument);
371 SrcItem->UpdateInformation();
372 NCoordinates /= SrcItem->GetRank();
373 SrcItem->GetDataDesc()->SelectCoordinates(NCoordinates, Coordinates);
374 SrcItem->Update();
375 // Steal The Array
376 ReturnArray = SrcItem->GetArray();
377 SrcItem->SetArrayIsMine(0);
378 ItemToDelete[ NTmp++ ] = TmpItem;
379 ItemToDelete[ NTmp++ ] = SrcItem;
380 delete Coordinates;
381 }
382 if(this->ItemType == XDMF_ITEM_HYPERSLAB){
383 // $0 is Selection $1 is Data Source
384 XdmfXmlNode Argument;
385 XdmfArray *TmpArray;
386 XdmfDataItem *TmpItem, *SrcItem;
387 XdmfInt64 Rank;
388 XdmfInt64 Start[ XDMF_MAX_DIMENSION ];
389 XdmfInt64 Stride[ XDMF_MAX_DIMENSION ];
390 XdmfInt64 Count[ XDMF_MAX_DIMENSION ];
391
392 XdmfDebug("Updating HyperSlab");
393 Argument = this->DOM->FindDataElement(0, this->Element);
394 TmpItem = new XdmfDataItem();
395 TmpItem->SetDOM(this->DOM);
396 TmpItem->SetElement(Argument);
397 TmpItem->UpdateInformation();
398 TmpItem->Update();
399 TmpArray = TmpItem->GetArray();
400 Rank = TmpArray->GetNumberOfElements() / 3; // Start, Stride, Count for each Source Dim
401 TmpArray->GetValues(0, Start, Rank);
402 TmpArray->GetValues(Rank, Stride, Rank);
403 TmpArray->GetValues(2 * Rank, Count, Rank);
404 XdmfDebug("Selection is " << TmpArray->GetValues());
405 // Now Access the Source Data
406 SrcItem = new XdmfDataItem();
407 Argument = this->DOM->FindDataElement(1, this->Element);
408 SrcItem->SetDOM(this->DOM);
409 SrcItem->SetElement(Argument);
410 SrcItem->UpdateInformation();
411 SrcItem->GetDataDesc()->SelectHyperSlab( Start, Stride, Count );
412 SrcItem->Update();
413 // Steal The Array
414 ReturnArray = SrcItem->GetArray();
415 SrcItem->SetArrayIsMine(0);
416 ItemToDelete[ NTmp++ ] = TmpItem;
417 ItemToDelete[ NTmp++ ] = SrcItem;
418
419 }
420 if(this->ItemType == XDMF_ITEM_FUNCTION){
421 ostrstream FunctionToEval;
422 char c, *StreamString, *scdata;
423
424
425 if(!this->Function){
426 XdmfErrorMessage("Function is NULL");
427 return(XDMF_FAIL);
428 }
429 XDMF_STRING_DUPLICATE(scdata, this->Function);
430 XdmfDebug("Transform Function = " << scdata);
431 XdmfConstString ch = scdata;
432 while( (c = *ch++) ) {
433 if( c == '$' ) {
434 XdmfXmlNode Argument;
435 XdmfArray *TmpArray;
436 XdmfDataItem *TmpItem;
437 Id = atoi(ch);
438 while( (c = *ch++) ) {
439 if( c > ' ') break;
440 }
441 Argument = this->DOM->FindDataElement(Id, this->Element );
442 TmpItem = new XdmfDataItem();
443 TmpItem->SetDOM(this->DOM);
444 TmpItem->SetElement(Argument);
445 TmpItem->UpdateInformation();
446 TmpItem->Update();
447 TmpArray = TmpItem->GetArray();
448 if( TmpArray->GetNumberOfElements() == 1 ){
449 XdmfDebug("Using Scalar = " << TmpArray->GetValueAsFloat64( 0 ) );
450 FunctionToEval << " " << TmpArray->GetValueAsFloat64( 0 ) << " ";
451 delete TmpArray;
452 } else {
453 ItemToDelete[ NTmp++ ] = TmpItem;
454 FunctionToEval << " " << TmpArray->GetTagName() << " ";
455 }
456 } else {
457 FunctionToEval << c;
458 }
459 }
460 delete [] scdata;
461 FunctionToEval << ends;
462 StreamString = FunctionToEval.str();
463 XdmfDebug("Function Translation = " << StreamString );
464 ReturnArray = XdmfExpr(StreamString);
465 delete [] StreamString;
466 }
467 // Reform and Cleanup
468 Value = this->DOM->Get( Element, "Dimensions" );
469 if(Value && ReturnArray){
470 ReturnArray->ReformFromString(Value);
471 }
472 free((void*)Value);;
473 // If only a portion of the DataItem was requested
474 // the XdmfValues did not reflect this selection since
475 // DataDesc was used to select HyperSlad | Coordinates | Function
476 if(this->DataDesc->GetSelectionType() != XDMF_SELECTALL){
477 XdmfArray *Portion;
478 XdmfInt64 SelectionSize = this->DataDesc->GetSelectionSize();
479
480 Portion = ReturnArray->Clone();
481 ReturnArray->SetShape(1, &SelectionSize);
482 ReturnArray->SelectAll();
483 Portion->CopySelection(this->DataDesc);
484 CopyArray(Portion, ReturnArray);
485 delete Portion;
486 }
487 while( NTmp ){
488 NTmp--;
489 XdmfDebug("Deleteing DataItem #" << NTmp );
490 delete ItemToDelete[ NTmp ];
491 }
492 this->SetArray(ReturnArray);
493 // We'll need to delete this
494 this->ArrayIsMine = 1;
495 return( XDMF_SUCCESS);
496 }
497
Update()498 XdmfInt32 XdmfDataItem::Update(){
499 if(XdmfElement::Update() != XDMF_SUCCESS) return(XDMF_FAIL);
500 if(this->IsReference){
501 XdmfDebug("This is a Reference");
502 }else{
503 XdmfDebug("This is not a Reference");
504 }
505 if(this->GetIsReference() && (this->GetReferenceObject(this->Element) != this)){
506 XdmfDebug("Reference DataItem Copied Info from another ReferenceObject");
507 return(XDMF_SUCCESS);
508 }
509 if(this->GetIsMultiple()){
510 XdmfDebug("Item Type does not evaluate to a single array. Done");
511 return(XDMF_SUCCESS);
512 }
513 if(this->ItemType != XDMF_ITEM_UNIFORM){
514 return(this->UpdateFunction());
515 }
516 if(this->Array->CopyType(this->DataDesc) != XDMF_SUCCESS) return(XDMF_FAIL);
517 // if(this->Array->CopyShape(this->DataDesc) != XDMF_SUCCESS) return(XDMF_FAIL);
518 // if(this->Array->CopySelection(this->DataDesc) != XDMF_SUCCESS) return(XDMF_FAIL);
519 if(this->CheckValues(this->Format) != XDMF_SUCCESS){
520 XdmfErrorMessage("Error Accessing Internal XdmfValues");
521 return(XDMF_FAIL);
522 }
523 if(this->Values->GetDataDesc()->CopySelection(this->DataDesc) != XDMF_SUCCESS) return(XDMF_FAIL);
524 XdmfDebug("Resize Array");
525 if(this->Array->SetShapeFromSelection(this->DataDesc) != XDMF_SUCCESS) return(XDMF_FAIL);
526 switch (this->Format) {
527 case XDMF_FORMAT_HDF :
528 this->Values->SetDebug(this->GetDebug());
529 // this->SetDsmBuffer(this->Values->GetDsmBuffer());
530 // cout << "Setting Values Dsm to " << this->DsmBuffer << endl;
531 this->Values->SetDsmBuffer(this->DsmBuffer);
532 XdmfDebug("Reading Data");
533 if(!((XdmfValuesHDF *)this->Values)->Read(this->Array)){
534 XdmfErrorMessage("Reading Values Failed");
535 return(XDMF_FAIL);
536 }
537 this->SetHeavyDataSetName(this->Values->GetHeavyDataSetName());
538 this->Array->SetHeavyDataSetName(this->Values->GetHeavyDataSetName());
539 break;
540 case XDMF_FORMAT_XML :
541 this->Values->SetDebug(this->GetDebug());
542 if(!((XdmfValuesXML *)this->Values)->Read(this->Array)){
543 XdmfErrorMessage("Reading Values Failed");
544 return(XDMF_FAIL);
545 }
546 break;
547 case XDMF_FORMAT_MYSQL :
548 this->Values->SetDebug(this->GetDebug());
549 #ifdef XDMF_USE_MYSQL
550 if(!((XdmfValuesMySQL *)this->Values)->Read(this->Array)){
551 XdmfErrorMessage("Reading Values Failed");
552 return(XDMF_FAIL);
553 }
554 #else
555 XdmfErrorMessage("XdmfValuesMySQL not enabled in this Xdmf");
556 return(XDMF_FAIL);
557 #endif
558
559 break;
560 case XDMF_FORMAT_BINARY :
561 this->Values->SetDebug(this->GetDebug());
562 if(!((XdmfValuesBinary *)this->Values)->Read(this->Array)){
563 XdmfErrorMessage("Reading Values Failed");
564 return(XDMF_FAIL);
565 }
566 break;
567 default :
568 XdmfErrorMessage("Unsupported Data Format");
569 return(XDMF_FAIL);
570 }
571
572 // Support for Fortran matrices (2D arrays) added by Dominik Szczerba, June 2009.
573 // Can be further optimized by e.g. in situ transpose methods
574 // discussed on http://en.wikipedia.org/wiki/In-place_matrix_transposition
575 if(ColumnMajor)
576 {
577 if(TransposeInMemory)
578 {
579 XdmfDebug("Transposing Array " << this->GetHeavyDataSetName());
580 XdmfInt32 rank = 0;
581 XdmfInt64 dims[XDMF_MAX_DIMENSION];
582 rank = GetShape(dims);
583 XdmfDebug("rank = " << rank);
584 if(rank!=2)
585 {
586 XdmfErrorMessage("transpose is only implemented for rank 2 arrays");
587 return(XDMF_FAIL);
588 }
589 // for(int i=0; i<rank; i++)
590 // cerr << "DEBUG: dims[" << i << "] = " << dims[i] << endl;
591
592 const int NI = dims[0], NJ = dims[1];
593
594 void* ArrayT;
595 switch(this->Array->GetNumberType())
596 {
597 case XDMF_FLOAT64_TYPE:
598 ArrayT = (XdmfFloat64*)new XdmfFloat64[NI*NJ];
599 break;
600 case XDMF_INT32_TYPE:
601 ArrayT = (XdmfInt32*)new XdmfInt32[NI*NJ];
602 break;
603 // TODO implement the other types
604 default:
605 XdmfErrorMessage("unknown data type");
606 return(XDMF_FAIL);
607 }
608
609 // XdmfPointer ArrayPointer, ArrayPointerT;
610 XdmfPointer ArrayPointer;
611
612 for(int j=0; j<NJ; j++)
613 {
614 for(int i=0; i<NI; i++)
615 {
616 const int idx = NI*j+i;
617 const int idxT = NJ*i+j;
618 // cerr << "DEBUG: idx/idxT = " << idx << " " << idxT << endl;
619 switch(this->Array->GetNumberType())
620 {
621 case XDMF_FLOAT64_TYPE:
622 ArrayPointer = (XdmfFloat64*)this->Array->GetDataPointer(idxT);
623 ((XdmfFloat64*)ArrayT)[idx] = *(XdmfFloat64*)ArrayPointer;
624 break;
625 case XDMF_INT32_TYPE:
626 ArrayPointer = (XdmfInt32*)this->Array->GetDataPointer(idxT);
627 ((XdmfInt32*)ArrayT)[idx] = *(XdmfInt32*)ArrayPointer;
628 break;
629 // TODO implement the other types
630 default:
631 XdmfErrorMessage("unknown data type");
632 return(XDMF_FAIL);
633 }
634 }
635 }
636
637 std::swap(dims[0], dims[1]);
638 Array->Reform(rank,dims);
639
640 for(int l=0; l<NI*NJ; l++)
641 {
642 switch(this->Array->GetNumberType())
643 {
644 case XDMF_FLOAT64_TYPE:
645 // cerr << "DEBUG: l = " << l << " " << ((XdmfFloat64*)ArrayT)[l] << endl;
646 this->Array->SetValue(l,((XdmfFloat64*)ArrayT)[l]);
647 break;
648 case XDMF_INT32_TYPE:
649 // cerr << "DEBUG: l = " << l << " " << ((XdmfInt32*)ArrayT)[l] << endl;
650 this->Array->SetValue(l,((XdmfInt32*)ArrayT)[l]);
651 break;
652 // TODO implement the other types
653 default:
654 XdmfErrorMessage("unknown data type");
655 return(XDMF_FAIL);
656 }
657 }
658
659 // delete [] ArrayT;
660 switch(this->Array->GetNumberType())
661 {
662 case XDMF_FLOAT64_TYPE:
663 delete [] (XdmfFloat64*)ArrayT;
664 break;
665 case XDMF_INT32_TYPE:
666 delete [] (XdmfInt32*)ArrayT;
667 break;
668 // TODO implement the other types
669 default:
670 XdmfErrorMessage("unknown data type");
671 return(XDMF_FAIL);
672 }
673
674 XdmfDebug("done transpose");
675
676 }
677 else
678 {
679 XdmfErrorMessage("out-of-core transpose not implemented yet");
680 return(XDMF_FAIL);
681 }
682
683
684 }
685
686 return(XDMF_SUCCESS);
687 }
688
GetDataValues(XdmfInt64 Index,XdmfInt64 NumberOfValues,XdmfInt64 ArrayStride)689 XdmfString XdmfDataItem::GetDataValues(XdmfInt64 Index, XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride){
690 if(!this->Array) return(NULL);
691 return(this->Array->GetValues(Index, NumberOfValues, ArrayStride));
692 }
693
SetDataValues(XdmfInt64 Index,XdmfConstString someValues,XdmfInt64 ArrayStride,XdmfInt64 ValuesStride)694 XdmfInt32 XdmfDataItem::SetDataValues(XdmfInt64 Index, XdmfConstString someValues, XdmfInt64 ArrayStride, XdmfInt64 ValuesStride){
695 if(!this->Array){
696 XdmfErrorMessage("DataItem has no XdmfArray");
697 return(XDMF_FAIL);
698 }
699 return(this->Array->SetValues(Index, someValues, ArrayStride, ValuesStride));
700 }
701
GetRank()702 XdmfInt32 XdmfDataItem::GetRank() {
703 if(!this->DataDesc){
704 XdmfErrorMessage("There is no XdmfDataDesc");
705 return(XDMF_FAIL);
706 }
707 return(this->DataDesc->GetRank());
708 }
709
SetShape(XdmfInt32 Rank,XdmfInt64 * Dimensions)710 XdmfInt32 XdmfDataItem::SetShape(XdmfInt32 Rank, XdmfInt64 *Dimensions){
711 if(!this->DataDesc){
712 XdmfErrorMessage("There is no XdmfDataDesc");
713 return(XDMF_FAIL);
714 }
715 return(this->DataDesc->SetShape(Rank, Dimensions));
716 }
717
GetShape(XdmfInt64 * Dimensions)718 XdmfInt32 XdmfDataItem::GetShape(XdmfInt64 *Dimensions){
719 if(!this->DataDesc){
720 XdmfErrorMessage("There is no XdmfDataDesc");
721 return(XDMF_FAIL);
722 }
723 return(this->DataDesc->GetShape(Dimensions));
724 }
725
SetDimensionsFromString(XdmfConstString Dimensions)726 XdmfInt32 XdmfDataItem::SetDimensionsFromString(XdmfConstString Dimensions){
727 if(!this->DataDesc){
728 XdmfErrorMessage("There is no XdmfDataDesc");
729 return(XDMF_FAIL);
730 }
731 return(this->DataDesc->SetShapeFromString(Dimensions));
732 }
733
GetShapeAsString()734 XdmfConstString XdmfDataItem::GetShapeAsString(){
735 if(!this->DataDesc){
736 XdmfErrorMessage("There is no XdmfDataDesc");
737 return(NULL);
738 }
739 return(this->DataDesc->GetShapeAsString());
740 }
741
Build()742 XdmfInt32 XdmfDataItem::Build(){
743 XdmfDataDesc *aDataDesc = this->DataDesc;
744 if(XdmfElement::Build() != XDMF_SUCCESS) return(XDMF_FAIL);
745 if(this->Array) aDataDesc = this->Array;
746 this->Set("Dimensions", aDataDesc->GetShapeAsString());
747 this->Set("NumberType", XdmfTypeToClassString(aDataDesc->GetNumberType()));
748 switch (aDataDesc->GetElementSize()) {
749 case 8 :
750 this->Set("Precision", "8");
751 break;
752 case 4 :
753 this->Set("Precision", "4");
754 break;
755 case 2 :
756 this->Set("Precision", "2");
757 break;
758 case 1 :
759 this->Set("Precision", "1");
760 break;
761 default :
762 break;
763 }
764 switch (this->Format) {
765 case XDMF_FORMAT_HDF :
766 this->Set("Format", "HDF");
767 break;
768 case XDMF_FORMAT_XML :
769 this->Set("Format", "XML");
770 break;
771 case XDMF_FORMAT_MYSQL :
772 this->Set("Format", "MYSQL");
773 break;
774 case XDMF_FORMAT_BINARY :
775 this->Set("Format", "BINARY");
776 break;
777 default :
778 XdmfErrorMessage("Unsupported Data Format");
779 return(XDMF_FAIL);
780 }
781 if(this->BuildFromDataXml(1) == XDMF_SUCCESS) return(XDMF_SUCCESS);
782 if(this->CheckValues(this->Format) != XDMF_SUCCESS){
783 XdmfErrorMessage("Error Accessing Internal XdmfValues");
784 return(XDMF_FAIL);
785 }
786 this->Values->SetDataDesc(aDataDesc);
787 switch (this->Format) {
788 case XDMF_FORMAT_HDF :
789 XdmfDebug("Writing Values in HDF Format");
790 Values->SetHeavyDataSetName(this->GetHeavyDataSetName());
791 Values->SetDsmBuffer(this->GetDsmBuffer());
792 if(((XdmfValuesHDF *)Values)->Write(this->Array) != XDMF_SUCCESS){
793 XdmfErrorMessage("Writing Values Failed");
794 return(XDMF_FAIL);
795 }
796 this->Set("Format", "HDF");
797 break;
798 case XDMF_FORMAT_XML :
799 XdmfDebug("Writing Values in XML Format");
800 if(((XdmfValuesXML *)Values)->Write(this->Array) != XDMF_SUCCESS){
801 XdmfErrorMessage("Writing Values Failed");
802 return(XDMF_FAIL);
803 }
804 this->Set("Format", "XML");
805 break;
806 default :
807 XdmfErrorMessage("Unsupported Data Format");
808 return(XDMF_FAIL);
809 }
810 return(XDMF_SUCCESS);
811 }
812
813 XdmfInt32
CheckValues(XdmfInt32 aFormat)814 XdmfDataItem::CheckValues(XdmfInt32 aFormat){
815 if(this->Values){
816 // Exists
817 if(this->Values->Format != aFormat){
818 // Wrong Format
819 XdmfDebug("CheckValues Changing Format");
820 delete this->Values;
821 this->Values = NULL;
822 }
823 }
824 if(!this->Values){
825 // Create One of the Proper Format
826 switch (this->Format) {
827 case XDMF_FORMAT_HDF :
828 this->Values = (XdmfValues *)new XdmfValuesHDF();
829 break;
830 case XDMF_FORMAT_XML :
831 this->Values = (XdmfValues *)new XdmfValuesXML();
832 break;
833 case XDMF_FORMAT_MYSQL :
834 #ifdef XDMF_USE_MYSQL
835 this->Values = (XdmfValues *)new XdmfValuesMySQL();
836 #else
837 XdmfErrorMessage("MySQL not supported in this Xdmf");
838 return(XDMF_FAIL);
839 #endif
840 break;
841 case XDMF_FORMAT_BINARY :
842 this->Values = (XdmfValues *)new XdmfValuesBinary();
843 break;
844 default :
845 XdmfErrorMessage("Unsupported Data Format");
846 return(XDMF_FAIL);
847 }
848 }
849 if(!this->Values){
850 XdmfErrorMessage("Error Creating new XdmfValues");
851 return(XDMF_FAIL);
852 }
853 if(this->Values->Inherit(this) != XDMF_SUCCESS){
854 XdmfErrorMessage("Error Inheriting DOM, Element, and DataDesc");
855 return(XDMF_FAIL);
856 }
857 return(XDMF_SUCCESS);
858 }
859
860 }
861