11 |
* |
* |
12 |
*******************************************************/ |
*******************************************************/ |
13 |
|
|
14 |
#include <escriptexport/DataVar.h> |
#include <weipa/DataVar.h> |
15 |
#include <escriptexport/ElementData.h> |
#include <weipa/DomainChunk.h> |
16 |
#include <escriptexport/FinleyMesh.h> |
#include <weipa/ElementData.h> |
17 |
#include <escriptexport/NodeData.h> |
#include <weipa/NodeData.h> |
18 |
#ifndef VISIT_PLUGIN |
#ifndef VISIT_PLUGIN |
19 |
#include <escript/Data.h> |
#include <escript/Data.h> |
20 |
#endif |
#endif |
27 |
#include <silo.h> |
#include <silo.h> |
28 |
#endif |
#endif |
29 |
|
|
30 |
|
#include <numeric> // for accumulate |
31 |
|
|
32 |
using namespace std; |
using namespace std; |
33 |
|
|
34 |
namespace escriptexport { |
namespace weipa { |
35 |
|
|
|
enum { |
|
|
NODE_CENTERED = 1, |
|
|
ZONE_CENTERED = 2 |
|
|
}; |
|
|
|
|
36 |
// |
// |
37 |
// Constructor |
// Constructor |
38 |
// |
// |
39 |
DataVar::DataVar(const string& name) : |
DataVar::DataVar(const string& name) : |
40 |
initialized(false), varName(name), |
initialized(false), varName(name), |
41 |
numSamples(0), rank(0), ptsPerSample(0), centering(0) |
numSamples(0), rank(0), ptsPerSample(0) |
42 |
{ |
{ |
43 |
} |
} |
44 |
|
|
46 |
// Copy constructor |
// Copy constructor |
47 |
// |
// |
48 |
DataVar::DataVar(const DataVar& d) : |
DataVar::DataVar(const DataVar& d) : |
49 |
initialized(d.initialized), finleyMesh(d.finleyMesh), |
initialized(d.initialized), domain(d.domain), |
50 |
varName(d.varName), numSamples(d.numSamples), |
varName(d.varName), numSamples(d.numSamples), |
51 |
rank(d.rank), ptsPerSample(d.ptsPerSample), centering(d.centering), |
rank(d.rank), ptsPerSample(d.ptsPerSample), funcSpace(d.funcSpace), |
52 |
funcSpace(d.funcSpace), shape(d.shape), sampleID(d.sampleID) |
centering(d.centering), shape(d.shape), sampleID(d.sampleID) |
53 |
{ |
{ |
54 |
if (numSamples > 0) { |
if (numSamples > 0) { |
55 |
CoordArray::const_iterator it; |
CoordArray::const_iterator it; |
87 |
// |
// |
88 |
// |
// |
89 |
// |
// |
90 |
bool DataVar::initFromEscript(escript::Data& escriptData, FinleyMesh_ptr mesh) |
bool DataVar::initFromEscript(escript::Data& escriptData, const_DomainChunk_ptr dom) |
91 |
{ |
{ |
92 |
#ifndef VISIT_PLUGIN |
#ifndef VISIT_PLUGIN |
93 |
cleanup(); |
cleanup(); |
97 |
return false; |
return false; |
98 |
} |
} |
99 |
|
|
100 |
finleyMesh = mesh; |
domain = dom; |
101 |
rank = escriptData.getDataPointRank(); |
rank = escriptData.getDataPointRank(); |
102 |
ptsPerSample = escriptData.getNumDataPointsPerSample(); |
ptsPerSample = escriptData.getNumDataPointsPerSample(); |
103 |
shape = escriptData.getDataPointShape(); |
shape = escriptData.getDataPointShape(); |
104 |
funcSpace = escriptData.getFunctionSpace().getTypeCode(); |
funcSpace = escriptData.getFunctionSpace().getTypeCode(); |
105 |
numSamples = escriptData.getNumSamples(); |
numSamples = escriptData.getNumSamples(); |
106 |
|
centering = domain->getCenteringForFunctionSpace(funcSpace); |
|
if (funcSpace == FINLEY_REDUCED_NODES || funcSpace == FINLEY_NODES) { |
|
|
centering = NODE_CENTERED; |
|
|
} else { |
|
|
centering = ZONE_CENTERED; |
|
|
} |
|
107 |
|
|
108 |
#ifdef _DEBUG |
#ifdef _DEBUG |
109 |
cout << varName << ":\t" << numSamples << " samples, " |
cout << varName << ":\t" << numSamples << " samples, " |
110 |
<< ptsPerSample << " pts/s, rank: " << rank << endl; |
<< ptsPerSample << " pts/s, rank: " << rank << endl; |
111 |
#endif |
#endif |
112 |
|
|
113 |
NodeData_ptr nodes = finleyMesh->getMeshForFinleyFS(funcSpace); |
NodeData_ptr nodes = domain->getMeshForFunctionSpace(funcSpace); |
114 |
if (nodes == NULL) |
if (nodes == NULL) |
115 |
return false; |
return false; |
116 |
|
|
165 |
} |
} |
166 |
|
|
167 |
// |
// |
168 |
// Initialise with mesh data |
// Initialise with domain data |
169 |
// |
// |
170 |
bool DataVar::initFromMesh(FinleyMesh_ptr mesh) |
bool DataVar::initFromMeshData(const_DomainChunk_ptr dom, const IntVec& data, |
171 |
|
int fsCode, Centering c, NodeData_ptr nodes, const IntVec& id) |
172 |
{ |
{ |
173 |
cleanup(); |
cleanup(); |
174 |
|
|
175 |
finleyMesh = mesh; |
domain = dom; |
176 |
rank = 0; |
rank = 0; |
177 |
ptsPerSample = 1; |
ptsPerSample = 1; |
178 |
NodeData_ptr nodes; |
sampleID = id; |
|
|
|
|
if (varName.find("ContactElements_") != varName.npos) { |
|
|
funcSpace = FINLEY_CONTACT_ELEMENTS_1; |
|
|
centering = ZONE_CENTERED; |
|
|
string elementName = varName.substr(0, varName.find('_')); |
|
|
ElementData_ptr elements = mesh->getElementsByName(elementName); |
|
|
nodes = elements->getNodeMesh(); |
|
|
sampleID = elements->getIDs(); |
|
|
} else if (varName.find("FaceElements_") != varName.npos) { |
|
|
funcSpace = FINLEY_FACE_ELEMENTS; |
|
|
centering = ZONE_CENTERED; |
|
|
string elementName = varName.substr(0, varName.find('_')); |
|
|
ElementData_ptr elements = mesh->getElementsByName(elementName); |
|
|
nodes = elements->getNodeMesh(); |
|
|
sampleID = elements->getIDs(); |
|
|
} else if (varName.find("Elements_") != varName.npos) { |
|
|
funcSpace = FINLEY_ELEMENTS; |
|
|
centering = ZONE_CENTERED; |
|
|
string elementName = varName.substr(0, varName.find('_')); |
|
|
ElementData_ptr elements = mesh->getElementsByName(elementName); |
|
|
nodes = elements->getNodeMesh(); |
|
|
sampleID = elements->getIDs(); |
|
|
} else if (varName.find("Nodes_") != varName.npos) { |
|
|
funcSpace = FINLEY_NODES; |
|
|
centering = NODE_CENTERED; |
|
|
nodes = mesh->getNodes(); |
|
|
sampleID = nodes->getNodeIDs(); |
|
|
} else { |
|
|
cerr << "WARNING: Unrecognized mesh variable '" << varName << "'\n"; |
|
|
return false; |
|
|
} |
|
|
|
|
179 |
meshName = nodes->getName(); |
meshName = nodes->getName(); |
180 |
siloMeshName = nodes->getFullSiloName(); |
siloMeshName = nodes->getFullSiloName(); |
|
|
|
|
const IntVec& data = mesh->getVarDataByName(varName); |
|
181 |
numSamples = data.size(); |
numSamples = data.size(); |
182 |
|
|
183 |
if (numSamples > 0) { |
if (numSamples > 0) { |
193 |
} |
} |
194 |
|
|
195 |
// |
// |
196 |
// Reads variable data from NetCDF file |
// Reads variable data from dump file |
197 |
// |
// |
198 |
bool DataVar::initFromNetCDF(const string& filename, FinleyMesh_ptr mesh) |
bool DataVar::initFromFile(const string& filename, const_DomainChunk_ptr dom) |
199 |
{ |
{ |
200 |
cleanup(); |
cleanup(); |
201 |
|
|
228 |
att = input->get_att("function_space_type"); |
att = input->get_att("function_space_type"); |
229 |
funcSpace = att->as_int(0); |
funcSpace = att->as_int(0); |
230 |
|
|
231 |
if (funcSpace == FINLEY_REDUCED_NODES || funcSpace == FINLEY_NODES) { |
centering = domain->getCenteringForFunctionSpace(funcSpace); |
|
centering = NODE_CENTERED; |
|
|
} else { |
|
|
centering = ZONE_CENTERED; |
|
|
} |
|
232 |
|
|
233 |
dim = input->get_dim("num_samples"); |
dim = input->get_dim("num_samples"); |
234 |
numSamples = dim->size(); |
numSamples = dim->size(); |
238 |
<< ptsPerSample << " pts/s, rank: " << rank << endl; |
<< ptsPerSample << " pts/s, rank: " << rank << endl; |
239 |
#endif |
#endif |
240 |
|
|
241 |
finleyMesh = mesh; |
domain = dom; |
242 |
NodeData_ptr nodes = finleyMesh->getMeshForFinleyFS(funcSpace); |
NodeData_ptr nodes = domain->getMeshForFunctionSpace(funcSpace); |
243 |
if (nodes == NULL) { |
if (nodes == NULL) { |
244 |
delete input; |
delete input; |
245 |
return false; |
return false; |
323 |
for (int i=0; i<numSamples; i++, src+=stride) |
for (int i=0; i<numSamples; i++, src+=stride) |
324 |
*dest++ = *src; |
*dest++ = *src; |
325 |
} else { |
} else { |
326 |
ElementData_ptr cells = finleyMesh->getElementsForFinleyFS(funcSpace); |
ElementData_ptr cells = domain->getElementsForFunctionSpace(funcSpace); |
327 |
int cellFactor = cells->getElementFactor(); |
int cellFactor = cells->getElementFactor(); |
328 |
res = new float[cellFactor * numSamples]; |
res = new float[cellFactor * numSamples]; |
329 |
float* dest = res; |
float* dest = res; |
330 |
QuadMaskInfo qmi = cells->getQuadMask(funcSpace); |
QuadMaskInfo qmi = cells->getQuadMask(funcSpace); |
331 |
if (qmi.mask.size() > 0) { |
if (!qmi.mask.empty()) { |
332 |
const float* tmpSrc = src; |
const float* tmpSrc = src; |
333 |
for (int i=0; i<numSamples; i++, tmpSrc+=stride*ptsPerSample) { |
for (int i=0; i<numSamples; i++, tmpSrc+=stride*ptsPerSample) { |
334 |
for (int l=0; l<cellFactor; l++) { |
for (int l=0; l<cellFactor; l++) { |
372 |
int cellFactor = 1; |
int cellFactor = 1; |
373 |
|
|
374 |
if (centering == NODE_CENTERED) { |
if (centering == NODE_CENTERED) { |
375 |
NodeData_ptr nodes = finleyMesh->getMeshForFinleyFS(funcSpace); |
NodeData_ptr nodes = domain->getMeshForFunctionSpace(funcSpace); |
376 |
requiredIDs = &nodes->getNodeIDs(); |
requiredIDs = &nodes->getNodeIDs(); |
377 |
requiredNumSamples = nodes->getNumNodes(); |
requiredNumSamples = nodes->getNumNodes(); |
378 |
} else { |
} else { |
379 |
ElementData_ptr cells = finleyMesh->getElementsForFinleyFS(funcSpace); |
ElementData_ptr cells = domain->getElementsForFunctionSpace(funcSpace); |
380 |
if (cells == NULL) |
if (cells == NULL) |
381 |
return false; |
return false; |
382 |
|
|
428 |
// |
// |
429 |
// |
// |
430 |
// |
// |
431 |
|
int DataVar::getNumberOfComponents() const |
432 |
|
{ |
433 |
|
return (rank == 0 ? 1 : accumulate(shape.begin(), shape.end(), 0)); |
434 |
|
} |
435 |
|
|
436 |
|
// |
437 |
|
// |
438 |
|
// |
439 |
|
float* DataVar::getDataFlat() const |
440 |
|
{ |
441 |
|
int totalSize = numSamples * getNumberOfComponents(); |
442 |
|
float* res = new float[totalSize]; |
443 |
|
if (rank == 0) { |
444 |
|
copy(dataArray[0], dataArray[0]+numSamples, res); |
445 |
|
} else if (rank == 1) { |
446 |
|
float *dest = res; |
447 |
|
for (size_t c=0; c<numSamples; c++) { |
448 |
|
for (size_t i=0; i<shape[0]; i++) { |
449 |
|
*dest++ = dataArray[i][c]; |
450 |
|
} |
451 |
|
} |
452 |
|
} else if (rank == 2) { |
453 |
|
float *dest = res; |
454 |
|
for (size_t c=0; c<numSamples; c++) { |
455 |
|
for (int i=0; i<shape[1]; i++) { |
456 |
|
for (int j=0; j<shape[0]; j++) { |
457 |
|
*dest++ = dataArray[i*shape[0]+j][c]; |
458 |
|
} |
459 |
|
} |
460 |
|
} |
461 |
|
} |
462 |
|
|
463 |
|
return res; |
464 |
|
} |
465 |
|
|
466 |
|
// |
467 |
|
// |
468 |
|
// |
469 |
void DataVar::sampleToStream(ostream& os, int index) |
void DataVar::sampleToStream(ostream& os, int index) |
470 |
{ |
{ |
471 |
if (rank == 0) { |
if (rank == 0) { |
507 |
if (isNodeCentered()) { |
if (isNodeCentered()) { |
508 |
// data was reordered in reorderSamples() but for VTK we write the |
// data was reordered in reorderSamples() but for VTK we write the |
509 |
// original node mesh and thus need the original ordering... |
// original node mesh and thus need the original ordering... |
510 |
const IntVec& requiredIDs = finleyMesh->getNodes()->getNodeIDs(); |
const IntVec& requiredIDs = domain->getNodes()->getNodeIDs(); |
511 |
const IntVec& nodeGNI = finleyMesh->getNodes()->getGlobalNodeIndices(); |
const IntVec& nodeGNI = domain->getNodes()->getGlobalNodeIndices(); |
512 |
const IntVec& nodeDist = finleyMesh->getNodes()->getNodeDistribution(); |
const IntVec& nodeDist = domain->getNodes()->getNodeDistribution(); |
513 |
int firstId = nodeDist[ownIndex]; |
int firstId = nodeDist[ownIndex]; |
514 |
int lastId = nodeDist[ownIndex+1]; |
int lastId = nodeDist[ownIndex+1]; |
515 |
IndexMap sampleID2idx = buildIndexMap(); |
IndexMap sampleID2idx = buildIndexMap(); |
522 |
} else { |
} else { |
523 |
// cell data: ghost cells have been removed so do not write ghost |
// cell data: ghost cells have been removed so do not write ghost |
524 |
// samples (which are the last elements in the arrays) |
// samples (which are the last elements in the arrays) |
525 |
int toWrite = |
int toWrite = domain->getElementsByName(meshName)->getNumElements(); |
|
finleyMesh->getElementsByName(meshName)->getNumElements(); |
|
526 |
for (int i=0; i<toWrite; i++) { |
for (int i=0; i<toWrite; i++) { |
527 |
sampleToStream(os, i); |
sampleToStream(os, i); |
528 |
} |
} |
579 |
|
|
580 |
// |
// |
581 |
// Writes the data to given Silo file under the virtual path provided. |
// Writes the data to given Silo file under the virtual path provided. |
582 |
// The corresponding mesh must have been written already and made known |
// The corresponding mesh must have been written already. |
|
// to this variable by a call to setMesh(). |
|
583 |
// |
// |
584 |
bool DataVar::writeToSilo(DBfile* dbfile, const string& siloPath) |
bool DataVar::writeToSilo(DBfile* dbfile, const string& siloPath, |
585 |
|
const string& units) |
586 |
{ |
{ |
587 |
#if USE_SILO |
#if USE_SILO |
588 |
if (!initialized) |
if (!initialized) |
601 |
|
|
602 |
char* siloMesh = const_cast<char*>(siloMeshName.c_str()); |
char* siloMesh = const_cast<char*>(siloMeshName.c_str()); |
603 |
int dcenter = (centering == NODE_CENTERED ? DB_NODECENT : DB_ZONECENT); |
int dcenter = (centering == NODE_CENTERED ? DB_NODECENT : DB_ZONECENT); |
604 |
|
DBoptlist* optList = DBMakeOptlist(2); |
605 |
|
if (units.length()>0) { |
606 |
|
DBAddOption(optList, DBOPT_UNITS, (void*)units.c_str()); |
607 |
|
} |
608 |
|
|
609 |
if (rank == 0) { |
if (rank == 0) { |
610 |
ret = DBPutUcdvar1(dbfile, varName.c_str(), siloMesh, dataArray[0], |
ret = DBPutUcdvar1(dbfile, varName.c_str(), siloMesh, dataArray[0], |
611 |
numSamples, NULL, 0, DB_FLOAT, dcenter, NULL); |
numSamples, NULL, 0, DB_FLOAT, dcenter, optList); |
612 |
} |
} |
613 |
else if (rank == 1) { |
else if (rank == 1) { |
614 |
const string comps[3] = { |
const string comps[3] = { |
620 |
|
|
621 |
ret = DBPutUcdvar(dbfile, varName.c_str(), siloMesh, shape[0], |
ret = DBPutUcdvar(dbfile, varName.c_str(), siloMesh, shape[0], |
622 |
(char**)varnames, &dataArray[0], numSamples, NULL, |
(char**)varnames, &dataArray[0], numSamples, NULL, |
623 |
0, DB_FLOAT, dcenter, NULL); |
0, DB_FLOAT, dcenter, optList); |
624 |
} |
} |
625 |
else { |
else { |
626 |
string tensorDir = varName+string("_comps/"); |
string tensorDir = varName+string("_comps/"); |
627 |
ret = DBMkdir(dbfile, tensorDir.c_str()); |
ret = DBMkdir(dbfile, tensorDir.c_str()); |
628 |
if (ret == 0) { |
if (ret == 0) { |
629 |
int one = 1; |
int one = 1; |
|
DBoptlist* optList = DBMakeOptlist(1); |
|
630 |
DBAddOption(optList, DBOPT_HIDE_FROM_GUI, &one); |
DBAddOption(optList, DBOPT_HIDE_FROM_GUI, &one); |
631 |
|
|
632 |
for (int i=0; i<shape[1]; i++) { |
for (int i=0; i<shape[1]; i++) { |
640 |
} |
} |
641 |
if (ret != 0) break; |
if (ret != 0) break; |
642 |
} |
} |
|
DBFreeOptlist(optList); |
|
643 |
} // ret==0 |
} // ret==0 |
644 |
} // rank |
} // rank |
645 |
|
|
646 |
|
DBFreeOptlist(optList); |
647 |
DBSetDir(dbfile, "/"); |
DBSetDir(dbfile, "/"); |
648 |
return (ret == 0); |
return (ret == 0); |
649 |
|
|
652 |
#endif |
#endif |
653 |
} |
} |
654 |
|
|
655 |
} // namespace escriptexport |
} // namespace weipa |
656 |
|
|