/[escript]/trunk/tools/libescriptreader/src/escriptreader/DataVar.cpp
ViewVC logotype

Annotation of /trunk/tools/libescriptreader/src/escriptreader/DataVar.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2187 - (hide annotations)
Tue Dec 23 04:13:15 2008 UTC (10 years, 3 months ago) by caltinay
File size: 22951 byte(s)
Moved escriptreader related classes into own namespace.

1 caltinay 2183
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 caltinay 2187 namespace EscriptReader {
28    
29 caltinay 2183 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 caltinay 2187 } // namespace EscriptReader
714    

  ViewVC Help
Powered by ViewVC 1.1.26