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 #include <OpenFOAM/argList.H>
00055 #include <OpenFOAM/Time.H>
00056 #include <OpenFOAM/IFstream.H>
00057 #include "hexBlock.H"
00058 #include <OpenFOAM/polyMesh.H>
00059 #include <OpenFOAM/wallPolyPatch.H>
00060 #include <OpenFOAM/symmetryPolyPatch.H>
00061 #include <OpenFOAM/preservePatchTypes.H>
00062 #include <OpenFOAM/cellShape.H>
00063 #include <OpenFOAM/cellModeller.H>
00064
00065 using namespace Foam;
00066
00067
00068
00069
00070 int main(int argc, char *argv[])
00071 {
00072 argList::noParallel();
00073 argList::validArgs.append("CFX geom file");
00074 argList::validOptions.insert("scale", "scale factor");
00075
00076 argList args(argc, argv);
00077
00078 if (!args.check())
00079 {
00080 FatalError.exit();
00081 }
00082
00083 scalar scaleFactor = 1.0;
00084 args.optionReadIfPresent("scale", scaleFactor);
00085
00086 # include <OpenFOAM/createTime.H>
00087
00088 IFstream cfxFile(args.additionalArgs()[0]);
00089
00090
00091
00092
00093 label nblock, npatch, nglue, nelem, npoint;
00094
00095 cfxFile >> nblock >> npatch >> nglue >> nelem >> npoint;
00096
00097 Info << "Reading blocks" << endl;
00098
00099 PtrList<hexBlock> blocks(nblock);
00100
00101 {
00102 word blockName;
00103 label nx, ny, nz;
00104
00105 forAll (blocks, blockI)
00106 {
00107 cfxFile >> blockName;
00108 cfxFile >> nx >> ny >> nz;
00109
00110 blocks.set(blockI, new hexBlock(nx, ny, nz));
00111 }
00112 }
00113
00114 Info << "Reading patch definitions" << endl;
00115
00116 wordList cfxPatchTypes(npatch);
00117 wordList cfxPatchNames(npatch);
00118 labelList patchMasterBlocks(npatch);
00119 labelList patchDirections(npatch);
00120 labelListList patchRanges(npatch);
00121
00122 {
00123 label no, blkNo, patchLabel;
00124
00125 forAll (cfxPatchTypes, patchI)
00126 {
00127
00128 cfxFile >> cfxPatchTypes[patchI] >> cfxPatchNames[patchI] >> no;
00129
00130
00131 patchRanges[patchI].setSize(6);
00132 labelList& curRange = patchRanges[patchI];
00133
00134 forAll (curRange, rI)
00135 {
00136 cfxFile >> curRange[rI];
00137 }
00138
00139
00140
00141
00142
00143
00144 cfxFile >> patchDirections[patchI] >> blkNo >> patchLabel;
00145
00146 patchMasterBlocks[patchI] = blkNo - 1;
00147 }
00148 }
00149
00150 Info << "Reading block glueing information" << endl;
00151
00152 labelList glueMasterPatches(nglue, -1);
00153 labelList glueSlavePatches(nglue, -1);
00154
00155 {
00156 label masterPatch, slavePatch;
00157 label dirIndex1, dirIndex2, dirIndex3, joinNumber;
00158
00159 for (label glueI = 0; glueI < nglue; glueI++)
00160 {
00161 cfxFile >> masterPatch >> slavePatch;
00162 cfxFile >> dirIndex1 >> dirIndex2 >> dirIndex3 >> joinNumber;
00163
00164 glueMasterPatches[glueI] = masterPatch - 1;
00165 glueSlavePatches[glueI] = slavePatch - 1;
00166 }
00167 }
00168
00169 Info << "Reading block points" << endl;
00170
00171 forAll (blocks, blockI)
00172 {
00173 Info << "block " << blockI << " is a ";
00174 blocks[blockI].readPoints(cfxFile);
00175 }
00176
00177 Info << "Calculating block offsets" << endl;
00178
00179 labelList blockOffsets(nblock, -1);
00180
00181 blockOffsets[0] = 0;
00182
00183 label nMeshPoints = blocks[0].nBlockPoints();
00184 label nMeshCells = blocks[0].nBlockCells();
00185
00186 for (label blockI = 1; blockI < nblock; blockI++)
00187 {
00188 nMeshPoints += blocks[blockI].nBlockPoints();
00189 nMeshCells += blocks[blockI].nBlockCells();
00190
00191 blockOffsets[blockI] =
00192 blockOffsets[blockI - 1]
00193 + blocks[blockI - 1].nBlockPoints();
00194 }
00195
00196 Info << "Assembling patches" << endl;
00197
00198 faceListList rawPatches(npatch);
00199
00200 forAll (rawPatches, patchI)
00201 {
00202 const word& patchType = cfxPatchTypes[patchI];
00203
00204
00205 if
00206 (
00207 patchType == "POROUS" || patchType == "SOLID"
00208 || patchType == "SOLCON" || patchType == "USER3D"
00209 )
00210 {
00211 patchMasterBlocks[patchI] = -1;
00212 rawPatches[patchI].setSize(0);
00213 }
00214 else
00215 {
00216
00217 rawPatches[patchI] =
00218 blocks[patchMasterBlocks[patchI]].patchFaces
00219 (
00220 patchDirections[patchI],
00221 patchRanges[patchI]
00222 );
00223
00224 }
00225 }
00226
00227 Info << "Merging points ";
00228
00229 labelList pointMergeList(nMeshPoints, -1);
00230
00231
00232
00233
00234
00235
00236 labelListListList glueMergePairs(glueMasterPatches.size());
00237
00238 forAll (glueMasterPatches, glueI)
00239 {
00240 const label masterPatch = glueMasterPatches[glueI];
00241 const label slavePatch = glueSlavePatches[glueI];
00242
00243 const label blockPlabel = patchMasterBlocks[masterPatch];
00244 const label blockNlabel = patchMasterBlocks[slavePatch];
00245
00246 const pointField& blockPpoints = blocks[blockPlabel].points();
00247 const pointField& blockNpoints = blocks[blockNlabel].points();
00248
00249 const faceList& blockPFaces = rawPatches[masterPatch];
00250 const faceList& blockNFaces = rawPatches[slavePatch];
00251
00252 labelListList& curPairs = glueMergePairs[glueI];
00253 curPairs.setSize(blockPFaces.size());
00254
00255 if (blockPFaces.size() != blockNFaces.size())
00256 {
00257 FatalErrorIn(args.executable())
00258 << "Inconsistent number of faces for glue pair "
00259 << glueI << " between blocks " << blockPlabel + 1
00260 << " and " << blockNlabel + 1
00261 << abort(FatalError);
00262 }
00263
00264
00265
00266
00267
00268
00269 scalar sqrMergeTol = GREAT;
00270
00271 forAll (blockPFaces, blockPFaceLabel)
00272 {
00273 const labelList& blockPFacePoints =
00274 blockPFaces[blockPFaceLabel];
00275
00276 forAll (blockPFacePoints, blockPFacePointI)
00277 {
00278 forAll (blockPFacePoints, blockPFacePointI2)
00279 {
00280 if (blockPFacePointI != blockPFacePointI2)
00281 {
00282 sqrMergeTol =
00283 min
00284 (
00285 sqrMergeTol,
00286 magSqr
00287 (
00288 blockPpoints
00289 [blockPFacePoints[blockPFacePointI]]
00290 - blockPpoints
00291 [blockPFacePoints[blockPFacePointI2]]
00292 )
00293 );
00294 }
00295 }
00296 }
00297 }
00298
00299 sqrMergeTol /= 10.0;
00300
00301 register bool found = false;
00302
00303
00304
00305 forAll (blockPFaces, blockPFaceLabel)
00306 {
00307 const labelList& blockPFacePoints =
00308 blockPFaces[blockPFaceLabel];
00309
00310 labelList& cp = curPairs[blockPFaceLabel];
00311 cp.setSize(blockPFacePoints.size());
00312
00313 forAll (blockPFacePoints, blockPFacePointI)
00314 {
00315 found = false;
00316
00317 forAll (blockNFaces, blockNFaceLabel)
00318 {
00319 const labelList& blockNFacePoints =
00320 blockNFaces[blockNFaceLabel];
00321
00322 forAll (blockNFacePoints, blockNFacePointI)
00323 {
00324 if
00325 (
00326 magSqr
00327 (
00328 blockPpoints
00329 [blockPFacePoints[blockPFacePointI]]
00330 - blockNpoints
00331 [blockNFacePoints[blockNFacePointI]]
00332 )
00333 < sqrMergeTol
00334 )
00335 {
00336
00337 found = true;
00338
00339 cp[blockPFacePointI] =
00340 blockNFacePoints[blockNFacePointI];
00341
00342 label PpointLabel =
00343 blockPFacePoints[blockPFacePointI]
00344 + blockOffsets[blockPlabel];
00345
00346 label NpointLabel =
00347 blockNFacePoints[blockNFacePointI]
00348 + blockOffsets[blockNlabel];
00349
00350 label minPN = min(PpointLabel, NpointLabel);
00351
00352 if (pointMergeList[PpointLabel] != -1)
00353 {
00354 minPN = min(minPN, pointMergeList[PpointLabel]);
00355 }
00356
00357 if (pointMergeList[NpointLabel] != -1)
00358 {
00359 minPN = min(minPN, pointMergeList[NpointLabel]);
00360 }
00361
00362 pointMergeList[PpointLabel]
00363 = pointMergeList[NpointLabel]
00364 = minPN;
00365
00366 break;
00367 }
00368 }
00369 if (found) break;
00370 }
00371 }
00372 }
00373 }
00374
00375
00376 register bool changedPointMerge = false;
00377 label nPasses = 0;
00378
00379 do
00380 {
00381 changedPointMerge = false;
00382 nPasses++;
00383
00384 forAll (glueMasterPatches, glueI)
00385 {
00386 const label masterPatch = glueMasterPatches[glueI];
00387 const label slavePatch = glueSlavePatches[glueI];
00388
00389 const label blockPlabel = patchMasterBlocks[masterPatch];
00390 const label blockNlabel = patchMasterBlocks[slavePatch];
00391
00392 const faceList& blockPFaces = rawPatches[masterPatch];
00393
00394 const labelListList& curPairs = glueMergePairs[glueI];
00395
00396 forAll (blockPFaces, blockPFaceLabel)
00397 {
00398 const labelList& blockPFacePoints =
00399 blockPFaces[blockPFaceLabel];
00400
00401 const labelList& cp = curPairs[blockPFaceLabel];
00402
00403 forAll (cp, blockPFacePointI)
00404 {
00405 label PpointLabel =
00406 blockPFacePoints[blockPFacePointI]
00407 + blockOffsets[blockPlabel];
00408
00409 label NpointLabel =
00410 cp[blockPFacePointI]
00411 + blockOffsets[blockNlabel];
00412
00413 if
00414 (
00415 pointMergeList[PpointLabel]
00416 != pointMergeList[NpointLabel]
00417 )
00418 {
00419 changedPointMerge = true;
00420
00421 pointMergeList[PpointLabel]
00422 = pointMergeList[NpointLabel]
00423 = min
00424 (
00425 pointMergeList[PpointLabel],
00426 pointMergeList[NpointLabel]
00427 );
00428 }
00429 }
00430 }
00431 }
00432 Info << "." << flush;
00433 }
00434 while (changedPointMerge && nPasses < 8);
00435 Info << endl;
00436
00437 if (changedPointMerge == true)
00438 {
00439 FatalErrorIn(args.executable())
00440 << "Point merging failed after max number of passes."
00441 << abort(FatalError);
00442 }
00443
00444
00445 forAll (glueMasterPatches, glueI)
00446 {
00447 const label masterPatch = glueMasterPatches[glueI];
00448 const label slavePatch = glueSlavePatches[glueI];
00449
00450 const label blockPlabel = patchMasterBlocks[masterPatch];
00451 const label blockNlabel = patchMasterBlocks[slavePatch];
00452
00453 const faceList& blockPFaces = rawPatches[masterPatch];
00454 const faceList& blockNFaces = rawPatches[slavePatch];
00455
00456
00457 forAll (blockPFaces, blockPFaceLabel)
00458 {
00459 const labelList& blockPFacePoints
00460 = blockPFaces[blockPFaceLabel];
00461
00462 forAll (blockPFacePoints, blockPFacePointI)
00463 {
00464 label PpointLabel =
00465 blockPFacePoints[blockPFacePointI]
00466 + blockOffsets[blockPlabel];
00467
00468 if (pointMergeList[PpointLabel] == -1)
00469 {
00470 FatalErrorIn(args.executable())
00471 << "Unable to merge point " << blockPFacePointI
00472 << " of face " << blockPFaceLabel
00473 << " of block " << blockPlabel
00474 << abort(FatalError);
00475 }
00476 }
00477 }
00478
00479 forAll (blockNFaces, blockNFaceLabel)
00480 {
00481 const labelList& blockNFacePoints
00482 = blockNFaces[blockNFaceLabel];
00483
00484 forAll (blockNFacePoints, blockNFacePointI)
00485 {
00486 label NpointLabel =
00487 blockNFacePoints[blockNFacePointI]
00488 + blockOffsets[blockNlabel];
00489
00490 if (pointMergeList[NpointLabel] == -1)
00491 {
00492 FatalErrorIn(args.executable())
00493 << "Unable to merge point " << blockNFacePointI
00494 << " of face " << blockNFaceLabel
00495 << " of block " << blockNlabel
00496 << abort(FatalError);
00497 }
00498 }
00499 }
00500 }
00501
00502
00503
00504
00505 label nNewPoints = 0;
00506
00507 forAll (pointMergeList, pointLabel)
00508 {
00509 if (pointMergeList[pointLabel] > pointLabel)
00510 {
00511 FatalErrorIn(args.executable())
00512 << "ouch" << abort(FatalError);
00513 }
00514
00515 if
00516 (
00517 (pointMergeList[pointLabel] == -1)
00518 || pointMergeList[pointLabel] == pointLabel
00519 )
00520 {
00521 pointMergeList[pointLabel] = nNewPoints;
00522 nNewPoints++;
00523 }
00524 else
00525 {
00526 pointMergeList[pointLabel] =
00527 pointMergeList[pointMergeList[pointLabel]];
00528 }
00529 }
00530
00531 nMeshPoints = nNewPoints;
00532
00533 Info << "Creating points" << endl;
00534
00535 pointField points(nMeshPoints);
00536
00537 forAll (blocks, blockI)
00538 {
00539 const pointField& blockPoints = blocks[blockI].points();
00540
00541 forAll (blockPoints, blockPointLabel)
00542 {
00543 points
00544 [
00545 pointMergeList
00546 [
00547 blockPointLabel
00548 + blockOffsets[blockI]
00549 ]
00550 ] = blockPoints[blockPointLabel];
00551 }
00552 }
00553
00554
00555 if (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
00556 {
00557 points *= scaleFactor;
00558 }
00559
00560 Info << "Creating cells" << endl;
00561
00562 cellShapeList cellShapes(nMeshCells);
00563
00564 const cellModel& hex = *(cellModeller::lookup("hex"));
00565
00566 label nCreatedCells = 0;
00567
00568 forAll (blocks, blockI)
00569 {
00570 labelListList curBlockCells = blocks[blockI].blockCells();
00571
00572 forAll (curBlockCells, blockCellI)
00573 {
00574 labelList cellPoints(curBlockCells[blockCellI].size());
00575
00576 forAll (cellPoints, pointI)
00577 {
00578 cellPoints[pointI] =
00579 pointMergeList
00580 [
00581 curBlockCells[blockCellI][pointI]
00582 + blockOffsets[blockI]
00583 ];
00584 }
00585
00586 cellShapes[nCreatedCells] = cellShape(hex, cellPoints);
00587
00588 nCreatedCells++;
00589 }
00590 }
00591
00592 Info << "Creating boundary patches" << endl;
00593
00594 faceListList boundary(npatch);
00595 wordList patchNames(npatch);
00596 wordList patchTypes(npatch);
00597 word defaultFacesName = "defaultFaces";
00598 word defaultFacesType = wallPolyPatch::typeName;
00599 wordList patchPhysicalTypes(npatch);
00600
00601 label nCreatedPatches = 0;
00602
00603 forAll (rawPatches, patchI)
00604 {
00605 if (rawPatches[patchI].size() && cfxPatchTypes[patchI] != "BLKBDY")
00606 {
00607
00608 label existingPatch = -1;
00609
00610 for (label oldPatchI = 0; oldPatchI < nCreatedPatches; oldPatchI++)
00611 {
00612 if (patchNames[oldPatchI] == cfxPatchNames[patchI])
00613 {
00614 existingPatch = oldPatchI;
00615 break;
00616 }
00617 }
00618
00619 const faceList& curRawPatch = rawPatches[patchI];
00620 label curBlock = patchMasterBlocks[patchI];
00621
00622 if (existingPatch >= 0)
00623 {
00624 Info << "CFX patch " << patchI
00625 << ", of type " << cfxPatchTypes[patchI]
00626 << ", name " << cfxPatchNames[patchI]
00627 << " already exists as FOAM patch " << existingPatch
00628 << ". Adding faces." << endl;
00629
00630 faceList& renumberedPatch = boundary[existingPatch];
00631 label oldSize = renumberedPatch.size();
00632 renumberedPatch.setSize(oldSize + curRawPatch.size());
00633
00634 forAll (curRawPatch, faceI)
00635 {
00636 const face& oldFace = curRawPatch[faceI];
00637
00638 face& newFace = renumberedPatch[oldSize + faceI];
00639 newFace.setSize(oldFace.size());
00640
00641 forAll (oldFace, pointI)
00642 {
00643 newFace[pointI] =
00644 pointMergeList
00645 [
00646 oldFace[pointI]
00647 + blockOffsets[curBlock]
00648 ];
00649 }
00650 }
00651 }
00652 else
00653 {
00654
00655 faceList& renumberedPatch = boundary[nCreatedPatches];
00656 renumberedPatch.setSize(curRawPatch.size());
00657
00658 forAll (curRawPatch, faceI)
00659 {
00660 const face& oldFace = curRawPatch[faceI];
00661
00662 face& newFace = renumberedPatch[faceI];
00663 newFace.setSize(oldFace.size());
00664
00665 forAll (oldFace, pointI)
00666 {
00667 newFace[pointI] =
00668 pointMergeList
00669 [
00670 oldFace[pointI]
00671 + blockOffsets[curBlock]
00672 ];
00673 }
00674 }
00675
00676 Info << "CFX patch " << patchI
00677 << ", of type " << cfxPatchTypes[patchI]
00678 << ", name " << cfxPatchNames[patchI]
00679 << " converted into FOAM patch " << nCreatedPatches
00680 << " type ";
00681
00682 if (cfxPatchTypes[patchI] == "WALL")
00683 {
00684 Info << "wall." << endl;
00685
00686 patchTypes[nCreatedPatches] = wallPolyPatch::typeName;
00687 patchNames[nCreatedPatches] = cfxPatchNames[patchI];
00688 nCreatedPatches++;
00689 }
00690 else if (cfxPatchTypes[patchI] == "SYMMET")
00691 {
00692 Info << "symmetryPlane." << endl;
00693
00694 patchTypes[nCreatedPatches] = symmetryPolyPatch::typeName;
00695 patchNames[nCreatedPatches] = cfxPatchNames[patchI];
00696 nCreatedPatches++;
00697 }
00698 else if
00699 (
00700 cfxPatchTypes[patchI] == "INLET"
00701 || cfxPatchTypes[patchI] == "OUTLET"
00702 || cfxPatchTypes[patchI] == "PRESS"
00703 || cfxPatchTypes[patchI] == "CNDBDY"
00704 || cfxPatchTypes[patchI] == "USER2D"
00705 )
00706 {
00707 Info << "generic." << endl;
00708
00709 patchTypes[nCreatedPatches] = polyPatch::typeName;
00710 patchNames[nCreatedPatches] = cfxPatchNames[patchI];
00711 nCreatedPatches++;
00712 }
00713 else
00714 {
00715 FatalErrorIn(args.executable())
00716 << "Unrecognised CFX patch type "
00717 << cfxPatchTypes[patchI]
00718 << abort(FatalError);
00719 }
00720 }
00721 }
00722 }
00723
00724 boundary.setSize(nCreatedPatches);
00725 patchTypes.setSize(nCreatedPatches);
00726 patchNames.setSize(nCreatedPatches);
00727
00728 preservePatchTypes
00729 (
00730 runTime,
00731 runTime.constant(),
00732 polyMesh::defaultRegion,
00733 patchNames,
00734 patchTypes,
00735 defaultFacesName,
00736 defaultFacesType,
00737 patchPhysicalTypes
00738 );
00739
00740 polyMesh pShapeMesh
00741 (
00742 IOobject
00743 (
00744 polyMesh::defaultRegion,
00745 runTime.constant(),
00746 runTime
00747 ),
00748 xferMove(points),
00749 cellShapes,
00750 boundary,
00751 patchNames,
00752 patchTypes,
00753 defaultFacesName,
00754 defaultFacesType,
00755 patchPhysicalTypes
00756 );
00757
00758
00759 IOstream::defaultPrecision(10);
00760
00761 Info << "Writing polyMesh" << endl;
00762 pShapeMesh.write();
00763
00764 Info << "End\n" << endl;
00765
00766 return 0;
00767 }
00768
00769
00770