1 |
|
2 |
/******************************************************* |
3 |
* |
4 |
* Copyright (c) 2003-2009 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 |
#include <escriptexport/ElementData.h> |
15 |
#include <escriptexport/NodeData.h> |
16 |
|
17 |
extern "C" { |
18 |
#include <finley/ElementFile.h> |
19 |
} |
20 |
|
21 |
#if USE_NETCDF |
22 |
#include <netcdf.hh> |
23 |
#endif |
24 |
|
25 |
#if USE_SILO |
26 |
#include <silo.h> |
27 |
#endif |
28 |
|
29 |
using namespace std; |
30 |
|
31 |
// The following arrays contain indices to convert unsupported element |
32 |
// types into supported ones (lines, triangles, quads, hexahedrons) |
33 |
|
34 |
static const size_t line3indices[2*2] = { |
35 |
0, 2, |
36 |
2, 1 |
37 |
}; |
38 |
static const size_t tri6indices[4*3] = { |
39 |
0, 3, 5, |
40 |
3, 1, 4, |
41 |
5, 4, 2, |
42 |
3, 4, 5 |
43 |
}; |
44 |
static const size_t rec8indices[6*3] = { |
45 |
0, 4, 7, |
46 |
4, 1, 5, |
47 |
5, 2, 6, |
48 |
6, 3, 7, |
49 |
7, 5, 6, |
50 |
7, 4, 5 |
51 |
}; |
52 |
static const size_t rec9indices[4*4] = { |
53 |
0, 4, 8, 7, |
54 |
4, 1, 5, 8, |
55 |
7, 8, 6, 3, |
56 |
8, 5, 2, 6 |
57 |
}; |
58 |
static const size_t tet10indices[8*4] = { |
59 |
6, 0, 7, 4, |
60 |
2, 6, 9, 5, |
61 |
9, 7, 3, 8, |
62 |
4, 1, 8, 5, |
63 |
6, 7, 9, 8, |
64 |
5, 6, 9, 8, |
65 |
6, 5, 4, 8, |
66 |
7, 6, 4, 8 |
67 |
}; |
68 |
static const size_t hex20indices[36*3] = { |
69 |
0, 8, 12, 8, 1, 13, 13, 5, 16, |
70 |
16, 4, 12, 8, 13, 16, 8, 16, 12, |
71 |
1, 9, 13, 9, 2, 14, 14, 6, 17, |
72 |
17, 5, 13, 9, 14, 17, 9, 17, 13, |
73 |
2, 10, 14, 10, 3, 15, 15, 7, 18, |
74 |
18, 14, 6, 10, 15, 18, 10, 18, 14, |
75 |
3, 11, 15, 11, 0, 12, 12, 4, 19, |
76 |
19, 7, 15, 11, 12, 19, 11, 19, 15, |
77 |
4, 16, 19, 16, 5, 17, 17, 6, 18, |
78 |
18, 7, 19, 16, 17, 18, 16, 18, 19, |
79 |
3, 10, 11, 10, 2, 9, 9, 1, 8, |
80 |
8, 0, 11, 10, 9, 8, 10, 8, 11 |
81 |
}; |
82 |
static const size_t hex27indices[8*8] = { |
83 |
0, 8, 20, 11, 12, 21, 26, 24, |
84 |
8, 1, 9, 20, 21, 13, 22, 26, |
85 |
11, 20, 10, 3, 24, 26, 23, 15, |
86 |
20, 9, 2, 10, 26, 22, 14, 23, |
87 |
12, 21, 26, 24, 4, 16, 25, 19, |
88 |
21, 13, 22, 26, 16, 5, 17, 25, |
89 |
24, 26, 23, 15, 19, 25, 18, 7, |
90 |
26, 22, 14, 23, 25, 17, 6, 18 |
91 |
}; |
92 |
|
93 |
namespace escriptexport { |
94 |
|
95 |
// |
96 |
// Constructor |
97 |
// |
98 |
ElementData::ElementData(const string& elementName, NodeData_ptr nodeData) |
99 |
: name(elementName), numElements(0), reducedNumElements(0), |
100 |
numGhostElements(0), numReducedGhostElements(0), originalNodes(nodeData), |
101 |
fullMeshIsOriginalMesh(false) |
102 |
{ |
103 |
} |
104 |
|
105 |
// |
106 |
// Copy constructor |
107 |
// |
108 |
ElementData::ElementData(const ElementData& e) |
109 |
{ |
110 |
name = e.name; |
111 |
numElements = e.numElements; |
112 |
reducedNumElements = e.reducedNumElements; |
113 |
numGhostElements = e.numGhostElements; |
114 |
numReducedGhostElements = e.numReducedGhostElements; |
115 |
numDims = e.numDims; |
116 |
type = e.type; |
117 |
reducedType = e.reducedType; |
118 |
nodesPerElement = e.nodesPerElement; |
119 |
reducedNodesPerElement = e.reducedNodesPerElement; |
120 |
|
121 |
originalNodes = e.originalNodes; |
122 |
fullMeshIsOriginalMesh = e.fullMeshIsOriginalMesh; |
123 |
if (fullMeshIsOriginalMesh) |
124 |
fullMesh = originalNodes; |
125 |
else if (e.fullMesh) |
126 |
fullMesh = NodeData_ptr(new NodeData(*e.fullMesh)); |
127 |
|
128 |
if (e.reducedMesh) |
129 |
reducedMesh = NodeData_ptr(new NodeData(*e.reducedMesh)); |
130 |
|
131 |
nodes = e.nodes; |
132 |
reducedNodes = e.reducedNodes; |
133 |
ID = e.ID; |
134 |
color = e.color; |
135 |
tag = e.tag; |
136 |
owner = e.owner; |
137 |
reducedOwner = e.reducedOwner; |
138 |
} |
139 |
|
140 |
// |
141 |
// Destructor |
142 |
// |
143 |
ElementData::~ElementData() |
144 |
{ |
145 |
} |
146 |
|
147 |
bool ElementData::initFromFinley(const Finley_ElementFile* finleyFile) |
148 |
{ |
149 |
numElements = finleyFile->numElements; |
150 |
|
151 |
if (numElements > 0) { |
152 |
nodesPerElement = finleyFile->numNodes; |
153 |
|
154 |
int* iPtr; |
155 |
|
156 |
iPtr = finleyFile->Nodes; |
157 |
nodes.clear(); |
158 |
nodes.insert(nodes.end(), numElements*nodesPerElement, 0); |
159 |
copy(iPtr, iPtr+numElements*nodesPerElement, nodes.begin()); |
160 |
|
161 |
iPtr = finleyFile->Color; |
162 |
color.clear(); |
163 |
color.insert(color.end(), numElements, 0); |
164 |
copy(iPtr, iPtr+numElements, color.begin()); |
165 |
|
166 |
iPtr = finleyFile->Id; |
167 |
ID.clear(); |
168 |
ID.insert(ID.end(), numElements, 0); |
169 |
copy(iPtr, iPtr+numElements, ID.begin()); |
170 |
|
171 |
iPtr = finleyFile->Owner; |
172 |
owner.clear(); |
173 |
owner.insert(owner.end(), numElements, 0); |
174 |
copy(iPtr, iPtr+numElements, owner.begin()); |
175 |
|
176 |
iPtr = finleyFile->Tag; |
177 |
tag.clear(); |
178 |
tag.insert(tag.end(), numElements, 0); |
179 |
copy(iPtr, iPtr+numElements, tag.begin()); |
180 |
|
181 |
ElementTypeId tid = finleyFile->referenceElementSet-> |
182 |
referenceElement->Type->TypeId; |
183 |
FinleyElementInfo f = getFinleyTypeInfo(tid); |
184 |
type = f.elementType; |
185 |
reducedType = f.reducedElementType; |
186 |
if (f.elementFactor > 1 || f.reducedElementSize != nodesPerElement) |
187 |
buildReducedElements(f); |
188 |
|
189 |
buildMeshes(); |
190 |
} |
191 |
return true; |
192 |
} |
193 |
|
194 |
StringVec ElementData::getMeshNames() const |
195 |
{ |
196 |
StringVec res; |
197 |
if (fullMesh && !fullMeshIsOriginalMesh) |
198 |
res.push_back(fullMesh->getName()); |
199 |
if (reducedMesh) |
200 |
res.push_back(reducedMesh->getName()); |
201 |
return res; |
202 |
} |
203 |
|
204 |
StringVec ElementData::getVarNames() const |
205 |
{ |
206 |
StringVec res; |
207 |
if (numElements > 0) { |
208 |
res.push_back(name + string("_Color")); |
209 |
res.push_back(name + string("_Id")); |
210 |
res.push_back(name + string("_Owner")); |
211 |
res.push_back(name + string("_Tag")); |
212 |
} |
213 |
return res; |
214 |
} |
215 |
|
216 |
const IntVec& ElementData::getVarDataByName(const string varName) const |
217 |
{ |
218 |
if (varName == name+string("_Color")) |
219 |
return color; |
220 |
else if (varName == name+string("_Id")) |
221 |
return ID; |
222 |
else if (varName == name+string("_Owner")) { |
223 |
if (reducedNumElements > 0) |
224 |
return reducedOwner; |
225 |
else |
226 |
return owner; |
227 |
} else if (varName == name+string("_Tag")) |
228 |
return tag; |
229 |
else |
230 |
throw "Invalid variable name"; |
231 |
} |
232 |
|
233 |
// |
234 |
// Reads element data from given NetCDF file |
235 |
// |
236 |
bool ElementData::readFromNc(NcFile* ncfile) |
237 |
{ |
238 |
#if USE_NETCDF |
239 |
string num_str("num_"); |
240 |
num_str += name; |
241 |
|
242 |
NcAtt* att = ncfile->get_att(num_str.c_str()); |
243 |
numElements = att->as_int(0); |
244 |
|
245 |
// Only attempt to read data if there are any elements. |
246 |
// Having no elements is not an error. |
247 |
if (numElements > 0) { |
248 |
att = ncfile->get_att((num_str + string("_numNodes")).c_str()); |
249 |
nodesPerElement = att->as_int(0); |
250 |
|
251 |
nodes.insert(nodes.end(), numElements*nodesPerElement, 0); |
252 |
NcVar* var = ncfile->get_var((name + string("_Nodes")).c_str()); |
253 |
var->get(&nodes[0], numElements, nodesPerElement); |
254 |
|
255 |
color.insert(color.end(), numElements, 0); |
256 |
var = ncfile->get_var((name + string("_Color")).c_str()); |
257 |
var->get(&color[0], numElements); |
258 |
|
259 |
ID.insert(ID.end(), numElements, 0); |
260 |
var = ncfile->get_var((name + string("_Id")).c_str()); |
261 |
var->get(&ID[0], numElements); |
262 |
|
263 |
owner.insert(owner.end(), numElements, 0); |
264 |
var = ncfile->get_var((name + string("_Owner")).c_str()); |
265 |
var->get(&owner[0], numElements); |
266 |
|
267 |
tag.insert(tag.end(), numElements, 0); |
268 |
var = ncfile->get_var((name + string("_Tag")).c_str()); |
269 |
var->get(&tag[0], numElements); |
270 |
|
271 |
att = ncfile->get_att((name + string("_TypeId")).c_str()); |
272 |
FinleyElementInfo f = getFinleyTypeInfo((ElementTypeId)att->as_int(0)); |
273 |
type = f.elementType; |
274 |
reducedType = f.reducedElementType; |
275 |
|
276 |
if (f.elementFactor > 1 || f.reducedElementSize != nodesPerElement) |
277 |
buildReducedElements(f); |
278 |
|
279 |
buildMeshes(); |
280 |
} |
281 |
|
282 |
return true; |
283 |
#else // !USE_NETCDF |
284 |
return false; |
285 |
#endif |
286 |
} |
287 |
|
288 |
// |
289 |
// |
290 |
// |
291 |
void ElementData::reorderArray(IntVec& v, const IntVec& idx, |
292 |
int elementsPerIndex) |
293 |
{ |
294 |
IntVec newArray(v.size()); |
295 |
IntVec::iterator arrIt = newArray.begin(); |
296 |
IntVec::const_iterator idxIt; |
297 |
if (elementsPerIndex == 1) { |
298 |
for (idxIt=idx.begin(); idxIt!=idx.end(); idxIt++) { |
299 |
*arrIt++ = v[*idxIt]; |
300 |
} |
301 |
} else { |
302 |
for (idxIt=idx.begin(); idxIt!=idx.end(); idxIt++) { |
303 |
int i = *idxIt; |
304 |
copy(&v[i*elementsPerIndex], &v[(i+1)*elementsPerIndex], arrIt); |
305 |
arrIt += elementsPerIndex; |
306 |
} |
307 |
} |
308 |
v.swap(newArray); |
309 |
} |
310 |
|
311 |
// |
312 |
// |
313 |
// |
314 |
void ElementData::buildReducedElements(const FinleyElementInfo& f) |
315 |
{ |
316 |
reducedNodes.clear(); |
317 |
reducedNodes.insert(reducedNodes.end(), |
318 |
f.reducedElementSize*numElements, 0); |
319 |
IntVec::iterator reducedIt = reducedNodes.begin(); |
320 |
IntVec::const_iterator origIt; |
321 |
for (origIt=nodes.begin(); origIt!=nodes.end(); |
322 |
origIt+=nodesPerElement) |
323 |
{ |
324 |
std::copy(origIt, origIt+f.reducedElementSize, reducedIt); |
325 |
reducedIt += f.reducedElementSize; |
326 |
} |
327 |
|
328 |
// Remove comment to save disk space - we don't really need the full |
329 |
// elements except for the main mesh |
330 |
if (f.elementFactor > 1 /*&& name == "Elements"*/) { |
331 |
// replace each element by multiple smaller ones |
332 |
IntVec fullNodes(f.elementSize*f.elementFactor*numElements); |
333 |
IntVec::iterator cellIt = fullNodes.begin(); |
334 |
|
335 |
// copy owner data |
336 |
owner.swap(reducedOwner); |
337 |
owner.clear(); |
338 |
for (int i=0; i < numElements; i++) { |
339 |
owner.insert(owner.end(), f.elementFactor, reducedOwner[i]); |
340 |
for (int j=0; j < f.elementFactor*f.elementSize; j++) |
341 |
*cellIt++ = nodes[ |
342 |
nodesPerElement*i+f.multiCellIndices[j]]; |
343 |
} |
344 |
nodes.swap(fullNodes); |
345 |
reducedNumElements = numElements; |
346 |
reducedNodesPerElement = f.reducedElementSize; |
347 |
nodesPerElement = f.elementSize; |
348 |
numElements *= f.elementFactor; |
349 |
} else { |
350 |
// we only keep the reduced elements but treat them as regular |
351 |
// ones, so replace the data accordingly |
352 |
nodes.swap(reducedNodes); |
353 |
reducedNodes.clear(); |
354 |
nodesPerElement = f.reducedElementSize; |
355 |
type = f.reducedElementType; |
356 |
} |
357 |
} |
358 |
|
359 |
// |
360 |
// |
361 |
// |
362 |
void ElementData::prepareGhostIndices(int ownIndex, IntVec& indexArray, |
363 |
IntVec& reducedIndexArray) |
364 |
{ |
365 |
indexArray.clear(); |
366 |
reducedIndexArray.clear(); |
367 |
numGhostElements = 0; |
368 |
numReducedGhostElements = 0; |
369 |
|
370 |
// move indices of "ghost zones" to the end to be able to reorder |
371 |
// data accordingly |
372 |
for (int i=0; i<numElements; i++) |
373 |
if (owner[i] == ownIndex) |
374 |
indexArray.push_back(i); |
375 |
|
376 |
for (int i=0; i<numElements; i++) |
377 |
if (owner[i] != ownIndex) { |
378 |
numGhostElements++; |
379 |
indexArray.push_back(i); |
380 |
} |
381 |
|
382 |
for (int i=0; i<reducedNumElements; i++) |
383 |
if (reducedOwner[i] == ownIndex) |
384 |
reducedIndexArray.push_back(i); |
385 |
|
386 |
for (int i=0; i<reducedNumElements; i++) |
387 |
if (reducedOwner[i] != ownIndex) { |
388 |
numReducedGhostElements++; |
389 |
reducedIndexArray.push_back(i); |
390 |
} |
391 |
} |
392 |
|
393 |
// |
394 |
// |
395 |
// |
396 |
void ElementData::reorderGhostZones(int ownIndex) |
397 |
{ |
398 |
IntVec indexArray, reducedIndexArray; |
399 |
prepareGhostIndices(ownIndex, indexArray, reducedIndexArray); |
400 |
|
401 |
// move "ghost data" to the end of the arrays |
402 |
if (numGhostElements > 0) { |
403 |
reorderArray(nodes, indexArray, nodesPerElement); |
404 |
reorderArray(owner, indexArray, 1); |
405 |
if (reducedNumElements == 0) { |
406 |
reorderArray(color, indexArray, 1); |
407 |
reorderArray(ID, indexArray, 1); |
408 |
reorderArray(tag, indexArray, 1); |
409 |
} |
410 |
} |
411 |
|
412 |
if (numReducedGhostElements > 0) { |
413 |
reorderArray(reducedNodes, reducedIndexArray, reducedNodesPerElement); |
414 |
reorderArray(reducedOwner, reducedIndexArray, 1); |
415 |
reorderArray(color, reducedIndexArray, 1); |
416 |
reorderArray(ID, reducedIndexArray, 1); |
417 |
reorderArray(tag, reducedIndexArray, 1); |
418 |
} |
419 |
} |
420 |
|
421 |
// |
422 |
// |
423 |
// |
424 |
void ElementData::removeGhostZones(int ownIndex) |
425 |
{ |
426 |
reorderGhostZones(ownIndex); |
427 |
|
428 |
if (numGhostElements > 0) { |
429 |
numElements -= numGhostElements; |
430 |
nodes.resize(numElements*nodesPerElement); |
431 |
owner.resize(numElements); |
432 |
if (reducedNumElements == 0) { |
433 |
color.resize(numElements); |
434 |
ID.resize(numElements); |
435 |
tag.resize(numElements); |
436 |
} |
437 |
numGhostElements = 0; |
438 |
} |
439 |
|
440 |
if (numReducedGhostElements > 0) { |
441 |
reducedNumElements -= numReducedGhostElements; |
442 |
reducedNodes.resize(reducedNumElements*reducedNodesPerElement); |
443 |
reducedOwner.resize(reducedNumElements); |
444 |
color.resize(reducedNumElements); |
445 |
ID.resize(reducedNumElements); |
446 |
tag.resize(reducedNumElements); |
447 |
numReducedGhostElements = 0; |
448 |
} |
449 |
buildMeshes(); |
450 |
if (numElements > 0) |
451 |
fullMesh->removeGhostNodes(ownIndex); |
452 |
if (reducedNumElements > 0) |
453 |
reducedMesh->removeGhostNodes(ownIndex); |
454 |
} |
455 |
|
456 |
// |
457 |
// |
458 |
// |
459 |
void ElementData::buildMeshes() |
460 |
{ |
461 |
// build a new mesh containing only the required nodes |
462 |
if (numElements > 0) { |
463 |
fullMesh = NodeData_ptr(new NodeData(originalNodes, nodes, name)); |
464 |
|
465 |
#ifdef _DEBUG |
466 |
cout << fullMesh->getName() << " has " << fullMesh->getNumNodes() |
467 |
<< " nodes, " << numElements << " elements" << endl; |
468 |
#endif |
469 |
} |
470 |
|
471 |
// build a reduced mesh if necessary |
472 |
if (reducedNumElements > 0) { |
473 |
reducedMesh = NodeData_ptr(new NodeData( |
474 |
originalNodes, reducedNodes, "Reduced"+name)); |
475 |
#ifdef _DEBUG |
476 |
cout << reducedMesh->getName() << " has " << newIdx |
477 |
<< " nodes, " << reducedNumElements << " elements" << endl; |
478 |
#endif |
479 |
} |
480 |
} |
481 |
|
482 |
#if USE_SILO |
483 |
// |
484 |
// |
485 |
// |
486 |
inline int toSiloElementType(int type) |
487 |
{ |
488 |
switch (type) { |
489 |
case ZONETYPE_BEAM: return DB_ZONETYPE_BEAM; |
490 |
case ZONETYPE_HEX: return DB_ZONETYPE_HEX; |
491 |
case ZONETYPE_POLYGON: return DB_ZONETYPE_POLYGON; |
492 |
case ZONETYPE_QUAD: return DB_ZONETYPE_QUAD; |
493 |
case ZONETYPE_TET: return DB_ZONETYPE_TET; |
494 |
case ZONETYPE_TRIANGLE: return DB_ZONETYPE_TRIANGLE; |
495 |
} |
496 |
return 0; |
497 |
} |
498 |
#endif |
499 |
|
500 |
// |
501 |
// |
502 |
// |
503 |
bool ElementData::writeToSilo(DBfile* dbfile, const string& siloPath) |
504 |
{ |
505 |
#if USE_SILO |
506 |
if (numElements == 0) |
507 |
return true; |
508 |
|
509 |
int numCells; |
510 |
string varName, siloMeshNameStr; |
511 |
int ret; |
512 |
|
513 |
if (siloPath != "") { |
514 |
ret = DBSetDir(dbfile, siloPath.c_str()); |
515 |
if (ret != 0) |
516 |
return false; |
517 |
} |
518 |
|
519 |
// write out the full mesh in any case |
520 |
fullMesh->setSiloPath(siloPath); |
521 |
siloMeshNameStr = fullMesh->getFullSiloName(); |
522 |
const char* siloMeshName = siloMeshNameStr.c_str(); |
523 |
int arraylen = numElements * nodesPerElement; |
524 |
int eltype = toSiloElementType(type); |
525 |
|
526 |
varName = name + string("_zones"); |
527 |
ret = DBPutZonelist2(dbfile, varName.c_str(), numElements, |
528 |
fullMesh->getNumDims(), &nodes[0], arraylen, 0, 0, |
529 |
numGhostElements, &eltype, &nodesPerElement, &numElements, 1, NULL); |
530 |
if (ret == 0) { |
531 |
CoordArray& coordbase = const_cast<CoordArray&>(fullMesh->getCoords()); |
532 |
ret = DBPutUcdmesh(dbfile, siloMeshName, |
533 |
fullMesh->getNumDims(), NULL, &coordbase[0], |
534 |
fullMesh->getNumNodes(), numElements, varName.c_str(), |
535 |
/*"facelist"*/NULL, DB_FLOAT, NULL); |
536 |
} |
537 |
|
538 |
// Point mesh is useful for debugging |
539 |
if (0) { |
540 |
CoordArray& coordbase = const_cast<CoordArray&>(fullMesh->getCoords()); |
541 |
DBPutPointmesh(dbfile, "/pointmesh", |
542 |
originalNodes->getNumDims(), &coordbase[0], |
543 |
fullMesh->getNumNodes(), DB_FLOAT, NULL); |
544 |
} |
545 |
|
546 |
if (ret != 0) |
547 |
return false; |
548 |
|
549 |
// decide whether to additionally write out the reduced mesh |
550 |
if (reducedNumElements > 0) { |
551 |
reducedMesh->setSiloPath(siloPath); |
552 |
siloMeshNameStr = reducedMesh->getFullSiloName(); |
553 |
siloMeshName = siloMeshNameStr.c_str(); |
554 |
arraylen = reducedNumElements * reducedNodesPerElement; |
555 |
eltype = toSiloElementType(reducedType); |
556 |
varName = string("Reduced") + name + string("_zones"); |
557 |
ret = DBPutZonelist2(dbfile, varName.c_str(), reducedNumElements, |
558 |
originalNodes->getNumDims(), &reducedNodes[0], arraylen, 0, 0, |
559 |
numReducedGhostElements, &eltype, &reducedNodesPerElement, |
560 |
&reducedNumElements, 1, NULL); |
561 |
if (ret == 0) { |
562 |
CoordArray& coordbase = const_cast<CoordArray&>(reducedMesh->getCoords()); |
563 |
ret = DBPutUcdmesh(dbfile, siloMeshName, |
564 |
reducedMesh->getNumDims(), NULL, &coordbase[0], |
565 |
reducedMesh->getNumNodes(), reducedNumElements, varName.c_str(), |
566 |
NULL, DB_FLOAT, NULL); |
567 |
} |
568 |
if (ret != 0) |
569 |
return false; |
570 |
numCells = reducedNumElements; |
571 |
} else { |
572 |
numCells = numElements; |
573 |
} |
574 |
|
575 |
// finally, write out the element-centered variables on the correct mesh |
576 |
varName = name + string("_Color"); |
577 |
ret = DBPutUcdvar1(dbfile, varName.c_str(), siloMeshName, |
578 |
(float*)&color[0], numCells, NULL, 0, DB_INT, DB_ZONECENT, NULL); |
579 |
if (ret == 0) { |
580 |
varName = name + string("_Id"); |
581 |
ret = DBPutUcdvar1(dbfile, varName.c_str(), siloMeshName, |
582 |
(float*)&ID[0], numCells, NULL, 0, DB_INT, DB_ZONECENT, NULL); |
583 |
} |
584 |
if (ret == 0) { |
585 |
varName = name + string("_Owner"); |
586 |
ret = DBPutUcdvar1(dbfile, varName.c_str(), siloMeshName, |
587 |
(float*)&owner[0], numCells, NULL, 0, DB_INT, DB_ZONECENT, NULL); |
588 |
} |
589 |
if (ret == 0) { |
590 |
varName = name + string("_Tag"); |
591 |
ret = DBPutUcdvar1(dbfile, varName.c_str(), siloMeshName, |
592 |
(float*)&tag[0], numCells, NULL, 0, DB_INT, DB_ZONECENT, NULL); |
593 |
} |
594 |
|
595 |
if (name == "Elements") { |
596 |
fullMesh->writeToSilo(dbfile); |
597 |
} |
598 |
|
599 |
DBSetDir(dbfile, "/"); |
600 |
return (ret == 0); |
601 |
|
602 |
#else // !USE_SILO |
603 |
return false; |
604 |
#endif |
605 |
} |
606 |
|
607 |
// |
608 |
// |
609 |
// |
610 |
FinleyElementInfo ElementData::getFinleyTypeInfo(ElementTypeId typeId) |
611 |
{ |
612 |
FinleyElementInfo ret; |
613 |
ret.multiCellIndices = NULL; |
614 |
ret.elementFactor = 1; |
615 |
|
616 |
switch (typeId) { |
617 |
case Point1_Contact://untested |
618 |
case Line2Face_Contact://untested |
619 |
case Line3Face_Contact://untested |
620 |
case Line2Face://untested |
621 |
case Line3Face://untested |
622 |
case Point1://untested |
623 |
cerr << "WARNING: Finley type " <<typeId<< " is untested!" << endl; |
624 |
ret.elementSize = 1; |
625 |
ret.elementType = ZONETYPE_POLYGON; |
626 |
break; |
627 |
|
628 |
case Tri3Face_Contact://untested |
629 |
case Tri3Face://untested |
630 |
cerr << "WARNING: Finley type " <<typeId<< " is untested!" << endl; |
631 |
case Line2_Contact: |
632 |
case Rec4Face_Contact: |
633 |
case Rec4Face: |
634 |
case Line2: |
635 |
ret.elementSize = ret.reducedElementSize = 2; |
636 |
ret.elementType = ret.reducedElementType = ZONETYPE_BEAM; |
637 |
break; |
638 |
|
639 |
case Line3: |
640 |
ret.multiCellIndices = line3indices; |
641 |
ret.elementFactor = 2; |
642 |
// fall through |
643 |
case Line3_Contact: |
644 |
case Tri6Face_Contact://untested |
645 |
case Rec8Face_Contact: |
646 |
case Tri6Face://untested |
647 |
case Rec8Face: |
648 |
//VTK_QUADRATIC_EDGE |
649 |
ret.elementSize = ret.reducedElementSize = 2; |
650 |
ret.elementType = ret.reducedElementType = ZONETYPE_BEAM; |
651 |
break; |
652 |
|
653 |
case Tet4Face_Contact://untested |
654 |
case Tet4Face://untested |
655 |
cerr << "WARNING: Finley type " <<typeId<< " is untested!" << endl; |
656 |
case Tri3_Contact: |
657 |
case Tri3: |
658 |
ret.elementSize = ret.reducedElementSize = 3; |
659 |
ret.elementType = ret.reducedElementType = ZONETYPE_TRIANGLE; |
660 |
break; |
661 |
|
662 |
case Rec4_Contact: |
663 |
case Hex8Face_Contact: |
664 |
case Hex8Face: |
665 |
case Rec4: |
666 |
ret.elementSize = ret.reducedElementSize = 4; |
667 |
ret.elementType = ret.reducedElementType = ZONETYPE_QUAD; |
668 |
break; |
669 |
|
670 |
case Rec9: |
671 |
ret.multiCellIndices = rec9indices; |
672 |
ret.elementFactor = 4; |
673 |
// fall through |
674 |
case Rec9_Contact: |
675 |
ret.elementSize = ret.reducedElementSize = 4; |
676 |
ret.elementType = ret.reducedElementType = ZONETYPE_QUAD; |
677 |
break; |
678 |
|
679 |
case Tet4: |
680 |
ret.elementSize = ret.reducedElementSize = 4; |
681 |
ret.elementType = ret.reducedElementType = ZONETYPE_TET; |
682 |
break; |
683 |
|
684 |
case Tri6: |
685 |
ret.multiCellIndices = tri6indices; |
686 |
ret.elementFactor = 4; |
687 |
// fall through |
688 |
case Tri6_Contact: |
689 |
case Tet10Face_Contact://untested |
690 |
case Tet10Face://untested |
691 |
//VTK_QUADRATIC_TRIANGLE |
692 |
ret.elementSize = ret.reducedElementSize = 3; |
693 |
ret.elementType = ret.reducedElementType = ZONETYPE_TRIANGLE; |
694 |
break; |
695 |
|
696 |
case Rec8: |
697 |
ret.multiCellIndices = rec8indices; |
698 |
ret.elementFactor = 6; |
699 |
// fall through |
700 |
case Hex20Face: |
701 |
case Rec8_Contact: |
702 |
case Hex20Face_Contact: |
703 |
//VTK_QUADRATIC_QUAD |
704 |
ret.elementSize = 3; |
705 |
ret.elementType = ZONETYPE_TRIANGLE; |
706 |
ret.reducedElementSize = 4; |
707 |
ret.reducedElementType = ZONETYPE_QUAD; |
708 |
break; |
709 |
|
710 |
case Tet10: |
711 |
//VTK_QUADRATIC_TETRA |
712 |
ret.multiCellIndices = tet10indices; |
713 |
ret.elementFactor = 8; |
714 |
ret.elementSize = ret.reducedElementSize = 4; |
715 |
ret.elementType = ret.reducedElementType = ZONETYPE_TET; |
716 |
break; |
717 |
|
718 |
case Hex20: |
719 |
//VTK_QUADRATIC_HEXAHEDRON |
720 |
ret.multiCellIndices = hex20indices; |
721 |
ret.elementFactor = 36; |
722 |
ret.elementSize = 3; |
723 |
ret.elementType = ZONETYPE_TRIANGLE; |
724 |
ret.reducedElementSize = 8; |
725 |
ret.reducedElementType = ZONETYPE_HEX; |
726 |
break; |
727 |
|
728 |
case Hex27: |
729 |
ret.multiCellIndices = hex27indices; |
730 |
ret.elementFactor = 8; |
731 |
// fall through |
732 |
case Hex8: |
733 |
ret.elementSize = ret.reducedElementSize = 8; |
734 |
ret.elementType = ret.reducedElementType = ZONETYPE_HEX; |
735 |
break; |
736 |
|
737 |
default: |
738 |
cerr << "WARNING: Unknown Finley Type " << typeId << endl; |
739 |
break; |
740 |
} |
741 |
return ret; |
742 |
} |
743 |
|
744 |
} // namespace escriptexport |
745 |
|