00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include <OpenFOAM/argList.H>
00058 #include <OpenFOAM/polyMesh.H>
00059 #include <OpenFOAM/Time.H>
00060 #include <OpenFOAM/IFstream.H>
00061 #include <OpenFOAM/cellModeller.H>
00062 #include <meshTools/cellSet.H>
00063 #include <meshTools/faceSet.H>
00064 #include <OpenFOAM/DynamicList.H>
00065 #include <triSurface/triSurface.H>
00066 #include <OpenFOAM/SortableList.H>
00067
00068 #include <cassert>
00069
00070 using namespace Foam;
00071
00072
00073
00074 namespace Foam
00075 {
00076 template<>
00077 inline unsigned Hash<face>::operator()(const face& t, unsigned seed) const
00078 {
00079 return Hasher(t.cdata(),t.size()*sizeof(label), seed);
00080 }
00081
00082 template<>
00083 inline unsigned Hash<face>::operator()(const face& t) const
00084 {
00085 return Hash<face>::operator()(t, 0);
00086 }
00087 }
00088 const string SEPARATOR(" -1");
00089
00090 bool isSeparator(const string& line)
00091 {
00092 return line.substr(0, 6) == SEPARATOR;
00093 }
00094
00095
00096
00097 label readTag(IFstream& is)
00098 {
00099 string tag;
00100 do
00101 {
00102 if (!is.good())
00103 {
00104 return -1;
00105 }
00106
00107 string line;
00108
00109 is.getLine(line);
00110
00111 if (line.size() < 6)
00112 {
00113 return -1;
00114 }
00115
00116 tag = line.substr(0, 6);
00117
00118 } while (tag == SEPARATOR);
00119
00120 return readLabel(IStringStream(tag)());
00121 }
00122
00123
00124
00125 void readHeader(IFstream& is)
00126 {
00127 string line;
00128
00129 while (is.good())
00130 {
00131 is.getLine(line);
00132
00133 if (isSeparator(line))
00134 {
00135 break;
00136 }
00137 else
00138 {
00139 Sout<< line << endl;
00140 }
00141 }
00142 }
00143
00144
00145
00146 void skipSection(IFstream& is)
00147 {
00148 Sout<< "Skipping section at line " << is.lineNumber() << '.' << endl;
00149
00150 string line;
00151
00152 while (is.good())
00153 {
00154 is.getLine(line);
00155
00156 if (isSeparator(line))
00157 {
00158 break;
00159 }
00160 }
00161 }
00162
00163
00164 scalar readUnvScalar(const string& unvString)
00165 {
00166 string s(unvString);
00167
00168 s.replaceAll("d", "E");
00169 s.replaceAll("D", "E");
00170
00171 return readScalar(IStringStream(s)());
00172 }
00173
00174
00175
00176 void readUnits
00177 (
00178 IFstream& is,
00179 scalar& lengthScale,
00180 scalar& forceScale,
00181 scalar& tempScale,
00182 scalar& tempOffset
00183 )
00184 {
00185 Sout<< "Starting reading units at line " << is.lineNumber() << '.' << endl;
00186
00187 string line;
00188 is.getLine(line);
00189
00190 label l = readLabel(IStringStream(line.substr(0, 10))());
00191 Sout<< "l:" << l << endl;
00192
00193 string units(line.substr(10, 20));
00194 Sout<< "units:" << units << endl;
00195
00196 label unitType = readLabel(IStringStream(line.substr(30, 10))());
00197 Sout<< "unitType:" << unitType << endl;
00198
00199
00200 is.getLine(line);
00201
00202 lengthScale = readUnvScalar(line.substr(0, 25));
00203 forceScale = readUnvScalar(line.substr(25, 25));
00204 tempScale = readUnvScalar(line.substr(50, 25));
00205
00206 is.getLine(line);
00207 tempOffset = readUnvScalar(line.substr(0, 25));
00208
00209 Sout<< "Unit factors:" << nl
00210 << " Length scale : " << lengthScale << nl
00211 << " Force scale : " << forceScale << nl
00212 << " Temperature scale : " << tempScale << nl
00213 << " Temperature offset : " << tempOffset << nl
00214 << endl;
00215 }
00216
00217
00218
00219 void readPoints
00220 (
00221 IFstream& is,
00222 DynamicList<point>& points,
00223 DynamicList<label>& unvPointID
00224 )
00225 {
00226 Sout<< "Starting reading points at line " << is.lineNumber() << '.' << endl;
00227
00228 static bool hasWarned = false;
00229
00230 while (true)
00231 {
00232 string line;
00233 is.getLine(line);
00234
00235 label pointI = readLabel(IStringStream(line.substr(0, 10))());
00236
00237 if (pointI == -1)
00238 {
00239 break;
00240 }
00241 else if (pointI != points.size()+1 && !hasWarned)
00242 {
00243 hasWarned = true;
00244
00245 IOWarningIn
00246 (
00247 "readPoints(IFstream&, label&, DynamicList<point>"
00248 ", DynamicList<label>&)",
00249 is
00250 ) << "Points not in order starting at point " << pointI
00251
00252
00253 << endl;
00254 }
00255
00256 point pt;
00257 is.getLine(line);
00258 pt[0] = readUnvScalar(line.substr(0, 25));
00259 pt[1] = readUnvScalar(line.substr(25, 25));
00260 pt[2] = readUnvScalar(line.substr(50, 25));
00261
00262 unvPointID.append(pointI);
00263 points.append(pt);
00264 }
00265
00266 points.shrink();
00267 unvPointID.shrink();
00268
00269 Sout<< "Read " << points.size() << " points." << endl;
00270 }
00271
00272 void addAndExtend
00273 (
00274 DynamicList<label>& indizes,
00275 label cellI,
00276 label val
00277 )
00278 {
00279 if (indizes.size() < (cellI+1))
00280 {
00281 indizes.setSize(cellI+1,-1);
00282 }
00283 indizes[cellI] = val;
00284 }
00285
00286
00287
00288
00289 void readCells
00290 (
00291 IFstream& is,
00292 DynamicList<cellShape>& cellVerts,
00293 DynamicList<label>& cellMaterial,
00294 DynamicList<label>& boundaryFaceIndices,
00295 DynamicList<face>& boundaryFaces,
00296 DynamicList<label>& cellCorrespondence,
00297 DynamicList<label>& unvPointID
00298 )
00299 {
00300 Sout<< "Starting reading cells at line " << is.lineNumber() << '.' << endl;
00301
00302
00303 label maxUnvPoint = 0;
00304 forAll(unvPointID, pointI)
00305 {
00306 maxUnvPoint = max(maxUnvPoint, unvPointID[pointI]);
00307 }
00308 labelList unvToFoam(invert(maxUnvPoint+1, unvPointID));
00309
00310
00311 const cellModel& hex = *(cellModeller::lookup("hex"));
00312 const cellModel& prism = *(cellModeller::lookup("prism"));
00313 const cellModel& tet = *(cellModeller::lookup("tet"));
00314
00315 labelHashSet skippedElements;
00316
00317 labelHashSet foundFeType;
00318
00319 while (true)
00320 {
00321 string line;
00322 is.getLine(line);
00323
00324 if (isSeparator(line))
00325 {
00326 break;
00327 }
00328
00329 IStringStream lineStr(line);
00330 label cellI, feID, physProp, matProp, colour, nNodes;
00331 lineStr >> cellI >> feID >> physProp >> matProp >> colour >> nNodes;
00332
00333 if (foundFeType.insert(feID))
00334 {
00335 Info<< "First occurrence of element type " << feID
00336 << " for cell " << cellI << " at line "
00337 << is.lineNumber() << endl;
00338 }
00339
00340 if (feID == 11)
00341 {
00342
00343 is.getLine(line);
00344 is.getLine(line);
00345 }
00346 else if (feID == 171)
00347 {
00348
00349 is.getLine(line);
00350 }
00351 else if (feID == 41 || feID == 91)
00352 {
00353
00354 is.getLine(line);
00355
00356 face cVerts(3);
00357 IStringStream lineStr(line);
00358 lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2];
00359 boundaryFaces.append(cVerts);
00360 boundaryFaceIndices.append(cellI);
00361 }
00362 else if (feID == 44 || feID == 94)
00363 {
00364
00365 is.getLine(line);
00366
00367 face cVerts(4);
00368 IStringStream lineStr(line);
00369 lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
00370 boundaryFaces.append(cVerts);
00371 boundaryFaceIndices.append(cellI);
00372 }
00373 else if (feID == 111)
00374 {
00375
00376 is.getLine(line);
00377
00378 labelList cVerts(4);
00379 IStringStream lineStr(line);
00380 lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3];
00381
00382 cellVerts.append(cellShape(tet, cVerts, true));
00383 cellMaterial.append(physProp);
00384 addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00385
00386 if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00387 {
00388 Pout<< "Line:" << is.lineNumber()
00389 << " element:" << cellI
00390 << " type:" << feID
00391 << " collapsed from " << cVerts << nl
00392 << " to:" << cellVerts[cellVerts.size()-1]
00393 << endl;
00394 }
00395 }
00396 else if (feID == 112)
00397 {
00398
00399 is.getLine(line);
00400
00401 labelList cVerts(6);
00402 IStringStream lineStr(line);
00403 lineStr >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3]
00404 >> cVerts[4] >> cVerts[5];
00405
00406 cellVerts.append(cellShape(prism, cVerts, true));
00407 cellMaterial.append(physProp);
00408 addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00409
00410 if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00411 {
00412 Pout<< "Line:" << is.lineNumber()
00413 << " element:" << cellI
00414 << " type:" << feID
00415 << " collapsed from " << cVerts << nl
00416 << " to:" << cellVerts[cellVerts.size()-1]
00417 << endl;
00418 }
00419 }
00420 else if (feID == 115)
00421 {
00422
00423 is.getLine(line);
00424
00425 labelList cVerts(8);
00426 IStringStream lineStr(line);
00427 lineStr
00428 >> cVerts[0] >> cVerts[1] >> cVerts[2] >> cVerts[3]
00429 >> cVerts[4] >> cVerts[5] >> cVerts[6] >> cVerts[7];
00430
00431 cellVerts.append(cellShape(hex, cVerts, true));
00432 cellMaterial.append(physProp);
00433 addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00434
00435 if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00436 {
00437 Pout<< "Line:" << is.lineNumber()
00438 << " element:" << cellI
00439 << " type:" << feID
00440 << " collapsed from " << cVerts << nl
00441 << " to:" << cellVerts[cellVerts.size()-1]
00442 << endl;
00443 }
00444 }
00445 else if (feID == 118)
00446 {
00447
00448
00449 is.getLine(line);
00450
00451 labelList cVerts(4);
00452 label dummy;
00453 {
00454 IStringStream lineStr(line);
00455 lineStr
00456 >> cVerts[0] >> dummy >> cVerts[1] >> dummy
00457 >> cVerts[2];
00458 }
00459 is.getLine(line);
00460 {
00461 IStringStream lineStr(line);
00462 lineStr >> dummy>> cVerts[3];
00463 }
00464
00465 cellVerts.append(cellShape(tet, cVerts, true));
00466 cellMaterial.append(physProp);
00467 addAndExtend(cellCorrespondence,cellI,cellMaterial.size()-1);
00468
00469 if (cellVerts[cellVerts.size()-1].size() != cVerts.size())
00470 {
00471 Pout<< "Line:" << is.lineNumber()
00472 << " element:" << cellI
00473 << " type:" << feID
00474 << " collapsed from " << cVerts << nl
00475 << " to:" << cellVerts[cellVerts.size()-1]
00476 << endl;
00477 }
00478 }
00479 else
00480 {
00481 if (skippedElements.insert(feID))
00482 {
00483 IOWarningIn("readCells(IFstream&, label&)", is)
00484 << "Cell type " << feID << " not supported" << endl;
00485 }
00486 is.getLine(line);
00487 }
00488 }
00489
00490 cellVerts.shrink();
00491 cellMaterial.shrink();
00492 boundaryFaces.shrink();
00493 boundaryFaceIndices.shrink();
00494 cellCorrespondence.shrink();
00495
00496 Sout<< "Read " << cellVerts.size() << " cells"
00497 << " and " << boundaryFaces.size() << " boundary faces." << endl;
00498 }
00499
00500
00501 void readSets
00502 (
00503 IFstream& is,
00504 DynamicList<word>& patchNames,
00505 DynamicList<labelList>& patchFaceIndices
00506 )
00507 {
00508 Sout<< "Starting reading patches at line " << is.lineNumber() << '.'
00509 << endl;
00510
00511 while(true)
00512 {
00513 string line;
00514 is.getLine(line);
00515
00516 if (isSeparator(line))
00517 {
00518 break;
00519 }
00520
00521 IStringStream lineStr(line);
00522 label group, constraintSet, restraintSet, loadSet, dofSet,
00523 tempSet, contactSet, nFaces;
00524 lineStr
00525 >> group >> constraintSet >> restraintSet >> loadSet
00526 >> dofSet >> tempSet >> contactSet >> nFaces;
00527
00528 is.getLine(line);
00529 word groupName = string::validate<word>(line);
00530
00531 Info<< "For group " << group
00532 << " named " << groupName
00533 << " trying to read " << nFaces << " patch face indices."
00534 << endl;
00535
00536 labelList groupIndices(nFaces);
00537 label groupType = -1;
00538 nFaces = 0;
00539
00540 while (nFaces < groupIndices.size())
00541 {
00542 is.getLine(line);
00543 IStringStream lineStr(line);
00544
00545
00546 label nRead = 2;
00547 if (nFaces == groupIndices.size()-1)
00548 {
00549 nRead = 1;
00550 }
00551
00552 for (label i = 0; i < nRead; i++)
00553 {
00554 label tag, nodeLeaf, component;
00555
00556 lineStr >> groupType >> tag >> nodeLeaf >> component;
00557
00558 groupIndices[nFaces++] = tag;
00559 }
00560 }
00561
00562
00563
00564 if (groupType == 8)
00565 {
00566 patchNames.append(groupName);
00567 patchFaceIndices.append(groupIndices);
00568 }
00569 else
00570 {
00571 IOWarningIn("readSets(..)", is)
00572 << "When reading patches expect entity type code 8"
00573 << nl << " Skipping group code " << groupType
00574 << endl;
00575 }
00576 }
00577
00578 patchNames.shrink();
00579 patchFaceIndices.shrink();
00580 }
00581
00582
00583
00584
00585 void readDOFS
00586 (
00587 IFstream& is,
00588 DynamicList<word>& patchNames,
00589 DynamicList<labelList>& dofVertices
00590 )
00591 {
00592 Sout<< "Starting reading constraints at line " << is.lineNumber() << '.'
00593 << endl;
00594
00595 string line;
00596 is.getLine(line);
00597 label group;
00598 {
00599 IStringStream lineStr(line);
00600 lineStr >> group;
00601 }
00602
00603 is.getLine(line);
00604 {
00605 IStringStream lineStr(line);
00606 patchNames.append(lineStr);
00607 }
00608
00609 Info<< "For DOF set " << group
00610 << " named " << patchNames[patchNames.size()-1]
00611 << " trying to read vertex indices."
00612 << endl;
00613
00614 DynamicList<label> vertices;
00615 while (true)
00616 {
00617 string line;
00618 is.getLine(line);
00619
00620 if (isSeparator(line))
00621 {
00622 break;
00623 }
00624
00625 IStringStream lineStr(line);
00626 label pointI;
00627 lineStr >> pointI;
00628
00629 vertices.append(pointI);
00630 }
00631
00632 Info<< "For DOF set " << group
00633 << " named " << patchNames[patchNames.size()-1]
00634 << " read " << vertices.size() << " vertex indices." << endl;
00635
00636 dofVertices.append(vertices.shrink());
00637
00638 patchNames.shrink();
00639 dofVertices.shrink();
00640 }
00641
00642
00643
00644 label findPatch(const List<labelHashSet>& dofGroups, const face& f)
00645 {
00646 forAll(dofGroups, patchI)
00647 {
00648 if (dofGroups[patchI].found(f[0]))
00649 {
00650 bool allInGroup = true;
00651
00652
00653 for (label fp = 1; fp < f.size(); fp++)
00654 {
00655 if (!dofGroups[patchI].found(f[fp]))
00656 {
00657 allInGroup = false;
00658 break;
00659 }
00660 }
00661
00662 if (allInGroup)
00663 {
00664 return patchI;
00665 }
00666 }
00667 }
00668 return -1;
00669 }
00670
00671
00672 const bool verbose=false;
00673
00674
00675
00676 int main(int argc, char *argv[])
00677 {
00678 argList::noParallel();
00679 argList::validArgs.append(".unv file");
00680 argList::validOptions.insert("dump", "");
00681
00682 # include <OpenFOAM/setRootCase.H>
00683 # include <OpenFOAM/createTime.H>
00684
00685 fileName ideasName(args.additionalArgs()[0]);
00686
00687 IFstream inFile(ideasName.c_str());
00688
00689 if (!inFile.good())
00690 {
00691 FatalErrorIn(args.executable())
00692 << "Cannot open file " << ideasName
00693 << exit(FatalError);
00694 }
00695
00696
00697
00698 scalar lengthScale = 1;
00699 scalar forceScale = 1;
00700 scalar tempScale = 1;
00701 scalar tempOffset = 0;
00702
00703
00704 DynamicList<point> points;
00705
00706 DynamicList<label> unvPointID;
00707
00708
00709 DynamicList<cellShape> cellVerts;
00710 DynamicList<label> cellMat;
00711 DynamicList<label> cellCorrespondence;
00712
00713
00714 DynamicList<label> boundaryFaceIndices;
00715 DynamicList<face> boundaryFaces;
00716
00717
00718 DynamicList<word> patchNames;
00719 DynamicList<labelList> patchFaceIndices;
00720 DynamicList<labelList> dofVertIndices;
00721
00722
00723 while (inFile.good())
00724 {
00725 label tag = readTag(inFile);
00726
00727 if (tag == -1)
00728 {
00729 break;
00730 }
00731
00732 Sout<< "Processing tag:" << tag << endl;
00733
00734 switch (tag)
00735 {
00736 case 151:
00737 readHeader(inFile);
00738 break;
00739
00740 case 164:
00741 readUnits
00742 (
00743 inFile,
00744 lengthScale,
00745 forceScale,
00746 tempScale,
00747 tempOffset
00748 );
00749 break;
00750
00751 case 2411:
00752 readPoints(inFile, points, unvPointID);
00753 break;
00754
00755 case 2412:
00756 readCells
00757 (
00758 inFile,
00759 cellVerts,
00760 cellMat,
00761 boundaryFaceIndices,
00762 boundaryFaces,
00763 cellCorrespondence,
00764 unvPointID
00765 );
00766 break;
00767
00768 case 2452:
00769 case 2467:
00770 readSets
00771 (
00772 inFile,
00773 patchNames,
00774 patchFaceIndices
00775 );
00776 break;
00777
00778 case 757:
00779 readDOFS
00780 (
00781 inFile,
00782 patchNames,
00783 dofVertIndices
00784 );
00785 break;
00786
00787 default:
00788 Sout<< "Skipping tag " << tag << " on line "
00789 << inFile.lineNumber() << endl;
00790 skipSection(inFile);
00791 break;
00792 }
00793 Sout<< endl;
00794 }
00795
00796
00797
00798 label maxUnvPoint = 0;
00799 forAll(unvPointID, pointI)
00800 {
00801 maxUnvPoint = max(maxUnvPoint, unvPointID[pointI]);
00802 }
00803 labelList unvToFoam(invert(maxUnvPoint+1, unvPointID));
00804
00805
00806
00807
00808 forAll(cellVerts, cellI)
00809 {
00810 labelList foamVerts
00811 (
00812 renumber
00813 (
00814 unvToFoam,
00815 static_cast<labelList&>(cellVerts[cellI])
00816 )
00817 );
00818
00819 if (findIndex(foamVerts, -1) != -1)
00820 {
00821 FatalErrorIn(args.executable())
00822 << "Cell " << cellI
00823 << " unv vertices " << cellVerts[cellI]
00824 << " has some undefined vertices " << foamVerts
00825 << abort(FatalError);
00826 }
00827
00828
00829 cellVerts[cellI].transfer(foamVerts);
00830 }
00831
00832
00833
00834 forAll(boundaryFaces, bFaceI)
00835 {
00836 labelList foamVerts(renumber(unvToFoam, boundaryFaces[bFaceI]));
00837
00838 if (findIndex(foamVerts, -1) != -1)
00839 {
00840 FatalErrorIn(args.executable())
00841 << "Boundary face " << bFaceI
00842 << " unv vertices " << boundaryFaces[bFaceI]
00843 << " has some undefined vertices " << foamVerts
00844 << abort(FatalError);
00845 }
00846
00847
00848 boundaryFaces[bFaceI].transfer(foamVerts);
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 List<faceList> patchFaceVerts;
00861
00862 labelList nrFaceCells(boundaryFaces.size(),0);
00863 HashTable<label,label> faceToCell[2];
00864
00865 {
00866 HashTable<label, face, Hash<face> > faceToFaceID(boundaryFaces.size());
00867 forAll(boundaryFaces,faceI)
00868 {
00869 SortableList<label> foo(boundaryFaces[faceI]);
00870 face theFace(foo);
00871 faceToFaceID.insert(theFace,faceI);
00872 }
00873
00874 forAll(cellVerts,cellI)
00875 {
00876 faceList faces = cellVerts[cellI].faces();
00877 forAll(faces,i)
00878 {
00879 SortableList<label> foo(faces[i]);
00880 face theFace(foo);
00881 if (faceToFaceID.found(theFace))
00882 {
00883 label faceI = faceToFaceID[theFace];
00884 if (nrFaceCells[faceI] < 2)
00885 {
00886 faceToCell[nrFaceCells[faceI]].insert(faceI,cellI);
00887 }
00888 nrFaceCells[faceI]++;
00889 }
00890 }
00891 }
00892
00893 label cnt = 0;
00894 forAll(nrFaceCells, faceI)
00895 {
00896 assert(nrFaceCells[faceI] == 1 || nrFaceCells[faceI] == 2);
00897 if (nrFaceCells[faceI]>1)
00898 {
00899 cnt++;
00900 }
00901 }
00902
00903 if (cnt>0)
00904 {
00905 Info << "Of " << boundaryFaces.size() << " so-called"
00906 << " boundary faces " << cnt << " belong to two cells "
00907 << "and are therefore internal" << endl;
00908 }
00909 }
00910
00911 HashTable<labelList,word> cellZones;
00912 HashTable<labelList,word> faceZones;
00913 List<bool> isAPatch(patchNames.size(),true);
00914
00915 if (dofVertIndices.size())
00916 {
00917
00918
00919
00920
00921
00922
00923 Info<< "Using " << dofVertIndices.size()
00924 << " DOF sets to detect boundary faces."<< endl;
00925
00926
00927 forAll(dofVertIndices, patchI)
00928 {
00929 inplaceRenumber(unvToFoam, dofVertIndices[patchI]);
00930 }
00931
00932
00933
00934 List<labelHashSet> dofGroups(dofVertIndices.size());
00935
00936 forAll(dofVertIndices, patchI)
00937 {
00938 const labelList& foamVerts = dofVertIndices[patchI];
00939
00940 forAll(foamVerts, i)
00941 {
00942 dofGroups[patchI].insert(foamVerts[i]);
00943 }
00944 }
00945
00946 List<DynamicList<face> > dynPatchFaces(dofVertIndices.size());
00947
00948 forAll(cellVerts, cellI)
00949 {
00950 const cellShape& shape = cellVerts[cellI];
00951
00952 const faceList shapeFaces(shape.faces());
00953
00954 forAll(shapeFaces, i)
00955 {
00956 label patchI = findPatch(dofGroups, shapeFaces[i]);
00957
00958 if (patchI != -1)
00959 {
00960 dynPatchFaces[patchI].append(shapeFaces[i]);
00961 }
00962 }
00963 }
00964
00965
00966 patchFaceVerts.setSize(dynPatchFaces.size());
00967
00968 forAll(dynPatchFaces, patchI)
00969 {
00970 patchFaceVerts[patchI].transfer(dynPatchFaces[patchI]);
00971 }
00972 }
00973 else
00974 {
00975
00976
00977
00978
00979 patchFaceVerts.setSize(patchFaceIndices.size());
00980
00981 Info<< "Sorting boundary faces according to group (patch)" << endl;
00982
00983
00984
00985 labelHashSet alreadyOnBoundary;
00986
00987
00988 Map<label> boundaryFaceToIndex(boundaryFaceIndices.size());
00989
00990 forAll(boundaryFaceIndices, i)
00991 {
00992 boundaryFaceToIndex.insert(boundaryFaceIndices[i], i);
00993 }
00994
00995 forAll(patchFaceVerts, patchI)
00996 {
00997 Info << patchI << ": " << patchNames[patchI] << " is " << flush;
00998
00999 faceList& patchFaces = patchFaceVerts[patchI];
01000 const labelList& faceIndices = patchFaceIndices[patchI];
01001
01002 patchFaces.setSize(faceIndices.size());
01003
01004 bool duplicateFaces = false;
01005
01006 label cnt = 0;
01007 forAll(patchFaces, i)
01008 {
01009 if (boundaryFaceToIndex.found(faceIndices[i]))
01010 {
01011 label bFaceI = boundaryFaceToIndex[faceIndices[i]];
01012 if (nrFaceCells[bFaceI] == 1)
01013 {
01014 patchFaces[cnt] = boundaryFaces[bFaceI];
01015 cnt++;
01016 if (alreadyOnBoundary.found(bFaceI))
01017 {
01018 duplicateFaces = true;
01019 }
01020 }
01021 }
01022 }
01023
01024 if (cnt!=patchFaces.size() || duplicateFaces)
01025 {
01026 isAPatch[patchI] = false;
01027
01028 if (verbose)
01029 {
01030 if (cnt != patchFaces.size())
01031 {
01032 WarningIn(args.executable())
01033 << "For patch " << patchI << " there were "
01034 << patchFaces.size()-cnt
01035 << " faces not used because they seem"
01036 << " to be internal. "
01037 << "This seems to be a face or a cell-zone"
01038 << endl;
01039 }
01040 else
01041 {
01042 WarningIn(args.executable())
01043 << "Patch "
01044 << patchI << " has faces that are already "
01045 << " in use on other boundary-patches,"
01046 << " Assuming faceZoneset." << endl;
01047 }
01048 }
01049
01050 patchFaces.setSize(0);
01051
01052 if (cellCorrespondence[faceIndices[0]] >= 0)
01053 {
01054 Info << "cellZone" << endl;
01055 labelList theCells(faceIndices.size());
01056 forAll(faceIndices, i)
01057 {
01058 if (cellCorrespondence[faceIndices[0]] < 0)
01059 {
01060 FatalErrorIn(args.executable())
01061 << "The face index " << faceIndices[i]
01062 << " was not found amongst the cells."
01063 << " This kills the theory that "
01064 << patchNames[patchI] << " is a cell zone"
01065 << endl
01066 << abort(FatalError);
01067 }
01068 theCells[i] = cellCorrespondence[faceIndices[i]];
01069 }
01070 cellZones.insert(patchNames[patchI], theCells);
01071 }
01072 else
01073 {
01074 Info << "faceZone" << endl;
01075 labelList theFaces(faceIndices.size());
01076 forAll(faceIndices, i)
01077 {
01078 theFaces[i] = boundaryFaceToIndex[faceIndices[i]];
01079 }
01080 faceZones.insert(patchNames[patchI],theFaces);
01081 }
01082 }
01083 else
01084 {
01085 Info << "patch" << endl;
01086
01087 forAll(patchFaces, i)
01088 {
01089 label bFaceI = boundaryFaceToIndex[faceIndices[i]];
01090 alreadyOnBoundary.insert(bFaceI);
01091 }
01092 }
01093 }
01094 }
01095
01096 pointField polyPoints;
01097 polyPoints.transfer(points);
01098
01099
01100 polyPoints /= lengthScale;
01101
01102
01103
01104 if (args.optionFound("dump"))
01105 {
01106 DynamicList<labelledTri> triangles(boundaryFaces.size());
01107
01108 forAll(boundaryFaces, i)
01109 {
01110 const face& f = boundaryFaces[i];
01111
01112 faceList triFaces(f.nTriangles(polyPoints));
01113 label nTri = 0;
01114 f.triangles(polyPoints, nTri, triFaces);
01115
01116 forAll(triFaces, triFaceI)
01117 {
01118 const face& f = triFaces[triFaceI];
01119 triangles.append(labelledTri(f[0], f[1], f[2], 0));
01120 }
01121 }
01122
01123
01124 triSurface rawSurface(triangles.shrink(), polyPoints);
01125
01126
01127 triSurface surface
01128 (
01129 rawSurface.localFaces(),
01130 rawSurface.localPoints()
01131 );
01132
01133 Info<< "Writing boundary faces to STL file boundaryFaces.stl"
01134 << nl << endl;
01135
01136 surface.write(runTime.path()/"boundaryFaces.stl");
01137 }
01138
01139
01140 Info<< "\nConstructing mesh with non-default patches of size:" << nl;
01141 DynamicList<word> usedPatchNames;
01142 DynamicList<faceList> usedPatchFaceVerts;
01143
01144 forAll(patchNames, patchI)
01145 {
01146 if (isAPatch[patchI]) {
01147 Info<< " " << patchNames[patchI] << '\t'
01148 << patchFaceVerts[patchI].size() << nl;
01149 usedPatchNames.append(patchNames[patchI]);
01150 usedPatchFaceVerts.append(patchFaceVerts[patchI]);
01151 }
01152 }
01153 usedPatchNames.shrink();
01154 usedPatchFaceVerts.shrink();
01155
01156 Info<< endl;
01157
01158
01159
01160
01161 polyMesh mesh
01162 (
01163 IOobject
01164 (
01165 polyMesh::defaultRegion,
01166 runTime.constant(),
01167 runTime
01168 ),
01169 xferMove(polyPoints),
01170 cellVerts,
01171 usedPatchFaceVerts,
01172 usedPatchNames,
01173 wordList(patchNames.size(), polyPatch::typeName),
01174 "defaultFaces",
01175 polyPatch::typeName,
01176 wordList(0)
01177 );
01178
01179
01180 if (faceZones.size()>0 || cellZones.size()>0)
01181 {
01182 Info << "Adding cell and face zones" << endl;
01183
01184 List<pointZone*> pZones(0);
01185 List<faceZone*> fZones(faceZones.size());
01186 List<cellZone*> cZones(cellZones.size());
01187
01188 if (cellZones.size()>0)
01189 {
01190 forAll(cellZones.toc(),cnt)
01191 {
01192 word name = cellZones.toc()[cnt];
01193 Info<< " Cell Zone " << name << " " << tab
01194 << cellZones[name].size() << endl;
01195
01196 cZones[cnt] = new cellZone
01197 (
01198 name,
01199 cellZones[name],
01200 cnt,
01201 mesh.cellZones()
01202 );
01203 }
01204 }
01205 if (faceZones.size() > 0)
01206 {
01207 const labelList& own = mesh.faceOwner();
01208 const labelList& nei = mesh.faceNeighbour();
01209 const pointField& centers = mesh.faceCentres();
01210 const pointField& points = mesh.points();
01211
01212 forAll(faceZones.toc(), cnt)
01213 {
01214 word name = faceZones.toc()[cnt];
01215 const labelList& oldIndizes = faceZones[name];
01216 labelList indizes(oldIndizes.size());
01217
01218 Info<< " Face Zone " << name << " " << tab
01219 << oldIndizes.size() << endl;
01220
01221 forAll(indizes, i)
01222 {
01223 const label old = oldIndizes[i];
01224 label noveau = -1;
01225 label c1 = -1, c2 = -1;
01226 if (faceToCell[0].found(old))
01227 {
01228 c1 = faceToCell[0][old];
01229 }
01230 if (faceToCell[1].found(old))
01231 {
01232 c2 = faceToCell[1][old];
01233 }
01234 if (c1<c2)
01235 {
01236 label tmp = c1;
01237 c1 = c2;
01238 c2 = tmp;
01239 }
01240 if (c2 == -1)
01241 {
01242
01243 forAll(own, j)
01244 {
01245 if (own[j] == c1)
01246 {
01247 const face& f = boundaryFaces[old];
01248 if (mag(centers[j]-f.centre(points))<SMALL)
01249 {
01250 noveau = j;
01251 break;
01252 }
01253 }
01254 }
01255 }
01256 else
01257 {
01258 forAll(nei, j)
01259 {
01260 if
01261 (
01262 (c1 == own[j] && c2 == nei[j])
01263 || (c2 == own[j] && c1 == nei[j])
01264 )
01265 {
01266 noveau = j;
01267 break;
01268 }
01269 }
01270 }
01271 assert(noveau>-1);
01272 indizes[i] = noveau;
01273 }
01274 fZones[cnt] = new faceZone
01275 (
01276 faceZones.toc()[cnt],
01277 indizes,
01278 boolList(indizes.size(),false),
01279 cnt,
01280 mesh.faceZones()
01281 );
01282 }
01283 }
01284 mesh.addZones(pZones, fZones, cZones);
01285
01286 Info << endl;
01287 }
01288
01289 mesh.write();
01290
01291 Info<< "End\n" << endl;
01292
01293 return 0;
01294 }
01295
01296
01297