/[escript]/trunk/dataexporter/src/ElementData.cpp
ViewVC logotype

Contents of /trunk/dataexporter/src/ElementData.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2810 - (show annotations)
Mon Dec 7 04:13:49 2009 UTC (10 years, 11 months ago) by caltinay
File size: 22377 byte(s)
Reincarnation of the escriptreader as a more flexible escriptexport library:
 - can be initialised with instances of escript::Data and Finley_Mesh
 - is now MPI aware at the EscriptDataset level including Silo writer
 - now uses boost shared pointers
The lib is currently only used by the escriptconvert tool but this is going to
change...

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

  ViewVC Help
Powered by ViewVC 1.1.26