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
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #include <finiteVolume/fvCFD.H>
00094 #include <dynamicMesh/polyTopoChanger.H>
00095 #include <OpenFOAM/mapPolyMesh.H>
00096 #include <OpenFOAM/ListOps.H>
00097 #include <dynamicMesh/slidingInterface.H>
00098 #include <dynamicMesh/perfectInterface.H>
00099 #include <OpenFOAM/IOobjectList.H>
00100 #include <OpenFOAM/ReadFields.H>
00101
00102
00103
00104
00105 label addPointZone(const polyMesh& mesh, const word& name)
00106 {
00107 label zoneID = mesh.pointZones().findZoneID(name);
00108
00109 if (zoneID != -1)
00110 {
00111 Info<< "Reusing existing pointZone "
00112 << mesh.pointZones()[zoneID].name()
00113 << " at index " << zoneID << endl;
00114 }
00115 else
00116 {
00117 pointZoneMesh& pointZones = const_cast<polyMesh&>(mesh).pointZones();
00118 zoneID = pointZones.size();
00119 Info<< "Adding pointZone " << name << " at index " << zoneID << endl;
00120
00121 pointZones.setSize(zoneID+1);
00122 pointZones.set
00123 (
00124 zoneID,
00125 new pointZone
00126 (
00127 name,
00128 labelList(0),
00129 zoneID,
00130 pointZones
00131 )
00132 );
00133 }
00134 return zoneID;
00135 }
00136
00137
00138 label addFaceZone(const polyMesh& mesh, const word& name)
00139 {
00140 label zoneID = mesh.faceZones().findZoneID(name);
00141
00142 if (zoneID != -1)
00143 {
00144 Info<< "Reusing existing faceZone " << mesh.faceZones()[zoneID].name()
00145 << " at index " << zoneID << endl;
00146 }
00147 else
00148 {
00149 faceZoneMesh& faceZones = const_cast<polyMesh&>(mesh).faceZones();
00150 zoneID = faceZones.size();
00151 Info<< "Adding faceZone " << name << " at index " << zoneID << endl;
00152
00153 faceZones.setSize(zoneID+1);
00154 faceZones.set
00155 (
00156 zoneID,
00157 new faceZone
00158 (
00159 name,
00160 labelList(0),
00161 boolList(),
00162 zoneID,
00163 faceZones
00164 )
00165 );
00166 }
00167 return zoneID;
00168 }
00169
00170
00171 label addCellZone(const polyMesh& mesh, const word& name)
00172 {
00173 label zoneID = mesh.cellZones().findZoneID(name);
00174
00175 if (zoneID != -1)
00176 {
00177 Info<< "Reusing existing cellZone " << mesh.cellZones()[zoneID].name()
00178 << " at index " << zoneID << endl;
00179 }
00180 else
00181 {
00182 cellZoneMesh& cellZones = const_cast<polyMesh&>(mesh).cellZones();
00183 zoneID = cellZones.size();
00184 Info<< "Adding cellZone " << name << " at index " << zoneID << endl;
00185
00186 cellZones.setSize(zoneID+1);
00187 cellZones.set
00188 (
00189 zoneID,
00190 new cellZone
00191 (
00192 name,
00193 labelList(0),
00194 zoneID,
00195 cellZones
00196 )
00197 );
00198 }
00199 return zoneID;
00200 }
00201
00202
00203
00204 void checkPatch(const polyBoundaryMesh& bMesh, const word& name)
00205 {
00206 label patchI = bMesh.findPatchID(name);
00207
00208 if (patchI == -1)
00209 {
00210 FatalErrorIn("checkPatch(const polyBoundaryMesh&, const word&)")
00211 << "Cannot find patch " << name << endl
00212 << "It should be present and of non-zero size" << endl
00213 << "Valid patches are " << bMesh.names()
00214 << exit(FatalError);
00215 }
00216
00217 if (bMesh[patchI].empty())
00218 {
00219 FatalErrorIn("checkPatch(const polyBoundaryMesh&, const word&)")
00220 << "Patch " << name << " is present but zero size"
00221 << exit(FatalError);
00222 }
00223 }
00224
00225
00226
00227
00228 int main(int argc, char *argv[])
00229 {
00230 Foam::argList::noParallel();
00231 # include <OpenFOAM/addRegionOption.H>
00232 Foam::argList::validArgs.append("masterPatch");
00233 Foam::argList::validArgs.append("slavePatch");
00234
00235 Foam::argList::validOptions.insert("partial", "");
00236 Foam::argList::validOptions.insert("perfect", "");
00237
00238 Foam::argList::validOptions.insert("overwrite", "");
00239
00240 Foam::argList::validOptions.insert("toleranceDict", "file with tolerances");
00241
00242 # include <OpenFOAM/setRootCase.H>
00243 # include <OpenFOAM/createTime.H>
00244 runTime.functionObjects().off();
00245 #include <OpenFOAM/createNamedMesh.H>
00246 const word oldInstance = mesh.pointsInstance();
00247
00248
00249 word masterPatchName(args.additionalArgs()[0]);
00250 word slavePatchName(args.additionalArgs()[1]);
00251
00252 bool partialCover = args.optionFound("partial");
00253 bool perfectCover = args.optionFound("perfect");
00254 bool overwrite = args.optionFound("overwrite");
00255
00256 if (partialCover && perfectCover)
00257 {
00258 FatalErrorIn(args.executable())
00259 << "Cannot both supply partial and perfect." << endl
00260 << "Use perfect match option if the patches perfectly align"
00261 << " (both vertex positions and face centres)" << endl
00262 << exit(FatalError);
00263 }
00264
00265
00266 const word mergePatchName(masterPatchName + slavePatchName);
00267 const word cutZoneName(mergePatchName + "CutFaceZone");
00268
00269 slidingInterface::typeOfMatch tom = slidingInterface::INTEGRAL;
00270
00271 if (partialCover)
00272 {
00273 Info<< "Coupling partially overlapping patches "
00274 << masterPatchName << " and " << slavePatchName << nl
00275 << "Resulting internal faces will be in faceZone " << cutZoneName
00276 << nl
00277 << "Any uncovered faces will remain in their patch"
00278 << endl;
00279
00280 tom = slidingInterface::PARTIAL;
00281 }
00282 else if (perfectCover)
00283 {
00284 Info<< "Coupling perfectly aligned patches "
00285 << masterPatchName << " and " << slavePatchName << nl
00286 << "Resulting (internal) faces will be in faceZone " << cutZoneName
00287 << nl << nl
00288 << "Note: both patches need to align perfectly." << nl
00289 << "Both the vertex"
00290 << " positions and the face centres need to align to within" << nl
00291 << "a tolerance given by the minimum edge length on the patch"
00292 << endl;
00293 }
00294 else
00295 {
00296 Info<< "Coupling patches " << masterPatchName << " and "
00297 << slavePatchName << nl
00298 << "Resulting (internal) faces will be in faceZone " << cutZoneName
00299 << nl << nl
00300 << "Note: the overall area covered by both patches should be"
00301 << " identical (\"integral\" interface)." << endl
00302 << "If this is not the case use the -partial option" << nl << endl;
00303 }
00304
00305
00306 dictionary slidingTolerances;
00307 if (args.options().found("toleranceDict"))
00308 {
00309 IOdictionary toleranceFile(
00310 IOobject(
00311 args.options()["toleranceDict"],
00312 runTime.constant(),
00313 mesh,
00314 IOobject::MUST_READ,
00315 IOobject::NO_WRITE
00316 )
00317 );
00318 slidingTolerances += toleranceFile;
00319 }
00320
00321
00322 checkPatch(mesh.boundaryMesh(), masterPatchName);
00323 checkPatch(mesh.boundaryMesh(), slavePatchName);
00324
00325
00326
00327
00328 const polyPatch& masterPatch =
00329 mesh.boundaryMesh()
00330 [
00331 mesh.boundaryMesh().findPatchID(masterPatchName)
00332 ];
00333
00334
00335 labelList isf(masterPatch.size());
00336
00337 forAll (isf, i)
00338 {
00339 isf[i] = masterPatch.start() + i;
00340 }
00341
00342 polyTopoChanger stitcher(mesh);
00343 stitcher.setSize(1);
00344
00345 mesh.pointZones().clearAddressing();
00346 mesh.faceZones().clearAddressing();
00347 mesh.cellZones().clearAddressing();
00348
00349 if (perfectCover)
00350 {
00351
00352 label cutZoneID = addFaceZone(mesh, cutZoneName);
00353
00354 mesh.faceZones()[cutZoneID].resetAddressing
00355 (
00356 isf,
00357 boolList(masterPatch.size(), false)
00358 );
00359
00360
00361 stitcher.set
00362 (
00363 0,
00364 new perfectInterface
00365 (
00366 "couple",
00367 0,
00368 stitcher,
00369 cutZoneName,
00370 masterPatchName,
00371 slavePatchName
00372 )
00373 );
00374 }
00375 else
00376 {
00377 label pointZoneID = addPointZone(mesh, mergePatchName + "CutPointZone");
00378 mesh.pointZones()[pointZoneID] = labelList(0);
00379
00380 label masterZoneID = addFaceZone(mesh, mergePatchName + "MasterZone");
00381
00382 mesh.faceZones()[masterZoneID].resetAddressing
00383 (
00384 isf,
00385 boolList(masterPatch.size(), false)
00386 );
00387
00388
00389 const polyPatch& slavePatch =
00390 mesh.boundaryMesh()
00391 [
00392 mesh.boundaryMesh().findPatchID(slavePatchName)
00393 ];
00394
00395 labelList osf(slavePatch.size());
00396
00397 forAll (osf, i)
00398 {
00399 osf[i] = slavePatch.start() + i;
00400 }
00401
00402 label slaveZoneID = addFaceZone(mesh, mergePatchName + "SlaveZone");
00403 mesh.faceZones()[slaveZoneID].resetAddressing
00404 (
00405 osf,
00406 boolList(slavePatch.size(), false)
00407 );
00408
00409
00410 label cutZoneID = addFaceZone(mesh, cutZoneName);
00411 mesh.faceZones()[cutZoneID].resetAddressing
00412 (
00413 labelList(0),
00414 boolList(0, false)
00415 );
00416
00417
00418
00419 stitcher.set
00420 (
00421 0,
00422 new slidingInterface
00423 (
00424 "couple",
00425 0,
00426 stitcher,
00427 mergePatchName + "MasterZone",
00428 mergePatchName + "SlaveZone",
00429 mergePatchName + "CutPointZone",
00430 cutZoneName,
00431 masterPatchName,
00432 slavePatchName,
00433 tom,
00434 true
00435 )
00436 );
00437 static_cast<slidingInterface&>(stitcher[0]).setTolerances
00438 (
00439 slidingTolerances,
00440 true
00441 );
00442 }
00443
00444
00445
00446 IOobjectList objects(mesh, runTime.timeName());
00447
00448
00449 Info<< "Reading all current volfields" << endl;
00450 PtrList<volScalarField> volScalarFields;
00451 ReadFields(mesh, objects, volScalarFields);
00452
00453 PtrList<volVectorField> volVectorFields;
00454 ReadFields(mesh, objects, volVectorFields);
00455
00456 PtrList<volSphericalTensorField> volSphericalTensorFields;
00457 ReadFields(mesh, objects, volSphericalTensorFields);
00458
00459 PtrList<volSymmTensorField> volSymmTensorFields;
00460 ReadFields(mesh, objects, volSymmTensorFields);
00461
00462 PtrList<volTensorField> volTensorFields;
00463 ReadFields(mesh, objects, volTensorFields);
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 if (!overwrite)
00477 {
00478 runTime++;
00479 }
00480
00481
00482 autoPtr<mapPolyMesh> morphMap = stitcher.changeMesh(true);
00483
00484 mesh.movePoints(morphMap->preMotionPoints());
00485
00486
00487 if (overwrite)
00488 {
00489 mesh.setInstance(oldInstance);
00490 stitcher.instance() = oldInstance;
00491 }
00492 Info << nl << "Writing polyMesh to time " << runTime.timeName() << endl;
00493
00494 IOstream::defaultPrecision(10);
00495
00496
00497 if
00498 (
00499 !runTime.objectRegistry::writeObject
00500 (
00501 runTime.writeFormat(),
00502 IOstream::currentVersion,
00503 runTime.writeCompression()
00504 )
00505 )
00506 {
00507 FatalErrorIn(args.executable())
00508 << "Failed writing polyMesh."
00509 << exit(FatalError);
00510 }
00511
00512 mesh.faceZones().write();
00513 mesh.pointZones().write();
00514 mesh.cellZones().write();
00515
00516
00517 runTime.write();
00518
00519 Info<< nl << "end" << endl;
00520
00521 return 0;
00522 }
00523
00524
00525