/[escript]/trunk/weipa/src/DataVar.cpp
ViewVC logotype

Contents of /trunk/weipa/src/DataVar.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2187 - (show annotations)
Tue Dec 23 04:13:15 2008 UTC (10 years, 4 months ago) by caltinay
Original Path: trunk/tools/libescriptreader/src/escriptreader/DataVar.cpp
File size: 22951 byte(s)
Moved escriptreader related classes into own namespace.

1
2 /*******************************************************
3 *
4 * Copyright (c) 2003-2008 by University of Queensland
5 * Earth Systems Science Computational Center (ESSCC)
6 * http://www.uq.edu.au/esscc
7 *
8 * Primary Business: Queensland, Australia
9 * Licensed under the Open Software License version 3.0
10 * http://www.opensource.org/licenses/osl-3.0.php
11 *
12 *******************************************************/
13
14 //
15 // DataVar.cpp
16 //
17 #include <escriptreader/DataVar.h>
18 #include <escriptreader/ElementData.h>
19 #include <escriptreader/MeshWithElements.h>
20 #include <netcdf.hh>
21 #if HAVE_SILO
22 #include <silo.h>
23 #endif
24
25 using namespace std;
26
27 namespace EscriptReader {
28
29 enum {
30 NODE_CENTERED = 1,
31 ZONE_CENTERED = 2
32 };
33
34 //
35 // Constructor
36 //
37 DataVar::DataVar(const string& name) :
38 varName(name), numSamples(0), rank(0), ptsPerSample(0), centering(0),
39 reorderedNumSamples(0), fullMesh(NULL)
40 {
41 }
42
43 //
44 // Destructor
45 //
46 DataVar::~DataVar()
47 {
48 CoordArray::iterator it;
49 for (it = reorderedData.begin(); it != reorderedData.end(); it++)
50 delete[] *it;
51 for (it = rawData.begin(); it != rawData.end(); it++)
52 delete[] *it;
53 }
54
55 //
56 // Copy constructor
57 // Performs a deep copy of the data values
58 //
59 DataVar::DataVar(const DataVar& d) :
60 varName(d.varName), numSamples(d.numSamples),
61 rank(d.rank), ptsPerSample(d.ptsPerSample), centering(d.centering),
62 funcSpace(d.funcSpace), shape(d.shape), sampleID(d.sampleID),
63 reorderedNumSamples(d.reorderedNumSamples), fullMesh(d.fullMesh)
64 {
65 CoordArray::const_iterator it;
66 for (it = d.rawData.begin(); it != d.rawData.end(); it++) {
67 float* c = new float[numSamples];
68 copy(*it, (*it)+numSamples, c);
69 rawData.push_back(c);
70 }
71 for (it = d.reorderedData.begin(); it != d.reorderedData.end(); it++) {
72 float* c = new float[reorderedNumSamples];
73 copy(*it, (*it)+reorderedNumSamples, c);
74 reorderedData.push_back(c);
75 }
76 }
77
78 //
79 // Special constructor for mesh data
80 // Used to store "special" integral mesh variables such as IDs or tags
81 //
82 DataVar::DataVar(const string& name, const IntVec& data,
83 MeshWithElements* mesh) :
84 varName(name)
85 {
86 numSamples = data.size();
87
88 float* c = new float[numSamples];
89 rawData.push_back(c);
90 IntVec::const_iterator it;
91 for (it=data.begin(); it != data.end(); it++)
92 *c++ = static_cast<float>(*it);
93
94 rank = 0;
95 ptsPerSample = 1;
96 if (name.compare(0, 6, "Nodes_") == 0) {
97 funcSpace = FINLEY_NODES;
98 centering = NODE_CENTERED;
99 sampleID.insert(sampleID.end(), mesh->getNodeIDs().begin(),
100 mesh->getNodeIDs().end());
101 } else if (name.compare(0, 9, "Elements_") == 0) {
102 funcSpace = FINLEY_ELEMENTS;
103 centering = ZONE_CENTERED;
104 sampleID.insert(sampleID.end(), mesh->getElements()->getIDs().begin(),
105 mesh->getElements()->getIDs().end());
106 } else if (name.compare(0, 13, "FaceElements_") == 0) {
107 funcSpace = FINLEY_FACE_ELEMENTS;
108 centering = ZONE_CENTERED;
109 sampleID.insert(sampleID.end(),
110 mesh->getFaceElements()->getIDs().begin(),
111 mesh->getFaceElements()->getIDs().end());
112 } else if (name.compare(0, 16, "ContactElements_") == 0) {
113 funcSpace = FINLEY_CONTACT_ELEMENTS_1;
114 centering = ZONE_CENTERED;
115 sampleID.insert(sampleID.end(),
116 mesh->getContactElements()->getIDs().begin(),
117 mesh->getContactElements()->getIDs().end());
118 } else if (name.compare(0, 7, "Points_") == 0) {
119 funcSpace = FINLEY_POINTS;
120 centering = NODE_CENTERED;
121 sampleID.insert(sampleID.end(), mesh->getPoints()->getIDs().begin(),
122 mesh->getPoints()->getIDs().end());
123 }
124
125 shape.clear();
126 reorderedNumSamples = 0;
127 }
128
129 //
130 // Appends raw data including IDs from rhs. Reordered data becomes invalid.
131 //
132 bool DataVar::append(const DataVar& rhs)
133 {
134 // check if variables are compatible
135 if (varName != rhs.varName || ptsPerSample != rhs.ptsPerSample ||
136 rank != rhs.rank || shape.size() != rhs.shape.size() ||
137 centering != rhs.centering)
138 return false;
139
140 for (size_t i=0; i<shape.size(); i++)
141 if (shape[i] != rhs.shape[i])
142 return false;
143
144 sampleID.insert(sampleID.end(), rhs.sampleID.begin(), rhs.sampleID.end());
145 for (size_t i=0; i<rawData.size(); i++) {
146 float* c = new float[numSamples+rhs.numSamples];
147 copy(rawData[i], rawData[i]+numSamples, c);
148 copy(rhs.rawData[i], rhs.rawData[i]+rhs.numSamples, c+numSamples);
149 delete[] rawData[i];
150 rawData[i] = c;
151 }
152 numSamples += rhs.numSamples;
153
154 // invalidate previously reordered data
155 CoordArray::iterator it;
156 for (it = reorderedData.begin(); it != reorderedData.end(); it++)
157 delete[] *it;
158 reorderedData.clear();
159 reorderedNumSamples = 0;
160
161 return true;
162 }
163
164 //
165 // Returns a subset of the src array according to stride parameter.
166 // If samples consist of multiple values they are averaged beforehand.
167 // Used to separate (x0,y0,z0,x1,y1,z1,...) into (x0,x1,...), (y0,y1,...) and
168 // (z0,z1,...)
169 //
170 float* DataVar::averageData(const float* src, size_t stride)
171 {
172 float* res = new float[numSamples];
173
174 if (ptsPerSample == 1) {
175 float* dest = res;
176 for (int i=0; i<numSamples; i++, src+=stride)
177 *dest++ = *src;
178 } else {
179 float* dest = res;
180 for (int i=0; i<numSamples; i++) {
181 double tmpVal = 0.0;
182 for (int j=0; j<ptsPerSample; j++, src+=stride)
183 tmpVal += *src;
184 *dest++ = (float)(tmpVal / ptsPerSample);
185 }
186 }
187 return res;
188 }
189
190 //
191 // Reads scalar data (rank=0) from NetCDF file and stores the values
192 // after averaging.
193 //
194 void DataVar::readRank0Data(NcFile* ncfile)
195 {
196 shape.clear();
197 float* tempData = new float[ptsPerSample*numSamples];
198 NcVar* var = ncfile->get_var("data");
199 var->get(tempData, ptsPerSample, numSamples);
200
201 float* c = averageData(tempData, 1);
202 rawData.push_back(c);
203
204 delete[] tempData;
205 }
206
207 //
208 // Reads vector data (rank=1) from NetCDF file and stores the components
209 // separately after averaging.
210 //
211 void DataVar::readRank1Data(NcFile* ncfile)
212 {
213 shape.clear();
214 NcDim* dim = ncfile->get_dim("d0");
215 shape.push_back(dim->size());
216
217 float* tempData = new float[shape[0]*ptsPerSample*numSamples];
218 NcVar* var = ncfile->get_var("data");
219 var->get(tempData, shape[0], ptsPerSample, numSamples);
220
221 for (int i=0; i<shape[0]; i++) {
222 const float* src = tempData;
223 src+=i;
224 float* c = averageData(src, shape[0]);
225 rawData.push_back(c);
226 }
227 delete[] tempData;
228 }
229
230 //
231 // Like readRank1Data() but for tensor data (rank=2).
232 //
233 void DataVar::readRank2Data(NcFile* ncfile)
234 {
235 shape.clear();
236 NcDim* dim = ncfile->get_dim("d0");
237 shape.push_back(dim->size());
238 dim = ncfile->get_dim("d1");
239 shape.push_back(dim->size());
240
241 float* tempData = new float[shape[0]*shape[1]*ptsPerSample*numSamples];
242 NcVar* var = ncfile->get_var("data");
243 var->get(tempData, shape[0], shape[1], ptsPerSample, numSamples);
244
245 for (int i=0; i<shape[1]; i++) {
246 for (int j=0; j<shape[0]; j++) {
247 const float* src = tempData;
248 src+=i*shape[0]+j;
249 float* c = averageData(src, shape[0]*shape[1]);
250 rawData.push_back(c);
251 }
252 }
253 delete[] tempData;
254 }
255
256 //
257 // Reads a NetCDF file in escript/finley format.
258 //
259 bool DataVar::readFromNc(const string& ncFile)
260 {
261 NcError ncerr(NcError::silent_nonfatal);
262 NcFile* input = new NcFile(ncFile.c_str());
263 if (!input->is_valid()) {
264 cerr << "Could not open input file " << ncFile.c_str() << "." << endl;
265 delete input;
266 return false;
267 }
268
269 NcDim* dim;
270 NcAtt* att;
271
272 dim = input->get_dim("num_samples");
273 numSamples = dim->size();
274
275 // if there are no data samples bail out
276 if (numSamples == 0) {
277 delete input;
278 return false;
279 }
280
281 att = input->get_att("type_id");
282 int typeID = att->as_int(0);
283 if (typeID != 2) {
284 cerr << "WARNING: Only expanded data supported at the moment!" << endl;
285 delete input;
286 return false;
287 }
288
289 att = input->get_att("rank");
290 rank = att->as_int(0);
291
292 dim = input->get_dim("num_data_points_per_sample");
293 ptsPerSample = dim->size();
294
295 att = input->get_att("function_space_type");
296 funcSpace = att->as_int(0);
297
298 #ifdef _DEBUG
299 cout << varName << ":\t" << numSamples << " samples, "
300 << ptsPerSample << " pts/s, rank: " << rank << endl;
301 #endif
302
303 sampleID.clear();
304 sampleID.insert(sampleID.end(), numSamples, 0);
305 NcVar* var = input->get_var("id");
306 var->get(&sampleID[0], numSamples);
307
308 switch (rank) {
309 case 0:
310 readRank0Data(input);
311 break;
312 case 1:
313 readRank1Data(input);
314 break;
315 case 2:
316 readRank2Data(input);
317 break;
318 default:
319 cerr << "WARNING: Rank " << rank << " data is not supported!\n";
320 delete input;
321 return false;
322 }
323
324 delete input;
325 return true;
326 }
327
328 //
329 // Returns one of the mesh names provided by mainMesh that matches the
330 // data variable's function space type and reduced/unreduced state.
331 //
332 string DataVar::getMeshName(MeshWithElements* mainMesh) const
333 {
334 string name;
335
336 switch (funcSpace) {
337 case FINLEY_REDUCED_NODES:
338 case FINLEY_REDUCED_DEGREES_OF_FREEDOM:
339 case FINLEY_REDUCED_ELEMENTS:
340 case FINLEY_ELEMENTS:
341 if (mainMesh->getElements()->reducedCount > 0) {
342 name = mainMesh->getElements()->reducedMesh->getName();
343 } else {
344 name = mainMesh->getElements()->fullMesh->getName();
345 }
346 break;
347
348 case FINLEY_REDUCED_FACE_ELEMENTS:
349 case FINLEY_FACE_ELEMENTS:
350 if (mainMesh->getFaceElements()->reducedCount > 0) {
351 name = mainMesh->getFaceElements()->reducedMesh->getName();
352 } else {
353 name = mainMesh->getFaceElements()->fullMesh->getName();
354 }
355 break;
356
357 case FINLEY_REDUCED_CONTACT_ELEMENTS_1:
358 case FINLEY_REDUCED_CONTACT_ELEMENTS_2:
359 case FINLEY_CONTACT_ELEMENTS_1:
360 case FINLEY_CONTACT_ELEMENTS_2:
361 if (mainMesh->getContactElements()->reducedCount > 0) {
362 name = mainMesh->getContactElements()->reducedMesh->getName();
363 } else {
364 name = mainMesh->getContactElements()->fullMesh->getName();
365 }
366 break;
367
368 case FINLEY_NODES:
369 case FINLEY_DEGREES_OF_FREEDOM:
370 name = mainMesh->getElements()->fullMesh->getName();
371 break;
372
373 case FINLEY_POINTS:
374 name = mainMesh->getPoints()->fullMesh->getName();
375 break;
376 }
377 return name;
378 }
379
380 //
381 // Returns true if the data values are nodal, false if they are zonal.
382 //
383 bool DataVar::isNodeCentered() const
384 {
385 return (funcSpace == FINLEY_REDUCED_NODES ||
386 funcSpace == FINLEY_REDUCED_DEGREES_OF_FREEDOM ||
387 funcSpace == FINLEY_NODES ||
388 funcSpace == FINLEY_DEGREES_OF_FREEDOM ||
389 funcSpace == FINLEY_POINTS);
390 }
391
392 //
393 // Filters and reorders the raw sample values according to the IDs provided
394 // in 'requiredIDs'. This is used to have data arrays ordered according to
395 // the underlying mesh (i.e. DataID[i]==MeshNodeID[i])
396 //
397 void DataVar::reorderSamples(const IndexMap& id2idxMap,
398 const IntVec& requiredIDs)
399 {
400 CoordArray::iterator it;
401 for (it = reorderedData.begin(); it != reorderedData.end(); it++)
402 delete[] *it;
403 reorderedData.clear();
404
405 buildIndexMap();
406 for (size_t i=0; i < rawData.size(); i++) {
407 float* c = new float[reorderedNumSamples];
408 reorderedData.push_back(c);
409 const float* src = rawData[i];
410 IntVec::const_iterator idIt = requiredIDs.begin();
411 for (; idIt != requiredIDs.end(); idIt++) {
412 size_t srcIdx = sampleID2idx.find(*idIt)->second;
413 size_t destIdx = id2idxMap.find(*idIt)->second;
414 c[destIdx] = src[srcIdx];
415 }
416 }
417 }
418
419 //
420 // For zonal data this method reorders the values according to the indices
421 // given in reorderArray. This is used to move ghost zones to the end of
422 // the arrays which conforms to Silo's expected format.
423 // Nodal data is not changed by this method.
424 //
425 void DataVar::handleGhostZones(const IntVec& reorderArray)
426 {
427 if (centering == NODE_CENTERED)
428 return;
429
430 vector<float*>::iterator it;
431 for (it = reorderedData.begin(); it!=reorderedData.end(); it++) {
432 float* original = *it;
433 float* reordered = new float[reorderedNumSamples];
434 float* arrIt = reordered;
435 IntVec::const_iterator idxIt;
436 for (idxIt=reorderArray.begin(); idxIt!=reorderArray.end(); idxIt++)
437 *arrIt++ = original[*idxIt];
438
439 delete[] *it;
440 *it = reordered;
441 }
442 }
443
444 //
445 // Makes the top-level mesh known to this data variable. The mesh is used
446 // to reorder and filter the samples and inquire the number of ghost zones.
447 //
448 bool DataVar::setMesh(MeshWithElements* mesh)
449 {
450 if (fullMesh == mesh)
451 return true;
452
453 const IndexMap* id2idxMap;
454 const IntVec* reqIDs;
455 const IntVec* reorderArray = NULL;
456
457 switch (funcSpace) {
458 case FINLEY_REDUCED_NODES:
459 case FINLEY_REDUCED_DEGREES_OF_FREEDOM:
460 {
461 centering = NODE_CENTERED;
462 ElementData* cells = mesh->getElements();
463 if (cells->reducedCount > 0) {
464 if (cells->getReducedGhostCount())
465 reorderArray = &cells->reducedIndexArray;
466 siloMeshName = cells->reducedMesh->getFullSiloName();
467 id2idxMap = &cells->reducedMesh->getIndexMap();
468 reqIDs = &cells->reducedMesh->getNodeIDs();
469 reorderedNumSamples = cells->reducedMesh->getNumNodes();
470 } else {
471 if (cells->getGhostCount())
472 reorderArray = &cells->indexArray;
473 siloMeshName = cells->fullMesh->getFullSiloName();
474 id2idxMap = &cells->fullMesh->getIndexMap();
475 reqIDs = &cells->fullMesh->getNodeIDs();
476 reorderedNumSamples = cells->fullMesh->getNumNodes();
477 }
478 }
479 break;
480
481 case FINLEY_NODES:
482 case FINLEY_DEGREES_OF_FREEDOM:
483 {
484 centering = NODE_CENTERED;
485 ElementData* cells = mesh->getElements();
486 if (cells->getGhostCount())
487 reorderArray = &cells->indexArray;
488 siloMeshName = cells->fullMesh->getFullSiloName();
489 id2idxMap = &cells->fullMesh->getIndexMap();
490 reqIDs = &cells->fullMesh->getNodeIDs();
491 reorderedNumSamples = cells->fullMesh->getNumNodes();
492 }
493 break;
494
495 case FINLEY_REDUCED_ELEMENTS:
496 case FINLEY_ELEMENTS:
497 {
498 centering = ZONE_CENTERED;
499 ElementData* cells = mesh->getElements();
500 id2idxMap = &cells->ID2idx;
501 reqIDs = &cells->getIDs();
502 if (cells->reducedCount > 0) {
503 if (cells->getReducedGhostCount())
504 reorderArray = &cells->reducedIndexArray;
505 reorderedNumSamples = cells->reducedCount;
506 siloMeshName = cells->reducedMesh->getFullSiloName();
507 } else {
508 if (cells->getGhostCount())
509 reorderArray = &cells->indexArray;
510 reorderedNumSamples = cells->count;
511 siloMeshName = cells->fullMesh->getFullSiloName();
512 }
513 }
514 break;
515
516 case FINLEY_REDUCED_FACE_ELEMENTS:
517 case FINLEY_FACE_ELEMENTS:
518 {
519 centering = ZONE_CENTERED;
520 ElementData* cells = mesh->getFaceElements();
521 id2idxMap = &cells->ID2idx;
522 reqIDs = &cells->getIDs();
523 if (cells->reducedCount > 0) {
524 if (cells->getReducedGhostCount())
525 reorderArray = &cells->reducedIndexArray;
526 reorderedNumSamples = cells->reducedCount;
527 siloMeshName = cells->reducedMesh->getFullSiloName();
528 } else {
529 if (cells->getGhostCount())
530 reorderArray = &cells->indexArray;
531 reorderedNumSamples = cells->count;
532 siloMeshName = cells->fullMesh->getFullSiloName();
533 }
534 }
535 break;
536
537 case FINLEY_REDUCED_CONTACT_ELEMENTS_1:
538 case FINLEY_REDUCED_CONTACT_ELEMENTS_2:
539 case FINLEY_CONTACT_ELEMENTS_1:
540 case FINLEY_CONTACT_ELEMENTS_2:
541 {
542 centering = ZONE_CENTERED;
543 ElementData* cells = mesh->getContactElements();
544 id2idxMap = &cells->ID2idx;
545 reqIDs = &cells->getIDs();
546 if (cells->reducedCount > 0) {
547 if (cells->getReducedGhostCount())
548 reorderArray = &cells->reducedIndexArray;
549 reorderedNumSamples = cells->reducedCount;
550 siloMeshName = cells->reducedMesh->getFullSiloName();
551 } else {
552 if (cells->getGhostCount())
553 reorderArray = &cells->indexArray;
554 reorderedNumSamples = cells->count;
555 siloMeshName = cells->fullMesh->getFullSiloName();
556 }
557 }
558 break;
559
560 case FINLEY_POINTS:
561 {
562 centering = NODE_CENTERED;
563 ElementData* cells = mesh->getPoints();
564 if (cells->getGhostCount())
565 reorderArray = &cells->indexArray;
566 siloMeshName = cells->fullMesh->getFullSiloName();
567 id2idxMap = &cells->ID2idx;
568 reqIDs = &cells->getIDs();
569 reorderedNumSamples = cells->count;
570 }
571 break;
572
573 default:
574 cerr << "Unknown function space type " << funcSpace << "!\n";
575 return false;
576 }
577
578 if (reorderedNumSamples > numSamples) {
579 cerr << "WARNING: " << varName << " has " << numSamples
580 << " instead of " << reorderedNumSamples << " samples!" << endl;
581 return false;
582 }
583
584 fullMesh = mesh;
585
586 reorderSamples(*id2idxMap, *reqIDs);
587 if (reorderArray)
588 handleGhostZones(*reorderArray);
589 return true;
590 }
591
592 ///////////////////////////////
593 // SILO related methods follow
594 ///////////////////////////////
595
596 //
597 // If the data is tensor data then the components of the tensor are stored
598 // separately in the Silo file. This method then returns a string that
599 // contains the proper Silo expression to put the tensor together again.
600 // For non-tensor data this method returns an empty string.
601 //
602 string DataVar::getTensorDef() const
603 {
604 if (rank < 2)
605 return string();
606
607 /// Format string for Silo 2x2 tensor
608 const string tensor2DefFmt =
609 "{{ <%sa_00>, <%sa_01> },"
610 " { <%sa_10>, <%sa_11> }}";
611
612 /// Format string for Silo 3x3 tensor
613 const string tensor3DefFmt =
614 "{{ <%sa_00>, <%sa_01>, <%sa_02> },"
615 " { <%sa_10>, <%sa_11>, <%sa_12> },"
616 " { <%sa_20>, <%sa_21>, <%sa_22> }}";
617
618 string tensorDef;
619 string tensorDir = varName+string("_comps/");
620 if (shape[1] == 3) {
621 char* tDef = new char[tensor3DefFmt.length()+9*tensorDir.length()];
622 sprintf(tDef, tensor3DefFmt.c_str(),
623 tensorDir.c_str(), tensorDir.c_str(), tensorDir.c_str(),
624 tensorDir.c_str(), tensorDir.c_str(), tensorDir.c_str(),
625 tensorDir.c_str(), tensorDir.c_str(), tensorDir.c_str());
626 tensorDef = tDef;
627 delete[] tDef;
628 } else {
629 char* tDef = new char[tensor2DefFmt.length()+4*tensorDir.length()];
630 sprintf(tDef, tensor2DefFmt.c_str(),
631 tensorDir.c_str(), tensorDir.c_str(),
632 tensorDir.c_str(), tensorDir.c_str(),
633 tensorDir.c_str(), tensorDir.c_str());
634 tensorDef = tDef;
635 delete[] tDef;
636 }
637 return tensorDef;
638 }
639
640 //
641 // Writes the data to given Silo file under the virtual path provided.
642 // The corresponding mesh must have been written already and made known
643 // to this variable by a call to setMesh().
644 //
645 bool DataVar::writeToSilo(DBfile* dbfile, const string& siloPath)
646 {
647 #if HAVE_SILO
648 if (numSamples == 0)
649 return true;
650
651 // have to set mesh first
652 if (!fullMesh)
653 return false;
654
655 int ret;
656
657 if (siloPath != "") {
658 ret = DBSetDir(dbfile, siloPath.c_str());
659 if (ret != 0)
660 return false;
661 }
662
663 char* meshName = (char*)siloMeshName.c_str();
664 int dcenter = (centering == NODE_CENTERED ? DB_NODECENT : DB_ZONECENT);
665
666 if (rank == 0) {
667 ret = DBPutUcdvar1(dbfile, varName.c_str(), meshName, reorderedData[0],
668 reorderedNumSamples, NULL, 0, DB_FLOAT, dcenter, NULL);
669 }
670 else if (rank == 1) {
671 const string comps[3] = {
672 varName+string("_x"), varName+string("_y"), varName+string("_z")
673 };
674 const char* varnames[3] = {
675 comps[0].c_str(), comps[1].c_str(), comps[2].c_str()
676 };
677
678 ret = DBPutUcdvar(dbfile, varName.c_str(), meshName, shape[0],
679 (char**)varnames, &reorderedData[0], reorderedNumSamples, NULL,
680 0, DB_FLOAT, dcenter, NULL);
681 }
682 else {
683 string tensorDir = varName+string("_comps/");
684 ret = DBMkdir(dbfile, tensorDir.c_str());
685 if (ret == 0) {
686 int one = 1;
687 DBoptlist* optList = DBMakeOptlist(1);
688 DBAddOption(optList, DBOPT_HIDE_FROM_GUI, &one);
689
690 for (int i=0; i<shape[1]; i++) {
691 for (int j=0; j<shape[0]; j++) {
692 ostringstream varname;
693 varname << tensorDir << "a_" << i << j;
694 ret = DBPutUcdvar1(dbfile, varname.str().c_str(), meshName,
695 reorderedData[i*shape[0]+j], reorderedNumSamples,
696 NULL, 0, DB_FLOAT, dcenter, optList);
697 if (ret != 0) break;
698 }
699 if (ret != 0) break;
700 }
701 DBFreeOptlist(optList);
702 } // ret==0
703 } // rank
704
705 DBSetDir(dbfile, "/");
706 return (ret == 0);
707
708 #else // !HAVE_SILO
709 return false;
710 #endif
711 }
712
713 } // namespace EscriptReader
714

  ViewVC Help
Powered by ViewVC 1.1.26