diff --git a/applications/test/extendedStencil/Test-ExtendedStencil.C b/applications/test/extendedStencil/Test-ExtendedStencil.C index 72c1afb2c11b96322b9266c35c93ed9d58e34cb7..0e50f8710fd009acbd5ae7d9e57fc019d9d28ebf 100644 --- a/applications/test/extendedStencil/Test-ExtendedStencil.C +++ b/applications/test/extendedStencil/Test-ExtendedStencil.C @@ -56,6 +56,8 @@ Description //#include "centredCFCFaceToCellStencilObject.H" #include "centredCECCellToCellStencilObject.H" +#include "centredCFCCellToCellStencilObject.H" +#include "centredCPCCellToCellStencilObject.H" using namespace Foam; @@ -460,7 +462,63 @@ int main(int argc, char *argv[]) { writeStencilOBJ ( - runTime.path()/"centredCell" + Foam::name(cellI) + ".obj", + runTime.path()/"centredCECCell" + Foam::name(cellI) + ".obj", + mesh.cellCentres()[cellI], + stencilPoints[cellI] + ); + } + } + { + const extendedCentredCellToCellStencil& addressing = + centredCPCCellToCellStencilObject::New + ( + mesh + ); + + Info<< "cellCellCell:" << endl; + writeStencilStats(addressing.stencil()); + + // Collect stencil cell centres + List<List<point> > stencilPoints(mesh.nCells()); + addressing.collectData + ( + mesh.C(), + stencilPoints + ); + + forAll(stencilPoints, cellI) + { + writeStencilOBJ + ( + runTime.path()/"centredCPCCell" + Foam::name(cellI) + ".obj", + mesh.cellCentres()[cellI], + stencilPoints[cellI] + ); + } + } + { + const extendedCentredCellToCellStencil& addressing = + centredCFCCellToCellStencilObject::New + ( + mesh + ); + + Info<< "cellCellCell:" << endl; + writeStencilStats(addressing.stencil()); + + // Collect stencil cell centres + List<List<point> > stencilPoints(mesh.nCells()); + addressing.collectData + ( + mesh.C(), + stencilPoints + ); + + forAll(stencilPoints, cellI) + { + writeStencilOBJ + ( + runTime.path()/"centredCFCCell" + Foam::name(cellI) + ".obj", mesh.cellCentres()[cellI], stencilPoints[cellI] ); diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C index f4ce2cc95de8e8863839a554ba845f43131dc4c9..f2c091e4adad7c2feedef870eb83e6f1980ec9e9 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C +++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C @@ -493,7 +493,6 @@ int main(int argc, char *argv[]) mesh.nFaces(), // start patchI, // index mesh.boundaryMesh(),// polyBoundaryMesh - Pstream::worldComm, // communicator Pstream::myProcNo(),// myProcNo nbrProcI // neighbProcNo ) diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict index f448faa40c15e46e34050fce7152c157d6c6c3c4..7d1ad76db3007982d4977face4a0b095f9697d57 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict @@ -152,6 +152,10 @@ castellatedMeshControls inGroups (meshedPatches); } + + //- Optional increment (on top of max level) in small gaps. + //gapLevelIncrement 2; + //- Optional angle to detect small-large cell situation // perpendicular to the surface. Is the angle of face w.r.t. // the local surface normal. Use on flat(ish) surfaces only. @@ -181,6 +185,15 @@ castellatedMeshControls resolveFeatureAngle 30; + // Planar angle: + // - used to determine if surface normals + // are roughly the same or opposite. Used e.g. in gap refinement + // and to decide when to merge free-standing baffles + // + // If not specified same as resolveFeatureAngle + planarAngle 15; + + // Region-wise refinement // ~~~~~~~~~~~~~~~~~~~~~~ @@ -222,11 +235,6 @@ castellatedMeshControls // are only on the boundary of corresponding cellZones or also allow // free-standing zone faces. Not used if there are no faceZones. allowFreeStandingZoneFaces true; - - - // Optional: whether all baffles get eroded away. WIP. Used for - // surface simplification. - //allowFreeStandingBaffles false; } // Settings for the snapping. @@ -456,20 +464,21 @@ meshQualityControls // 1 = hex, <= 0 = folded or flattened illegal cell minDeterminant 0.001; - // minFaceWeight (0 -> 0.5) + // Relative position of face in relation to cell centres (0.5 for orthogonal + // mesh) (0 -> 0.5) minFaceWeight 0.05; - // minVolRatio (0 -> 1) + // Volume ratio of neighbouring cells (0 -> 1) minVolRatio 0.01; // must be >0 for Fluent compatibility minTriangleTwist -1; - //- if >0 : preserve single cells with all points on the surface if the + //- if >0 : preserve cells with all points on the surface if the // resulting volume after snapping (by approximation) is larger than // minVolCollapseRatio times old volume (i.e. not collapsed to flat cell). // If <0 : delete always. - //minVolCollapseRatio 0.5; + //minVolCollapseRatio 0.1; // Advanced diff --git a/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict b/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict index b392f0764278002f565c875be900379d73f6e039..ef2eb96227f804d67ccc9b686455c4e6833b442e 100644 --- a/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict +++ b/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict @@ -14,6 +14,20 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Sample for creating baffles: +// - usually converting internal faces into two boundary faces +// - or converting boundary faces into a boundary face +// (internalFacesOnly=false)(though should use really createPatch +// to do this) +// - can also create duplicate (overlapping) sets of baffles: +// - internalFacesOnly = false +// - have 4 entries in patches: +// - master +// - slave +// - additional master +// - additional slave + + // Whether to convert internal faces only (so leave boundary faces intact). // This is only relevant if your face selection type can pick up boundary // faces. diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C index f563978b60bbef5b1e4f7494df4e8fe0b332702c..15cbd85d11eae6b7bc74b968312f7bdffab3d333 100644 --- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C +++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C @@ -448,7 +448,6 @@ bool Foam::domainDecomposition::writeDecomposition() curStart, nPatches, procMesh.boundaryMesh(), - Pstream::worldComm, procI, curNeighbourProcessors[procPatchI] ); @@ -476,7 +475,6 @@ bool Foam::domainDecomposition::writeDecomposition() curStart, nPatches, procMesh.boundaryMesh(), - Pstream::worldComm, procI, curNeighbourProcessors[procPatchI], referPatch, diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index edb29d3998a04146ad3e97cacef211d2ff50a0ad..d50bf96448867f078ac8225d15d7fe0b544d2e85 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -240,7 +240,7 @@ int main(int argc, char *argv[]) wordHashSet allCloudNames; if (Pstream::master()) { - word geomFileName = prepend + "000"; + word geomFileName = prepend + "0000"; // test pre check variable if there is a moving mesh if (meshMoving) diff --git a/applications/utilities/preProcessing/viewFactorsGen/searchingEngine.H b/applications/utilities/preProcessing/viewFactorsGen/searchingEngine.H index ed1d9031ec055d74e0c34168d0a5262474b38539..ef5b264a54278ce4b9f8eecb0a9e3cb3183668aa 100644 --- a/applications/utilities/preProcessing/viewFactorsGen/searchingEngine.H +++ b/applications/utilities/preProcessing/viewFactorsGen/searchingEngine.H @@ -26,7 +26,8 @@ dict.add("mergeDistance", SMALL); labelHashSet includePatches; forAll(patches, patchI) { - if (!isA<processorPolyPatch>(patches[patchI])) + const polyPatch& pp = patches[patchI]; + if (!pp.coupled() && !isA<cyclicAMIPolyPatch>(pp)) { includePatches.insert(patchI); } diff --git a/applications/utilities/preProcessing/viewFactorsGen/viewFactorsGen.C b/applications/utilities/preProcessing/viewFactorsGen/viewFactorsGen.C index c9aa219d13227b7b5d4eb56c7ac1e53964017ded..8276528945aef132cd0782bb8acb476a1c126965 100644 --- a/applications/utilities/preProcessing/viewFactorsGen/viewFactorsGen.C +++ b/applications/utilities/preProcessing/viewFactorsGen/viewFactorsGen.C @@ -44,6 +44,7 @@ Description #include "volFields.H" #include "surfaceFields.H" #include "distributedTriSurfaceMesh.H" +#include "cyclicAMIPolyPatch.H" #include "triSurfaceTools.H" #include "mapDistribute.H" diff --git a/etc/caseDicts/setConstraintTypes b/etc/caseDicts/setConstraintTypes index 85d6ec525c5dd1b2a58d35f4fd00fe956db10bef..1678e2a147933ba98dd05283b45e64ba6586dbad 100644 --- a/etc/caseDicts/setConstraintTypes +++ b/etc/caseDicts/setConstraintTypes @@ -16,6 +16,11 @@ cyclicAMI type cyclicAMI; } +cyclicACMI +{ + type cyclicACMI; +} + cyclicSlip { type cyclicSlip; diff --git a/etc/controlDict b/etc/controlDict index b9c41cb3a432c8e9842c4fa5ea9f4968a612ce19..fba02069de7fadaea270d2eee0e8732683f38ced 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -135,7 +135,7 @@ DebugSwitches FDIC 0; FaceCellWave 0; GAMG 0; - GAMGAgglomeration 0; + GAMGAgglomeration 1; GAMGInterface 0; GAMGInterfaceField 0; Gamma 0; diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 19a8138fe5d1fc5f988befd6d5f388e639052c93..6d346617c1ae9e3a1d8b760f8baafdaecd8090ef 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -331,10 +331,8 @@ eagerGAMGProcAgglomeration = $(GAMGProcAgglomerations)/eagerGAMGProcAgglomeratio $(eagerGAMGProcAgglomeration)/eagerGAMGProcAgglomeration.C noneGAMGProcAgglomeration = $(GAMGProcAgglomerations)/noneGAMGProcAgglomeration $(noneGAMGProcAgglomeration)/noneGAMGProcAgglomeration.C -/* -cellFaceRatioGAMGProcAgglomeration = $(GAMGProcAgglomerations)/cellFaceRatioGAMGProcAgglomeration -$(cellFaceRatioGAMGProcAgglomeration)/cellFaceRatioGAMGProcAgglomeration.C -*/ +procFacesGAMGProcAgglomeration = $(GAMGProcAgglomerations)/procFacesGAMGProcAgglomeration +$(procFacesGAMGProcAgglomeration)/procFacesGAMGProcAgglomeration.C meshes/lduMesh/lduMesh.C diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C index c1b516e97cefb1319594da61f0c0838c010f48b7..c024d98389b64ee3d8b573ba119c58e3f6a0cb96 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -49,21 +49,16 @@ readField << endl; } - // Patch or patch-groups. (using non-wild card entries of dictionaries) + + // 1. Handle explicit patch names forAllConstIter(dictionary, dict, iter) { if (iter().isDict() && !iter().keyword().isPattern()) { - const labelList patchIDs = bmesh_.findIndices - ( - iter().keyword(), - true - ); + label patchi = bmesh_.findPatchID(iter().keyword()); - forAll(patchIDs, i) + if (patchi != -1) { - label patchi = patchIDs[i]; - this->set ( patchi, @@ -78,7 +73,43 @@ readField } } - // Check for wildcard patch overrides + + // 2. Patch-groups. (using non-wild card entries of dictionaries) + // (patchnames already matched above) + // Note: in order of entries in the dictionary (first patchGroups wins) + forAllConstIter(dictionary, dict, iter) + { + if (iter().isDict() && !iter().keyword().isPattern()) + { + const labelList patchIDs = bmesh_.findIndices + ( + iter().keyword(), + true // use patchGroups + ); + + forAll(patchIDs, i) + { + label patchi = patchIDs[i]; + + if (!this->set(patchi)) + { + this->set + ( + patchi, + PatchField<Type>::New + ( + bmesh_[patchi], + field, + iter().dict() + ) + ); + } + } + } + } + + + // 3. Wildcard patch overrides forAll(bmesh_, patchi) { if (!this->set(patchi)) diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C index e6781ed23f248bcc7d1dcae6a100e740f47717d6..066aa39d3b3bef9cbd4ee5bdf03261c3211c7214 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C @@ -351,7 +351,7 @@ void Foam::GAMGAgglomeration::agglomerateLduAddressing ); - if (debug) + if (debug & 2) { Pout<< "GAMGAgglomeration :" << " agglomerated level " << fineLevelIndex diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C index d1551eb3997eed9fec9f94a32d802387e2525ceb..75af8eb20a2744a24952b9e44fcfc91a570745c1 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C @@ -27,9 +27,9 @@ License #include "lduMesh.H" #include "lduMatrix.H" #include "Time.H" -#include "dlLibraryTable.H" #include "GAMGInterface.H" #include "GAMGProcAgglomeration.H" +#include "IOmanip.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -67,23 +67,112 @@ void Foam::GAMGAgglomeration::compactLevels(const label nCreatedLevels) procBoundaryFaceMap_.setSize(nCreatedLevels); procAgglomeratorPtr_().agglomerate(); - } - if (debug) - { - for (label levelI = 0; levelI <= size(); levelI++) + + if (debug) { - if (hasMeshLevel(levelI)) - { - const lduMesh& fineMesh = meshLevel(levelI); - Pout<< "Level " << levelI << " fine mesh:"<< nl; - Pout<< fineMesh.info() << endl; - } - else + + Info<< "GAMGAgglomeration:" << nl + << " local agglomerator : " << type() << nl + << " processor agglomerator : " + << procAgglomeratorPtr_().type() << nl + << nl; + + Info<< setw(40) << "nCells" + << setw(24) << "nFaces/nCells" + << setw(24) << "nInterfaces" + << setw(24) << "nIntFaces/nCells" << nl + << setw(8) << "Level" + << setw(8) << "nProcs" + << " " + << setw(8) << "avg" + << setw(8) << "max" + << " " + << setw(8) << "avg" + << setw(8) << "max" + << " " + << setw(8) << "avg" + << setw(8) << "max" + << " " << setw(4) << "avg" + << " " << setw(4) << "max" + << nl + << setw(8) << "-----" + << setw(8) << "------" + << " " + << setw(8) << "---" + << setw(8) << "---" + << " " + << setw(8) << "---" + << setw(8) << "---" + << " " << setw(4) << "---" + << " " << setw(4) << "---" + << nl; + + for (label levelI = 0; levelI <= size(); levelI++) { - Pout<< "Level " << levelI << " has no fine mesh:" << nl - << endl; + label nProcs = 0; + label nCells = 0; + scalar faceCellRatio = 0; + label nInterfaces = 0; + label nIntFaces = 0; + scalar ratio = 0.0; + + if (hasMeshLevel(levelI)) + { + nProcs = 1; + + const lduMesh& fineMesh = meshLevel(levelI); + nCells = fineMesh.lduAddr().size(); + faceCellRatio = + scalar(fineMesh.lduAddr().lowerAddr().size())/nCells; + + const lduInterfacePtrsList interfaces = + fineMesh.interfaces(); + forAll(interfaces, i) + { + if (interfaces.set(i)) + { + nInterfaces++; + nIntFaces += interfaces[i].faceCells().size(); + } + } + ratio = scalar(nIntFaces)/nCells; + } + + label totNprocs = returnReduce(nProcs, sumOp<label>()); + + label maxNCells = returnReduce(nCells, maxOp<label>()); + label totNCells = returnReduce(nCells, sumOp<label>()); + + scalar maxFaceCellRatio = + returnReduce(faceCellRatio, maxOp<scalar>()); + scalar totFaceCellRatio = + returnReduce(faceCellRatio, sumOp<scalar>()); + + label maxNInt = returnReduce(nInterfaces, maxOp<label>()); + label totNInt = returnReduce(nInterfaces, sumOp<label>()); + + scalar maxRatio = returnReduce(ratio, maxOp<scalar>()); + scalar totRatio = returnReduce(ratio, sumOp<scalar>()); + + Info<< setw(8) << levelI + << setw(8) << totNprocs + + << setw(16) << totNCells/totNprocs + << setw(8) << maxNCells + + << " " + << setw(8) << setprecision(4) << totFaceCellRatio/totNprocs + << setw(8) << setprecision(4) << maxFaceCellRatio + << " " + << setw(8) << totNInt/totNprocs + << setw(8) << maxNInt + << " " + << setw(8) << setprecision(4) << totRatio/totNprocs + << setw(8) << setprecision(4) << maxRatio + << nl; } + Info<< endl; } } } @@ -190,9 +279,9 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New "(const lduMesh& mesh, const dictionary& controlDict)" ) << "Unknown GAMGAgglomeration type " << agglomeratorType << ".\n" - << "Valid algebraic GAMGAgglomeration types are :" + << "Valid matrix GAMGAgglomeration types are :" << lduMatrixConstructorTablePtr_->sortedToc() << endl - << "Valid algebraic GAMGAgglomeration types are :" + << "Valid geometric GAMGAgglomeration types are :" << lduMeshConstructorTablePtr_->sortedToc() << exit(FatalError); } @@ -285,7 +374,8 @@ Foam::autoPtr<Foam::GAMGAgglomeration> Foam::GAMGAgglomeration::New FatalErrorIn ( "GAMGAgglomeration::New" - "(const lduMesh& mesh, const dictionary& controlDict)" + "(const lduMesh& mesh, const scalarField&" + ", const vectorField&, const dictionary& controlDict)" ) << "Unknown GAMGAgglomeration type " << agglomeratorType << ".\n" << "Valid geometric GAMGAgglomeration types are :" diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomeration.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomeration.H index 2867cac2f6e5eb8073304d801f0b15a7f979debc..59de4b1e4df3378afc478508e1f22247e6b4f097 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomeration.H +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/pairGAMGAgglomeration/pairGAMGAgglomeration.H @@ -61,14 +61,6 @@ protected: // Protected Member Functions - //- Calculate and return agglomeration of given level - tmp<labelField> agglomerate - ( - label& nCoarseCells, - const lduAddressing& fineMatrixAddressing, - const scalarField& faceWeights - ); - //- Agglomerate all levels starting from the given face weights void agglomerate ( @@ -97,6 +89,15 @@ public: const lduMesh& mesh, const dictionary& controlDict ); + + //- Calculate and return agglomeration + static tmp<labelField> agglomerate + ( + label& nCoarseCells, + const lduAddressing& fineMatrixAddressing, + const scalarField& faceWeights + ); + }; diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/procFacesGAMGProcAgglomeration/procFacesGAMGProcAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/procFacesGAMGProcAgglomeration/procFacesGAMGProcAgglomeration.C new file mode 100644 index 0000000000000000000000000000000000000000..6e13d52c993de47c4cb65b94c137f2865b4b414a --- /dev/null +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/procFacesGAMGProcAgglomeration/procFacesGAMGProcAgglomeration.C @@ -0,0 +1,333 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "procFacesGAMGProcAgglomeration.H" +#include "addToRunTimeSelectionTable.H" +#include "GAMGAgglomeration.H" +#include "Random.H" +#include "lduMesh.H" +#include "processorLduInterface.H" +#include "processorGAMGInterface.H" +#include "pairGAMGAgglomeration.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(procFacesGAMGProcAgglomeration, 0); + + addToRunTimeSelectionTable + ( + GAMGProcAgglomeration, + procFacesGAMGProcAgglomeration, + GAMGAgglomeration + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Create single cell mesh +Foam::autoPtr<Foam::lduPrimitiveMesh> +Foam::procFacesGAMGProcAgglomeration::singleCellMesh +( + const label singleCellMeshComm, + const lduMesh& mesh, + scalarField& faceWeights +) const +{ + // Count number of faces per processor + List<Map<label> > procFaces(UPstream::nProcs(mesh.comm())); + Map<label>& myNeighbours = procFaces[UPstream::myProcNo(mesh.comm())]; + + { + const lduInterfacePtrsList interfaces(mesh.interfaces()); + forAll(interfaces, intI) + { + if (interfaces.set(intI)) + { + const processorLduInterface& pp = + refCast<const processorLduInterface> + ( + interfaces[intI] + ); + label size = interfaces[intI].faceCells().size(); + myNeighbours.insert(pp.neighbProcNo(), size); + } + } + } + + Pstream::gatherList(procFaces, Pstream::msgType(), mesh.comm()); + Pstream::scatterList(procFaces, Pstream::msgType(), mesh.comm()); + + autoPtr<lduPrimitiveMesh> singleCellMeshPtr; + + if (Pstream::master(mesh.comm())) + { + // I am master + label nCells = Pstream::nProcs(mesh.comm()); + + DynamicList<label> l(3*nCells); + DynamicList<label> u(3*nCells); + DynamicList<scalar> weight(3*nCells); + + DynamicList<label> nbrs; + DynamicList<scalar> weights; + + forAll(procFaces, procI) + { + const Map<label>& neighbours = procFaces[procI]; + + // Add all the higher processors + nbrs.clear(); + weights.clear(); + forAllConstIter(Map<label>, neighbours, iter) + { + if (iter.key() > procI) + { + nbrs.append(iter.key()); + weights.append(iter()); + } + sort(nbrs); + forAll(nbrs, i) + { + l.append(procI); + u.append(nbrs[i]); + weight.append(weights[i]); + } + } + } + + faceWeights.transfer(weight); + + PtrList<const lduInterface> primitiveInterfaces(0); + const lduSchedule ps(0); + + singleCellMeshPtr.reset + ( + new lduPrimitiveMesh + ( + nCells, + l, + u, + primitiveInterfaces, + ps, + singleCellMeshComm + ) + ); + } + return singleCellMeshPtr; +} + + +Foam::tmp<Foam::labelField> +Foam::procFacesGAMGProcAgglomeration::processorAgglomeration +( + const lduMesh& mesh +) const +{ + label singleCellMeshComm = UPstream::allocateCommunicator + ( + mesh.comm(), + labelList(1, 0) // only processor 0 + ); + + scalarField faceWeights; + autoPtr<lduPrimitiveMesh> singleCellMeshPtr + ( + singleCellMesh + ( + singleCellMeshComm, + mesh, + faceWeights + ) + ); + + tmp<labelField> tfineToCoarse(new labelField(0)); + labelField& fineToCoarse = tfineToCoarse(); + + if (singleCellMeshPtr.valid()) + { + // On master call the agglomerator + const lduPrimitiveMesh& singleCellMesh = singleCellMeshPtr(); + + label nCoarseProcs; + fineToCoarse = pairGAMGAgglomeration::agglomerate + ( + nCoarseProcs, + singleCellMesh, + faceWeights + ); + + labelList coarseToMaster(nCoarseProcs, labelMax); + forAll(fineToCoarse, cellI) + { + label coarseI = fineToCoarse[cellI]; + coarseToMaster[coarseI] = min(coarseToMaster[coarseI], cellI); + } + + // Sort according to master and redo restriction + labelList newToOld; + sortedOrder(coarseToMaster, newToOld); + labelList oldToNew(invert(newToOld.size(), newToOld)); + + fineToCoarse = UIndirectList<label>(oldToNew, fineToCoarse)(); + } + + Pstream::scatter(fineToCoarse, Pstream::msgType(), mesh.comm()); + UPstream::freeCommunicator(singleCellMeshComm); + + return tfineToCoarse; +} + + +bool Foam::procFacesGAMGProcAgglomeration::doProcessorAgglomeration +( + const lduMesh& mesh +) const +{ + // Check the need for further agglomeration on all processors + bool doAgg = mesh.lduAddr().size() < nAgglomeratingCells_; + mesh.reduce(doAgg, orOp<bool>()); + return doAgg; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::procFacesGAMGProcAgglomeration::procFacesGAMGProcAgglomeration +( + GAMGAgglomeration& agglom, + const dictionary& controlDict +) +: + GAMGProcAgglomeration(agglom, controlDict), + nAgglomeratingCells_(readLabel(controlDict.lookup("nAgglomeratingCells"))) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::procFacesGAMGProcAgglomeration::~procFacesGAMGProcAgglomeration() +{ + forAllReverse(comms_, i) + { + if (comms_[i] != -1) + { + UPstream::freeCommunicator(comms_[i]); + } + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::procFacesGAMGProcAgglomeration::agglomerate() +{ + if (debug) + { + Pout<< nl << "Starting mesh overview" << endl; + printStats(Pout, agglom_); + } + + if (agglom_.size() >= 1) + { + Random rndGen(0); + + for + ( + label fineLevelIndex = 2; + fineLevelIndex < agglom_.size(); + fineLevelIndex++ + ) + { + if (agglom_.hasMeshLevel(fineLevelIndex)) + { + // Get the fine mesh + const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex); + + label levelComm = levelMesh.comm(); + label nProcs = UPstream::nProcs(levelComm); + + if (nProcs > 1 && doProcessorAgglomeration(levelMesh)) + { + tmp<labelField> tprocAgglomMap + ( + processorAgglomeration(levelMesh) + ); + const labelField& procAgglomMap = tprocAgglomMap(); + + // Master processor + labelList masterProcs; + // Local processors that agglomerate. agglomProcIDs[0] is in + // masterProc. + List<int> agglomProcIDs; + GAMGAgglomeration::calculateRegionMaster + ( + levelComm, + procAgglomMap, + masterProcs, + agglomProcIDs + ); + + // Allocate a communicator for the processor-agglomerated + // matrix + comms_.append + ( + UPstream::allocateCommunicator + ( + levelComm, + masterProcs + ) + ); + + + // Use procesor agglomeration maps to do the actual + // collecting. + GAMGProcAgglomeration::agglomerate + ( + fineLevelIndex, + procAgglomMap, + masterProcs, + agglomProcIDs, + comms_.last() + ); + } + } + } + } + + // Print a bit + if (debug) + { + Pout<< nl << "Agglomerated mesh overview" << endl; + printStats(Pout, agglom_); + } + + return true; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/procFacesGAMGProcAgglomeration/procFacesGAMGProcAgglomeration.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/procFacesGAMGProcAgglomeration/procFacesGAMGProcAgglomeration.H new file mode 100644 index 0000000000000000000000000000000000000000..5c574c41581443413a67ee504ccb28d554643bd1 --- /dev/null +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/procFacesGAMGProcAgglomeration/procFacesGAMGProcAgglomeration.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::procFacesGAMGProcAgglomeration + +Description + Processor agglomeration of GAMGAgglomerations. Needs nAgglomeratingCells + which is when to start agglomerating processors. Processors get agglomerated + by constructing a single cell mesh for each processor with each + processor interface a face. This then gets agglomerated using + the pairGAMGAgglomeration algorithm with the number of faces + on the original processor interface as face weight. + +SourceFiles + procFacesGAMGProcAgglomeration.C + +\*---------------------------------------------------------------------------*/ + +#ifndef procFacesGAMGProcAgglomeration_H +#define procFacesGAMGProcAgglomeration_H + +#include "GAMGProcAgglomeration.H" +#include "DynamicList.H" +#include "labelField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class GAMGAgglomeration; +class lduMesh; +class lduPrimitiveMesh; + +/*---------------------------------------------------------------------------*\ + Class procFacesGAMGProcAgglomeration Declaration +\*---------------------------------------------------------------------------*/ + +class procFacesGAMGProcAgglomeration +: + public GAMGProcAgglomeration +{ + // Private data + + //- When to processor agglomerate + const label nAgglomeratingCells_; + + //- Allocated communicators + DynamicList<label> comms_; + + // Private Member Functions + + //- Return (on master) all single-cell meshes collected. single-cell + // meshes are just one cell with all proc faces intact. + autoPtr<lduPrimitiveMesh> singleCellMesh + ( + const label singleCellMeshComm, + const lduMesh& mesh, + scalarField& faceWeights + ) const; + + //- Construct processor agglomeration: for every processor the + // coarse processor-cluster it agglomerates onto + tmp<labelField> processorAgglomeration(const lduMesh&) const; + + //- Do we need to agglomerate across processors? + bool doProcessorAgglomeration(const lduMesh&) const; + + //- Disallow default bitwise copy construct + procFacesGAMGProcAgglomeration + ( + const procFacesGAMGProcAgglomeration& + ); + + //- Disallow default bitwise assignment + void operator=(const procFacesGAMGProcAgglomeration&); + + +public: + + //- Runtime type information + TypeName("procFaces"); + + + // Constructors + + //- Construct given agglomerator and controls + procFacesGAMGProcAgglomeration + ( + GAMGAgglomeration& agglom, + const dictionary& controlDict + ); + + + //- Destructor + virtual ~procFacesGAMGProcAgglomeration(); + + + // Member Functions + + //- Modify agglomeration. Return true if modified + virtual bool agglomerate(); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/memory/autoPtr/autoPtr.H b/src/OpenFOAM/memory/autoPtr/autoPtr.H index 7732ecc1cf6feba174e91036146b113e2878266e..0d5944128ef5760da6eda3d50fc93709d8e0202d 100644 --- a/src/OpenFOAM/memory/autoPtr/autoPtr.H +++ b/src/OpenFOAM/memory/autoPtr/autoPtr.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -67,6 +67,10 @@ public: // setting the arguments pointer to NULL inline autoPtr(const autoPtr<T>&); + //- Construct either by transfering pointer or cloning. Should + // only be called with type that supports cloning. + inline autoPtr(const autoPtr<T>&, const bool reUse); + //- Destructor, delete object if pointer is not NULL inline ~autoPtr(); diff --git a/src/OpenFOAM/memory/autoPtr/autoPtrI.H b/src/OpenFOAM/memory/autoPtr/autoPtrI.H index df7ea51d1af2d7c41c7f722eb05636ba1c7ff9a1..55e032fcd4548cebe3e8d99164ffc37e22d0e397 100644 --- a/src/OpenFOAM/memory/autoPtr/autoPtrI.H +++ b/src/OpenFOAM/memory/autoPtr/autoPtrI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "error.H" +#include <typeinfo> // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -43,6 +44,21 @@ inline Foam::autoPtr<T>::autoPtr(const autoPtr<T>& ap) } +template<class T> +inline Foam::autoPtr<T>::autoPtr(const autoPtr<T>& ap, const bool reUse) +{ + if (reUse) + { + ptr_ = ap.ptr_; + ap.ptr_ = 0; + } + else + { + ptr_ = ap().clone().ptr(); + } +} + + template<class T> inline Foam::autoPtr<T>::~autoPtr() { @@ -81,7 +97,8 @@ inline void Foam::autoPtr<T>::set(T* p) if (ptr_) { FatalErrorIn("void Foam::autoPtr<T>::set(T*)") - << "object already allocated" + << "object of type " << typeid(T).name() + << " already allocated" << abort(FatalError); } @@ -116,7 +133,8 @@ inline T& Foam::autoPtr<T>::operator()() if (!ptr_) { FatalErrorIn("T& Foam::autoPtr<T>::operator()()") - << "object is not allocated" + << "object of type " << typeid(T).name() + << " is not allocated" << abort(FatalError); } @@ -130,7 +148,8 @@ inline const T& Foam::autoPtr<T>::operator()() const if (!ptr_) { FatalErrorIn("const T& Foam::autoPtr<T>::operator()() const") - << "object is not allocated" + << "object of type " << typeid(T).name() + << " is not allocated" << abort(FatalError); } @@ -151,7 +170,8 @@ inline T* Foam::autoPtr<T>::operator->() if (!ptr_) { FatalErrorIn("Foam::autoPtr<T>::operator->()") - << "object is not allocated" + << "object of type " << typeid(T).name() + << " is not allocated" << abort(FatalError); } diff --git a/src/OpenFOAM/memory/tmp/tmpI.H b/src/OpenFOAM/memory/tmp/tmpI.H index c3a51f3564c1a916132f8bb4ea5156f39cceea92..ad34bb4b17fa6ce138653965689ae8af3e6db095 100644 --- a/src/OpenFOAM/memory/tmp/tmpI.H +++ b/src/OpenFOAM/memory/tmp/tmpI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "error.H" +#include <typeinfo> // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -62,6 +63,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t) { FatalErrorIn("Foam::tmp<T>::tmp(const tmp<T>&)") << "attempted copy of a deallocated temporary" + << " of type " << typeid(T).name() << abort(FatalError); } } @@ -93,6 +95,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer) ( "Foam::tmp<T>::tmp(const tmp<T>&, bool allowTransfer)" ) << "attempted copy of a deallocated temporary" + << " of type " << typeid(T).name() << abort(FatalError); } } @@ -149,7 +152,7 @@ inline T* Foam::tmp<T>::ptr() const if (!ptr_) { FatalErrorIn("Foam::tmp<T>::ptr() const") - << "temporary deallocated" + << "temporary of type " << typeid(T).name() << " deallocated" << abort(FatalError); } @@ -188,7 +191,7 @@ inline T& Foam::tmp<T>::operator()() if (!ptr_) { FatalErrorIn("T& Foam::tmp<T>::operator()()") - << "temporary deallocated" + << "temporary of type " << typeid(T).name() << " deallocated" << abort(FatalError); } @@ -217,7 +220,7 @@ inline const T& Foam::tmp<T>::operator()() const if (!ptr_) { FatalErrorIn("const T& Foam::tmp<T>::operator()() const") - << "temporary deallocated" + << "temporary of type " << typeid(T).name() << " deallocated" << abort(FatalError); } @@ -245,7 +248,7 @@ inline T* Foam::tmp<T>::operator->() if (!ptr_) { FatalErrorIn("Foam::tmp<T>::operator->()") - << "temporary deallocated" + << "temporary of type " << typeid(T).name() << " deallocated" << abort(FatalError); } @@ -294,6 +297,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t) { FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)") << "attempted copy of a deallocated temporary" + << " of type " << typeid(T).name() << abort(FatalError); } } @@ -301,6 +305,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t) { FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)") << "attempted to assign to a const reference to constant object" + << " of type " << typeid(T).name() << abort(FatalError); } } diff --git a/src/OpenFOAM/meshes/MeshObject/meshObject.C b/src/OpenFOAM/meshes/MeshObject/meshObject.C index 7130f38b5dfd738ff2d9ef9b4c6f2316dc24badd..a616f777b061eaa02b009d92ef261099af797905 100644 --- a/src/OpenFOAM/meshes/MeshObject/meshObject.C +++ b/src/OpenFOAM/meshes/MeshObject/meshObject.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.C b/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.C index 070edd4b6915dccf72887575c7f90201f3fee86d..507fc425efdb4f56f44dccf3eab0944779c4fc5b 100644 --- a/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.C +++ b/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.C @@ -254,7 +254,7 @@ Foam::lduPrimitiveMesh::lduPrimitiveMesh const label nCells, labelList& l, labelList& u, - const Xfer<PtrList<const lduInterface> >& primitiveInterfaces, + PtrList<const lduInterface>& primitiveInterfaces, const lduSchedule& ps, const label comm ) @@ -262,10 +262,12 @@ Foam::lduPrimitiveMesh::lduPrimitiveMesh lduAddressing(nCells), lowerAddr_(l, true), upperAddr_(u, true), - primitiveInterfaces_(primitiveInterfaces), + primitiveInterfaces_(0), patchSchedule_(ps), comm_(comm) { + primitiveInterfaces_.transfer(primitiveInterfaces); + // Create interfaces interfaces_.setSize(primitiveInterfaces_.size()); forAll(primitiveInterfaces_, i) diff --git a/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H b/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H index 66c26dc37ed5707167beb305f7a86f13360fc204..5bd7901c8bba004f307aae09f4bc1b49238650e2 100644 --- a/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H +++ b/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H @@ -133,7 +133,7 @@ public: const label nCells, labelList& l, labelList& u, - const Xfer<PtrList<const lduInterface> >& primitiveInterfaces, + PtrList<const lduInterface>& primitiveInterfaces, const lduSchedule& ps, const label comm ); diff --git a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C index c8ec20fff2c03ac53301d391839364f9851e7369..adddf9777c43811861e57aa8b5531144e4bd78cf 100644 --- a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C +++ b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -58,6 +58,12 @@ Foam::pointBoundaryMesh::pointBoundaryMesh // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +Foam::label Foam::pointBoundaryMesh::findPatchID(const word& patchName) const +{ + return mesh()().boundaryMesh().findPatchID(patchName); +} + + Foam::labelList Foam::pointBoundaryMesh::findIndices ( const keyType& key, diff --git a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H index afbc52c93f91d856be9f8262ca47147a3e05610d..f07b03ea9a0f4818830495a770623191040d0109 100644 --- a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H +++ b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -96,6 +96,9 @@ public: return mesh_; } + //- Find patch index given a name + label findPatchID(const word& patchName) const; + //- Find patch indices given a name labelList findIndices(const keyType&, const bool useGroups) const; diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshTools.C b/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshTools.C index 3af85508be1304af48032919b768bf6d95a80803..4945eb0b098d73b50721c055a6c9001fa10e10ed 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshTools.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshTools.C @@ -97,7 +97,6 @@ Foam::tmp<Foam::scalarField> Foam::polyMeshTools::faceSkewness { const labelList& own = mesh.faceOwner(); const labelList& nei = mesh.faceNeighbour(); - const faceList& fcs = mesh.faces(); const polyBoundaryMesh& pbm = mesh.boundaryMesh(); tmp<scalarField> tskew(new scalarField(mesh.nFaces())); @@ -154,31 +153,16 @@ Foam::tmp<Foam::scalarField> Foam::polyMeshTools::faceSkewness { label faceI = pp.start() + i; - vector Cpf = fCtrs[faceI] - cellCtrs[own[faceI]]; - - vector normal = fAreas[faceI]; - normal /= mag(normal) + VSMALL; - vector d = normal*(normal & Cpf); - - - // Skewness vector - vector sv = - Cpf - - ((fAreas[faceI] & Cpf)/((fAreas[faceI] & d) + VSMALL))*d; - vector svHat = sv/(mag(sv) + VSMALL); - - // Normalisation distance calculated as the approximate distance - // from the face centre to the edge of the face in the direction - // of the skewness - scalar fd = 0.4*mag(d) + VSMALL; - const face& f = fcs[faceI]; - forAll(f, pi) - { - fd = max(fd, mag(svHat & (p[f[pi]] - fCtrs[faceI]))); - } + skew[faceI] = primitiveMeshTools::boundaryFaceSkewness + ( + mesh, + p, + fCtrs, + fAreas, - // Normalised skewness - skew[faceI] = mag(sv)/fd; + faceI, + cellCtrs[own[faceI]] + ); } } } diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C index 515a78bbb82c6d236dbe67d45fb83368482bd648..8a29a7e06d72cf376730d4af9f16b6e3b9fd4a4b 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C +++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C @@ -54,14 +54,12 @@ Foam::processorPolyPatch::processorPolyPatch const label start, const label index, const polyBoundaryMesh& bm, - const label comm, const int myProcNo, const int neighbProcNo, const transformType transform ) : coupledPolyPatch(name, size, start, index, bm, typeName, transform), -// comm_(comm), myProcNo_(myProcNo), neighbProcNo_(neighbProcNo), neighbFaceCentres_(), @@ -80,10 +78,6 @@ Foam::processorPolyPatch::processorPolyPatch ) : coupledPolyPatch(name, dict, index, bm, patchType), -// comm_ -// ( -// dict.lookupOrDefault("communicator", UPstream::worldComm) -// ), myProcNo_(readLabel(dict.lookup("myProcNo"))), neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))), neighbFaceCentres_(), @@ -99,7 +93,6 @@ Foam::processorPolyPatch::processorPolyPatch ) : coupledPolyPatch(pp, bm), -// comm_(pp.comm_), myProcNo_(pp.myProcNo_), neighbProcNo_(pp.neighbProcNo_), neighbFaceCentres_(), @@ -118,7 +111,6 @@ Foam::processorPolyPatch::processorPolyPatch ) : coupledPolyPatch(pp, bm, index, newSize, newStart), -// comm_(pp.comm_), myProcNo_(pp.myProcNo_), neighbProcNo_(pp.neighbProcNo_), neighbFaceCentres_(), @@ -137,7 +129,6 @@ Foam::processorPolyPatch::processorPolyPatch ) : coupledPolyPatch(pp, bm, index, mapAddressing, newStart), -// comm_(pp.comm_), myProcNo_(pp.myProcNo_), neighbProcNo_(pp.neighbProcNo_), neighbFaceCentres_(), @@ -1091,11 +1082,6 @@ bool Foam::processorPolyPatch::order void Foam::processorPolyPatch::write(Ostream& os) const { coupledPolyPatch::write(os); -// if (comm_ != UPstream::worldComm) -// { -// os.writeKeyword("communicator") << comm_ -// << token::END_STATEMENT << nl; -// } os.writeKeyword("myProcNo") << myProcNo_ << token::END_STATEMENT << nl; os.writeKeyword("neighbProcNo") << neighbProcNo_ diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H index c5a6226dc89f895cc1811ca42b87057db27f68a1..6a3d202a4288f2a9c784f6c7e65372cae276557d 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H +++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H @@ -134,7 +134,6 @@ public: const label start, const label index, const polyBoundaryMesh& bm, - const label comm, const int myProcNo, const int neighbProcNo, const transformType transform = UNKNOWN // transformation type diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.C index fd8ed4d30f362925e69bdc0a15a9f79f9ee136d9..137339e631ee2d9c3153883b8f52430583e2fc70 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.C +++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.C @@ -46,7 +46,6 @@ Foam::processorCyclicPolyPatch::processorCyclicPolyPatch const label start, const label index, const polyBoundaryMesh& bm, - const label comm, const int myProcNo, const int neighbProcNo, const word& referPatchName, @@ -60,7 +59,6 @@ Foam::processorCyclicPolyPatch::processorCyclicPolyPatch start, index, bm, - comm, myProcNo, neighbProcNo, transform diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.H index 7f749b3286343e2112dd111f75e6b57be73a7720..76a833ba612e9adb0c77353c60913195e8fc853d 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.H +++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.H @@ -119,7 +119,6 @@ public: const label start, const label index, const polyBoundaryMesh& bm, - const label comm, const int myProcNo, const int neighbProcNo, const word& referPatchName, diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C index e94c8edbf77a1709d63377a11c6fb98e5765e067..241f4eef8ed91e131a37c6e5ae9288ac1087e8a1 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -64,6 +64,44 @@ Foam::scalar Foam::primitiveMeshTools::faceSkewness return mag(sv)/fd; } +Foam::scalar Foam::primitiveMeshTools::boundaryFaceSkewness +( + const primitiveMesh& mesh, + const pointField& p, + const vectorField& fCtrs, + const vectorField& fAreas, + + const label faceI, + const point& ownCc +) +{ + vector Cpf = fCtrs[faceI] - ownCc; + + vector normal = fAreas[faceI]; + normal /= mag(normal) + VSMALL; + vector d = normal*(normal & Cpf); + + + // Skewness vector + vector sv = + Cpf + - ((fAreas[faceI] & Cpf)/((fAreas[faceI] & d) + VSMALL))*d; + vector svHat = sv/(mag(sv) + VSMALL); + + // Normalisation distance calculated as the approximate distance + // from the face centre to the edge of the face in the direction + // of the skewness + scalar fd = 0.4*mag(d) + VSMALL; + const face& f = mesh.faces()[faceI]; + forAll(f, pi) + { + fd = max(fd, mag(svHat & (p[f[pi]] - fCtrs[faceI]))); + } + + // Normalised skewness + return mag(sv)/fd; +} + Foam::scalar Foam::primitiveMeshTools::faceOrthogonality ( @@ -119,7 +157,6 @@ Foam::tmp<Foam::scalarField> Foam::primitiveMeshTools::faceSkewness { const labelList& own = mesh.faceOwner(); const labelList& nei = mesh.faceNeighbour(); - const faceList& fcs = mesh.faces(); tmp<scalarField> tskew(new scalarField(mesh.nFaces())); scalarField& skew = tskew(); @@ -145,31 +182,15 @@ Foam::tmp<Foam::scalarField> Foam::primitiveMeshTools::faceSkewness for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) { - vector Cpf = fCtrs[faceI] - cellCtrs[own[faceI]]; - - vector normal = fAreas[faceI]; - normal /= mag(normal) + VSMALL; - vector d = normal*(normal & Cpf); - - - // Skewness vector - vector sv = - Cpf - - ((fAreas[faceI] & Cpf)/((fAreas[faceI] & d) + VSMALL))*d; - vector svHat = sv/(mag(sv) + VSMALL); - - // Normalisation distance calculated as the approximate distance - // from the face centre to the edge of the face in the direction - // of the skewness - scalar fd = 0.4*mag(d) + VSMALL; - const face& f = fcs[faceI]; - forAll(f, pi) - { - fd = max(fd, mag(svHat & (p[f[pi]] - fCtrs[faceI]))); - } - - // Normalised skewness - skew[faceI] = mag(sv)/fd; + skew[faceI] = boundaryFaceSkewness + ( + mesh, + p, + fCtrs, + fAreas, + faceI, + cellCtrs[own[faceI]] + ); } return tskew; diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H index 5e3b2c07fd4b03aaacab2f82fca09c83187e74c9..170d089e117a9be1831d5b0c00733919b0102a2d 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -48,32 +48,6 @@ namespace Foam class primitiveMeshTools { - -protected: - - // Protected Member Functions - - //- Skewness of single face - static scalar faceSkewness - ( - const primitiveMesh& mesh, - const pointField& p, - const vectorField& fCtrs, - const vectorField& fAreas, - - const label faceI, - const point& ownCc, - const point& neiCc - ); - - //- Orthogonality of single face - static scalar faceOrthogonality - ( - const point& ownCc, - const point& neiCc, - const vector& s - ); - public: //- Generate non-orthogonality field (internal faces only) @@ -154,6 +128,41 @@ public: const PackedBoolList& internalOrCoupledFace ); + + // Helpers: single face check + + //- Skewness of single face + static scalar faceSkewness + ( + const primitiveMesh& mesh, + const pointField& p, + const vectorField& fCtrs, + const vectorField& fAreas, + + const label faceI, + const point& ownCc, + const point& neiCc + ); + + //- Skewness of single boundary face + static scalar boundaryFaceSkewness + ( + const primitiveMesh& mesh, + const pointField& p, + const vectorField& fCtrs, + const vectorField& fAreas, + + const label faceI, + const point& ownCc + ); + + //- Orthogonality of single face + static scalar faceOrthogonality + ( + const point& ownCc, + const point& neiCc, + const vector& s + ); }; diff --git a/src/OpenFOAM/primitives/functions/DataEntry/DataEntry/DataEntry.H b/src/OpenFOAM/primitives/functions/DataEntry/DataEntry/DataEntry.H index 9cfdb66e2560d1cdd9396a645b692907a8cf0d6a..a9b1686d5871a1193c4eed0d3414e664cfcb20f1 100644 --- a/src/OpenFOAM/primitives/functions/DataEntry/DataEntry/DataEntry.H +++ b/src/OpenFOAM/primitives/functions/DataEntry/DataEntry/DataEntry.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -142,62 +142,60 @@ public: virtual void convertTimeBase(const Time& t); -public: - + // Evaluation - // Evaluation + //- Return value as a function of (scalar) independent variable + virtual Type value(const scalar x) const; - //- Return value as a function of (scalar) independent variable - virtual Type value(const scalar x) const; + //- Return value as a function of (scalar) independent variable + virtual tmp<Field<Type> > value(const scalarField& x) const; - //- Return value as a function of (scalar) independent variable - virtual tmp<Field<Type> > value(const scalarField& x) const; + //- Integrate between two (scalar) values + virtual Type integrate(const scalar x1, const scalar x2) const; - //- Integrate between two (scalar) values - virtual Type integrate(const scalar x1, const scalar x2) const; - - //- Integrate between two (scalar) values - virtual tmp<Field<Type> > integrate - ( - const scalarField& x1, - const scalarField& x2 - ) const; + //- Integrate between two (scalar) values + virtual tmp<Field<Type> > integrate + ( + const scalarField& x1, + const scalarField& x2 + ) const; - //- Return dimensioned type - virtual dimensioned<Type> dimValue(const scalar x) const; + //- Return dimensioned type + virtual dimensioned<Type> dimValue(const scalar x) const; - //- Return dimensioned type as a function of (scalar) - virtual tmp<Field<dimensioned<Type> > > dimValue - ( - const scalarField& x - ) const; + //- Return dimensioned type as a function of (scalar) + virtual tmp<Field<dimensioned<Type> > > dimValue + ( + const scalarField& x + ) const; - //- Integrate between two scalars and returns a dimensioned type - virtual dimensioned<Type> dimIntegrate - ( - const scalar x1, - const scalar x2 - ) const; + //- Integrate between two scalars and return a dimensioned type + virtual dimensioned<Type> dimIntegrate + ( + const scalar x1, + const scalar x2 + ) const; - //- Integrate between two scalars and returns list of dimensioned type - virtual tmp<Field<dimensioned<Type> > > dimIntegrate - ( - const scalarField& x1, - const scalarField& x2 - ) const; + //- Integrate between two scalar fields and return a field of + // dimensioned type + virtual tmp<Field<dimensioned<Type> > > dimIntegrate + ( + const scalarField& x1, + const scalarField& x2 + ) const; - // I/O + // I/O - //- Ostream Operator - friend Ostream& operator<< <Type> - ( - Ostream& os, - const DataEntry<Type>& de - ); + //- Ostream Operator + friend Ostream& operator<< <Type> + ( + Ostream& os, + const DataEntry<Type>& de + ); - //- Write in dictionary format - virtual void writeData(Ostream& os) const; + //- Write in dictionary format + virtual void writeData(Ostream& os) const; }; diff --git a/src/OpenFOAM/primitives/strings/word/wordIOList.C b/src/OpenFOAM/primitives/strings/word/wordIOList.C index ede987af5323b7779464e7d2c2f349fcd0f7eb47..58456cb0ac963baaebd098d6715eb98f2d431744 100644 --- a/src/OpenFOAM/primitives/strings/word/wordIOList.C +++ b/src/OpenFOAM/primitives/strings/word/wordIOList.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -38,12 +38,17 @@ namespace Foam } -void Foam::printTable(const List<wordList>& wll, Ostream& os) +void Foam::printTable +( + const List<wordList>& wll, + List<string::size_type>& columnWidth, + Ostream& os +) { if (!wll.size()) return; // Find the maximum word length for each column - List<string::size_type> columnWidth(wll[0].size(), string::size_type(0)); + columnWidth.setSize(wll[0].size(), string::size_type(0)); forAll(columnWidth, j) { forAll(wll, i) @@ -75,4 +80,11 @@ void Foam::printTable(const List<wordList>& wll, Ostream& os) } +void Foam::printTable(const List<wordList>& wll, Ostream& os) +{ + List<string::size_type> columnWidth; + printTable(wll, columnWidth, os); +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/word/wordIOList.H b/src/OpenFOAM/primitives/strings/word/wordIOList.H index c560a33a9564c88d834a5d90831183c6253f9aa1..da9d5aa426a57da3a1c152fb10bb847adb67c4e7 100644 --- a/src/OpenFOAM/primitives/strings/word/wordIOList.H +++ b/src/OpenFOAM/primitives/strings/word/wordIOList.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,6 +43,7 @@ namespace Foam typedef IOList<wordList> wordListIOList; // Print word list list as a table + void printTable(const List<wordList>&, List<string::size_type>&, Ostream&); void printTable(const List<wordList>&, Ostream&); } diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C index f6e8bc02dc20c8eed379bcbab9f74d2054719b19..61cc9986a8f5eaf38542f1cd69f6858957bda839 100644 --- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C +++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C @@ -945,7 +945,6 @@ void Foam::fvMeshDistribute::addProcPatches mesh_.nFaces(), mesh_.boundaryMesh().size(), mesh_.boundaryMesh(), - Pstream::worldComm, Pstream::myProcNo(), nbrProc[bFaceI] ); @@ -989,7 +988,6 @@ void Foam::fvMeshDistribute::addProcPatches mesh_.nFaces(), mesh_.boundaryMesh().size(), mesh_.boundaryMesh(), - Pstream::worldComm, Pstream::myProcNo(), nbrProc[bFaceI], cycName, diff --git a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C index 77ce89ca71e2a7d238d973b5af6c13a766a59b37..3efb62a995ae9f66cb46e096950f17a0869c9957 100644 --- a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C +++ b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -239,6 +239,7 @@ bool Foam::motionSmoother::checkMesh maxIntSkew, maxBounSkew, mesh, + mesh.points(), mesh.cellCentres(), mesh.faceCentres(), mesh.faceAreas(), @@ -481,14 +482,14 @@ bool Foam::motionSmoother::checkMesh ( readScalar(dict.lookup("minArea", true)) ); - const scalar maxIntSkew - ( - readScalar(dict.lookup("maxInternalSkewness", true)) - ); - const scalar maxBounSkew - ( - readScalar(dict.lookup("maxBoundarySkewness", true)) - ); + //const scalar maxIntSkew + //( + // readScalar(dict.lookup("maxInternalSkewness", true)) + //); + //const scalar maxBounSkew + //( + // readScalar(dict.lookup("maxBoundarySkewness", true)) + //); const scalar minWeight ( readScalar(dict.lookup("minFaceWeight", true)) @@ -615,27 +616,30 @@ bool Foam::motionSmoother::checkMesh nWrongFaces = nNewWrongFaces; } - if (maxIntSkew > 0 || maxBounSkew > 0) - { - meshGeom.checkFaceSkewness - ( - report, - maxIntSkew, - maxBounSkew, - checkFaces, - baffles, - &wrongFaces - ); - - label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>()); - - Info<< " faces with skewness > " - << setw(3) << maxIntSkew - << " (internal) or " << setw(3) << maxBounSkew - << " (boundary) : " << nNewWrongFaces-nWrongFaces << endl; - nWrongFaces = nNewWrongFaces; - } + //- Note: cannot check the skewness without the points and don't want + // to store them on polyMeshGeometry. + //if (maxIntSkew > 0 || maxBounSkew > 0) + //{ + // meshGeom.checkFaceSkewness + // ( + // report, + // maxIntSkew, + // maxBounSkew, + // checkFaces, + // baffles, + // &wrongFaces + // ); + // + // label nNewWrongFaces = returnReduce(wrongFaces.size(),sumOp<label>()); + // + // Info<< " faces with skewness > " + // << setw(3) << maxIntSkew + // << " (internal) or " << setw(3) << maxBounSkew + // << " (boundary) : " << nNewWrongFaces-nWrongFaces << endl; + // + // nWrongFaces = nNewWrongFaces; + //} if (minWeight >= 0 && minWeight < 1) { diff --git a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C index d3b69d392f391a8d554d3557d677b006a3d8902e..57725dc57c95aaf24cabc25133b7a70b9b110afb 100644 --- a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C +++ b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C @@ -29,6 +29,7 @@ License #include "tetrahedron.H" #include "syncTools.H" #include "unitConversion.H" +#include "primitiveMeshTools.H" namespace Foam { @@ -286,29 +287,6 @@ Foam::scalar Foam::polyMeshGeometry::checkNonOrtho } -Foam::scalar Foam::polyMeshGeometry::calcSkewness -( - const point& ownCc, - const point& neiCc, - const point& fc -) -{ - scalar dOwn = mag(fc - ownCc); - scalar dNei = mag(fc - neiCc); - - point faceIntersection = - ownCc*dNei/(dOwn+dNei+VSMALL) - + neiCc*dOwn/(dOwn+dNei+VSMALL); - - return - mag(fc - faceIntersection) - / ( - mag(neiCc-ownCc) - + VSMALL - ); -} - - // Create the neighbour pyramid - it will have positive volume bool Foam::polyMeshGeometry::checkFaceTet ( @@ -1008,6 +986,7 @@ bool Foam::polyMeshGeometry::checkFaceSkewness const scalar internalSkew, const scalar boundarySkew, const polyMesh& mesh, + const pointField& points, const vectorField& cellCentres, const vectorField& faceCentres, const vectorField& faceAreas, @@ -1024,14 +1003,8 @@ bool Foam::polyMeshGeometry::checkFaceSkewness const polyBoundaryMesh& patches = mesh.boundaryMesh(); // Calculate coupled cell centre - pointField neiCc(mesh.nFaces()-mesh.nInternalFaces()); - - for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) - { - neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]]; - } - syncTools::swapBoundaryFacePositions(mesh, neiCc); - + pointField neiCc; + syncTools::swapBoundaryCellPositions(mesh, cellCentres, neiCc); scalar maxSkew = 0; @@ -1043,11 +1016,16 @@ bool Foam::polyMeshGeometry::checkFaceSkewness if (mesh.isInternalFace(faceI)) { - scalar skewness = calcSkewness + scalar skewness = primitiveMeshTools::faceSkewness ( + mesh, + points, + faceCentres, + faceAreas, + + faceI, cellCentres[own[faceI]], - cellCentres[nei[faceI]], - faceCentres[faceI] + cellCentres[nei[faceI]] ); // Check if the skewness vector is greater than the PN vector. @@ -1073,11 +1051,16 @@ bool Foam::polyMeshGeometry::checkFaceSkewness } else if (patches[patches.whichPatch(faceI)].coupled()) { - scalar skewness = calcSkewness + scalar skewness = primitiveMeshTools::faceSkewness ( + mesh, + points, + faceCentres, + faceAreas, + + faceI, cellCentres[own[faceI]], - neiCc[faceI-mesh.nInternalFaces()], - faceCentres[faceI] + neiCc[faceI-mesh.nInternalFaces()] ); // Check if the skewness vector is greater than the PN vector. @@ -1103,21 +1086,17 @@ bool Foam::polyMeshGeometry::checkFaceSkewness } else { - // Boundary faces: consider them to have only skewness error. - // (i.e. treat as if mirror cell on other side) - - vector faceNormal = faceAreas[faceI]; - faceNormal /= mag(faceNormal) + ROOTVSMALL; - - vector dOwn = faceCentres[faceI] - cellCentres[own[faceI]]; - - vector dWall = faceNormal*(faceNormal & dOwn); + scalar skewness = primitiveMeshTools::boundaryFaceSkewness + ( + mesh, + points, + faceCentres, + faceAreas, - point faceIntersection = cellCentres[own[faceI]] + dWall; + faceI, + cellCentres[own[faceI]] + ); - scalar skewness = - mag(faceCentres[faceI] - faceIntersection) - /(2*mag(dWall) + ROOTVSMALL); // Check if the skewness vector is greater than the PN vector. // This does not cause trouble but is a good indication of a poor @@ -1148,12 +1127,18 @@ bool Foam::polyMeshGeometry::checkFaceSkewness label face1 = baffles[i].second(); const point& ownCc = cellCentres[own[face0]]; + const point& neiCc = cellCentres[own[face1]]; - scalar skewness = calcSkewness + scalar skewness = primitiveMeshTools::faceSkewness ( + mesh, + points, + faceCentres, + faceAreas, + + face0, ownCc, - cellCentres[own[face1]], - faceCentres[face0] + neiCc ); // Check if the skewness vector is greater than the PN vector. @@ -2361,30 +2346,30 @@ bool Foam::polyMeshGeometry::checkFaceTets } -bool Foam::polyMeshGeometry::checkFaceSkewness -( - const bool report, - const scalar internalSkew, - const scalar boundarySkew, - const labelList& checkFaces, - const List<labelPair>& baffles, - labelHashSet* setPtr -) const -{ - return checkFaceSkewness - ( - report, - internalSkew, - boundarySkew, - mesh_, - cellCentres_, - faceCentres_, - faceAreas_, - checkFaces, - baffles, - setPtr - ); -} +//bool Foam::polyMeshGeometry::checkFaceSkewness +//( +// const bool report, +// const scalar internalSkew, +// const scalar boundarySkew, +// const labelList& checkFaces, +// const List<labelPair>& baffles, +// labelHashSet* setPtr +//) const +//{ +// return checkFaceSkewness +// ( +// report, +// internalSkew, +// boundarySkew, +// mesh_, +// cellCentres_, +// faceCentres_, +// faceAreas_, +// checkFaces, +// baffles, +// setPtr +// ); +//} bool Foam::polyMeshGeometry::checkFaceWeights diff --git a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H index 2ef8604cac8714a45711323d82f2cbc4f475d574..405564a175273efd8d273725ef121558bc816f60 100644 --- a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H +++ b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -229,6 +229,7 @@ public: const scalar internalSkew, const scalar boundarySkew, const polyMesh& mesh, + const pointField& points, const vectorField& cellCentres, const vectorField& faceCentres, const vectorField& faceAreas, @@ -372,16 +373,6 @@ public: labelHashSet* setPtr ) const; - bool checkFaceSkewness - ( - const bool report, - const scalar internalSkew, - const scalar boundarySkew, - const labelList& checkFaces, - const List<labelPair>& baffles, - labelHashSet* setPtr - ) const; - bool checkFaceWeights ( const bool report, diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 35a308ff000e995d632460df6f2b26885522fcba..7316c116cbacc1036f01dc72646297596e93cff1 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -18,6 +18,7 @@ $(basicFvPatches)/generic/genericFvPatch.C constraintFvPatches = $(fvPatches)/constraint $(constraintFvPatches)/cyclic/cyclicFvPatch.C $(constraintFvPatches)/cyclicAMI/cyclicAMIFvPatch.C +$(constraintFvPatches)/cyclicACMI/cyclicACMIFvPatch.C $(constraintFvPatches)/cyclicSlip/cyclicSlipFvPatch.C $(constraintFvPatches)/empty/emptyFvPatch.C $(constraintFvPatches)/nonuniformTransformCyclic/nonuniformTransformCyclicFvPatch.C @@ -109,6 +110,7 @@ $(basicFvPatchFields)/zeroGradient/zeroGradientFvPatchFields.C constraintFvPatchFields = $(fvPatchFields)/constraint $(constraintFvPatchFields)/cyclic/cyclicFvPatchFields.C $(constraintFvPatchFields)/cyclicAMI/cyclicAMIFvPatchFields.C +$(constraintFvPatchFields)/cyclicACMI/cyclicACMIFvPatchFields.C $(constraintFvPatchFields)/cyclicSlip/cyclicSlipFvPatchFields.C $(constraintFvPatchFields)/empty/emptyFvPatchFields.C $(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C @@ -203,6 +205,7 @@ $(basicFvsPatchFields)/sliced/slicedFvsPatchFields.C constraintFvsPatchFields = $(fvsPatchFields)/constraint $(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C $(constraintFvsPatchFields)/cyclicAMI/cyclicAMIFvsPatchFields.C +$(constraintFvsPatchFields)/cyclicACMI/cyclicACMIFvsPatchFields.C $(constraintFvsPatchFields)/cyclicSlip/cyclicSlipFvsPatchFields.C $(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C $(constraintFvsPatchFields)/nonuniformTransformCyclic/nonuniformTransformCyclicFvsPatchFields.C diff --git a/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C b/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C index 206e7c4e95e5da9ce5e12b583d9a8e8175f12330..27622aeeb7795ba7b9c3fe67c93e34ad7d28c8fe 100644 --- a/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C +++ b/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -56,11 +56,7 @@ bool Foam::adjustPhi if (!isA<processorFvsPatchScalarField>(phip)) { - if - ( - Up.fixesValue() - && !isA<inletOutletFvPatchVectorField>(Up) - ) + if (Up.fixesValue() && !isA<inletOutletFvPatchVectorField>(Up)) { forAll(phip, i) { @@ -113,8 +109,12 @@ bool Foam::adjustPhi { FatalErrorIn ( - "adjustPhi(surfaceScalarField& phi, const volVectorField& U," - "const volScalarField& p" + "adjustPhi" + "(" + "surfaceScalarField&, " + "const volVectorField&," + "volScalarField&" + ")" ) << "Continuity error cannot be removed by adjusting the" " outflow.\nPlease check the velocity boundary conditions" " and/or run potentialFoam to initialise the outflow." << nl diff --git a/src/finiteVolume/cfdTools/general/porosityModel/DarcyForchheimer/DarcyForchheimer.C b/src/finiteVolume/cfdTools/general/porosityModel/DarcyForchheimer/DarcyForchheimer.C index 472fc4019b8c0b0561fd8dbe5cb83980424827fc..4fb8d7f212463254c073e922b9f7c901ff9f038f 100644 --- a/src/finiteVolume/cfdTools/general/porosityModel/DarcyForchheimer/DarcyForchheimer.C +++ b/src/finiteVolume/cfdTools/general/porosityModel/DarcyForchheimer/DarcyForchheimer.C @@ -130,8 +130,8 @@ void Foam::porosityModels::DarcyForchheimer::calcForce vectorField& force ) const { - scalarField Udiag(U.size()); - vectorField Usource(U.size()); + scalarField Udiag(U.size(), 0.0); + vectorField Usource(U.size(), vector::zero); const scalarField& V = mesh_.V(); apply(Udiag, Usource, V, rho, mu, U); diff --git a/src/finiteVolume/cfdTools/general/porosityModel/fixedCoeff/fixedCoeff.C b/src/finiteVolume/cfdTools/general/porosityModel/fixedCoeff/fixedCoeff.C index ee19f0dc45a49c58baa2d1c063bcb04c535ee302..bb7c3c9d7ecbf08b29e7b9c62053a71ffb5e98e0 100644 --- a/src/finiteVolume/cfdTools/general/porosityModel/fixedCoeff/fixedCoeff.C +++ b/src/finiteVolume/cfdTools/general/porosityModel/fixedCoeff/fixedCoeff.C @@ -183,8 +183,8 @@ void Foam::porosityModels::fixedCoeff::calcForce vectorField& force ) const { - scalarField Udiag(U.size()); - vectorField Usource(U.size()); + scalarField Udiag(U.size(), 0.0); + vectorField Usource(U.size(), vector::zero); const scalarField& V = mesh_.V(); scalar rhoRef = readScalar(coeffs_.lookup("rhoRef")); diff --git a/src/finiteVolume/cfdTools/general/porosityModel/porosityModel/porosityModel.C b/src/finiteVolume/cfdTools/general/porosityModel/porosityModel/porosityModel.C index ad83fb0cdab635de3a957475842aebcae8952576..738f87d0a86506bbd13622545308f3ac2467d34a 100644 --- a/src/finiteVolume/cfdTools/general/porosityModel/porosityModel/porosityModel.C +++ b/src/finiteVolume/cfdTools/general/porosityModel/porosityModel/porosityModel.C @@ -155,7 +155,7 @@ Foam::tmp<Foam::vectorField> Foam::porosityModel::porosityModel::force } -void Foam::porosityModel::porosityModel::addResistance +void Foam::porosityModel::addResistance ( fvVectorMatrix& UEqn ) const @@ -169,7 +169,7 @@ void Foam::porosityModel::porosityModel::addResistance } -void Foam::porosityModel::porosityModel::addResistance +void Foam::porosityModel::addResistance ( fvVectorMatrix& UEqn, const volScalarField& rho, @@ -185,7 +185,7 @@ void Foam::porosityModel::porosityModel::addResistance } -void Foam::porosityModel::porosityModel::addResistance +void Foam::porosityModel::addResistance ( const fvVectorMatrix& UEqn, volTensorField& AU, @@ -209,14 +209,14 @@ void Foam::porosityModel::porosityModel::addResistance } -bool Foam::porosityModel::porosityModel::movePoints() +bool Foam::porosityModel::movePoints() { // no updates necessary; all member data independent of mesh return true; } -void Foam::porosityModel::porosityModel::updateMesh(const mapPolyMesh& mpm) +void Foam::porosityModel::updateMesh(const mapPolyMesh& mpm) { // no updates necessary; all member data independent of mesh } diff --git a/src/finiteVolume/cfdTools/general/porosityModel/powerLaw/powerLaw.C b/src/finiteVolume/cfdTools/general/porosityModel/powerLaw/powerLaw.C index ee3157e43e9f3c2e730c0d1ec6eed9bc92505150..ae9d5641e436acfef7260fa063fede226d6a43c1 100644 --- a/src/finiteVolume/cfdTools/general/porosityModel/powerLaw/powerLaw.C +++ b/src/finiteVolume/cfdTools/general/porosityModel/powerLaw/powerLaw.C @@ -74,7 +74,7 @@ void Foam::porosityModels::powerLaw::calcForce vectorField& force ) const { - scalarField Udiag(U.size()); + scalarField Udiag(U.size(), 0.0); const scalarField& V = mesh_.V(); apply(Udiag, V, rho, U); diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C new file mode 100644 index 0000000000000000000000000000000000000000..905a565b0af131b6dcce71557470e1c15a212181 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C @@ -0,0 +1,411 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIFvPatchField.H" +#include "transformField.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class Type> +Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField +( + const fvPatch& p, + const DimensionedField<Type, volMesh>& iF +) +: + cyclicACMILduInterfaceField(), + coupledFvPatchField<Type>(p, iF), + cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p)) +{} + + +template<class Type> +Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField +( + const cyclicACMIFvPatchField<Type>& ptf, + const fvPatch& p, + const DimensionedField<Type, volMesh>& iF, + const fvPatchFieldMapper& mapper +) +: + cyclicACMILduInterfaceField(), + coupledFvPatchField<Type>(ptf, p, iF, mapper), + cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p)) +{ + if (!isA<cyclicACMIFvPatch>(this->patch())) + { + FatalErrorIn + ( + "cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField" + "(" + "const cyclicACMIFvPatchField<Type>& ," + "const fvPatch&, " + "const DimensionedField<Type, volMesh>&, " + "const fvPatchFieldMapper&" + ")" + ) << " patch type '" << p.type() + << "' not constraint type '" << typeName << "'" + << "\n for patch " << p.name() + << " of field " << this->dimensionedInternalField().name() + << " in file " << this->dimensionedInternalField().objectPath() + << exit(FatalIOError); + } +} + + +template<class Type> +Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField +( + const fvPatch& p, + const DimensionedField<Type, volMesh>& iF, + const dictionary& dict +) +: + cyclicACMILduInterfaceField(), + coupledFvPatchField<Type>(p, iF, dict), + cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p)) +{ + if (!isA<cyclicACMIFvPatch>(p)) + { + FatalIOErrorIn + ( + "cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField" + "(" + "const fvPatch&, " + "const DimensionedField<Type, volMesh>&, " + "const dictionary&" + ")", + dict + ) << " patch type '" << p.type() + << "' not constraint type '" << typeName << "'" + << "\n for patch " << p.name() + << " of field " << this->dimensionedInternalField().name() + << " in file " << this->dimensionedInternalField().objectPath() + << exit(FatalIOError); + } + + if (!dict.found("value") && this->coupled()) + { + this->evaluate(Pstream::blocking); + } +} + + +template<class Type> +Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField +( + const cyclicACMIFvPatchField<Type>& ptf +) +: + cyclicACMILduInterfaceField(), + coupledFvPatchField<Type>(ptf), + cyclicACMIPatch_(ptf.cyclicACMIPatch_) +{} + + +template<class Type> +Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField +( + const cyclicACMIFvPatchField<Type>& ptf, + const DimensionedField<Type, volMesh>& iF +) +: + cyclicACMILduInterfaceField(), + coupledFvPatchField<Type>(ptf, iF), + cyclicACMIPatch_(ptf.cyclicACMIPatch_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +bool Foam::cyclicACMIFvPatchField<Type>::coupled() const +{ + return cyclicACMIPatch_.coupled(); +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField() const +{ + const Field<Type>& iField = this->internalField(); + const labelUList& nbrFaceCellsCoupled = + cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells(); + const labelUList& nbrFaceCellsNonOverlap = + cyclicACMIPatch_.cyclicACMIPatch().nonOverlapPatch().faceCells(); + + Field<Type> pnfCoupled(iField, nbrFaceCellsCoupled); + Field<Type> pnfNonOverlap(iField, nbrFaceCellsNonOverlap); + + tmp<Field<Type> > tpnf + ( + new Field<Type> + ( + cyclicACMIPatch_.interpolate + ( + pnfCoupled, + pnfNonOverlap + ) + ) + ); + + if (doTransform()) + { + tpnf() = transform(forwardT(), tpnf()); + } + + return tpnf; +} + + +template<class Type> +const Foam::cyclicACMIFvPatchField<Type>& +Foam::cyclicACMIFvPatchField<Type>::neighbourPatchField() const +{ + const GeometricField<Type, fvPatchField, volMesh>& fld = + static_cast<const GeometricField<Type, fvPatchField, volMesh>&> + ( + this->internalField() + ); + + return refCast<const cyclicACMIFvPatchField<Type> > + ( + fld.boundaryField()[cyclicACMIPatch_.neighbPatchID()] + ); +} + + +template<class Type> +const Foam::fvPatchField<Type>& +Foam::cyclicACMIFvPatchField<Type>::nonOverlapPatchField() const +{ + const GeometricField<Type, fvPatchField, volMesh>& fld = + static_cast<const GeometricField<Type, fvPatchField, volMesh>&> + ( + this->internalField() + ); + + return fld.boundaryField()[cyclicACMIPatch_.nonOverlapPatchID()]; +} + + +template<class Type> +void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix +( + scalarField& result, + const scalarField& psiInternal, + const scalarField& coeffs, + const direction cmpt, + const Pstream::commsTypes +) const +{ + // note: only applying coupled contribution + + const labelUList& nbrFaceCellsCoupled = + cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells(); + + scalarField pnf(psiInternal, nbrFaceCellsCoupled); + + // Transform according to the transformation tensors + transformCoupleField(pnf, cmpt); + + const labelUList& faceCells = cyclicACMIPatch_.faceCells(); + + pnf = cyclicACMIPatch_.interpolate(pnf); + + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + } +} + + +template<class Type> +void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix +( + Field<Type>& result, + const Field<Type>& psiInternal, + const scalarField& coeffs, + const Pstream::commsTypes +) const +{ + // note: only applying coupled contribution + + const labelUList& nbrFaceCellsCoupled = + cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells(); + + Field<Type> pnf(psiInternal, nbrFaceCellsCoupled); + + // Transform according to the transformation tensors + transformCoupleField(pnf); + + const labelUList& faceCells = cyclicACMIPatch_.faceCells(); + + pnf = cyclicACMIPatch_.interpolate(pnf); + + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + } +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > Foam::cyclicACMIFvPatchField<Type>::snGrad +( + const scalarField& deltaCoeffs +) const +{ + // note: only applying coupled contribution + return coupledFvPatchField<Type>::snGrad(deltaCoeffs); +} + + +template<class Type> +void Foam::cyclicACMIFvPatchField<Type>::updateCoeffs() +{ + const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask(); + + const fvPatchField<Type>& npf = nonOverlapPatchField(); + const_cast<fvPatchField<Type>&>(npf).updateCoeffs(mask); +} + + +template<class Type> +void Foam::cyclicACMIFvPatchField<Type>::evaluate +( + const Pstream::commsTypes comms +) +{ + // blend contrubutions from the coupled and non-overlap patches + const fvPatchField<Type>& npf = nonOverlapPatchField(); + const_cast<fvPatchField<Type>&>(npf).evaluate(); + + coupledFvPatchField<Type>::evaluate(comms); + const Field<Type>& cpf = *this; + + const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask(); + Field<Type>::operator=(mask*cpf + (1.0 - mask)*npf); + + fvPatchField<Type>::evaluate(); +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::cyclicACMIFvPatchField<Type>::valueInternalCoeffs +( + const tmp<scalarField>& w +) const +{ + // note: do not blend based on mask field + // - when applied this is scaled by the areas which area already scaled + return coupledFvPatchField<Type>::valueInternalCoeffs(w); +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::cyclicACMIFvPatchField<Type>::valueBoundaryCoeffs +( + const tmp<scalarField>& w +) const +{ + // note: do not blend based on mask field + // - when applied this is scaled by the areas which area already scaled + return coupledFvPatchField<Type>::valueBoundaryCoeffs(w); +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs +( + const scalarField& deltaCoeffs +) const +{ + // note: do not blend based on mask field + // - when applied this is scaled by the areas which area already scaled + return coupledFvPatchField<Type>::gradientInternalCoeffs(deltaCoeffs); +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs() const +{ + // note: do not blend based on mask field + // - when applied this is scaled by the areas which area already scaled + return coupledFvPatchField<Type>::gradientInternalCoeffs(); +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs +( + const scalarField& deltaCoeffs +) const +{ + // note: do not blend based on mask field + // - when applied this is scaled by the areas which area already scaled + return coupledFvPatchField<Type>::gradientBoundaryCoeffs(deltaCoeffs); +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > +Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs() const +{ + // note: do not blend based on mask field + // - when applied this is scaled by the areas which area already scaled + return coupledFvPatchField<Type>::gradientBoundaryCoeffs(); +} + + +template<class Type> +void Foam::cyclicACMIFvPatchField<Type>::manipulateMatrix +( + fvMatrix<Type>& matrix +) +{ + // blend contrubutions from the coupled and non-overlap patches + const fvPatchField<Type>& npf = nonOverlapPatchField(); + + const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask(); + const_cast<fvPatchField<Type>&>(npf).manipulateMatrix(matrix, mask); +} + + +template<class Type> +void Foam::cyclicACMIFvPatchField<Type>::write(Ostream& os) const +{ + fvPatchField<Type>::write(os); + this->writeEntry("value", os); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H new file mode 100644 index 0000000000000000000000000000000000000000..91f414d32117f5f583db05c7ef3f8b83ed98e7a0 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H @@ -0,0 +1,304 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIFvPatchField + +Group + grpCoupledBoundaryConditions + +Description + This boundary condition enforces a cyclic condition between a pair of + boundaries, whereby communication between the patches is performed using + an arbitrarily coupled mesh interface (ACMI) interpolation. + + \heading Patch usage + + Example of the boundary condition specification: + \verbatim + myPatch + { + type cyclicACMI; + } + \endverbatim + +SeeAlso + Foam::AMIInterpolation + +SourceFiles + cyclicACMIFvPatchField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIFvPatchField_H +#define cyclicACMIFvPatchField_H + +#include "coupledFvPatchField.H" +#include "cyclicACMILduInterfaceField.H" +#include "cyclicACMIFvPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIFvPatchField Declaration +\*---------------------------------------------------------------------------*/ + +template<class Type> +class cyclicACMIFvPatchField +: + virtual public cyclicACMILduInterfaceField, + public coupledFvPatchField<Type> +{ + // Private data + + //- Local reference cast into the cyclic patch + const cyclicACMIFvPatch& cyclicACMIPatch_; + + + // Private Member Functions + + //- Return neighbour side field given internal fields + template<class Type2> + tmp<Field<Type2> > neighbourSideField + ( + const Field<Type2>& + ) const; + + +public: + + //- Runtime type information + TypeName(cyclicACMIFvPatch::typeName_()); + + + // Constructors + + //- Construct from patch and internal field + cyclicACMIFvPatchField + ( + const fvPatch&, + const DimensionedField<Type, volMesh>& + ); + + //- Construct from patch, internal field and dictionary + cyclicACMIFvPatchField + ( + const fvPatch&, + const DimensionedField<Type, volMesh>&, + const dictionary& + ); + + //- Construct by mapping given cyclicACMIFvPatchField onto a new patch + cyclicACMIFvPatchField + ( + const cyclicACMIFvPatchField<Type>&, + const fvPatch&, + const DimensionedField<Type, volMesh>&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + cyclicACMIFvPatchField(const cyclicACMIFvPatchField<Type>&); + + //- Construct and return a clone + virtual tmp<fvPatchField<Type> > clone() const + { + return tmp<fvPatchField<Type> > + ( + new cyclicACMIFvPatchField<Type>(*this) + ); + } + + //- Construct as copy setting internal field reference + cyclicACMIFvPatchField + ( + const cyclicACMIFvPatchField<Type>&, + const DimensionedField<Type, volMesh>& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp<fvPatchField<Type> > clone + ( + const DimensionedField<Type, volMesh>& iF + ) const + { + return tmp<fvPatchField<Type> > + ( + new cyclicACMIFvPatchField<Type>(*this, iF) + ); + } + + + // Member functions + + // Access + + //- Return local reference cast into the cyclic AMI patch + const cyclicACMIFvPatch& cyclicACMIPatch() const + { + return cyclicACMIPatch_; + } + + + // Evaluation functions + + //- Return true if coupled. Note that the underlying patch + // is not coupled() - the points don't align. + virtual bool coupled() const; + + //- Return neighbour coupled internal cell data + virtual tmp<Field<Type> > patchNeighbourField() const; + + //- Return reference to neighbour patchField + const cyclicACMIFvPatchField<Type>& neighbourPatchField() const; + + //- Return reference to non-overlapping patchField + const fvPatchField<Type>& nonOverlapPatchField() const; + + //- Update result field based on interface functionality + virtual void updateInterfaceMatrix + ( + scalarField& result, + const scalarField& psiInternal, + const scalarField& coeffs, + const direction cmpt, + const Pstream::commsTypes commsType + ) const; + + //- Update result field based on interface functionality + virtual void updateInterfaceMatrix + ( + Field<Type>&, + const Field<Type>&, + const scalarField&, + const Pstream::commsTypes commsType + ) const; + + //- Return patch-normal gradient + virtual tmp<Field<Type> > snGrad + ( + const scalarField& deltaCoeffs + ) const; + + //- Update the coefficients associated with the patch field + void updateCoeffs(); + + //- Evaluate the patch field + virtual void evaluate + ( + const Pstream::commsTypes commsType + ); + + //- Return the matrix diagonal coefficients corresponding to the + // evaluation of the value of this patchField with given weights + virtual tmp<Field<Type> > valueInternalCoeffs + ( + const tmp<scalarField>& + ) const; + + //- Return the matrix source coefficients corresponding to the + // evaluation of the value of this patchField with given weights + virtual tmp<Field<Type> > valueBoundaryCoeffs + ( + const tmp<scalarField>& + ) const; + + //- Return the matrix diagonal coefficients corresponding to the + // evaluation of the gradient of this patchField + virtual tmp<Field<Type> > gradientInternalCoeffs + ( + const scalarField& deltaCoeffs + ) const; + + //- Return the matrix diagonal coefficients corresponding to the + // evaluation of the gradient of this patchField + virtual tmp<Field<Type> > gradientInternalCoeffs() const; + + //- Return the matrix source coefficients corresponding to the + // evaluation of the gradient of this patchField + virtual tmp<Field<Type> > gradientBoundaryCoeffs + ( + const scalarField& deltaCoeffs + ) const; + + //- Return the matrix source coefficients corresponding to the + // evaluation of the gradient of this patchField + virtual tmp<Field<Type> > gradientBoundaryCoeffs() const; + + //- Manipulate matrix + virtual void manipulateMatrix(fvMatrix<Type>& matrix); + + + // Cyclic AMI coupled interface functions + + //- Does the patch field perform the transformation + virtual bool doTransform() const + { + return + !(cyclicACMIPatch_.parallel() || pTraits<Type>::rank == 0); + } + + //- Return face transformation tensor + virtual const tensorField& forwardT() const + { + return cyclicACMIPatch_.forwardT(); + } + + //- Return neighbour-cell transformation tensor + virtual const tensorField& reverseT() const + { + return cyclicACMIPatch_.reverseT(); + } + + //- Return rank of component for transform + virtual int rank() const + { + return pTraits<Type>::rank; + } + + + // I-O + + //- Write + virtual void write(Ostream& os) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "cyclicACMIFvPatchField.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFields.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFields.C new file mode 100644 index 0000000000000000000000000000000000000000..470a1613d32292dc0764dd8763c9b17f0a9f178d --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFields.C @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIFvPatchFields.H" +#include "addToRunTimeSelectionTable.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +makePatchFields(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFields.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFields.H new file mode 100644 index 0000000000000000000000000000000000000000..13aee99a8459a7bbab9720ea85844e45381b80d3 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFields.H @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIFvPatchFields_H +#define cyclicACMIFvPatchFields_H + +#include "cyclicACMIFvPatchField.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +makePatchTypeFieldTypedefs(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFieldsFwd.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFieldsFwd.H new file mode 100644 index 0000000000000000000000000000000000000000..155d6a8f2b0465d2cfe2ec2154bb9a1797b52fac --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchFieldsFwd.H @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIFvPatchFieldsFwd_H +#define cyclicACMIFvPatchFieldsFwd_H + +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> class cyclicACMIFvPatchField; + +makePatchTypeFieldTypedefs(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C index 6ea997f3fd8e41fc4e1d9ba464744ad40b03574f..df9c571397ff80bb8e30923918390bfa6b5fa225 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C @@ -46,6 +46,7 @@ timeVaryingMappedFixedValueFvPatchField fieldTableName_(iF.name()), setAverage_(false), perturb_(0), + mapperPtr_(NULL), sampleTimes_(0), startSampleTime_(-1), startSampledValues_(0), @@ -71,7 +72,7 @@ timeVaryingMappedFixedValueFvPatchField fieldTableName_(ptf.fieldTableName_), setAverage_(ptf.setAverage_), perturb_(ptf.perturb_), - mapperPtr_(ptf.mapperPtr_), + mapperPtr_(NULL), sampleTimes_(0), startSampleTime_(-1), startSampledValues_(0), @@ -79,7 +80,12 @@ timeVaryingMappedFixedValueFvPatchField endSampleTime_(-1), endSampledValues_(0), endAverage_(pTraits<Type>::zero), - offset_(ptf.offset_().clone().ptr()) + offset_ + ( + ptf.offset_.valid() + ? ptf.offset_().clone().ptr() + : NULL + ) {} @@ -130,7 +136,7 @@ timeVaryingMappedFixedValueFvPatchField fieldTableName_(ptf.fieldTableName_), setAverage_(ptf.setAverage_), perturb_(ptf.perturb_), - mapperPtr_(ptf.mapperPtr_), + mapperPtr_(NULL), sampleTimes_(ptf.sampleTimes_), startSampleTime_(ptf.startSampleTime_), startSampledValues_(ptf.startSampledValues_), @@ -138,11 +144,15 @@ timeVaryingMappedFixedValueFvPatchField endSampleTime_(ptf.endSampleTime_), endSampledValues_(ptf.endSampledValues_), endAverage_(ptf.endAverage_), - offset_(ptf.offset_().clone().ptr()) + offset_ + ( + ptf.offset_.valid() + ? ptf.offset_().clone().ptr() + : NULL + ) {} - template<class Type> timeVaryingMappedFixedValueFvPatchField<Type>:: timeVaryingMappedFixedValueFvPatchField @@ -155,7 +165,7 @@ timeVaryingMappedFixedValueFvPatchField fieldTableName_(ptf.fieldTableName_), setAverage_(ptf.setAverage_), perturb_(ptf.perturb_), - mapperPtr_(ptf.mapperPtr_), + mapperPtr_(NULL), sampleTimes_(ptf.sampleTimes_), startSampleTime_(ptf.startSampleTime_), startSampledValues_(ptf.startSampledValues_), @@ -163,7 +173,12 @@ timeVaryingMappedFixedValueFvPatchField endSampleTime_(ptf.endSampleTime_), endSampledValues_(ptf.endSampledValues_), endAverage_(ptf.endAverage_), - offset_(ptf.offset_().clone().ptr()) + offset_ + ( + ptf.offset_.valid() + ? ptf.offset_().clone().ptr() + : NULL + ) {} diff --git a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C index fa3d6d7a315e0fcea6297366534e853e408fa9bc..7fd83f41b1f26612b4fe3e7d8c6ede1eebf4f5e6 100644 --- a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C @@ -42,6 +42,7 @@ Foam::fvPatchField<Type>::fvPatchField patch_(p), internalField_(iF), updated_(false), + manipulatedMatrix_(false), patchType_(word::null) {} @@ -58,6 +59,7 @@ Foam::fvPatchField<Type>::fvPatchField patch_(p), internalField_(iF), updated_(false), + manipulatedMatrix_(false), patchType_(word::null) {} @@ -75,6 +77,7 @@ Foam::fvPatchField<Type>::fvPatchField patch_(p), internalField_(iF), updated_(false), + manipulatedMatrix_(false), patchType_(ptf.patchType_) {} @@ -92,6 +95,7 @@ Foam::fvPatchField<Type>::fvPatchField patch_(p), internalField_(iF), updated_(false), + manipulatedMatrix_(false), patchType_(dict.lookupOrDefault<word>("patchType", word::null)) { if (dict.found("value")) @@ -133,6 +137,7 @@ Foam::fvPatchField<Type>::fvPatchField patch_(ptf.patch_), internalField_(ptf.internalField_), updated_(false), + manipulatedMatrix_(false), patchType_(ptf.patchType_) {} @@ -148,6 +153,7 @@ Foam::fvPatchField<Type>::fvPatchField patch_(ptf.patch_), internalField_(iF), updated_(false), + manipulatedMatrix_(false), patchType_(ptf.patchType_) {} @@ -267,6 +273,28 @@ void Foam::fvPatchField<Type>::rmap } +template<class Type> +void Foam::fvPatchField<Type>::updateCoeffs() +{ + updated_ = true; +} + + +template<class Type> +void Foam::fvPatchField<Type>::updateCoeffs(const scalarField& weights) +{ + if (!updated_) + { + updateCoeffs(); + + Field<Type>& fld = *this; + fld *= weights; + + updated_ = true; + } +} + + template<class Type> void Foam::fvPatchField<Type>::evaluate(const Pstream::commsTypes) { @@ -276,13 +304,25 @@ void Foam::fvPatchField<Type>::evaluate(const Pstream::commsTypes) } updated_ = false; + manipulatedMatrix_ = false; } template<class Type> void Foam::fvPatchField<Type>::manipulateMatrix(fvMatrix<Type>& matrix) { - // do nothing + manipulatedMatrix_ = true; +} + + +template<class Type> +void Foam::fvPatchField<Type>::manipulateMatrix +( + fvMatrix<Type>& matrix, + const scalarField& weights +) +{ + manipulatedMatrix_ = true; } diff --git a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H index 6047f1e4af794e10a5abbcc8e89176c337a90cf6..d3b2ed4e70f8ef1ec856f17055ca2a385e97c8ef 100644 --- a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H @@ -93,6 +93,10 @@ class fvPatchField // the construction of the matrix bool updated_; + //- Update index used so that manipulateMatrix is called only once + // during the construction of the matrix + bool manipulatedMatrix_; + //- Optional patch type, used to allow specified boundary conditions // to be applied to constraint patches by providing the constraint // patch type as 'patchType' @@ -327,6 +331,12 @@ public: return updated_; } + //- Return true if the matrix has already been manipulated + bool manipulatedMatrix() const + { + return manipulatedMatrix_; + } + // Mapping functions @@ -365,10 +375,12 @@ public: //- Update the coefficients associated with the patch field // Sets Updated to true - virtual void updateCoeffs() - { - updated_ = true; - } + virtual void updateCoeffs(); + + //- Update the coefficients associated with the patch field + // and apply weight field + // Sets Updated to true + virtual void updateCoeffs(const scalarField& weights); //- Return internal field next to patch as patch field virtual tmp<Field<Type> > patchInternalField() const; @@ -479,6 +491,13 @@ public: //- Manipulate matrix virtual void manipulateMatrix(fvMatrix<Type>& matrix); + //- Manipulate matrix with given weights + virtual void manipulateMatrix + ( + fvMatrix<Type>& matrix, + const scalarField& weights + ); + // I-O diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchField.C b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchField.C new file mode 100644 index 0000000000000000000000000000000000000000..7fc9d7688c48ff0f5cbd00624d21f16d2361bcf2 --- /dev/null +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchField.C @@ -0,0 +1,149 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIFvsPatchField.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class Type> +Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField +( + const fvPatch& p, + const DimensionedField<Type, surfaceMesh>& iF +) +: + coupledFvsPatchField<Type>(p, iF), + cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p)) +{} + + +template<class Type> +Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField +( + const cyclicACMIFvsPatchField<Type>& ptf, + const fvPatch& p, + const DimensionedField<Type, surfaceMesh>& iF, + const fvPatchFieldMapper& mapper +) +: + coupledFvsPatchField<Type>(ptf, p, iF, mapper), + cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p)) +{ + if (!isA<cyclicACMIFvPatch>(this->patch())) + { + FatalErrorIn + ( + "cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField\n" + "(" + "const cyclicACMIFvsPatchField<Type>&, " + "const fvPatch&, " + "const DimensionedField<Type, surfaceMesh>&, " + "const fvPatchFieldMapper&" + ")" + ) << "Field type does not correspond to patch type for patch " + << this->patch().index() << "." << endl + << "Field type: " << typeName << endl + << "Patch type: " << this->patch().type() + << exit(FatalError); + } +} + + +template<class Type> +Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField +( + const fvPatch& p, + const DimensionedField<Type, surfaceMesh>& iF, + const dictionary& dict +) +: + coupledFvsPatchField<Type>(p, iF, dict), + cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p)) +{ + if (!isA<cyclicACMIFvPatch>(p)) + { + FatalIOErrorIn + ( + "cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField" + "(" + "const fvPatch&, " + "const Field<Type>&, " + "const dictionary&" + ")", + dict + ) << "patch " << this->patch().index() << " not cyclicACMI type. " + << "Patch type = " << p.type() + << exit(FatalIOError); + } +} + + +template<class Type> +Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField +( + const cyclicACMIFvsPatchField<Type>& ptf +) +: + coupledFvsPatchField<Type>(ptf), + cyclicACMIPatch_(ptf.cyclicACMIPatch_) +{} + + +template<class Type> +Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField +( + const cyclicACMIFvsPatchField<Type>& ptf, + const DimensionedField<Type, surfaceMesh>& iF +) +: + coupledFvsPatchField<Type>(ptf, iF), + cyclicACMIPatch_(ptf.cyclicACMIPatch_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +bool Foam::cyclicACMIFvsPatchField<Type>::coupled() const +{ + if + ( + Pstream::parRun() + || ( + this->cyclicACMIPatch_.size() + && this->cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().size() + ) + ) + { + return true; + } + else + { + return false; + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchField.H b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchField.H new file mode 100644 index 0000000000000000000000000000000000000000..edd7b9bf1548e37b43e25ed1a8c8c7196d61a73d --- /dev/null +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchField.H @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIFvsPatchField + +Description + Foam::cyclicACMIFvsPatchField + +SourceFiles + cyclicACMIFvsPatchField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIFvsPatchField_H +#define cyclicACMIFvsPatchField_H + +#include "coupledFvsPatchField.H" +#include "cyclicACMIFvPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIFvsPatchField Declaration +\*---------------------------------------------------------------------------*/ + +template<class Type> +class cyclicACMIFvsPatchField +: + public coupledFvsPatchField<Type> +{ + // Private data + + //- Local reference cast into the cyclic patch + const cyclicACMIFvPatch& cyclicACMIPatch_; + + +public: + + //- Runtime type information + TypeName(cyclicACMIFvPatch::typeName_()); + + + // Constructors + + //- Construct from patch and internal field + cyclicACMIFvsPatchField + ( + const fvPatch&, + const DimensionedField<Type, surfaceMesh>& + ); + + //- Construct from patch, internal field and dictionary + cyclicACMIFvsPatchField + ( + const fvPatch&, + const DimensionedField<Type, surfaceMesh>&, + const dictionary& + ); + + //- Construct by mapping given cyclicACMIFvsPatchField onto a new patch + cyclicACMIFvsPatchField + ( + const cyclicACMIFvsPatchField<Type>&, + const fvPatch&, + const DimensionedField<Type, surfaceMesh>&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + cyclicACMIFvsPatchField + ( + const cyclicACMIFvsPatchField<Type>& + ); + + //- Construct and return a clone + virtual tmp<fvsPatchField<Type> > clone() const + { + return tmp<fvsPatchField<Type> > + ( + new cyclicACMIFvsPatchField<Type>(*this) + ); + } + + //- Construct as copy setting internal field reference + cyclicACMIFvsPatchField + ( + const cyclicACMIFvsPatchField<Type>&, + const DimensionedField<Type, surfaceMesh>& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp<fvsPatchField<Type> > clone + ( + const DimensionedField<Type, surfaceMesh>& iF + ) const + { + return tmp<fvsPatchField<Type> > + ( + new cyclicACMIFvsPatchField<Type>(*this, iF) + ); + } + + // Member functions + + // Access + + //- Return true if running parallel + virtual bool coupled() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "cyclicACMIFvsPatchField.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFields.C b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFields.C new file mode 100644 index 0000000000000000000000000000000000000000..efe05703d956bf52a8225ddc6406e533eb39ad7f --- /dev/null +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFields.C @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIFvsPatchFields.H" +#include "fvsPatchFields.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +makeFvsPatchFields(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFields.H b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFields.H new file mode 100644 index 0000000000000000000000000000000000000000..11801d8cd2757626bd40d421e86df4c80d5a9106 --- /dev/null +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFields.H @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIFvsPatchFields_H +#define cyclicACMIFvsPatchFields_H + +#include "cyclicACMIFvsPatchField.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +makeFvsPatchTypeFieldTypedefs(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFieldsFwd.H b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFieldsFwd.H new file mode 100644 index 0000000000000000000000000000000000000000..41b42881b98b721fc91869b6d21d42ffdbbcae29 --- /dev/null +++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicACMI/cyclicACMIFvsPatchFieldsFwd.H @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIFvsPatchFieldsFwd_H +#define cyclicACMIFvsPatchFieldsFwd_H + +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> class cyclicACMIFvsPatchField; + +makeFvsPatchTypeFieldTypedefs(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C b/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C index 9bfcda020cb7667a93a0100736f326c434d04b5e..42a35f5c1be754f1289ba3635a245f7a1a249e9a 100644 --- a/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C +++ b/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C @@ -90,8 +90,6 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration : pairGAMGAgglomeration(mesh, controlDict) { - vectorField n(faceAreas/mag(faceAreas)); - //agglomerate(mesh, sqrt(mag(faceAreas))); agglomerate ( @@ -100,7 +98,8 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration ( cmptMultiply ( - n, + faceAreas + /sqrt(mag(faceAreas)), vector(1, 1.01, 1.02) //vector::one ) diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C new file mode 100644 index 0000000000000000000000000000000000000000..fe674cf98e3c5e5d58fa5d8ce3559e62dba00a29 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C @@ -0,0 +1,202 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIFvPatch.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "transform.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(cyclicACMIFvPatch, 0); + addToRunTimeSelectionTable(fvPatch, cyclicACMIFvPatch, polyPatch); +} + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +void Foam::cyclicACMIFvPatch::updateAreas() const +{ + if (cyclicACMIPolyPatch_.updated()) + { + // Set Sf and magSf for both sides' coupled and non-overlapping patches + + // owner couple + const_cast<vectorField&>(Sf()) = patch().faceAreas(); + const_cast<scalarField&>(magSf()) = mag(patch().faceAreas()); + + // owner non-overlapping + const fvPatch& nonOverlapPatch = this->nonOverlapPatch(); + const_cast<vectorField&>(nonOverlapPatch.Sf()) = + nonOverlapPatch.patch().faceAreas(); + const_cast<scalarField&>(nonOverlapPatch.magSf()) = + mag(nonOverlapPatch.patch().faceAreas()); + + // neighbour couple + const cyclicACMIFvPatch& nbrACMI = neighbPatch(); + const_cast<vectorField&>(nbrACMI.Sf()) = + nbrACMI.patch().faceAreas(); + const_cast<scalarField&>(nbrACMI.magSf()) = + mag(nbrACMI.patch().faceAreas()); + + // neighbour non-overlapping + const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch(); + const_cast<vectorField&>(nbrNonOverlapPatch.Sf()) = + nbrNonOverlapPatch.patch().faceAreas(); + const_cast<scalarField&>(nbrNonOverlapPatch.magSf()) = + mag(nbrNonOverlapPatch.patch().faceAreas()); + + // set the updated flag + cyclicACMIPolyPatch_.setUpdated(false); + } +} + + +void Foam::cyclicACMIFvPatch::makeWeights(scalarField& w) const +{ + if (coupled()) + { + const cyclicACMIFvPatch& nbrPatch = neighbFvPatch(); + const fvPatch& nbrPatchNonOverlap = nonOverlapPatch(); + + const scalarField deltas(nf() & fvPatch::delta()); + + const scalarField nbrDeltas + ( + interpolate + ( + nbrPatch.nf() & nbrPatch.fvPatch::delta(), + nbrPatchNonOverlap.nf() & nbrPatchNonOverlap.delta() + ) + ); + + forAll(deltas, faceI) + { + scalar di = deltas[faceI]; + scalar dni = nbrDeltas[faceI]; + + w[faceI] = dni/(di + dni); + } + } + else + { + // Behave as uncoupled patch + fvPatch::makeWeights(w); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::cyclicACMIFvPatch::coupled() const +{ + return Pstream::parRun() || (this->size() && neighbFvPatch().size()); +} + + +Foam::tmp<Foam::vectorField> Foam::cyclicACMIFvPatch::delta() const +{ + if (coupled()) + { + const cyclicACMIFvPatch& nbrPatchCoupled = neighbFvPatch(); + const fvPatch& nbrPatchNonOverlap = nonOverlapPatch(); + + const vectorField patchD(fvPatch::delta()); + + vectorField nbrPatchD + ( + interpolate + ( + nbrPatchCoupled.fvPatch::delta(), + nbrPatchNonOverlap.delta() + ) + ); + + const vectorField nbrPatchD0 + ( + interpolate + ( + vectorField(nbrPatchCoupled.size(), vector::zero), + nbrPatchNonOverlap.delta()() + ) + ); + + nbrPatchD -= nbrPatchD0; + + tmp<vectorField> tpdv(new vectorField(patchD.size())); + vectorField& pdv = tpdv(); + + // do the transformation if necessary + if (parallel()) + { + forAll(patchD, faceI) + { + const vector& ddi = patchD[faceI]; + const vector& dni = nbrPatchD[faceI]; + + pdv[faceI] = ddi - dni; + } + } + else + { + forAll(patchD, faceI) + { + const vector& ddi = patchD[faceI]; + const vector& dni = nbrPatchD[faceI]; + + pdv[faceI] = ddi - transform(forwardT()[0], dni); + } + } + + return tpdv; + } + else + { + return fvPatch::delta(); + } +} + + +Foam::tmp<Foam::labelField> Foam::cyclicACMIFvPatch::interfaceInternalField +( + const labelUList& internalData +) const +{ + return patchInternalField(internalData); +} + + +Foam::tmp<Foam::labelField> Foam::cyclicACMIFvPatch::internalFieldTransfer +( + const Pstream::commsTypes commsType, + const labelUList& iF +) const +{ + return neighbFvPatch().patchInternalField(iF); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H new file mode 100644 index 0000000000000000000000000000000000000000..7ed1693696535d5d6b76f8b491d63979b72f450c --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H @@ -0,0 +1,268 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIFvPatch + +Description + Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI) + +SourceFiles + cyclicACMIFvPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIFvPatch_H +#define cyclicACMIFvPatch_H + +#include "coupledFvPatch.H" +#include "cyclicACMILduInterface.H" +#include "cyclicACMIPolyPatch.H" +#include "fvBoundaryMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIFvPatch Declaration +\*---------------------------------------------------------------------------*/ + +class cyclicACMIFvPatch +: + public coupledFvPatch, + public cyclicACMILduInterface +{ + // Private data + + const cyclicACMIPolyPatch& cyclicACMIPolyPatch_; + + +protected: + + // Protected Member functions + + //- Update the patch areas after AMI update + void updateAreas() const; + + //- Make patch weighting factors + void makeWeights(scalarField&) const; + + +public: + + //- Runtime type information + TypeName(cyclicACMIPolyPatch::typeName_()); + + + // Constructors + + //- Construct from polyPatch + cyclicACMIFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm) + : + coupledFvPatch(patch, bm), + cyclicACMILduInterface(), + cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch)) + {} + + + // Member functions + + // Access + + //- Return local reference cast into the cyclic patch + const cyclicACMIPolyPatch& cyclicACMIPatch() const + { + return cyclicACMIPolyPatch_; + } + + //- Return neighbour + virtual label neighbPatchID() const + { + return cyclicACMIPolyPatch_.neighbPatchID(); + } + + virtual bool owner() const + { + return cyclicACMIPolyPatch_.owner(); + } + + //- Return neighbour fvPatch + virtual const cyclicACMIFvPatch& neighbPatch() const + { + return refCast<const cyclicACMIFvPatch> + ( + this->boundaryMesh()[cyclicACMIPolyPatch_.neighbPatchID()] + ); + } + + //- Return neighbour + virtual label nonOverlapPatchID() const + { + return cyclicACMIPolyPatch_.nonOverlapPatchID(); + } + + //- Return non-overlapping fvPatch + virtual const fvPatch& nonOverlapPatch() const + { + return this->boundaryMesh()[nonOverlapPatchID()]; + } + + //- Return a reference to the AMI interpolator + virtual const AMIPatchToPatchInterpolation& AMI() const + { + const AMIPatchToPatchInterpolation& AMI = + cyclicACMIPolyPatch_.AMI(); + + updateAreas(); + + return AMI; + } + + //- Are the cyclic planes parallel + virtual bool parallel() const + { + return cyclicACMIPolyPatch_.parallel(); + } + + //- Return face transformation tensor + virtual const tensorField& forwardT() const + { + return cyclicACMIPolyPatch_.forwardT(); + } + + //- Return neighbour-cell transformation tensor + virtual const tensorField& reverseT() const + { + return cyclicACMIPolyPatch_.reverseT(); + } + + const cyclicACMIFvPatch& neighbFvPatch() const + { + return refCast<const cyclicACMIFvPatch> + ( + this->boundaryMesh()[cyclicACMIPolyPatch_.neighbPatchID()] + ); + } + + //- Return true if this patch is coupled. This is equivalent + // to the coupledPolyPatch::coupled() if parallel running or + // both sides present, false otherwise + virtual bool coupled() const; + + //- Return delta (P to N) vectors across coupled patch + virtual tmp<vectorField> delta() const; + + template<class Type> + tmp<Field<Type> > interpolate + ( + const Field<Type>& fldCoupled + ) const + { + updateAreas(); + + return + cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate + ( + fldCoupled + ); + } + + template<class Type> + tmp<Field<Type> > interpolate + ( + const tmp<Field<Type> >& tfldCoupled + ) const + { + updateAreas(); + + return + cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate + ( + tfldCoupled + ); + } + + template<class Type> + tmp<Field<Type> > interpolate + ( + const Field<Type>& fldCoupled, + const Field<Type>& fldNonOverlap + ) const + { + updateAreas(); + + return + cyclicACMIPolyPatch_.interpolate + ( + fldCoupled, + fldNonOverlap + ); + } + + template<class Type> + tmp<Field<Type> > interpolate + ( + const tmp<Field<Type> >& tFldCoupled, + const tmp<Field<Type> >& tFldNonOverlap + ) const + { + updateAreas(); + + return + cyclicACMIPolyPatch_.interpolate + ( + tFldCoupled, + tFldNonOverlap + ); + } + + + // Interface transfer functions + + //- Return the values of the given internal data adjacent to + // the interface as a field + virtual tmp<labelField> interfaceInternalField + ( + const labelUList& internalData + ) const; + + //- Return neighbour field + virtual tmp<labelField> internalFieldTransfer + ( + const Pstream::commsTypes commsType, + const labelUList& internalData + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fvAgglomerationMethods/MGridGenGamgAgglomeration/MGridGenGAMGAgglomeration.C b/src/fvAgglomerationMethods/MGridGenGamgAgglomeration/MGridGenGAMGAgglomeration.C index 46bcbc8953d52a00bb6a7f50dafb2814cd69eab8..59c45bc11b29424d529c7389d850b7710cfc6f82 100644 --- a/src/fvAgglomerationMethods/MGridGenGamgAgglomeration/MGridGenGAMGAgglomeration.C +++ b/src/fvAgglomerationMethods/MGridGenGamgAgglomeration/MGridGenGAMGAgglomeration.C @@ -59,7 +59,11 @@ Foam::MGridGenGAMGAgglomeration::MGridGenGAMGAgglomeration // Start geometric agglomeration from the cell volumes and areas of the mesh scalarField* VPtr = const_cast<scalarField*>(&fvMesh_.cellVolumes()); - vectorField* SfPtr = const_cast<vectorField*>(&fvMesh_.faceAreas()); + SubField<vector> Sf(fvMesh_.faceAreas(), fvMesh_.nInternalFaces()); + vectorField* SfPtr = const_cast<vectorField*> + ( + &Sf.operator const vectorField&() + ); // Create the boundary area cell field scalarField* SbPtr(new scalarField(fvMesh_.nCells(), 0)); diff --git a/src/fvAgglomerationMethods/pairPatchAgglomeration/pairPatchAgglomeration.C b/src/fvAgglomerationMethods/pairPatchAgglomeration/pairPatchAgglomeration.C index 9a7462127cded0319c428f707a19272ccf94e150..9467906f154b6b14df9d7c8ad2ce2fe04525cd9c 100644 --- a/src/fvAgglomerationMethods/pairPatchAgglomeration/pairPatchAgglomeration.C +++ b/src/fvAgglomerationMethods/pairPatchAgglomeration/pairPatchAgglomeration.C @@ -44,9 +44,7 @@ bool Foam::pairPatchAgglomeration::continueAgglomerating { // Check the need for further agglomeration on all processors label localnCoarseFaces = nCoarseFaces; -// reduce(localnCoarseFaces, sumOp<label>()); bool contAgg = localnCoarseFaces >= nFacesInCoarsestLevel_; - //reduce(contAgg, andOp<bool>()); return contAgg; } diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C index 66e54468e5cf9eb3239598adcde3e8b3300f4710..445775a9286e997229f9ea05dd23209edbb1f460 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C @@ -566,7 +566,11 @@ void Foam::KinematicCloud<CloudType>::checkParcelProperties { const scalar carrierDt = mesh_.time().deltaTValue(); parcel.stepFraction() = (carrierDt - lagrangianDt)/carrierDt; - parcel.typeId() = constProps_.parcelTypeId(); + + if (parcel.typeId() == -1) + { + parcel.typeId() = constProps_.parcelTypeId(); + } } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C index cebed76580d9df8b0e399bcefcb9a55681804ddf..97c3c819a03f8daa4e3f02d68d104a0d6ad256d1 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -167,7 +167,8 @@ Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection "Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection" "(" "const dictionary&, " - "CloudType&" + "CloudType&, " + "const word&" ")" )<< "innerNozzleDiameter >= outerNozzleDiameter" << nl << exit(FatalError); @@ -369,6 +370,7 @@ void Foam::ConeNozzleInjection<CloudType>::setPositionAndCell "const scalar, " "vector&, " "label&, " + "label&, " "label&" ")" )<< "Unknown injectionMethod type" << nl diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C index c40a95fbaceed0370bc01540a19126eeea63be59..293fd7d740c1013e1701209bb7cb052258272c1f 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,6 +43,7 @@ Foam::KinematicLookupTableInjection<CloudType>::KinematicLookupTableInjection ( readScalar(this->coeffDict().lookup("parcelsPerSecond")) ), + randomise_(readBool(this->coeffDict().lookup("randomise"))), injectors_ ( IOobject @@ -87,6 +88,7 @@ Foam::KinematicLookupTableInjection<CloudType>::KinematicLookupTableInjection inputFileName_(im.inputFileName_), duration_(im.duration_), parcelsPerSecond_(im.parcelsPerSecond_), + randomise_(im.randomise_), injectors_(im.injectors_), injectorCells_(im.injectorCells_), injectorTetFaces_(im.injectorTetFaces_), @@ -177,7 +179,16 @@ void Foam::KinematicLookupTableInjection<CloudType>::setPositionAndCell label& tetPtI ) { - label injectorI = parcelI*injectorCells_.size()/nParcels; + label injectorI = 0; + if (randomise_) + { + cachedRandom& rnd = this->owner().rndGen(); + injectorI = rnd.position<label>(0, injectorCells_.size() - 1); + } + else + { + injectorI = parcelI*injectorCells_.size()/nParcels; + } position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H index d156f4793a0fa7d5e7a5d86f1b7e963cc86c091b..f17410bc1dd5d4b97b7c4db699c8fc346590c94a 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/KinematicLookupTableInjection/KinematicLookupTableInjection.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -78,6 +78,9 @@ class KinematicLookupTableInjection //- Number of parcels per injector - common to all injection sources const scalar parcelsPerSecond_; + //- Flag to indicate to randomise injection positions + bool randomise_; + //- List of injectors kinematicParcelInjectionDataIOList injectors_; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/Lift/LiftForce/LiftForce.C b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/Lift/LiftForce/LiftForce.C index 290d2f3c3d6b2be325c5c7e649712f176e2f14bd..a4faceeec75275b79c7621249697635058b4c5e4 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/Lift/LiftForce/LiftForce.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/Lift/LiftForce/LiftForce.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -141,7 +141,7 @@ Foam::forceSuSp Foam::LiftForce<CloudType>::calcCoupled scalar Cl = this->Cl(p, curlUc, Re, muc); - value.Su() = mass/p.rho()*p.d()/2.0*p.rhoc()*Cl*((p.Uc() - p.U())^curlUc); + value.Su() = mass/p.rho()*p.rhoc()*Cl*((p.Uc() - p.U())^curlUc); return value; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/SRF/SRFForce.C b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/SRF/SRFForce.C index 758e58743b1291dec9828bd73a8e33f0f02a656b..eed0c800d08d30ade1ba1f33d9f48f37f267adc2 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/SRF/SRFForce.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/SRF/SRFForce.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -95,7 +95,9 @@ Foam::forceSuSp Foam::SRFForce<CloudType>::calcNonCoupled const vector& r = p.position(); // Coriolis and centrifugal acceleration terms - value.Su() = mass*(2.0*(p.U() ^ omega) + (omega ^ (r ^ omega))); + value.Su() = + mass*(1.0 - p.rhoc()/p.rho()) + *(2.0*(p.U() ^ omega) + (omega ^ (r ^ omega))); return value; } diff --git a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C index 711b3cec7a04263d16f1e628d60523e0f3f44112..1259da7e3718318cd6683b9bc8effe47d8300fea 100644 --- a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -42,6 +42,7 @@ Foam::ReactingLookupTableInjection<CloudType>::ReactingLookupTableInjection ( readScalar(this->coeffDict().lookup("parcelsPerSecond")) ), + randomise_(readBool(this->coeffDict().lookup("randomise"))), injectors_ ( IOobject @@ -86,6 +87,7 @@ Foam::ReactingLookupTableInjection<CloudType>::ReactingLookupTableInjection inputFileName_(im.inputFileName_), duration_(im.duration_), parcelsPerSecond_(im.parcelsPerSecond_), + randomise_(im.randomise_), injectors_(im.injectors_), injectorCells_(im.injectorCells_), injectorTetFaces_(im.injectorTetFaces_), @@ -176,7 +178,16 @@ void Foam::ReactingLookupTableInjection<CloudType>::setPositionAndCell label& tetPtI ) { - label injectorI = parcelI*injectorCells_.size()/nParcels; + label injectorI = 0; + if (randomise_) + { + cachedRandom& rnd = this->owner().rndGen(); + injectorI = rnd.position<label>(0, injectorCells_.size() - 1); + } + else + { + injectorI = parcelI*injectorCells_.size()/nParcels; + } position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; diff --git a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H index ef062fd72bd2ccc3a2214af2f3912e54a13574df..654109c509b8bc96c1b3cdfda46d94d1259da086 100644 --- a/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/Reacting/InjectionModel/ReactingLookupTableInjection/ReactingLookupTableInjection.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -81,6 +81,9 @@ class ReactingLookupTableInjection //- Number of parcels per injector - common to all injection sources const scalar parcelsPerSecond_; + //- Flag to indicate to randomise injection positions + bool randomise_; + //- List of injectors reactingParcelInjectionDataIOList injectors_; diff --git a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C index bd630d879dafdf1f668992f3614fdb7e40105348..179b846cafab2f17428ea898ada2699654d7ded4 100644 --- a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,6 +43,7 @@ ReactingMultiphaseLookupTableInjection ( readScalar(this->coeffDict().lookup("parcelsPerSecond")) ), + randomise_(readBool(this->coeffDict().lookup("randomise"))), injectors_ ( IOobject @@ -88,6 +89,7 @@ ReactingMultiphaseLookupTableInjection inputFileName_(im.inputFileName_), duration_(im.duration_), parcelsPerSecond_(im.parcelsPerSecond_), + randomise_(im.randomise_), injectors_(im.injectors_), injectorCells_(im.injectorCells_), injectorTetFaces_(im.injectorTetFaces_), @@ -182,7 +184,16 @@ void Foam::ReactingMultiphaseLookupTableInjection<CloudType>::setPositionAndCell label& tetPtI ) { - label injectorI = parcelI*injectorCells_.size()/nParcels; + label injectorI = 0; + if (randomise_) + { + cachedRandom& rnd = this->owner().rndGen(); + injectorI = rnd.position<label>(0, injectorCells_.size() - 1); + } + else + { + injectorI = parcelI*injectorCells_.size()/nParcels; + } position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; diff --git a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H index 7e6c32855817f3c85823f199886bbd2b8c55458d..81f41d42ded505580b184d66fb714fb504a65ea6 100644 --- a/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/ReactingMultiphase/InjectionModel/ReactingMultiphaseLookupTableInjection/ReactingMultiphaseLookupTableInjection.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -84,6 +84,9 @@ class ReactingMultiphaseLookupTableInjection //- Number of parcels per injector - common to all injection sources const scalar parcelsPerSecond_; + //- Flag to indicate to randomise injection positions + bool randomise_; + //- List of injectors reactingMultiphaseParcelInjectionDataIOList injectors_; diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C index fdc0a3b4a3eeb79d23cd2e81c40d4f1d06b6d62c..682fc9c3ea1951c306da3672dabf1f8f276bb156 100644 --- a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C +++ b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,6 +43,7 @@ Foam::ThermoLookupTableInjection<CloudType>::ThermoLookupTableInjection ( readScalar(this->coeffDict().lookup("parcelsPerSecond")) ), + randomise_(readBool(this->coeffDict().lookup("randomise"))), injectors_ ( IOobject @@ -87,6 +88,7 @@ Foam::ThermoLookupTableInjection<CloudType>::ThermoLookupTableInjection inputFileName_(im.inputFileName_), duration_(im.duration_), parcelsPerSecond_(im.parcelsPerSecond_), + randomise_(im.randomise_), injectors_(im.injectors_), injectorCells_(im.injectorCells_), injectorTetFaces_(im.injectorTetFaces_), @@ -177,7 +179,16 @@ void Foam::ThermoLookupTableInjection<CloudType>::setPositionAndCell label& tetPtI ) { - label injectorI = parcelI*injectorCells_.size()/nParcels; + label injectorI = 0; + if (randomise_) + { + cachedRandom& rnd = this->owner().rndGen(); + injectorI = rnd.position<label>(0, injectorCells_.size() - 1); + } + else + { + injectorI = parcelI*injectorCells_.size()/nParcels; + } position = injectors_[injectorI].x(); cellOwner = injectorCells_[injectorI]; diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H index efb83c3614e04fe8ffb8993a5cd9b062c5061ec0..42c48f290dd88da1ce6b60f39c696c92fd2b4378 100644 --- a/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H +++ b/src/lagrangian/intermediate/submodels/Thermodynamic/InjectionModel/ThermoLookupTableInjection/ThermoLookupTableInjection.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -80,6 +80,9 @@ class ThermoLookupTableInjection //- Number of parcels per injector - common to all injection sources const scalar parcelsPerSecond_; + //- Flag to indicate to randomise injection positions + bool randomise_; + //- List of injectors kinematicParcelInjectionDataIOList injectors_; diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C index 3a7c4fb2496a98fcb0befd6c099dc9961c51b6ae..bed0e3c52fcd03d6e64fe3d93052b46984ca894f 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C @@ -336,7 +336,7 @@ void Foam::autoLayerDriver::smoothNormals ) const { // Get smoothly varying internal normals field. - Info<< "shrinkMeshDistance : Smoothing normals ..." << endl; + Info<< "shrinkMeshDistance : Smoothing normals in interior ..." << endl; const fvMesh& mesh = meshRefiner_.mesh(); const edgeList& edges = mesh.edges(); @@ -1161,6 +1161,11 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo scalar mDist = medialDist[pointI]; if (wDist2 < sqr(SMALL) && mDist < SMALL) + //- Note: maybe less strict: + //( + // wDist2 < sqr(meshRefiner_.mergeDistance()) + // && mDist < meshRefiner_.mergeDistance() + //) { medialRatio[pointI] = 0.0; } diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C index 484f851c0f65fe26375bd1064db074db3d6290e9..d78866bcd78b781a5814552394fbdae5548dbe4b 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C @@ -46,9 +46,6 @@ defineTypeNameAndDebug(autoRefineDriver, 0); } // End namespace Foam -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components @@ -97,12 +94,14 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine ( refineParams.keepPoints()[0], // For now only use one. refineParams.curvature(), + refineParams.planarAngle(), true, // featureRefinement false, // featureDistanceRefinement false, // internalRefinement false, // surfaceRefinement false, // curvatureRefinement + false, // gapRefinement refineParams.maxGlobalCells(), refineParams.maxLocalCells() ) @@ -208,12 +207,14 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine ( refineParams.keepPoints()[0], refineParams.curvature(), + refineParams.planarAngle(), false, // featureRefinement false, // featureDistanceRefinement false, // internalRefinement true, // surfaceRefinement true, // curvatureRefinement + false, // gapRefinement refineParams.maxGlobalCells(), refineParams.maxLocalCells() ) @@ -294,6 +295,371 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine } +Foam::label Foam::autoRefineDriver::gapOnlyRefine +( + const refinementParameters& refineParams, + const label maxIter +) +{ + const fvMesh& mesh = meshRefiner_.mesh(); + + // Determine the maximum refinement level over all surfaces. This + // determines the minumum number of surface refinement iterations. + + label maxIncrement = 0; + const labelList& maxLevel = meshRefiner_.surfaces().maxLevel(); + const labelList& gapLevel = meshRefiner_.surfaces().gapLevel(); + + forAll(maxLevel, i) + { + maxIncrement = max(maxIncrement, gapLevel[i]-maxLevel[i]); + } + + label iter = 0; + + if (maxIncrement == 0) + { + return iter; + } + + for (iter = 0; iter < maxIter; iter++) + { + Info<< nl + << "Gap refinement iteration " << iter << nl + << "--------------------------" << nl + << endl; + + + // Determine cells to refine + // ~~~~~~~~~~~~~~~~~~~~~~~~~ + // Only look at surface intersections (minLevel and surface curvature), + // do not do internal refinement (refinementShells) + + labelList candidateCells + ( + meshRefiner_.refineCandidates + ( + refineParams.keepPoints()[0], + refineParams.curvature(), + refineParams.planarAngle(), + + false, // featureRefinement + false, // featureDistanceRefinement + false, // internalRefinement + false, // surfaceRefinement + false, // curvatureRefinement + true, // gapRefinement + refineParams.maxGlobalCells(), + refineParams.maxLocalCells() + ) + ); + + if (debug&meshRefinement::MESH) + { + Pout<< "Dumping " << candidateCells.size() + << " cells to cellSet candidateCellsFromGap." << endl; + cellSet c(mesh, "candidateCellsFromGap", candidateCells); + c.instance() = meshRefiner_.timeName(); + c.write(); + } + + // Grow by one layer to make sure we're covering the gap + { + boolList isCandidateCell(mesh.nCells(), false); + forAll(candidateCells, i) + { + isCandidateCell[candidateCells[i]] = true; + } + + for (label i=0; i<1; i++) + { + boolList newIsCandidateCell(isCandidateCell); + + // Internal faces + for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) + { + label own = mesh.faceOwner()[faceI]; + label nei = mesh.faceNeighbour()[faceI]; + + if (isCandidateCell[own] != isCandidateCell[nei]) + { + newIsCandidateCell[own] = true; + newIsCandidateCell[nei] = true; + } + } + + // Get coupled boundary condition values + boolList neiIsCandidateCell; + syncTools::swapBoundaryCellList + ( + mesh, + isCandidateCell, + neiIsCandidateCell + ); + + // Boundary faces + for + ( + label faceI = mesh.nInternalFaces(); + faceI < mesh.nFaces(); + faceI++ + ) + { + label own = mesh.faceOwner()[faceI]; + label bFaceI = faceI-mesh.nInternalFaces(); + + if (isCandidateCell[own] != neiIsCandidateCell[bFaceI]) + { + newIsCandidateCell[own] = true; + } + } + + isCandidateCell.transfer(newIsCandidateCell); + } + + label n = 0; + forAll(isCandidateCell, cellI) + { + if (isCandidateCell[cellI]) + { + n++; + } + } + candidateCells.setSize(n); + n = 0; + forAll(isCandidateCell, cellI) + { + if (isCandidateCell[cellI]) + { + candidateCells[n++] = cellI; + } + } + } + + + if (debug&meshRefinement::MESH) + { + Pout<< "Dumping " << candidateCells.size() + << " cells to cellSet candidateCellsFromGapPlusBuffer." << endl; + cellSet c(mesh, "candidateCellsFromGapPlusBuffer", candidateCells); + c.instance() = meshRefiner_.timeName(); + c.write(); + } + + + labelList cellsToRefine + ( + meshRefiner_.meshCutter().consistentRefinement + ( + candidateCells, + true + ) + ); + Info<< "Determined cells to refine in = " + << mesh.time().cpuTimeIncrement() << " s" << endl; + + + label nCellsToRefine = cellsToRefine.size(); + reduce(nCellsToRefine, sumOp<label>()); + + Info<< "Selected for refinement : " << nCellsToRefine + << " cells (out of " << mesh.globalData().nTotalCells() + << ')' << endl; + + // Stop when no cells to refine or have done minimum necessary + // iterations and not enough cells to refine. + if + ( + nCellsToRefine == 0 + || ( + iter >= maxIncrement + && nCellsToRefine <= refineParams.minRefineCells() + ) + ) + { + Info<< "Stopping refining since too few cells selected." + << nl << endl; + break; + } + + + if (debug) + { + const_cast<Time&>(mesh.time())++; + } + + + if + ( + returnReduce + ( + (mesh.nCells() >= refineParams.maxLocalCells()), + orOp<bool>() + ) + ) + { + meshRefiner_.balanceAndRefine + ( + "gap refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + else + { + meshRefiner_.refineAndBalance + ( + "gap refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + } + return iter; +} + + +Foam::label Foam::autoRefineDriver::danglingCellRefine +( + const refinementParameters& refineParams, + const label nFaces, + const label maxIter +) +{ + const fvMesh& mesh = meshRefiner_.mesh(); + + label iter; + for (iter = 0; iter < maxIter; iter++) + { + Info<< nl + << "Dangling coarse cells refinement iteration " << iter << nl + << "--------------------------------------------" << nl + << endl; + + + // Determine cells to refine + // ~~~~~~~~~~~~~~~~~~~~~~~~~ + + const cellList& cells = mesh.cells(); + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + + labelList candidateCells; + { + cellSet candidateCellSet(mesh, "candidateCells", cells.size()/1000); + + forAll(cells, cellI) + { + const cell& cFaces = cells[cellI]; + + label nIntFaces = 0; + forAll(cFaces, i) + { + label bFaceI = cFaces[i]-mesh.nInternalFaces(); + if (bFaceI < 0) + { + nIntFaces++; + } + else + { + label patchI = pbm.patchID()[bFaceI]; + if (pbm[patchI].coupled()) + { + nIntFaces++; + } + } + } + + if (nIntFaces == nFaces) + { + candidateCellSet.insert(cellI); + } + } + + if (debug&meshRefinement::MESH) + { + Pout<< "Dumping " << candidateCellSet.size() + << " cells to cellSet candidateCellSet." << endl; + candidateCellSet.instance() = meshRefiner_.timeName(); + candidateCellSet.write(); + } + candidateCells = candidateCellSet.toc(); + } + + + + labelList cellsToRefine + ( + meshRefiner_.meshCutter().consistentRefinement + ( + candidateCells, + true + ) + ); + Info<< "Determined cells to refine in = " + << mesh.time().cpuTimeIncrement() << " s" << endl; + + + label nCellsToRefine = cellsToRefine.size(); + reduce(nCellsToRefine, sumOp<label>()); + + Info<< "Selected for refinement : " << nCellsToRefine + << " cells (out of " << mesh.globalData().nTotalCells() + << ')' << endl; + + // Stop when no cells to refine. No checking of minRefineCells since + // too few cells + if (nCellsToRefine == 0) + { + Info<< "Stopping refining since too few cells selected." + << nl << endl; + break; + } + + + if (debug) + { + const_cast<Time&>(mesh.time())++; + } + + + if + ( + returnReduce + ( + (mesh.nCells() >= refineParams.maxLocalCells()), + orOp<bool>() + ) + ) + { + meshRefiner_.balanceAndRefine + ( + "coarse cell refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + else + { + meshRefiner_.refineAndBalance + ( + "coarse cell refinement iteration " + name(iter), + decomposer_, + distributor_, + cellsToRefine, + refineParams.maxLoadUnbalance() + ); + } + } + return iter; +} + + void Foam::autoRefineDriver::removeInsideCells ( const refinementParameters& refineParams, @@ -371,12 +737,14 @@ Foam::label Foam::autoRefineDriver::shellRefine ( refineParams.keepPoints()[0], refineParams.curvature(), + refineParams.planarAngle(), false, // featureRefinement true, // featureDistanceRefinement true, // internalRefinement false, // surfaceRefinement false, // curvatureRefinement + false, // gapRefinement refineParams.maxGlobalCells(), refineParams.maxLocalCells() ) @@ -522,6 +890,7 @@ void Foam::autoRefineDriver::baffleAndSplitMesh false, // perpendicular edge connected cells scalarField(0), // per region perpendicular angle !handleSnapProblems, // merge free standing baffles? + refineParams.planarAngle(), motionDict, const_cast<Time&>(mesh.time()), globalToMasterPatch_, @@ -606,8 +975,8 @@ void Foam::autoRefineDriver::splitAndMergeBaffles handleSnapProblems, handleSnapProblems, // remove perp edge connected cells perpAngle, // perp angle - false, // merge free standing baffles? - //true, // merge free standing baffles? + true, // merge free standing baffles? + refineParams.planarAngle(), // planar angle motionDict, const_cast<Time&>(mesh.time()), globalToMasterPatch_, @@ -652,6 +1021,16 @@ void Foam::autoRefineDriver::splitAndMergeBaffles // Debug:test all is still synced across proc patches meshRefiner_.checkData(); } + + // Remove any now dangling parts + meshRefiner_.splitMeshRegions(refineParams.keepPoints()[0]); + + if (debug) + { + // Debug:test all is still synced across proc patches + meshRefiner_.checkData(); + } + Info<< "Merged free-standing baffles in = " << mesh.time().cpuTimeIncrement() << " s." << endl; } @@ -731,6 +1110,12 @@ void Foam::autoRefineDriver::doRefine 100 // maxIter ); + gapOnlyRefine + ( + refineParams, + 100 // maxIter + ); + // Remove cells (a certain distance) beyond surface intersections removeInsideCells ( @@ -745,6 +1130,20 @@ void Foam::autoRefineDriver::doRefine 100 // maxIter ); + // Refine any hexes with 5 or 6 faces refined to make smooth edges + danglingCellRefine + ( + refineParams, + 21, // 1 coarse face + 5 refined faces + 100 // maxIter + ); + danglingCellRefine + ( + refineParams, + 24, // 0 coarse faces + 6 refined faces + 100 // maxIter + ); + // Introduce baffles at surface intersections. Remove sections unreachable // from keepPoint. baffleAndSplitMesh(refineParams, prepareForSnapping, motionDict); diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.H b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.H index 37a0f6b10258fd7ed7a1d54b6a66c447720ee678..c44a14a79457e33cdb82643d24c0701781fea566 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.H +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -88,6 +88,21 @@ class autoRefineDriver const label maxIter ); + //- Refine all cells in small gaps + label gapOnlyRefine + ( + const refinementParameters& refineParams, + const label maxIter + ); + + //- Refine cells with almost all sides refined + label danglingCellRefine + ( + const refinementParameters& refineParams, + const label nFaces, + const label maxIter + ); + //- Remove all cells within intersected region void removeInsideCells ( diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.C index ab2140a4ec73c7795d3bde4a83f780c6f8146865..7bf8d8cf6c40f65f1bd2a6eea082d551e3cecb38 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -41,6 +41,7 @@ Foam::refinementParameters::refinementParameters maxLocalCells_(readLabel(dict.lookup("procCellLimit"))), minRefineCells_(readLabel(dict.lookup("minimumRefine"))), curvature_(readScalar(dict.lookup("curvature"))), + planarAngle_(dict.lookupOrDefault("planarAngle", curvature_)), nBufferLayers_(readLabel(dict.lookup("nBufferLayers"))), keepPoints_(dict.lookup("keepPoints")), allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")), @@ -53,6 +54,14 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict) maxGlobalCells_(readLabel(dict.lookup("maxGlobalCells"))), maxLocalCells_(readLabel(dict.lookup("maxLocalCells"))), minRefineCells_(readLabel(dict.lookup("minRefinementCells"))), + planarAngle_ + ( + dict.lookupOrDefault + ( + "planarAngle", + readScalar(dict.lookup("resolveFeatureAngle")) + ) + ), nBufferLayers_(readLabel(dict.lookup("nCellsBetweenLevels"))), keepPoints_(pointField(1, dict.lookup("locationInMesh"))), allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")), diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.H b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.H index 66867e7f555315ea8acb8ae7bda833cf457ef580..4fb05644e80b1748c7a39c59dfd9f76112943ba0 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.H +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/refinementParameters/refinementParameters.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -67,6 +67,9 @@ class refinementParameters //- Curvature scalar curvature_; + //- Planarity criterion + scalar planarAngle_; + //- Number of layers between different refinement levels const label nBufferLayers_; @@ -129,6 +132,12 @@ public: return curvature_; } + //- Angle when two intersections are considered to be planar + scalar planarAngle() const + { + return planarAngle_; + } + //- Number of layers between different refinement levels label nBufferLayers() const { diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H index 6ab861d8a4bc16ba9ddeaa2ebba5b38104d23f8d..7487e8a2bf12b00072e8913133d01af81b5a0e51 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H @@ -253,6 +253,14 @@ private: label& nRefine ); + //- Mark every cell with level of feature passing through it + // (or -1 if not passed through). Uses tracking. + void markFeatureCellLevel + ( + const point& keepPoint, + labelList& maxFeatureLevel + ) const; + //- Calculate list of cells to refine based on intersection of // features. label markFeatureRefinement @@ -327,6 +335,48 @@ private: label& nRefine ) const; + //- Is local topology a small gap? + bool isGap + ( + const scalar, + const vector&, + const vector&, + const vector&, + const vector& + ) const; + + //- Mark cell if local a gap topology or + bool checkProximity + ( + const scalar planarCos, + const label nAllowRefine, + + const label surfaceLevel, + const vector& surfaceLocation, + const vector& surfaceNormal, + + const label cellI, + + label& cellMaxLevel, + vector& cellMaxLocation, + vector& cellMaxNormal, + + labelList& refineCell, + label& nRefine + ) const; + + //- Mark cells for surface proximity based refinement. + label markProximityRefinement + ( + const scalar curvature, + const label nAllowRefine, + const labelList& neiLevel, + const pointField& neiCc, + + labelList& refineCell, + label& nRefine + ) const; + // Baffle handling //- Get faces to repatch. Returns map from face to patch. @@ -337,16 +387,6 @@ private: const labelList& globalToSlavePatch ) const; - //- Geometric test on see whether face needs to be baffled: - // is face boundary face and perpendicular to surface normal? - bool validBaffleTopology - ( - const label faceI, - const vector& n1, - const vector& n2, - const vector& testDir - ) const; - //- Determine patches for baffles void getBafflePatches ( @@ -435,7 +475,11 @@ private: //- Extract those baffles (duplicate) faces that are on the edge // of a baffle region. These are candidates for merging. - List<labelPair> freeStandingBaffles(const List<labelPair>&) const; + List<labelPair> freeStandingBaffles + ( + const List<labelPair>&, + const scalar freeStandingAngle + ) const; // Zone handling @@ -489,6 +533,16 @@ private: labelList& namedSurfaceIndex ) const; + //- Remove any loose standing cells + void handleSnapProblems + ( + const bool removeEdgeConnectedCells, + const scalarField& perpendicularAngle, + const dictionary& motionDict, + Time& runTime, + const labelList& globalToMasterPatch, + const labelList& globalToSlavePatch + ); //- Disallow default bitwise copy construct meshRefinement(const meshRefinement&); @@ -664,12 +718,14 @@ public: ( const point& keepPoint, const scalar curvature, + const scalar planarAngle, const bool featureRefinement, const bool featureDistanceRefinement, const bool internalRefinement, const bool surfaceRefinement, const bool curvatureRefinement, + const bool gapRefinement, const label maxGlobalCells, const label maxLocalCells ) const; @@ -707,6 +763,7 @@ public: const bool removeEdgeConnectedCells, const scalarField& perpendicularAngle, const bool mergeFreeStanding, + const scalar freeStandingAngle, const dictionary& motionDict, Time& runTime, const labelList& globalToMasterPatch, diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C index 339e51cd7fde79148ef53b9eb6eb9fa99c42a046..628dd7898ac9fb7327eb45f8df981152601b2794 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C @@ -44,6 +44,7 @@ License #include "regionSplit.H" #include "removeCells.H" #include "unitConversion.H" +#include "OBJstream.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -217,43 +218,43 @@ Foam::label Foam::meshRefinement::getBafflePatch } -// Check if we are a boundary face and normal of surface does -// not align with test vector. In this case there'd probably be -// a freestanding 'baffle' so we might as well not create it. -// Note that since it is not a proper baffle we cannot detect it -// afterwards so this code cannot be merged with the -// filterDuplicateFaces code. -bool Foam::meshRefinement::validBaffleTopology -( - const label faceI, - const vector& n1, - const vector& n2, - const vector& testDir -) const -{ - - label patchI = mesh_.boundaryMesh().whichPatch(faceI); - if (patchI == -1 || mesh_.boundaryMesh()[patchI].coupled()) - { - return true; - } - else if (mag(n1&n2) > cos(degToRad(30))) - { - // Both normals aligned. Check that test vector perpendicularish to - // surface normal - scalar magTestDir = mag(testDir); - if (magTestDir > VSMALL) - { - if (mag(n1&(testDir/magTestDir)) < cos(degToRad(45))) - { - //Pout<< "** disabling baffling face " - // << mesh_.faceCentres()[faceI] << endl; - return false; - } - } - } - return true; -} +//// Check if we are a boundary face and normal of surface does +//// not align with test vector. In this case there'd probably be +//// a freestanding 'baffle' so we might as well not create it. +//// Note that since it is not a proper baffle we cannot detect it +//// afterwards so this code cannot be merged with the +//// filterDuplicateFaces code. +//bool Foam::meshRefinement::validBaffleTopology +//( +// const label faceI, +// const vector& n1, +// const vector& n2, +// const vector& testDir +//) const +//{ +// +// label patchI = mesh_.boundaryMesh().whichPatch(faceI); +// if (patchI == -1 || mesh_.boundaryMesh()[patchI].coupled()) +// { +// return true; +// } +// else if (mag(n1&n2) > cos(degToRad(30))) +// { +// // Both normals aligned. Check that test vector perpendicularish to +// // surface normal +// scalar magTestDir = mag(testDir); +// if (magTestDir > VSMALL) +// { +// if (mag(n1&(testDir/magTestDir)) < cos(degToRad(45))) +// { +// //Pout<< "** disabling baffling face " +// // << mesh_.faceCentres()[faceI] << endl; +// return false; +// } +// } +// } +// return true; +//} // Determine patches for baffles on all intersected unnamed faces @@ -800,7 +801,8 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::createZoneBaffles // region. Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles ( - const List<labelPair>& couples + const List<labelPair>& couples, + const scalar planarAngle ) const { // All duplicate faces on edge of the patch are to be merged. @@ -809,6 +811,22 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles labelList nBafflesPerEdge(mesh_.nEdges(), 0); + // This algorithm is quite tricky. We don't want to use edgeFaces and + // also want it to run in parallel so it is now an algorithm over + // all (boundary) faces instead. + // We want to pick up any edges that are only used by the baffle + // or internal faces but not by any other boundary faces. So + // - increment count on an edge by 1 if it is used by any (uncoupled) + // boundary face. + // - increment count on an edge by 1000000 if it is used by a baffle face + // - sum in parallel + // + // So now any edge that is used by baffle faces only will have the + // value 2*1000000+2*1. + + + const label baffleValue = 1000000; + // Count number of boundary faces per edge // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -847,18 +865,22 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles forAll(couples, i) { - const labelList& fEdges0 = mesh_.faceEdges(couples[i].first(), fe0); - - forAll(fEdges0, fEdgeI) { - nBafflesPerEdge[fEdges0[fEdgeI]] += 1000000; + label f0 = couples[i].first(); + const labelList& fEdges0 = mesh_.faceEdges(f0, fe0); + forAll(fEdges0, fEdgeI) + { + nBafflesPerEdge[fEdges0[fEdgeI]] += baffleValue; + } } - const labelList& fEdges1 = mesh_.faceEdges(couples[i].second(), fe1); - - forAll(fEdges1, fEdgeI) { - nBafflesPerEdge[fEdges1[fEdgeI]] += 1000000; + label f1 = couples[i].second(); + const labelList& fEdges1 = mesh_.faceEdges(f1, fe1); + forAll(fEdges1, fEdgeI) + { + nBafflesPerEdge[fEdges1[fEdgeI]] += baffleValue; + } } } @@ -873,8 +895,8 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles // Baffles which are not next to other boundaries and baffles will have - // nBafflesPerEdge value 2*1000000+2*1 (from 2 boundary faces which are - // both baffle faces) + // nBafflesPerEdge value 2*baffleValue+2*1 (from 2 boundary faces which + // are both baffle faces) List<labelPair> filteredCouples(couples.size()); label filterI = 0; @@ -889,15 +911,15 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles == patches.whichPatch(couple.second()) ) { - const labelList& fEdges = mesh_.faceEdges(couples[i].first()); + const labelList& fEdges = mesh_.faceEdges(couple.first()); forAll(fEdges, fEdgeI) { label edgeI = fEdges[fEdgeI]; - if (nBafflesPerEdge[edgeI] == 2*1000000+2*1) + if (nBafflesPerEdge[edgeI] == 2*baffleValue+2*1) { - filteredCouples[filterI++] = couples[i]; + filteredCouples[filterI++] = couple; break; } } @@ -905,111 +927,127 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles } filteredCouples.setSize(filterI); - //Info<< "freeStandingBaffles : from " - // << returnReduce(couples.size(), sumOp<label>()) - // << " down to " - // << returnReduce(filteredCouples.size(), sumOp<label>()) - // << " baffles." << nl << endl; + label nFiltered = returnReduce(filteredCouples.size(), sumOp<label>()); + Info<< "freeStandingBaffles : detected " + << nFiltered + << " free-standing baffles out of " + << returnReduce(couples.size(), sumOp<label>()) + << nl << endl; -//XXXXXX -// { -// // Collect segments -// // ~~~~~~~~~~~~~~~~ -// -// pointField start(filteredCouples.size()); -// pointField end(filteredCouples.size()); -// -// const pointField& cellCentres = mesh_.cellCentres(); -// -// forAll(filteredCouples, i) -// { -// const labelPair& couple = couples[i]; -// start[i] = cellCentres[mesh_.faceOwner()[couple.first()]]; -// end[i] = cellCentres[mesh_.faceOwner()[couple.second()]]; -// } -// -// // Extend segments a bit -// { -// const vectorField smallVec(Foam::sqrt(SMALL)*(end-start)); -// start -= smallVec; -// end += smallVec; -// } -// -// -// // Do test for intersections -// // ~~~~~~~~~~~~~~~~~~~~~~~~~ -// labelList surface1; -// List<pointIndexHit> hit1; -// labelList region1; -// vectorField normal1; -// -// labelList surface2; -// List<pointIndexHit> hit2; -// labelList region2; -// vectorField normal2; -// -// surfaces_.findNearestIntersection -// ( -// surfacesToBaffle, -// start, -// end, -// -// surface1, -// hit1, -// region1, -// normal1, -// -// surface2, -// hit2, -// region2, -// normal2 -// ); -// -// forAll(testFaces, i) -// { -// if (hit1[i].hit() && hit2[i].hit()) -// { -// bool createBaffle = true; -// -// label faceI = couples[i].first(); -// label patchI = mesh_.boundaryMesh().whichPatch(faceI); -// if (patchI != -1 && !mesh_.boundaryMesh()[patchI].coupled()) -// { -// // Check if we are a boundary face and normal of surface -// // does -// // not align with test vector. In this case there'd -// // probably be -// // a freestanding 'baffle' so we might as well not -// // create it. -// // Note that since it is not a proper baffle we cannot -// // detect it -// // afterwards so this code cannot be merged with the -// // filterDuplicateFaces code. -// if (mag(normal1[i]&normal2[i]) > cos(degToRad(30))) -// { -// // Both normals aligned -// vector n = end[i]-start[i]; -// scalar magN = mag(n); -// if (magN > VSMALL) -// { -// n /= magN; -// -// if (mag(normal1[i]&n) < cos(degToRad(45))) -// { -// Pout<< "** disabling baffling face " -// << mesh_.faceCentres()[faceI] << endl; -// createBaffle = false; -// } -// } -// } -// } -// -// -// } -//XXXXXX + if (nFiltered > 0) + { + // Collect segments + // ~~~~~~~~~~~~~~~~ + + pointField start(filteredCouples.size()); + pointField end(filteredCouples.size()); + + const pointField& cellCentres = mesh_.cellCentres(); + + forAll(filteredCouples, i) + { + const labelPair& couple = filteredCouples[i]; + start[i] = cellCentres[mesh_.faceOwner()[couple.first()]]; + end[i] = cellCentres[mesh_.faceOwner()[couple.second()]]; + } + + // Extend segments a bit + { + const vectorField smallVec(Foam::sqrt(SMALL)*(end-start)); + start -= smallVec; + end += smallVec; + } + + + // Do test for intersections + // ~~~~~~~~~~~~~~~~~~~~~~~~~ + labelList surface1; + List<pointIndexHit> hit1; + labelList region1; + vectorField normal1; + + labelList surface2; + List<pointIndexHit> hit2; + labelList region2; + vectorField normal2; + + surfaces_.findNearestIntersection + ( + identity(surfaces_.surfaces().size()), + start, + end, + + surface1, + hit1, + region1, + normal1, + + surface2, + hit2, + region2, + normal2 + ); + + //mkDir(mesh_.time().path()/timeName()); + //OBJstream str + //( + // mesh_.time().path()/timeName()/"flatBaffles.obj" + //); + + const scalar planarAngleCos = Foam::cos(degToRad(planarAngle)); + + label filterI = 0; + forAll(filteredCouples, i) + { + const labelPair& couple = filteredCouples[i]; + + if + ( + hit1[i].hit() + && hit2[i].hit() + && ( + surface1[i] != surface2[i] + || hit1[i].index() != hit2[i].index() + ) + ) + { + // Two different hits. Check angle. + //str.write + //( + // linePointRef(hit1[i].hitPoint(), hit2[i].hitPoint()), + // normal1[i], + // normal2[i] + //); + + if ((normal1[i]&normal2[i]) > planarAngleCos) + { + // Both normals aligned + vector n = end[i]-start[i]; + scalar magN = mag(n); + if (magN > VSMALL) + { + filteredCouples[filterI++] = couple; + } + } + } + else if (hit1[i].hit() || hit2[i].hit()) + { + // Single hit. Do not include in freestanding baffles. + } + } + + filteredCouples.setSize(filterI); + + Info<< "freeStandingBaffles : detected " + << returnReduce(filterI, sumOp<label>()) + << " planar (within " << planarAngle + << " degrees) free-standing baffles out of " + << nFiltered + << nl << endl; + } return filteredCouples; } @@ -1832,15 +1870,102 @@ void Foam::meshRefinement::makeConsistentFaceIndex } +void Foam::meshRefinement::handleSnapProblems +( + const bool removeEdgeConnectedCells, + const scalarField& perpendicularAngle, + const dictionary& motionDict, + Time& runTime, + const labelList& globalToMasterPatch, + const labelList& globalToSlavePatch +) +{ + Info<< nl + << "Introducing baffles to block off problem cells" << nl + << "----------------------------------------------" << nl + << endl; + + labelList facePatch + ( + markFacesOnProblemCells + ( + motionDict, + removeEdgeConnectedCells, + perpendicularAngle, + globalToMasterPatch + ) + ); + Info<< "Analyzed problem cells in = " + << runTime.cpuTimeIncrement() << " s\n" << nl << endl; + + if (debug&meshRefinement::MESH) + { + faceSet problemTopo(mesh_, "problemFacesTopo", 100); + + const labelList facePatchTopo + ( + markFacesOnProblemCells + ( + motionDict, + removeEdgeConnectedCells, + perpendicularAngle, + globalToMasterPatch + ) + ); + forAll(facePatchTopo, faceI) + { + if (facePatchTopo[faceI] != -1) + { + problemTopo.insert(faceI); + } + } + problemTopo.instance() = timeName(); + Pout<< "Dumping " << problemTopo.size() + << " problem faces to " << problemTopo.objectPath() << endl; + problemTopo.write(); + } + + Info<< "Introducing baffles to delete problem cells." << nl << endl; + + if (debug) + { + runTime++; + } + + // Create baffles with same owner and neighbour for now. + createBaffles(facePatch, facePatch); + + if (debug) + { + // Debug:test all is still synced across proc patches + checkData(); + } + Info<< "Created baffles in = " + << runTime.cpuTimeIncrement() << " s\n" << nl << endl; + + printMeshInfo(debug, "After introducing baffles"); + + if (debug&meshRefinement::MESH) + { + Pout<< "Writing extra baffled mesh to time " + << timeName() << endl; + write(debug, runTime.path()/"extraBaffles"); + Pout<< "Dumped debug data in = " + << runTime.cpuTimeIncrement() << " s\n" << nl << endl; + } +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // Split off unreachable areas of mesh. void Foam::meshRefinement::baffleAndSplitMesh ( - const bool handleSnapProblems, + const bool doHandleSnapProblems, const bool removeEdgeConnectedCells, const scalarField& perpendicularAngle, const bool mergeFreeStanding, + const scalar planarAngle, const dictionary& motionDict, Time& runTime, const labelList& globalToMasterPatch, @@ -1902,82 +2027,92 @@ void Foam::meshRefinement::baffleAndSplitMesh // Create some additional baffles where we want surface cells removed. - if (handleSnapProblems) - { - Info<< nl - << "Introducing baffles to block off problem cells" << nl - << "----------------------------------------------" << nl - << endl; - - labelList facePatch + if (doHandleSnapProblems) + { + //Info<< nl + // << "Introducing baffles to block off problem cells" << nl + // << "----------------------------------------------" << nl + // << endl; + // + //labelList facePatch + //( + // markFacesOnProblemCells + // ( + // motionDict, + // removeEdgeConnectedCells, + // perpendicularAngle, + // globalToMasterPatch + // ) + // //markFacesOnProblemCellsGeometric(motionDict) + //); + //Info<< "Analyzed problem cells in = " + // << runTime.cpuTimeIncrement() << " s\n" << nl << endl; + // + //if (debug&meshRefinement::MESH) + //{ + // faceSet problemTopo(mesh_, "problemFacesTopo", 100); + // + // const labelList facePatchTopo + // ( + // markFacesOnProblemCells + // ( + // motionDict, + // removeEdgeConnectedCells, + // perpendicularAngle, + // globalToMasterPatch + // ) + // ); + // forAll(facePatchTopo, faceI) + // { + // if (facePatchTopo[faceI] != -1) + // { + // problemTopo.insert(faceI); + // } + // } + // problemTopo.instance() = timeName(); + // Pout<< "Dumping " << problemTopo.size() + // << " problem faces to " << problemTopo.objectPath() << endl; + // problemTopo.write(); + //} + // + //Info<< "Introducing baffles to delete problem cells." << nl << endl; + // + //if (debug) + //{ + // runTime++; + //} + // + //// Create baffles with same owner and neighbour for now. + //createBaffles(facePatch, facePatch); + // + //if (debug) + //{ + // // Debug:test all is still synced across proc patches + // checkData(); + //} + //Info<< "Created baffles in = " + // << runTime.cpuTimeIncrement() << " s\n" << nl << endl; + // + //printMeshInfo(debug, "After introducing baffles"); + // + //if (debug&meshRefinement::MESH) + //{ + // Pout<< "Writing extra baffled mesh to time " + // << timeName() << endl; + // write(debug, runTime.path()/"extraBaffles"); + // Pout<< "Dumped debug data in = " + // << runTime.cpuTimeIncrement() << " s\n" << nl << endl; + //} + + handleSnapProblems ( - markFacesOnProblemCells - ( - motionDict, - removeEdgeConnectedCells, - perpendicularAngle, - globalToMasterPatch - ) - //markFacesOnProblemCellsGeometric(motionDict) + removeEdgeConnectedCells, + perpendicularAngle, + motionDict, + runTime, + globalToMasterPatch, + globalToSlavePatch ); - Info<< "Analyzed problem cells in = " - << runTime.cpuTimeIncrement() << " s\n" << nl << endl; - - if (debug&meshRefinement::MESH) - { - faceSet problemTopo(mesh_, "problemFacesTopo", 100); - - const labelList facePatchTopo - ( - markFacesOnProblemCells - ( - motionDict, - removeEdgeConnectedCells, - perpendicularAngle, - globalToMasterPatch - ) - ); - forAll(facePatchTopo, faceI) - { - if (facePatchTopo[faceI] != -1) - { - problemTopo.insert(faceI); - } - } - problemTopo.instance() = timeName(); - Pout<< "Dumping " << problemTopo.size() - << " problem faces to " << problemTopo.objectPath() << endl; - problemTopo.write(); - } - - Info<< "Introducing baffles to delete problem cells." << nl << endl; - - if (debug) - { - runTime++; - } - - // Create baffles with same owner and neighbour for now. - createBaffles(facePatch, facePatch); - - if (debug) - { - // Debug:test all is still synced across proc patches - checkData(); - } - Info<< "Created baffles in = " - << runTime.cpuTimeIncrement() << " s\n" << nl << endl; - - printMeshInfo(debug, "After introducing baffles"); - - if (debug&meshRefinement::MESH) - { - Pout<< "Writing extra baffled mesh to time " - << timeName() << endl; - write(debug, runTime.path()/"extraBaffles"); - Pout<< "Dumped debug data in = " - << runTime.cpuTimeIncrement() << " s\n" << nl << endl; - } } @@ -2036,7 +2171,8 @@ void Foam::meshRefinement::baffleAndSplitMesh ( identity(mesh_.nFaces()-mesh_.nInternalFaces()) +mesh_.nInternalFaces() - ) + ), + planarAngle ) ); @@ -2052,6 +2188,18 @@ void Foam::meshRefinement::baffleAndSplitMesh // from them. mergeBaffles(couples); + // Detect any problem cells resulting from merging of baffles + // and delete them + handleSnapProblems + ( + removeEdgeConnectedCells, + perpendicularAngle, + motionDict, + runTime, + globalToMasterPatch, + globalToSlavePatch + ); + if (debug) { // Debug:test all is still synced across proc patches @@ -2663,18 +2811,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify if (surface1[i] != -1) { - //- Not allowed not to create baffle - is vital for regioning. - // Have logic instead at erosion! - //bool createBaffle = validBaffleTopology - //( - // faceI, - // normal1[i], - // normal2[i], - // end[i]-start[i] - //); - // - - // If both hit should probably choose 'nearest' if ( diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C index 42e7983e5a73aa2274c81e05ff712b46d90fdcd9..9667750cf56f4d8e1d8b162a24bb37648184cc06 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C @@ -38,6 +38,7 @@ License #include "featureEdgeMesh.H" #include "Cloud.H" //#include "globalIndex.H" +//#include "OBJstream.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -244,14 +245,10 @@ bool Foam::meshRefinement::markForRefine } -// Calculates list of cells to refine based on intersection with feature edge. -Foam::label Foam::meshRefinement::markFeatureRefinement +void Foam::meshRefinement::markFeatureCellLevel ( const point& keepPoint, - const label nAllowRefine, - - labelList& refineCell, - label& nRefine + labelList& maxFeatureLevel ) const { // We want to refine all cells containing a feature edge. @@ -384,7 +381,7 @@ Foam::label Foam::meshRefinement::markFeatureRefinement // Largest refinement level of any feature passed through - labelList maxFeatureLevel(mesh_.nCells(), -1); + maxFeatureLevel = labelList(mesh_.nCells(), -1); // Database to pass into trackedParticle::move trackedParticle::trackingData td(cloud, maxFeatureLevel); @@ -467,7 +464,22 @@ Foam::label Foam::meshRefinement::markFeatureRefinement // Track all particles to their end position. cloud.move(td, GREAT); } +} + + +// Calculates list of cells to refine based on intersection with feature edge. +Foam::label Foam::meshRefinement::markFeatureRefinement +( + const point& keepPoint, + const label nAllowRefine, + labelList& refineCell, + label& nRefine +) const +{ + // Largest refinement level of any feature passed through + labelList maxFeatureLevel; + markFeatureCellLevel(keepPoint, maxFeatureLevel); // See which cells to refine. maxFeatureLevel will hold highest level // of any feature edge that passed through. @@ -1011,6 +1023,9 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement end, minLevel, // max level of surface has to be bigger // than min level of neighbouring cells + + surfaces_.maxLevel(), + surfaceNormal, surfaceLevel ); @@ -1199,6 +1214,473 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement } +// Mark small gaps +bool Foam::meshRefinement::isGap +( + const scalar planarCos, + const vector& point0, + const vector& normal0, + + const vector& point1, + const vector& normal1 +) const +{ + ////- hits differ and angles are oppositeish + //return + // (mag(point0-point1) > mergeDistance()) + // && ((normal0 & normal1) < (-1+planarCos)); + + + //- hits differ and angles are oppositeish and + // hits have a normal distance + vector d = point1-point0; + scalar magD = mag(d); + + if (magD > mergeDistance()) + { + scalar cosAngle = (normal0 & normal1); + + vector avg = vector::zero; + if (cosAngle < (-1+planarCos)) + { + // Opposite normals + avg = 0.5*(normal0-normal1); + } + else if (cosAngle > (1-planarCos)) + { + avg = 0.5*(normal0+normal1); + } + + if (avg != vector::zero) + { + avg /= mag(avg); + d /= magD; + + // Check average normal with respect to intersection locations + if (mag(avg&d) > Foam::cos(degToRad(45))) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + else + { + return false; + } +} + + +bool Foam::meshRefinement::checkProximity +( + const scalar planarCos, + const label nAllowRefine, + + const label surfaceLevel, // current intersection max level + const vector& surfaceLocation, // current intersection location + const vector& surfaceNormal, // current intersection normal + + const label cellI, + + label& cellMaxLevel, // cached max surface level for this cell + vector& cellMaxLocation, // cached surface normal for this cell + vector& cellMaxNormal, // cached surface normal for this cell + + labelList& refineCell, + label& nRefine +) const +{ + const labelList& cellLevel = meshCutter_.cellLevel(); + + // Test if surface applicable + if (surfaceLevel > cellLevel[cellI]) + { + if (cellMaxLevel == -1) + { + // First visit of cell. Store + cellMaxLevel = surfaceLevel; + cellMaxLocation = surfaceLocation; + cellMaxNormal = surfaceNormal; + } + else + { + // Second or more visit. + // Check if + // - different location + // - opposite surface + + bool closeSurfaces = isGap + ( + planarCos, + cellMaxLocation, + cellMaxNormal, + surfaceLocation, + surfaceNormal + ); + + // Set normal to that of highest surface. Not really necessary + // over here but we reuse cellMax info when doing coupled faces. + if (surfaceLevel > cellMaxLevel) + { + cellMaxLevel = surfaceLevel; + cellMaxLocation = surfaceLocation; + cellMaxNormal = surfaceNormal; + } + + + if (closeSurfaces) + { + //Pout<< "Found gap:" << nl + // << " location:" << surfaceLocation + // << "\tnormal :" << surfaceNormal << nl + /// << " location:" << cellMaxLocation + // << "\tnormal :" << cellMaxNormal << nl + // << "\tcos :" << (surfaceNormal&cellMaxNormal) << nl + // << endl; + + return markForRefine + ( + surfaceLevel, // mark with any non-neg number. + nAllowRefine, + refineCell[cellI], + nRefine + ); + } + } + } + + // Did not reach refinement limit. + return true; +} + + +Foam::label Foam::meshRefinement::markProximityRefinement +( + const scalar planarCos, + const label nAllowRefine, + const labelList& neiLevel, + const pointField& neiCc, + + labelList& refineCell, + label& nRefine +) const +{ + const labelList& cellLevel = meshCutter_.cellLevel(); + const pointField& cellCentres = mesh_.cellCentres(); + + label oldNRefine = nRefine; + + // 1. local test: any cell on more than one surface gets refined + // (if its current level is < max of the surface max level) + + // 2. 'global' test: any cell on only one surface with a neighbour + // on a different surface gets refined (if its current level etc.) + + + // Collect candidate faces (i.e. intersecting any surface and + // owner/neighbour not yet refined. + labelList testFaces(getRefineCandidateFaces(refineCell)); + + // Collect segments + pointField start(testFaces.size()); + pointField end(testFaces.size()); + labelList minLevel(testFaces.size()); + + forAll(testFaces, i) + { + label faceI = testFaces[i]; + + label own = mesh_.faceOwner()[faceI]; + + if (mesh_.isInternalFace(faceI)) + { + label nei = mesh_.faceNeighbour()[faceI]; + + start[i] = cellCentres[own]; + end[i] = cellCentres[nei]; + minLevel[i] = min(cellLevel[own], cellLevel[nei]); + } + else + { + label bFaceI = faceI - mesh_.nInternalFaces(); + + start[i] = cellCentres[own]; + end[i] = neiCc[bFaceI]; + minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]); + } + } + + // Extend segments a bit + { + const vectorField smallVec(Foam::sqrt(SMALL)*(end-start)); + start -= smallVec; + end += smallVec; + } + + + // Test for all intersections (with surfaces of higher gap level than + // minLevel) and cache per cell the max surface level and the local normal + // on that surface. + labelList cellMaxLevel(mesh_.nCells(), -1); + vectorField cellMaxNormal(mesh_.nCells(), vector::zero); + pointField cellMaxLocation(mesh_.nCells(), vector::zero); + + { + // Per segment the normals of the surfaces + List<vectorList> surfaceLocation; + List<vectorList> surfaceNormal; + // Per segment the list of levels of the surfaces + labelListList surfaceLevel; + + surfaces_.findAllHigherIntersections + ( + start, + end, + minLevel, // gap level of surface has to be bigger + // than min level of neighbouring cells + + surfaces_.gapLevel(), + + surfaceLocation, + surfaceNormal, + surfaceLevel + ); + // Clear out unnecessary data + start.clear(); + end.clear(); + minLevel.clear(); + + //// Extract per cell information on the surface with the highest max + //OBJstream str + //( + // mesh_.time().path() + // / "findAllHigherIntersections_" + // + mesh_.time().timeName() + // + ".obj" + //); + //// All intersections + //OBJstream str2 + //( + // mesh_.time().path() + // / "findAllHigherIntersections2_" + // + mesh_.time().timeName() + // + ".obj" + //); + + forAll(testFaces, i) + { + label faceI = testFaces[i]; + label own = mesh_.faceOwner()[faceI]; + + const labelList& fLevels = surfaceLevel[i]; + const vectorList& fPoints = surfaceLocation[i]; + const vectorList& fNormals = surfaceNormal[i]; + + forAll(fLevels, hitI) + { + checkProximity + ( + planarCos, + nAllowRefine, + + fLevels[hitI], + fPoints[hitI], + fNormals[hitI], + + own, + cellMaxLevel[own], + cellMaxLocation[own], + cellMaxNormal[own], + + refineCell, + nRefine + ); + } + + if (mesh_.isInternalFace(faceI)) + { + label nei = mesh_.faceNeighbour()[faceI]; + + forAll(fLevels, hitI) + { + checkProximity + ( + planarCos, + nAllowRefine, + + fLevels[hitI], + fPoints[hitI], + fNormals[hitI], + + nei, + cellMaxLevel[nei], + cellMaxLocation[nei], + cellMaxNormal[nei], + + refineCell, + nRefine + ); + } + } + } + } + + // 2. Find out a measure of surface curvature and region edges. + // Send over surface region and surface normal to neighbour cell. + + labelList neiBndMaxLevel(mesh_.nFaces()-mesh_.nInternalFaces()); + pointField neiBndMaxLocation(mesh_.nFaces()-mesh_.nInternalFaces()); + vectorField neiBndMaxNormal(mesh_.nFaces()-mesh_.nInternalFaces()); + + for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++) + { + label bFaceI = faceI-mesh_.nInternalFaces(); + label own = mesh_.faceOwner()[faceI]; + + neiBndMaxLevel[bFaceI] = cellMaxLevel[own]; + neiBndMaxLocation[bFaceI] = cellMaxLocation[own]; + neiBndMaxNormal[bFaceI] = cellMaxNormal[own]; + } + syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLevel); + syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLocation); + syncTools::swapBoundaryFaceList(mesh_, neiBndMaxNormal); + + // Loop over all faces. Could only be checkFaces.. except if they're coupled + + // Internal faces + for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) + { + label own = mesh_.faceOwner()[faceI]; + label nei = mesh_.faceNeighbour()[faceI]; + + if (cellMaxLevel[own] != -1 && cellMaxLevel[nei] != -1) + { + // Have valid data on both sides. Check planarCos. + if + ( + isGap + ( + planarCos, + cellMaxLocation[own], + cellMaxNormal[own], + cellMaxLocation[nei], + cellMaxNormal[nei] + ) + ) + { + // See which side to refine + if (cellLevel[own] < cellMaxLevel[own]) + { + if + ( + !markForRefine + ( + cellMaxLevel[own], + nAllowRefine, + refineCell[own], + nRefine + ) + ) + { + if (debug) + { + Pout<< "Stopped refining since reaching my cell" + << " limit of " << mesh_.nCells()+7*nRefine + << endl; + } + break; + } + } + + if (cellLevel[nei] < cellMaxLevel[nei]) + { + if + ( + !markForRefine + ( + cellMaxLevel[nei], + nAllowRefine, + refineCell[nei], + nRefine + ) + ) + { + if (debug) + { + Pout<< "Stopped refining since reaching my cell" + << " limit of " << mesh_.nCells()+7*nRefine + << endl; + } + break; + } + } + } + } + } + // Boundary faces + for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++) + { + label own = mesh_.faceOwner()[faceI]; + label bFaceI = faceI - mesh_.nInternalFaces(); + + if (cellLevel[own] < cellMaxLevel[own] && neiBndMaxLevel[bFaceI] != -1) + { + // Have valid data on both sides. Check planarCos. + if + ( + isGap + ( + planarCos, + cellMaxLocation[own], + cellMaxNormal[own], + neiBndMaxLocation[bFaceI], + neiBndMaxNormal[bFaceI] + ) + ) + { + if + ( + !markForRefine + ( + cellMaxLevel[own], + nAllowRefine, + refineCell[own], + nRefine + ) + ) + { + if (debug) + { + Pout<< "Stopped refining since reaching my cell" + << " limit of " << mesh_.nCells()+7*nRefine + << endl; + } + break; + } + } + } + } + + if + ( + returnReduce(nRefine, sumOp<label>()) + > returnReduce(nAllowRefine, sumOp<label>()) + ) + { + Info<< "Reached refinement limit." << endl; + } + + return returnReduce(nRefine-oldNRefine, sumOp<label>()); +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // Calculate list of cells to refine. Gets for any edge (start - end) @@ -1210,12 +1692,14 @@ Foam::labelList Foam::meshRefinement::refineCandidates ( const point& keepPoint, const scalar curvature, + const scalar planarAngle, const bool featureRefinement, const bool featureDistanceRefinement, const bool internalRefinement, const bool surfaceRefinement, const bool curvatureRefinement, + const bool gapRefinement, const label maxGlobalCells, const label maxLocalCells ) const @@ -1359,6 +1843,35 @@ Foam::labelList Foam::meshRefinement::refineCandidates << ": " << nCurv << " cells." << endl; } + + const scalar planarCos = Foam::cos(degToRad(planarAngle)); + + if + ( + gapRefinement + && (planarCos >= -1 && planarCos <= 1) + && (max(surfaces_.gapLevel()) > -1) + ) + { + Info<< "Specified gap level : " << max(surfaces_.gapLevel()) + << ", planar angle " << planarAngle << endl; + + label nGap = markProximityRefinement + ( + planarCos, + nAllowRefine, + neiLevel, + neiCc, + + refineCell, + nRefine + ); + Info<< "Marked for refinement due to close opposite surfaces " + << ": " << nGap << " cells." << endl; + } + + + // Pack cells-to-refine // ~~~~~~~~~~~~~~~~~~~~ diff --git a/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C b/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C index f53968532c36a0b54c38a0a215bf92517b904793..f1917ee6f94a14a5f8e9462319a0fbfdd12b4425 100644 --- a/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C +++ b/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C @@ -116,10 +116,12 @@ Foam::refinementSurfaces::refinementSurfaces labelList globalMinLevel(surfI, 0); labelList globalMaxLevel(surfI, 0); + labelList globalLevelIncr(surfI, 0); scalarField globalAngle(surfI, -GREAT); PtrList<dictionary> globalPatchInfo(surfI); List<Map<label> > regionMinLevel(surfI); List<Map<label> > regionMaxLevel(surfI); + List<Map<label> > regionLevelIncr(surfI); List<Map<scalar> > regionAngle(surfI); List<Map<autoPtr<dictionary> > > regionPatchInfo(surfI); @@ -138,6 +140,31 @@ Foam::refinementSurfaces::refinementSurfaces const labelPair refLevel(dict.lookup("level")); globalMinLevel[surfI] = refLevel[0]; globalMaxLevel[surfI] = refLevel[1]; + globalLevelIncr[surfI] = dict.lookupOrDefault + ( + "gapLevelIncrement", + 0 + ); + + if + ( + globalMinLevel[surfI] < 0 + || globalMaxLevel[surfI] < globalMinLevel[surfI] + || globalLevelIncr[surfI] < 0 + ) + { + FatalErrorIn + ( + "refinementSurfaces::refinementSurfaces" + "(const searchableSurfaces&, const dictionary>&" + ) << "Illegal level specification for surface " + << names_[surfI] + << " : minLevel:" << globalMinLevel[surfI] + << " maxLevel:" << globalMaxLevel[surfI] + << " levelIncrement:" << globalLevelIncr[surfI] + << exit(FatalError); + } + // Global zone names per surface if (dict.readIfPresent("faceZone", faceZoneNames_[surfI])) @@ -244,6 +271,34 @@ Foam::refinementSurfaces::refinementSurfaces regionMinLevel[surfI].insert(regionI, refLevel[0]); regionMaxLevel[surfI].insert(regionI, refLevel[1]); + label levelIncr = regionDict.lookupOrDefault + ( + "gapLevelIncrement", + 0 + ); + regionLevelIncr[surfI].insert(regionI, levelIncr); + + if + ( + refLevel[0] < 0 + || refLevel[1] < refLevel[0] + || levelIncr < 0 + ) + { + FatalErrorIn + ( + "refinementSurfaces::refinementSurfaces" + "(const searchableSurfaces&, const dictionary>&" + ) << "Illegal level specification for surface " + << names_[surfI] << " region " + << regionNames[regionI] + << " : minLevel:" << refLevel[0] + << " maxLevel:" << refLevel[1] + << " levelIncrement:" << levelIncr + << exit(FatalError); + } + + if (regionDict.found("perpendicularAngle")) { @@ -286,6 +341,8 @@ Foam::refinementSurfaces::refinementSurfaces minLevel_ = 0; maxLevel_.setSize(nRegions); maxLevel_ = 0; + gapLevel_.setSize(nRegions); + gapLevel_ = -1; perpendicularAngle_.setSize(nRegions); perpendicularAngle_ = -GREAT; patchInfo_.setSize(nRegions); @@ -301,6 +358,10 @@ Foam::refinementSurfaces::refinementSurfaces label globalRegionI = regionOffset_[surfI] + i; minLevel_[globalRegionI] = globalMinLevel[surfI]; maxLevel_[globalRegionI] = globalMaxLevel[surfI]; + gapLevel_[globalRegionI] = + maxLevel_[globalRegionI] + + globalLevelIncr[surfI]; + perpendicularAngle_[globalRegionI] = globalAngle[surfI]; if (globalPatchInfo.set(surfI)) { @@ -319,24 +380,9 @@ Foam::refinementSurfaces::refinementSurfaces minLevel_[globalRegionI] = iter(); maxLevel_[globalRegionI] = regionMaxLevel[surfI][iter.key()]; - - // Check validity - if - ( - minLevel_[globalRegionI] < 0 - || maxLevel_[globalRegionI] < minLevel_[globalRegionI] - ) - { - FatalErrorIn - ( - "refinementSurfaces::refinementSurfaces" - "(const searchableSurfaces&, const dictionary>&" - ) << "Illegal level or layer specification for surface " - << names_[surfI] - << " : minLevel:" << minLevel_[globalRegionI] - << " maxLevel:" << maxLevel_[globalRegionI] - << exit(FatalError); - } + gapLevel_[globalRegionI] = + maxLevel_[globalRegionI] + + regionLevelIncr[surfI][iter.key()]; } forAllConstIter(Map<scalar>, regionAngle[surfI], iter) { @@ -714,6 +760,8 @@ void Foam::refinementSurfaces::findAllHigherIntersections const pointField& end, const labelList& currentLevel, // current cell refinement level + const labelList& globalRegionLevel, + List<vectorList>& surfaceNormal, labelListList& surfaceLevel ) const @@ -777,15 +825,103 @@ void Foam::refinementSurfaces::findAllHigherIntersections label region = globalRegion(surfI, surfRegion[i]); label pointI = pointMap[i]; - if (maxLevel_[region] > currentLevel[pointI]) + if (globalRegionLevel[region] > currentLevel[pointI]) + { + // Append to pointI info + label sz = surfaceNormal[pointI].size(); + surfaceNormal[pointI].setSize(sz+1); + surfaceNormal[pointI][sz] = surfNormal[i]; + + surfaceLevel[pointI].setSize(sz+1); + surfaceLevel[pointI][sz] = globalRegionLevel[region]; + } + } + } +} + + +void Foam::refinementSurfaces::findAllHigherIntersections +( + const pointField& start, + const pointField& end, + const labelList& currentLevel, // current cell refinement level + + const labelList& globalRegionLevel, + + List<pointList>& surfaceLocation, + List<vectorList>& surfaceNormal, + labelListList& surfaceLevel +) const +{ + surfaceLevel.setSize(start.size()); + surfaceNormal.setSize(start.size()); + surfaceLocation.setSize(start.size()); + + if (surfaces_.empty()) + { + return; + } + + // Work arrays + List<List<pointIndexHit> > hitInfo; + labelList pRegions; + vectorField pNormals; + + forAll(surfaces_, surfI) + { + allGeometry_[surfaces_[surfI]].findLineAll(start, end, hitInfo); + + // Repack hits for surface into flat list + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // To avoid overhead of calling getRegion for every point + + label n = 0; + forAll(hitInfo, pointI) + { + n += hitInfo[pointI].size(); + } + + List<pointIndexHit> surfInfo(n); + labelList pointMap(n); + n = 0; + + forAll(hitInfo, pointI) + { + const List<pointIndexHit>& pHits = hitInfo[pointI]; + + forAll(pHits, i) + { + surfInfo[n] = pHits[i]; + pointMap[n] = pointI; + n++; + } + } + + labelList surfRegion(n); + vectorField surfNormal(n); + allGeometry_[surfaces_[surfI]].getRegion(surfInfo, surfRegion); + allGeometry_[surfaces_[surfI]].getNormal(surfInfo, surfNormal); + + // Extract back into pointwise + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + forAll(surfRegion, i) + { + label region = globalRegion(surfI, surfRegion[i]); + label pointI = pointMap[i]; + + if (globalRegionLevel[region] > currentLevel[pointI]) { // Append to pointI info label sz = surfaceNormal[pointI].size(); + surfaceLocation[pointI].setSize(sz+1); + surfaceLocation[pointI][sz] = surfInfo[i].hitPoint(); + surfaceNormal[pointI].setSize(sz+1); surfaceNormal[pointI][sz] = surfNormal[i]; surfaceLevel[pointI].setSize(sz+1); - surfaceLevel[pointI][sz] = maxLevel_[region]; + surfaceLevel[pointI][sz] = globalRegionLevel[region]; } } } diff --git a/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H b/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H index aed21821b5cb1ea994617490a919f694becc39c2..c9773398e5f9734c31caf8644b32434f605ff91d 100644 --- a/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H +++ b/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -51,6 +51,8 @@ class searchableSurfaces; class shellSurfaces; class triSurfaceMesh; +typedef List<point> pointList; + /*---------------------------------------------------------------------------*\ Class refinementSurfaces Declaration \*---------------------------------------------------------------------------*/ @@ -120,6 +122,9 @@ private: //- From global region number to refinement level labelList maxLevel_; + //- From global region number to small-gap level + labelList gapLevel_; + //- From global region number to perpendicular angle scalarField perpendicularAngle_; @@ -226,6 +231,12 @@ public: return maxLevel_; } + //- From global region number to small gap refinement level + const labelList& gapLevel() const + { + return gapLevel_; + } + //- From global region number to perpendicular angle const scalarField& perpendicularAngle() const { @@ -295,7 +306,21 @@ public: const pointField& start, const pointField& end, const labelList& currentLevel, // current cell refinement level + const labelList& globalRegionLevel, // level per surfregion + + List<vectorList>& surfaceNormal, + labelListList& surfaceLevel + ) const; + + //- Find all intersections of edge. Unsorted order. + void findAllHigherIntersections + ( + const pointField& start, + const pointField& end, + const labelList& currentLevel, // current cell refinement level + const labelList& globalRegionLevel, // level per surfregion + List<pointList>& surfaceLocation, List<vectorList>& surfaceNormal, labelListList& surfaceLevel ) const; diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C index 8bc8b86d2ec8c601338af8226ccb3d2dcf1b6b8b..10ec0bf5d0141e8a8ddf36328dbf8ca913f659d4 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C @@ -56,6 +56,11 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolationMethodToWord method = "faceAreaWeightAMI"; break; } + case imPartialFaceAreaWeight: + { + method = "partialFaceAreaWeightAMI"; + break; + } default: { FatalErrorIn @@ -87,7 +92,15 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::wordTointerpolationMethod wordList methods ( - IStringStream("(directAMI mapNearestAMI faceAreaWeightAMI)")() + IStringStream + ( + "(" + "directAMI " + "mapNearestAMI " + "faceAreaWeightAMI " + "partialFaceAreaWeightAMI" + ")" + )() ); if (im == "directAMI") @@ -102,6 +115,10 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::wordTointerpolationMethod { method = imFaceAreaWeight; } + else if (im == "partialFaceAreaWeightAMI") + { + method = imPartialFaceAreaWeight; + } else { FatalErrorIn @@ -183,6 +200,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights const labelListList& addr, scalarListList& wght, scalarField& wghtSum, + const bool conformal, const bool output ) { @@ -191,12 +209,19 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights forAll(wght, faceI) { scalarList& w = wght[faceI]; + scalar denom = patchAreas[faceI]; + scalar s = sum(w); - scalar t = s/patchAreas[faceI]; + scalar t = s/denom; + + if (conformal) + { + denom = s; + } forAll(w, i) { - w[i] /= s; + w[i] /= denom; } wghtSum[faceI] = t; @@ -476,6 +501,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::agglomerate srcAddress, srcWeights, srcWeightsSum, + true, false ); } @@ -749,7 +775,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points()); } - // Calculate if patches present on multiple processors singlePatchProc_ = calcDistribution(srcPatch, tgtPatch); @@ -794,32 +819,28 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update newTgtPoints ); - // calculate AMI interpolation - { - autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr - ( - AMIMethod<SourcePatch, TargetPatch>::New - ( - interpolationMethodToWord(method_), - srcPatch, - newTgtPatch, - srcMagSf_, - tgtMagSf_, - triMode_, - reverseTarget_ - ) - ); - - AMIPtr->calculate + autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr + ( + AMIMethod<SourcePatch, TargetPatch>::New ( - srcAddress_, - srcWeights_, - tgtAddress_, - tgtWeights_ - ); - } + interpolationMethodToWord(method_), + srcPatch, + newTgtPatch, + srcMagSf_, + tgtMagSf_, + triMode_, + reverseTarget_ + ) + ); + AMIPtr->calculate + ( + srcAddress_, + srcWeights_, + tgtAddress_, + tgtWeights_ + ); // Now // ~~~ @@ -886,6 +907,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update srcAddress_, srcWeights_, srcWeightsSum_, + AMIPtr->conformal(), true ); normaliseWeights @@ -895,6 +917,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update tgtAddress_, tgtWeights_, tgtWeightsSum_, + AMIPtr->conformal(), true ); @@ -903,7 +926,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap)); tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap)); - if (debug) { writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_); @@ -913,29 +935,27 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update { // calculate AMI interpolation - { - autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr + autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr + ( + AMIMethod<SourcePatch, TargetPatch>::New ( - AMIMethod<SourcePatch, TargetPatch>::New - ( - interpolationMethodToWord(method_), - srcPatch, - tgtPatch, - srcMagSf_, - tgtMagSf_, - triMode_, - reverseTarget_ - ) - ); + interpolationMethodToWord(method_), + srcPatch, + tgtPatch, + srcMagSf_, + tgtMagSf_, + triMode_, + reverseTarget_ + ) + ); - AMIPtr->calculate - ( - srcAddress_, - srcWeights_, - tgtAddress_, - tgtWeights_ - ); - } + AMIPtr->calculate + ( + srcAddress_, + srcWeights_, + tgtAddress_, + tgtWeights_ + ); normaliseWeights ( @@ -944,6 +964,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update srcAddress_, srcWeights_, srcWeightsSum_, + AMIPtr->conformal(), true ); normaliseWeights @@ -953,6 +974,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update tgtAddress_, tgtWeights_, tgtWeightsSum_, + AMIPtr->conformal(), true ); } diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H index e31eb91e1c6105deaaee94a117ce08f38d769422..3aea35473fae5ad702dec2a0638b9c3cf3c971ce 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H @@ -88,7 +88,8 @@ public: { imDirect, imMapNearest, - imFaceAreaWeight + imFaceAreaWeight, + imPartialFaceAreaWeight }; //- Convert interpolationMethod to word representation @@ -236,6 +237,7 @@ private: const labelListList& addr, scalarListList& wght, scalarField& wghtSum, + const bool conformal, const bool output ); diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C index b5ab236b92976c10123e30428dd7eef618904fc4..bb1e61d210f3603d9e2d65f11a64b4be7a7340b2 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C @@ -41,24 +41,28 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const } - const scalar maxBoundsError = 0.05; + if (conformal()) + { + const scalar maxBoundsError = 0.05; - // check bounds of source and target - boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true); - boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true); + // check bounds of source and target + boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true); + boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true); - boundBox bbTgtInf(bbTgt); - bbTgtInf.inflate(maxBoundsError); + boundBox bbTgtInf(bbTgt); + bbTgtInf.inflate(maxBoundsError); - if (!bbTgtInf.contains(bbSrc)) - { - WarningIn("AMIMethod<SourcePatch, TargetPatch>::checkPatches()") - << "Source and target patch bounding boxes are not similar" << nl - << " source box span : " << bbSrc.span() << nl - << " target box span : " << bbTgt.span() << nl - << " source box : " << bbSrc << nl - << " target box : " << bbTgt << nl - << " inflated target box : " << bbTgtInf << endl; + if (!bbTgtInf.contains(bbSrc)) + { + WarningIn("AMIMethod<SourcePatch, TargetPatch>::checkPatches()") + << "Source and target patch bounding boxes are not similar" + << nl + << " source box span : " << bbSrc.span() << nl + << " target box span : " << bbTgt.span() << nl + << " source box : " << bbSrc << nl + << " target box : " << bbTgt << nl + << " inflated target box : " << bbTgtInf << endl; + } } } @@ -74,6 +78,8 @@ bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise label& tgtFaceI ) { + checkPatches(); + // set initial sizes for weights and addressing - must be done even if // returns false below srcAddress.setSize(srcPatch_.size()); @@ -241,17 +247,16 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea); - - if (debug) - { - Pout<< "Source point = " << srcPt << ", Sample point = " - << sample.hitPoint() << ", Sample index = " << sample.index() - << endl; - } - if (sample.hit()) { targetFaceI = sample.index(); + + if (debug) + { + Pout<< "Source point = " << srcPt << ", Sample point = " + << sample.hitPoint() << ", Sample index = " << sample.index() + << endl; + } } return targetFaceI; @@ -334,8 +339,6 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::AMIMethod srcNonOverlap_(), triMode_(triMode) { - checkPatches(); - label srcSize = returnReduce(srcPatch_.size(), sumOp<label>()); label tgtSize = returnReduce(tgtPatch_.size(), sumOp<label>()); @@ -352,4 +355,13 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::~AMIMethod() {} +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class SourcePatch, class TargetPatch> +bool Foam::AMIMethod<SourcePatch, TargetPatch>::conformal() const +{ + return true; +} + + // ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H index 7b6482b7c6cfe1850461b39895f088000f4e3119..673a695a3301121f16a6b07da6913bbfee9d1773 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H @@ -207,6 +207,9 @@ public: // Note: this should be empty for correct functioning inline const labelList& srcNonOverlap() const; + //- Flag to indicate that interpolation patches are conformal + virtual bool conformal() const; + // Manipulation diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C index ab47c3afb4d4cfab76f6e9233c12e3d5f9483016..ed4ae2d9f01f7ca3498cf72d709105e9347df963 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C @@ -25,7 +25,85 @@ License #include "faceAreaWeightAMI.H" -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +template<class SourcePatch, class TargetPatch> +void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing +( + List<DynamicList<label> >& srcAddr, + List<DynamicList<scalar> >& srcWght, + List<DynamicList<label> >& tgtAddr, + List<DynamicList<scalar> >& tgtWght, + label srcFaceI, + label tgtFaceI +) +{ + // construct weights and addressing + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + label nFacesRemaining = srcAddr.size(); + + // list of tgt face neighbour faces + DynamicList<label> nbrFaces(10); + + // list of faces currently visited for srcFaceI to avoid multiple hits + DynamicList<label> visitedFaces(10); + + // list to keep track of tgt faces used to seed src faces + labelList seedFaces(nFacesRemaining, -1); + seedFaces[srcFaceI] = tgtFaceI; + + // list to keep track of whether src face can be mapped + boolList mapFlag(nFacesRemaining, true); + + // reset starting seed + label startSeedI = 0; + + DynamicList<label> nonOverlapFaces; + do + { + // Do advancing front starting from srcFaceI,tgtFaceI + bool faceProcessed = processSourceFace + ( + srcFaceI, + tgtFaceI, + + nbrFaces, + visitedFaces, + + srcAddr, + srcWght, + tgtAddr, + tgtWght + ); + + mapFlag[srcFaceI] = false; + + nFacesRemaining--; + + if (!faceProcessed) + { + nonOverlapFaces.append(srcFaceI); + } + + // choose new src face from current src face neighbour + if (nFacesRemaining > 0) + { + setNextFaces + ( + startSeedI, + srcFaceI, + tgtFaceI, + mapFlag, + seedFaces, + visitedFaces + ); + } + } while (nFacesRemaining > 0); + + this->srcNonOverlap_.transfer(nonOverlapFaces); +} + template<class SourcePatch, class TargetPatch> bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace @@ -45,6 +123,11 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace List<DynamicList<scalar> >& tgtWght ) { + if (tgtStartFaceI == -1) + { + return false; + } + nbrFaces.clear(); visitedFaces.clear(); @@ -101,11 +184,15 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces label& tgtFaceI, const boolList& mapFlag, labelList& seedFaces, - const DynamicList<label>& visitedFaces + const DynamicList<label>& visitedFaces, + bool errorOnNotFound ) const { const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFaceI]; + // initialise tgtFaceI + tgtFaceI = -1; + // set possible seeds for later use bool valuesSet = false; forAll(srcNbrFaces, i) @@ -195,19 +282,23 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces } } - FatalErrorIn - ( - "void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::" - "setNextFaces" - "(" - "label&, " - "label&, " - "label&, " - "const boolList&, " - "labelList&, " - "const DynamicList<label>&" - ") const" - ) << "Unable to set source and target faces" << abort(FatalError); + if (errorOnNotFound) + { + FatalErrorIn + ( + "void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::" + "setNextFaces" + "(" + "label&, " + "label&, " + "label&, " + "const boolList&, " + "labelList&, " + "const DynamicList<label>&, " + "bool" + ") const" + ) << "Unable to set source and target faces" << abort(FatalError); + } } } @@ -447,77 +538,21 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate List<DynamicList<label> > tgtAddr(this->tgtPatch_.size()); List<DynamicList<scalar> > tgtWght(tgtAddr.size()); + calcAddressing + ( + srcAddr, + srcWght, + tgtAddr, + tgtWght, + srcFaceI, + tgtFaceI + ); - // construct weights and addressing - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - label nFacesRemaining = srcAddr.size(); - - // list of tgt face neighbour faces - DynamicList<label> nbrFaces(10); - - // list of faces currently visited for srcFaceI to avoid multiple hits - DynamicList<label> visitedFaces(10); - - // list to keep track of tgt faces used to seed src faces - labelList seedFaces(nFacesRemaining, -1); - seedFaces[srcFaceI] = tgtFaceI; - - // list to keep track of whether src face can be mapped - boolList mapFlag(nFacesRemaining, true); - - // reset starting seed - label startSeedI = 0; - - DynamicList<label> nonOverlapFaces; - do - { - // Do advancing front starting from srcFaceI,tgtFaceI - bool faceProcessed = processSourceFace - ( - srcFaceI, - tgtFaceI, - - nbrFaces, - visitedFaces, - - srcAddr, - srcWght, - tgtAddr, - tgtWght - ); - - mapFlag[srcFaceI] = false; - - nFacesRemaining--; - - if (!faceProcessed) - { - nonOverlapFaces.append(srcFaceI); - } - - // choose new src face from current src face neighbour - if (nFacesRemaining > 0) - { - setNextFaces - ( - startSeedI, - srcFaceI, - tgtFaceI, - mapFlag, - seedFaces, - visitedFaces - ); - } - } while (nFacesRemaining > 0); - - if (nonOverlapFaces.size() != 0) + if (this->srcNonOverlap_.size() != 0) { - Pout<< " AMI: " << nonOverlapFaces.size() + Pout<< " AMI: " << this->srcNonOverlap_.size() << " non-overlap faces identified" << endl; - - this->srcNonOverlap_.transfer(nonOverlapFaces); } diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H index 82061d2727ae239bbcc238a6ddf009f72940108f..2aff1977450ad095aed86821c260f7cf1f9e30fc 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H @@ -52,9 +52,9 @@ class faceAreaWeightAMI public AMIMethod<SourcePatch, TargetPatch> { -private: +protected: - // Private Member Functions + // Protected Member Functions //- Disallow default bitwise copy construct faceAreaWeightAMI(const faceAreaWeightAMI&); @@ -64,8 +64,19 @@ private: // Marching front + //- Calculate addressing and weights using temporary storage + virtual void calcAddressing + ( + List<DynamicList<label> >& srcAddress, + List<DynamicList<scalar> >& srcWeights, + List<DynamicList<label> >& tgtAddress, + List<DynamicList<scalar> >& tgtWeights, + label srcFaceI, + label tgtFaceI + ); + //- Determine overlap contributions for source face srcFaceI - bool processSourceFace + virtual bool processSourceFace ( const label srcFaceI, const label tgtStartFaceI, @@ -78,7 +89,7 @@ private: ); //- Attempt to re-evaluate source faces that have not been included - void restartUncoveredSourceFace + virtual void restartUncoveredSourceFace ( List<DynamicList<label> >& srcAddr, List<DynamicList<scalar> >& srcWght, @@ -87,21 +98,22 @@ private: ); //- Set the source and target seed faces - void setNextFaces + virtual void setNextFaces ( label& startSeedI, label& srcFaceI, label& tgtFaceI, const boolList& mapFlag, labelList& seedFaces, - const DynamicList<label>& visitedFaces + const DynamicList<label>& visitedFaces, + bool errorOnNotFound = true ) const; // Evaluation //- Area of intersection between source and target faces - scalar interArea + virtual scalar interArea ( const label srcFaceI, const label tgtFaceI diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C new file mode 100644 index 0000000000000000000000000000000000000000..ad0f6376b13990f8306d4364db35e554dcbaec1d --- /dev/null +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C @@ -0,0 +1,155 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "partialFaceAreaWeightAMI.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class SourcePatch, class TargetPatch> +void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces +( + label& startSeedI, + label& srcFaceI, + label& tgtFaceI, + const boolList& mapFlag, + labelList& seedFaces, + const DynamicList<label>& visitedFaces, + const bool errorOnNotFound +) const +{ + faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces + ( + startSeedI, + srcFaceI, + tgtFaceI, + mapFlag, + seedFaces, + visitedFaces, + false // no error on not found + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class SourcePatch, class TargetPatch> +Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>:: +partialFaceAreaWeightAMI +( + const SourcePatch& srcPatch, + const TargetPatch& tgtPatch, + const scalarField& srcMagSf, + const scalarField& tgtMagSf, + const faceAreaIntersect::triangulationMode& triMode, + const bool reverseTarget +) +: + faceAreaWeightAMI<SourcePatch, TargetPatch> + ( + srcPatch, + tgtPatch, + srcMagSf, + tgtMagSf, + triMode, + reverseTarget + ) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template<class SourcePatch, class TargetPatch> +Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>:: +~partialFaceAreaWeightAMI() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class SourcePatch, class TargetPatch> +bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::conformal() const +{ + return false; +} + + +template<class SourcePatch, class TargetPatch> +void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::calculate +( + labelListList& srcAddress, + scalarListList& srcWeights, + labelListList& tgtAddress, + scalarListList& tgtWeights, + label srcFaceI, + label tgtFaceI +) +{ + bool ok = + this->initialise + ( + srcAddress, + srcWeights, + tgtAddress, + tgtWeights, + srcFaceI, + tgtFaceI + ); + + if (!ok) + { + return; + } + + // temporary storage for addressing and weights + List<DynamicList<label> > srcAddr(this->srcPatch_.size()); + List<DynamicList<scalar> > srcWght(srcAddr.size()); + List<DynamicList<label> > tgtAddr(this->tgtPatch_.size()); + List<DynamicList<scalar> > tgtWght(tgtAddr.size()); + + faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing + ( + srcAddr, + srcWght, + tgtAddr, + tgtWght, + srcFaceI, + tgtFaceI + ); + + // transfer data to persistent storage + forAll(srcAddr, i) + { + srcAddress[i].transfer(srcAddr[i]); + srcWeights[i].transfer(srcWght[i]); + } + forAll(tgtAddr, i) + { + tgtAddress[i].transfer(tgtAddr[i]); + tgtWeights[i].transfer(tgtWght[i]); + } +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.H new file mode 100644 index 0000000000000000000000000000000000000000..4fd0ea2494c5876219c5b0d31ff555c6e0b69cde --- /dev/null +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.H @@ -0,0 +1,141 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::partialFaceAreaWeightAMI + +Description + Partial face area weighted Arbitrary Mesh Interface (AMI) method + +SourceFiles + partialFaceAreaWeightAMI.C + +\*---------------------------------------------------------------------------*/ + +#ifndef partialFaceAreaWeightAMI_H +#define partialFaceAreaWeightAMI_H + +#include "faceAreaWeightAMI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class partialFaceAreaWeightAMI Declaration +\*---------------------------------------------------------------------------*/ + +template<class SourcePatch, class TargetPatch> +class partialFaceAreaWeightAMI +: + public faceAreaWeightAMI<SourcePatch, TargetPatch> +{ + +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + partialFaceAreaWeightAMI(const partialFaceAreaWeightAMI&); + + //- Disallow default bitwise assignment + void operator=(const partialFaceAreaWeightAMI&); + + // Marching front + + //- Set the source and target seed faces + virtual void setNextFaces + ( + label& startSeedI, + label& srcFaceI, + label& tgtFaceI, + const boolList& mapFlag, + labelList& seedFaces, + const DynamicList<label>& visitedFaces, + bool errorOnNotFound = true + ) const; + + +public: + + //- Runtime type information + TypeName("partialFaceAreaWeightAMI"); + + + // Constructors + + //- Construct from components + partialFaceAreaWeightAMI + ( + const SourcePatch& srcPatch, + const TargetPatch& tgtPatch, + const scalarField& srcMagSf, + const scalarField& tgtMagSf, + const faceAreaIntersect::triangulationMode& triMode, + const bool reverseTarget = false + ); + + + //- Destructor + virtual ~partialFaceAreaWeightAMI(); + + + // Member Functions + + // Access + + //- Flag to indicate that interpolation patches are conformal + virtual bool conformal() const; + + + // Manipulation + + //- Update addressing and weights + virtual void calculate + ( + labelListList& srcAddress, + scalarListList& srcWeights, + labelListList& tgtAddress, + scalarListList& tgtWeights, + label srcFaceI = -1, + label tgtFaceI = -1 + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "partialFaceAreaWeightAMI.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C index 6cb5678aafd2bdbbdb77e97bf9c20938e3a0dd86..319f83759331f7c917d946d28100278b6d41d246 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C @@ -28,6 +28,7 @@ License #include "directAMI.H" #include "mapNearestAMI.H" #include "faceAreaWeightAMI.H" +#include "partialFaceAreaWeightAMI.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -38,6 +39,7 @@ namespace Foam makeAMIMethodType(AMIPatchToPatchInterpolation, directAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, mapNearestAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, faceAreaWeightAMI); + makeAMIMethodType(AMIPatchToPatchInterpolation, partialFaceAreaWeightAMI); } diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C new file mode 100644 index 0000000000000000000000000000000000000000..4963d926cd549201a980ce57297b2d3293973700 --- /dev/null +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C @@ -0,0 +1,129 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIGAMGInterfaceField.H" +#include "addToRunTimeSelectionTable.H" +#include "lduMatrix.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(cyclicACMIGAMGInterfaceField, 0); + addToRunTimeSelectionTable + ( + GAMGInterfaceField, + cyclicACMIGAMGInterfaceField, + lduInterface + ); + addToRunTimeSelectionTable + ( + GAMGInterfaceField, + cyclicACMIGAMGInterfaceField, + lduInterfaceField + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField +( + const GAMGInterface& GAMGCp, + const lduInterfaceField& fineInterface +) +: + GAMGInterfaceField(GAMGCp, fineInterface), + cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), + doTransform_(false), + rank_(0) +{ + const cyclicAMILduInterfaceField& p = + refCast<const cyclicAMILduInterfaceField>(fineInterface); + + doTransform_ = p.doTransform(); + rank_ = p.rank(); +} + + +Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField +( + const GAMGInterface& GAMGCp, + const bool doTransform, + const int rank +) +: + GAMGInterfaceField(GAMGCp, doTransform, rank), + cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)), + doTransform_(doTransform), + rank_(rank) +{} + + +// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * // + +Foam::cyclicACMIGAMGInterfaceField::~cyclicACMIGAMGInterfaceField() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix +( + scalarField& result, + const scalarField& psiInternal, + const scalarField& coeffs, + const direction cmpt, + const Pstream::commsTypes +) const +{ + // Get neighbouring field + scalarField pnf + ( + cyclicACMIInterface_.neighbPatch().interfaceInternalField(psiInternal) + ); + + // Transform according to the transformation tensors + transformCoupleField(pnf, cmpt); + + if (cyclicACMIInterface_.owner()) + { + pnf = cyclicACMIInterface_.AMI().interpolateToSource(pnf); + } + else + { + pnf = cyclicACMIInterface_.neighbPatch().AMI().interpolateToTarget(pnf); + } + + const labelUList& faceCells = cyclicACMIInterface_.faceCells(); + + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + } +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H new file mode 100644 index 0000000000000000000000000000000000000000..e06d76328d983e8664e9099959b7dc4b747a3df0 --- /dev/null +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.H @@ -0,0 +1,166 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIGAMGInterfaceField + +Description + GAMG agglomerated cyclic interface for Arbitrarily Coupled Mesh Interface + (ACMI) fields. + +SourceFiles + cyclicACMIGAMGInterfaceField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIGAMGInterfaceField_H +#define cyclicACMIGAMGInterfaceField_H + +#include "GAMGInterfaceField.H" +#include "cyclicACMIGAMGInterface.H" +#include "cyclicACMILduInterfaceField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIGAMGInterfaceField Declaration +\*---------------------------------------------------------------------------*/ + +class cyclicACMIGAMGInterfaceField +: + public GAMGInterfaceField, + virtual public cyclicACMILduInterfaceField +{ + // Private data + + //- Local reference cast into the cyclic interface + const cyclicACMIGAMGInterface& cyclicACMIInterface_; + + //- Is the transform required + bool doTransform_; + + //- Rank of component for transformation + int rank_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + cyclicACMIGAMGInterfaceField(const cyclicACMIGAMGInterfaceField&); + + //- Disallow default bitwise assignment + void operator=(const cyclicACMIGAMGInterfaceField&); + + +public: + + //- Runtime type information + TypeName("cyclicACMI"); + + + // Constructors + + //- Construct from GAMG interface and fine level interface field + cyclicACMIGAMGInterfaceField + ( + const GAMGInterface& GAMGCp, + const lduInterfaceField& fineInterfaceField + ); + + //- Construct from GAMG interface and fine level interface field + cyclicACMIGAMGInterfaceField + ( + const GAMGInterface& GAMGCp, + const bool doTransform, + const int rank + ); + + + //- Destructor + virtual ~cyclicACMIGAMGInterfaceField(); + + + // Member Functions + + // Access + + //- Return size + label size() const + { + return cyclicACMIInterface_.size(); + } + + + // Interface matrix update + + //- Update result field based on interface functionality + virtual void updateInterfaceMatrix + ( + scalarField& result, + const scalarField& psiInternal, + const scalarField& coeffs, + const direction cmpt, + const Pstream::commsTypes commsType + ) const; + + + //- Cyclic interface functions + + //- Does the interface field perform the transfromation + virtual bool doTransform() const + { + return doTransform_; + } + + //- Return face transformation tensor + virtual const tensorField& forwardT() const + { + return cyclicACMIInterface_.forwardT(); + } + + //- Return neighbour-cell transformation tensor + virtual const tensorField& reverseT() const + { + return cyclicACMIInterface_.reverseT(); + } + + //- Return rank of component for transform + virtual int rank() const + { + return rank_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.C b/src/meshTools/AMIInterpolation/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.C new file mode 100644 index 0000000000000000000000000000000000000000..d9e3a0fb77ea458d335683192945561b6de0ee82 --- /dev/null +++ b/src/meshTools/AMIInterpolation/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.C @@ -0,0 +1,198 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "AMIInterpolation.H" +#include "cyclicACMIGAMGInterface.H" +#include "addToRunTimeSelectionTable.H" +#include "Map.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(cyclicACMIGAMGInterface, 0); + addToRunTimeSelectionTable + ( + GAMGInterface, + cyclicACMIGAMGInterface, + lduInterface + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cyclicACMIGAMGInterface::cyclicACMIGAMGInterface +( + const label index, + const lduInterfacePtrsList& coarseInterfaces, + const lduInterface& fineInterface, + const labelField& localRestrictAddressing, + const labelField& neighbourRestrictAddressing, + const label fineLevelIndex, + const label coarseComm +) +: + GAMGInterface + ( + index, + coarseInterfaces + ), + fineCyclicACMIInterface_ + ( + refCast<const cyclicACMILduInterface>(fineInterface) + ) +{ + // Construct face agglomeration from cell agglomeration + { + // From coarse face to cell + DynamicList<label> dynFaceCells(localRestrictAddressing.size()); + + // From face to coarse face + DynamicList<label> dynFaceRestrictAddressing + ( + localRestrictAddressing.size() + ); + + Map<label> masterToCoarseFace(localRestrictAddressing.size()); + + forAll(localRestrictAddressing, ffi) + { + label curMaster = localRestrictAddressing[ffi]; + + Map<label>::const_iterator fnd = masterToCoarseFace.find + ( + curMaster + ); + + if (fnd == masterToCoarseFace.end()) + { + // New coarse face + label coarseI = dynFaceCells.size(); + dynFaceRestrictAddressing.append(coarseI); + dynFaceCells.append(curMaster); + masterToCoarseFace.insert(curMaster, coarseI); + } + else + { + // Already have coarse face + dynFaceRestrictAddressing.append(fnd()); + } + } + + faceCells_.transfer(dynFaceCells); + faceRestrictAddressing_.transfer(dynFaceRestrictAddressing); + } + + + // On the owner side construct the AMI + + if (fineCyclicACMIInterface_.owner()) + { + // Construct the neighbour side agglomeration (as the neighbour would + // do it so it the exact loop above using neighbourRestrictAddressing + // instead of localRestrictAddressing) + + labelList nbrFaceRestrictAddressing; + { + // From face to coarse face + DynamicList<label> dynNbrFaceRestrictAddressing + ( + neighbourRestrictAddressing.size() + ); + + Map<label> masterToCoarseFace(neighbourRestrictAddressing.size()); + + forAll(neighbourRestrictAddressing, ffi) + { + label curMaster = neighbourRestrictAddressing[ffi]; + + Map<label>::const_iterator fnd = masterToCoarseFace.find + ( + curMaster + ); + + if (fnd == masterToCoarseFace.end()) + { + // New coarse face + label coarseI = masterToCoarseFace.size(); + dynNbrFaceRestrictAddressing.append(coarseI); + masterToCoarseFace.insert(curMaster, coarseI); + } + else + { + // Already have coarse face + dynNbrFaceRestrictAddressing.append(fnd()); + } + } + + nbrFaceRestrictAddressing.transfer(dynNbrFaceRestrictAddressing); + } + + amiPtr_.reset + ( + new AMIPatchToPatchInterpolation + ( + fineCyclicACMIInterface_.AMI(), + faceRestrictAddressing_, + nbrFaceRestrictAddressing + ) + ); + } +} + + +// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * // + +Foam::cyclicACMIGAMGInterface::~cyclicACMIGAMGInterface() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::tmp<Foam::labelField> +Foam::cyclicACMIGAMGInterface::internalFieldTransfer +( + const Pstream::commsTypes, + const labelUList& iF +) const +{ + const cyclicACMIGAMGInterface& nbr = + dynamic_cast<const cyclicACMIGAMGInterface&>(neighbPatch()); + const labelUList& nbrFaceCells = nbr.faceCells(); + + tmp<labelField> tpnf(new labelField(nbrFaceCells.size())); + labelField& pnf = tpnf(); + + forAll(pnf, facei) + { + pnf[facei] = iF[nbrFaceCells[facei]]; + } + + return tpnf; +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.H b/src/meshTools/AMIInterpolation/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.H new file mode 100644 index 0000000000000000000000000000000000000000..3bf7bb34100ca2d32c09ff6ed9520f974a16cd5e --- /dev/null +++ b/src/meshTools/AMIInterpolation/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.H @@ -0,0 +1,174 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIGAMGInterface + +Description + GAMG agglomerated cyclic ACMI interface. + +SourceFiles + cyclicACMIGAMGInterface.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIGAMGInterface_H +#define cyclicACMIGAMGInterface_H + +#include "GAMGInterface.H" +#include "cyclicACMILduInterface.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIGAMGInterface Declaration +\*---------------------------------------------------------------------------*/ + +class cyclicACMIGAMGInterface +: + public GAMGInterface, + virtual public cyclicACMILduInterface +{ + // Private data + + //- Reference for the cyclicLduInterface from which this is + // agglomerated + const cyclicACMILduInterface& fineCyclicACMIInterface_; + + //- AMI interface + autoPtr<AMIPatchToPatchInterpolation> amiPtr_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + cyclicACMIGAMGInterface(const cyclicACMIGAMGInterface&); + + //- Disallow default bitwise assignment + void operator=(const cyclicACMIGAMGInterface&); + + +public: + + //- Runtime type information + TypeName("cyclicACMI"); + + + // Constructors + + //- Construct from fine level interface, + // local and neighbour restrict addressing + cyclicACMIGAMGInterface + ( + const label index, + const lduInterfacePtrsList& coarseInterfaces, + const lduInterface& fineInterface, + const labelField& restrictAddressing, + const labelField& neighbourRestrictAddressing, + const label fineLevelIndex, + const label coarseComm + ); + + + //- Destructor + virtual ~cyclicACMIGAMGInterface(); + + + // Member Functions + + // Interface transfer functions + + //- Transfer and return internal field adjacent to the interface + virtual tmp<labelField> internalFieldTransfer + ( + const Pstream::commsTypes commsType, + const labelUList& iF + ) const; + + + //- Cyclic interface functions + + //- Return neigbour processor number + virtual label neighbPatchID() const + { + return fineCyclicACMIInterface_.neighbPatchID(); + } + + virtual bool owner() const + { + return fineCyclicACMIInterface_.owner(); + } + + virtual const cyclicACMIGAMGInterface& neighbPatch() const + { + return dynamic_cast<const cyclicACMIGAMGInterface&> + ( + coarseInterfaces_[neighbPatchID()] + ); + } + + virtual const AMIPatchToPatchInterpolation& AMI() const + { + return amiPtr_(); + } + + //- Return face transformation tensor + virtual const tensorField& forwardT() const + { + return fineCyclicACMIInterface_.forwardT(); + } + + //- Return neighbour-cell transformation tensor + virtual const tensorField& reverseT() const + { + return fineCyclicACMIInterface_.reverseT(); + } + + + // I/O + + //- Write to stream + virtual void write(Ostream&) const + { + //TBD. How to serialise the AMI such that we can stream + // cyclicACMIGAMGInterface. + notImplemented + ( + "cyclicACMIGAMGInterface::write(Ostream&) const" + ); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterface.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterface.C new file mode 100644 index 0000000000000000000000000000000000000000..08c5c570a3b03362f70c357bb76203fb3f5f5245 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterface.C @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMILduInterface.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +defineTypeNameAndDebug(cyclicACMILduInterface, 0); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cyclicACMILduInterface::~cyclicACMILduInterface() +{} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterface.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterface.H new file mode 100644 index 0000000000000000000000000000000000000000..3d25637ce6ec08c0616673b8aaa17c88d3801ad0 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterface.H @@ -0,0 +1,80 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMILduInterface + +Description + An abstract base class for cyclic ACMI coupled interfaces + +SourceFiles + cyclicACMILduInterface.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMILduInterface_H +#define cyclicACMILduInterface_H + +#include "cyclicAMILduInterface.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMILduInterface Declaration +\*---------------------------------------------------------------------------*/ + +class cyclicACMILduInterface +: + public cyclicAMILduInterface +{ + +public: + + //- Runtime type information + TypeName("cyclicACMILduInterface"); + + + // Constructors + + //- Construct null + cyclicACMILduInterface() + {} + + + //- Destructor + virtual ~cyclicACMILduInterface(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C new file mode 100644 index 0000000000000000000000000000000000000000..b8232352558808ddd2b55bdb022e919215b1be64 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C @@ -0,0 +1,55 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMILduInterfaceField.H" +#include "diagTensorField.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +defineTypeNameAndDebug(cyclicACMILduInterfaceField, 0); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cyclicACMILduInterfaceField::~cyclicACMILduInterfaceField() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::cyclicACMILduInterfaceField::transformCoupleField +( + scalarField& f, + const direction cmpt +) const +{ + cyclicAMILduInterfaceField::transformCoupleField(f, cmpt); +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.H new file mode 100644 index 0000000000000000000000000000000000000000..5d0ec6e6e427815fbb357cb4e00d688696fc9414 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.H @@ -0,0 +1,108 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMILduInterfaceField + +Description + Abstract base class for cyclic ACMI coupled interfaces + +SourceFiles + cyclicACMILduInterfaceField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMILduInterfaceField_H +#define cyclicACMILduInterfaceField_H + +#include "cyclicAMILduInterfaceField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMILduInterfaceField Declaration +\*---------------------------------------------------------------------------*/ + +class cyclicACMILduInterfaceField +: + public cyclicAMILduInterfaceField +{ + +public: + + //- Runtime type information + TypeName("cyclicACMILduInterfaceField"); + + + // Constructors + + //- Construct null + cyclicACMILduInterfaceField() + {} + + + //- Destructor + virtual ~cyclicACMILduInterfaceField(); + + + // Member Functions + + //- Transform given patch field + template<class Type> + void transformCoupleField(Field<Type>& f) const; + + //- Transform given patch internal field + void transformCoupleField + ( + scalarField& psiInternal, + const direction cmpt + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "tensorField.H" + +template<class Type> +void Foam::cyclicACMILduInterfaceField::transformCoupleField +( + Field<Type>& f +) const +{ + cyclicAMILduInterfaceField::transformCoupleField(f); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatch/cyclicACMIPointPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatch/cyclicACMIPointPatch.C new file mode 100644 index 0000000000000000000000000000000000000000..d7feb7f2313a511e46a4519043cc46b30d1d742c --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatch/cyclicACMIPointPatch.C @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIPointPatch.H" +#include "pointBoundaryMesh.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(cyclicACMIPointPatch, 0); + addToRunTimeSelectionTable + ( + facePointPatch, + cyclicACMIPointPatch, + polyPatch + ); +} + + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +void Foam::cyclicACMIPointPatch::initGeometry(PstreamBuffers&) +{} + + +void Foam::cyclicACMIPointPatch::calcGeometry(PstreamBuffers&) +{} + + +void Foam::cyclicACMIPointPatch::initMovePoints +( + PstreamBuffers&, + const pointField& +) +{} + + +void Foam::cyclicACMIPointPatch::movePoints(PstreamBuffers&, const pointField&) +{} + + +void Foam::cyclicACMIPointPatch::initUpdateMesh(PstreamBuffers& pBufs) +{ + facePointPatch::initUpdateMesh(pBufs); +// cyclicACMIPointPatch::initGeometry(pBufs); +} + + +void Foam::cyclicACMIPointPatch::updateMesh(PstreamBuffers& pBufs) +{ + facePointPatch::updateMesh(pBufs); +// cyclicACMIPointPatch::calcGeometry(pBufs); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cyclicACMIPointPatch::cyclicACMIPointPatch +( + const polyPatch& patch, + const pointBoundaryMesh& bm +) +: + coupledFacePointPatch(patch, bm), + cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch)) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cyclicACMIPointPatch::~cyclicACMIPointPatch() +{} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatch/cyclicACMIPointPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatch/cyclicACMIPointPatch.H new file mode 100644 index 0000000000000000000000000000000000000000..1ed4f26cdb355932a92d624b98f67c6e9115481f --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatch/cyclicACMIPointPatch.H @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIPointPatch + +Description + Cyclic AMI point patch - place holder only + +SourceFiles + cyclicACMIPointPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIPointPatch_H +#define cyclicACMIPointPatch_H + +#include "coupledFacePointPatch.H" +#include "cyclicACMIPolyPatch.H" +#include "pointBoundaryMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIPointPatch Declaration +\*---------------------------------------------------------------------------*/ + +class cyclicACMIPointPatch +: + public coupledFacePointPatch +{ + // Private data + + //- Local reference cast into the cyclic AMI patch + const cyclicACMIPolyPatch& cyclicACMIPolyPatch_; + + + // Private Member Functions + + //- Disallow default construct as copy + cyclicACMIPointPatch(const cyclicACMIPointPatch&); + + //- Disallow default assignment + void operator=(const cyclicACMIPointPatch&); + + +protected: + + // Protected Member Functions + + //- Initialise the calculation of the patch geometry + virtual void initGeometry(PstreamBuffers&); + + //- Calculate the patch geometry + virtual void calcGeometry(PstreamBuffers&); + + //- Initialise the patches for moving points + virtual void initMovePoints(PstreamBuffers&, const pointField&); + + //- Correct patches after moving points + virtual void movePoints(PstreamBuffers&, const pointField&); + + //- Initialise the update of the patch topology + virtual void initUpdateMesh(PstreamBuffers&); + + //- Update of the patch topology + virtual void updateMesh(PstreamBuffers&); + + +public: + + //- Runtime type information + TypeName(cyclicACMIPolyPatch::typeName_()); + + + // Constructors + + //- Construct from components + cyclicACMIPointPatch + ( + const polyPatch& patch, + const pointBoundaryMesh& bm + ); + + + //- Destructor + virtual ~cyclicACMIPointPatch(); + + + // Member Functions + + //- Is patch 'coupled'. Note that on AMI the geometry is not + // coupled but the fields are! + virtual bool coupled() const + { + return false; + } + + //- Return the constraint type this pointPatch implements. + virtual const word& constraintType() const + { + return type(); + } + + //- Return the underlying cyclicAMIPolyPatch + const cyclicACMIPolyPatch& cyclicACMIPatch() const + { + return cyclicACMIPolyPatch_; + } + + //- Return neighbour point patch + const cyclicACMIPointPatch& neighbPatch() const + { + label patchI = cyclicACMIPolyPatch_.neighbPatchID(); + const pointPatch& pp = this->boundaryMesh()[patchI]; + return refCast<const cyclicACMIPointPatch>(pp); + } + + //- Are the cyclic planes parallel + bool parallel() const + { + return cyclicACMIPolyPatch_.parallel(); + } + + //- Return face transformation tensor + const tensorField& forwardT() const + { + return cyclicACMIPolyPatch_.forwardT(); + } + + //- Return neighbour-cell transformation tensor + const tensorField& reverseT() const + { + return cyclicACMIPolyPatch_.reverseT(); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchField.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchField.C new file mode 100644 index 0000000000000000000000000000000000000000..cc15eaf02fac31fb62876f068a10da1c02750205 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchField.C @@ -0,0 +1,210 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIPointPatchField.H" +#include "Swap.H" +#include "transformField.H" +#include "pointFields.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class Type> +Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField +( + const pointPatch& p, + const DimensionedField<Type, pointMesh>& iF +) +: + coupledPointPatchField<Type>(p, iF), + cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)), + ppiPtr_(NULL), + nbrPpiPtr_(NULL) +{} + + +template<class Type> +Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField +( + const pointPatch& p, + const DimensionedField<Type, pointMesh>& iF, + const dictionary& dict +) +: + coupledPointPatchField<Type>(p, iF, dict), + cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)), + ppiPtr_(NULL), + nbrPpiPtr_(NULL) +{ + if (!isType<cyclicACMIPointPatch>(p)) + { + FatalIOErrorIn + ( + "cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField\n" + "(\n" + " const pointPatch&,\n" + " const DimensionedField<Type, pointMesh>&,\n" + " const dictionary&\n" + ")\n", + dict + ) << "patch " << this->patch().index() << " not cyclicACMI type. " + << "Patch type = " << p.type() + << exit(FatalIOError); + } +} + + +template<class Type> +Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField +( + const cyclicACMIPointPatchField<Type>& ptf, + const pointPatch& p, + const DimensionedField<Type, pointMesh>& iF, + const pointPatchFieldMapper& mapper +) +: + coupledPointPatchField<Type>(ptf, p, iF, mapper), + cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)), + ppiPtr_(NULL), + nbrPpiPtr_(NULL) +{ + if (!isType<cyclicACMIPointPatch>(this->patch())) + { + FatalErrorIn + ( + "cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField\n" + "(\n" + " const cyclicACMIPointPatchField<Type>&,\n" + " const pointPatch&,\n" + " const DimensionedField<Type, pointMesh>&,\n" + " const pointPatchFieldMapper&\n" + ")\n" + ) << "Field type does not correspond to patch type for patch " + << this->patch().index() << "." << endl + << "Field type: " << typeName << endl + << "Patch type: " << this->patch().type() + << exit(FatalError); + } +} + + +template<class Type> +Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField +( + const cyclicACMIPointPatchField<Type>& ptf, + const DimensionedField<Type, pointMesh>& iF +) +: + coupledPointPatchField<Type>(ptf, iF), + cyclicACMIPatch_(ptf.cyclicACMIPatch_), + ppiPtr_(NULL), + nbrPpiPtr_(NULL) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +void Foam::cyclicACMIPointPatchField<Type>::swapAddSeparated +( + const Pstream::commsTypes, + Field<Type>& pField +) const +{ + if (cyclicACMIPatch_.cyclicACMIPatch().owner()) + { + // We inplace modify pField. To prevent the other side (which gets + // evaluated at a later date) using already changed values we do + // all swaps on the side that gets evaluated first. + + // Get neighbouring pointPatch + const cyclicACMIPointPatch& nbrPatch = cyclicACMIPatch_.neighbPatch(); + + // Get neighbouring pointPatchField + const GeometricField<Type, pointPatchField, pointMesh>& fld = + refCast<const GeometricField<Type, pointPatchField, pointMesh> > + ( + this->dimensionedInternalField() + ); + + const cyclicACMIPointPatchField<Type>& nbr = + refCast<const cyclicACMIPointPatchField<Type> > + ( + fld.boundaryField()[nbrPatch.index()] + ); + + + Field<Type> ptFld(this->patchInternalField(pField)); + Field<Type> nbrPtFld(nbr.patchInternalField(pField)); + + + if (doTransform()) + { + const tensor& forwardT = this->forwardT()[0]; + const tensor& reverseT = this->reverseT()[0]; + + transform(ptFld, reverseT, ptFld); + transform(nbrPtFld, forwardT, nbrPtFld); + } + + // convert point field to face field, AMI interpolate, then + // face back to point + { + // add neighbour side contribution to owner + Field<Type> nbrFcFld(nbrPpi().pointToFaceInterpolate(nbrPtFld)); + + const cyclicAMIPolyPatch& cami = cyclicACMIPatch_.cyclicACMIPatch(); + + // interpolate to owner + nbrFcFld = cami.interpolate(nbrFcFld); + + // add to internal field + this->addToInternalField + ( + pField, + ppi().faceToPointInterpolate(nbrFcFld)() + ); + } + + { + // add owner side contribution to neighbour + Field<Type> fcFld(ppi().pointToFaceInterpolate(ptFld)); + + const cyclicAMIPolyPatch& cami = cyclicACMIPatch_.cyclicACMIPatch(); + + // interpolate to neighbour + fcFld = cami.neighbPatch().cyclicAMIPolyPatch::interpolate(fcFld); + + // add to internal field + nbr.addToInternalField + ( + pField, + nbrPpi().faceToPointInterpolate(fcFld)() + ); + } + } +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchField.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchField.H new file mode 100644 index 0000000000000000000000000000000000000000..7d490280bf1f2eb849c981d362e4977a7a2e7e7b --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchField.H @@ -0,0 +1,241 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIPointPatchField + +Description + Cyclic ACMI front and back plane patch field + +SourceFiles + cyclicACMIPointPatchField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIPointPatchField_H +#define cyclicACMIPointPatchField_H + +#include "coupledPointPatchField.H" +#include "cyclicACMIPointPatch.H" +#include "PrimitivePatchInterpolation.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIPointPatchField Declaration +\*---------------------------------------------------------------------------*/ + +template<class Type> +class cyclicACMIPointPatchField +: + public coupledPointPatchField<Type> +{ + // Private data + + //- Local reference cast into the cyclicACMI patch + const cyclicACMIPointPatch& cyclicACMIPatch_; + + //- Owner side patch interpolation pointer + mutable autoPtr<PrimitivePatchInterpolation<primitivePatch> > ppiPtr_; + + //- Neighbour side patch interpolation pointer + mutable autoPtr<PrimitivePatchInterpolation<primitivePatch> > + nbrPpiPtr_; + + + // Private Member Functions + + //- Owner side patch interpolation + const PrimitivePatchInterpolation<primitivePatch>& ppi() const + { + if (!ppiPtr_.valid()) + { + ppiPtr_.reset + ( + new PrimitivePatchInterpolation<primitivePatch> + ( + cyclicACMIPatch_.cyclicACMIPatch() + ) + ); + } + + return ppiPtr_(); + } + + //- Neighbour side patch interpolation + const PrimitivePatchInterpolation<primitivePatch>& nbrPpi() const + { + if (!nbrPpiPtr_.valid()) + { + nbrPpiPtr_.reset + ( + new PrimitivePatchInterpolation<primitivePatch> + ( + cyclicACMIPatch_.cyclicACMIPatch().neighbPatch() + ) + ); + } + + return nbrPpiPtr_(); + } + + +public: + + //- Runtime type information + TypeName(cyclicACMIPointPatch::typeName_()); + + + // Constructors + + //- Construct from patch and internal field + cyclicACMIPointPatchField + ( + const pointPatch&, + const DimensionedField<Type, pointMesh>& + ); + + //- Construct from patch, internal field and dictionary + cyclicACMIPointPatchField + ( + const pointPatch&, + const DimensionedField<Type, pointMesh>&, + const dictionary& + ); + + //- Construct by mapping given patchField<Type> onto a new patch + cyclicACMIPointPatchField + ( + const cyclicACMIPointPatchField<Type>&, + const pointPatch&, + const DimensionedField<Type, pointMesh>&, + const pointPatchFieldMapper& + ); + + //- Construct and return a clone + virtual autoPtr<pointPatchField<Type> > clone() const + { + return autoPtr<pointPatchField<Type> > + ( + new cyclicACMIPointPatchField<Type> + ( + *this + ) + ); + } + + //- Construct as copy setting internal field reference + cyclicACMIPointPatchField + ( + const cyclicACMIPointPatchField<Type>&, + const DimensionedField<Type, pointMesh>& + ); + + //- Construct and return a clone setting internal field reference + virtual autoPtr<pointPatchField<Type> > clone + ( + const DimensionedField<Type, pointMesh>& iF + ) const + { + return autoPtr<pointPatchField<Type> > + ( + new cyclicACMIPointPatchField<Type> + ( + *this, iF + ) + ); + } + + + // Member functions + + // Constraint handling + + //- Return the constraint type this pointPatchField implements + virtual const word& constraintType() const + { + return cyclicACMIPointPatch::typeName; + } + + + // Cyclic AMI coupled interface functions + + //- Does the patch field perform the transfromation + virtual bool doTransform() const + { + return + !( + cyclicACMIPatch_.parallel() + || pTraits<Type>::rank == 0 + ); + } + + //- Return face transformation tensor + virtual const tensorField& forwardT() const + { + return cyclicACMIPatch_.forwardT(); + } + + //- Return neighbour-cell transformation tensor + virtual const tensorField& reverseT() const + { + return cyclicACMIPatch_.reverseT(); + } + + + // Evaluation functions + + //- Evaluate the patch field + virtual void evaluate + ( + const Pstream::commsTypes commsType=Pstream::blocking + ) + {} + + //- Complete swap of patch point values and add to local values + virtual void swapAddSeparated + ( + const Pstream::commsTypes commsType, + Field<Type>& + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "cyclicACMIPointPatchField.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.C new file mode 100644 index 0000000000000000000000000000000000000000..e2d743bb4e66af5b865760891e8b2a4a3fca269c --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.C @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIPointPatchFields.H" +#include "pointPatchFields.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +makePointPatchFields(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.H new file mode 100644 index 0000000000000000000000000000000000000000..e36f1ef9ed980c26ed1b70b10abda2bdf06b31b1 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.H @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIPointPatchFields_H +#define cyclicACMIPointPatchFields_H + +#include "cyclicACMIPointPatchField.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +makePointPatchFieldTypedefs(cyclicACMI); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C new file mode 100644 index 0000000000000000000000000000000000000000..30ae0adf376a83d34ca4b33c18a6090bcbf40981 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C @@ -0,0 +1,453 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cyclicACMIPolyPatch.H" +#include "transformField.H" +#include "SubField.H" +#include "polyMesh.H" +#include "Time.H" +#include "faceAreaIntersect.H" +#include "ops.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(cyclicACMIPolyPatch, 0); + + addToRunTimeSelectionTable(polyPatch, cyclicACMIPolyPatch, word); + addToRunTimeSelectionTable(polyPatch, cyclicACMIPolyPatch, dictionary); +} + +const Foam::scalar Foam::cyclicACMIPolyPatch::tolerance_ = 1e-6; + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::cyclicACMIPolyPatch::initPatchFaceAreas() const +{ + if (!empty() && faceAreas0_.empty()) + { + faceAreas0_ = faceAreas(); + } + + const cyclicACMIPolyPatch& nbrACMI = + refCast<const cyclicACMIPolyPatch>(this->neighbPatch()); + + if (!nbrACMI.empty() && nbrACMI.faceAreas0().empty()) + { + nbrACMI.initPatchFaceAreas(); + } +} + + +void Foam::cyclicACMIPolyPatch::resetAMI +( + const AMIPatchToPatchInterpolation::interpolationMethod& +) const +{ + if (owner()) + { + const polyPatch& nonOverlapPatch = this->nonOverlapPatch(); + + initPatchFaceAreas(); + + // reset patch face areas based on original patch for AMI calculation + vectorField::subField Sf = faceAreas(); + vectorField::subField noSf = nonOverlapPatch.faceAreas(); + + forAll(Sf, faceI) + { + Sf[faceI] = faceAreas0_[faceI]; + noSf[faceI] = faceAreas0_[faceI]; + } + + // calculate the AMI using partial face-area-weighted + cyclicAMIPolyPatch::resetAMI + ( + AMIPatchToPatchInterpolation::imPartialFaceAreaWeight + ); + + const scalarField& srcWeightSum = AMI().srcWeightsSum(); + + // set patch face areas based on sum of AMI weights per face + forAll(Sf, faceI) + { + scalar w = srcWeightSum[faceI]; + w = min(1.0 - tolerance_, max(tolerance_, w)); + + Sf[faceI] *= w; + noSf[faceI] *= 1.0 - w; + } + + setNeighbourFaceAreas(); + + // set the updated flag + updated_ = true; + } +} + + +void Foam::cyclicACMIPolyPatch::setNeighbourFaceAreas() const +{ + const cyclicACMIPolyPatch& cp = + refCast<const cyclicACMIPolyPatch>(this->neighbPatch()); + const polyPatch& pp = cp.nonOverlapPatch(); + + const scalarField& tgtWeightSum = AMI().tgtWeightsSum(); + + const vectorField& faceAreas0 = cp.faceAreas0(); + + vectorField::subField Sf = cp.faceAreas(); + vectorField::subField noSf = pp.faceAreas(); + + forAll(Sf, faceI) + { + scalar w = tgtWeightSum[faceI]; + w = min(1.0 - tolerance_, max(tolerance_, w)); + + Sf[faceI] = w*faceAreas0[faceI]; + noSf[faceI] = (1.0 - w)*faceAreas0[faceI]; + } +} + + +void Foam::cyclicACMIPolyPatch::initGeometry(PstreamBuffers& pBufs) +{ + cyclicAMIPolyPatch::initGeometry(pBufs); +} + + +void Foam::cyclicACMIPolyPatch::calcGeometry(PstreamBuffers& pBufs) +{ + cyclicAMIPolyPatch::calcGeometry(pBufs); +} + + +void Foam::cyclicACMIPolyPatch::initMovePoints +( + PstreamBuffers& pBufs, + const pointField& p +) +{ + cyclicAMIPolyPatch::initMovePoints(pBufs, p); +} + + +void Foam::cyclicACMIPolyPatch::movePoints +( + PstreamBuffers& pBufs, + const pointField& p +) +{ + cyclicAMIPolyPatch::movePoints(pBufs, p); +} + + +void Foam::cyclicACMIPolyPatch::initUpdateMesh(PstreamBuffers& pBufs) +{ + cyclicAMIPolyPatch::initUpdateMesh(pBufs); +} + + +void Foam::cyclicACMIPolyPatch::updateMesh(PstreamBuffers& pBufs) +{ + cyclicAMIPolyPatch::updateMesh(pBufs); +} + + +void Foam::cyclicACMIPolyPatch::clearGeom() +{ + cyclicAMIPolyPatch::clearGeom(); +} + + +// * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * // + +Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch +( + const word& name, + const label size, + const label start, + const label index, + const polyBoundaryMesh& bm, + const word& patchType, + const transformType transform +) +: + cyclicAMIPolyPatch(name, size, start, index, bm, patchType, transform), + faceAreas0_(), + nonOverlapPatchName_(word::null), + nonOverlapPatchID_(-1), + updated_(false) +{ + // Non-overlapping patch might not be valid yet so cannot determine + // associated patchID +} + + +Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch +( + const word& name, + const dictionary& dict, + const label index, + const polyBoundaryMesh& bm, + const word& patchType +) +: + cyclicAMIPolyPatch(name, dict, index, bm, patchType), + faceAreas0_(), + nonOverlapPatchName_(dict.lookup("nonOverlapPatch")), + nonOverlapPatchID_(-1), + updated_(false) +{ + if (nonOverlapPatchName_ == name) + { + FatalIOErrorIn + ( + "cyclicACMIPolyPatch::cyclicACMIPolyPatch" + "(" + "const word&, " + "const dictionary&, " + "const label, " + "const polyBoundaryMesh&, " + "const word&" + ")", + dict + ) << "Non-overlapping patch name " << nonOverlapPatchName_ + << " cannot be the same as this patch " << name + << exit(FatalIOError); + } + + // Non-overlapping patch might not be valid yet so cannot determine + // associated patchID +} + + +Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch +( + const cyclicACMIPolyPatch& pp, + const polyBoundaryMesh& bm +) +: + cyclicAMIPolyPatch(pp, bm), + faceAreas0_(), + nonOverlapPatchName_(pp.nonOverlapPatchName_), + nonOverlapPatchID_(-1), + updated_(false) +{ + // Non-overlapping patch might not be valid yet so cannot determine + // associated patchID +} + + +Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch +( + const cyclicACMIPolyPatch& pp, + const polyBoundaryMesh& bm, + const label index, + const label newSize, + const label newStart, + const word& nbrPatchName, + const word& nonOverlapPatchName +) +: + cyclicAMIPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName), + faceAreas0_(), + nonOverlapPatchName_(nonOverlapPatchName), + nonOverlapPatchID_(-1), + updated_(false) +{ + if (nonOverlapPatchName_ == name()) + { + FatalErrorIn + ( + "const cyclicACMIPolyPatch& " + "const polyBoundaryMesh&, " + "const label, " + "const label, " + "const label, " + "const word&, " + "const word&" + ) << "Non-overlapping patch name " << nonOverlapPatchName_ + << " cannot be the same as this patch " << name() + << exit(FatalError); + } + + // Non-overlapping patch might not be valid yet so cannot determine + // associated patchID +} + + +Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch +( + const cyclicACMIPolyPatch& pp, + const polyBoundaryMesh& bm, + const label index, + const labelUList& mapAddressing, + const label newStart +) +: + cyclicAMIPolyPatch(pp, bm, index, mapAddressing, newStart), + faceAreas0_(), + nonOverlapPatchName_(pp.nonOverlapPatchName_), + nonOverlapPatchID_(-1), + updated_(false) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cyclicACMIPolyPatch::~cyclicACMIPolyPatch() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::cyclicACMIPolyPatch::nonOverlapPatchID() const +{ + if (nonOverlapPatchID_ == -1) + { + nonOverlapPatchID_ = + this->boundaryMesh().findPatchID(nonOverlapPatchName_); + + if (nonOverlapPatchID_ == -1) + { + FatalErrorIn("cyclicPolyAMIPatch::neighbPatchID() const") + << "Illegal non-overlapping patch name " << nonOverlapPatchName_ + << nl << "Valid patch names are " + << this->boundaryMesh().names() + << exit(FatalError); + } + + if (nonOverlapPatchID_ < index()) + { + FatalErrorIn("cyclicPolyAMIPatch::neighbPatchID() const") + << "Boundary ordering error: " << type() + << " patch must be defined prior to its non-overlapping patch" + << nl + << type() << " patch: " << name() << ", ID:" << index() << nl + << "Non-overlap patch: " << nonOverlapPatchName_ + << ", ID:" << nonOverlapPatchID_ << nl + << exit(FatalError); + } + + const polyPatch& noPp = this->boundaryMesh()[nonOverlapPatchID_]; + + bool ok = true; + + if (size() == noPp.size()) + { + const scalarField magSf(mag(faceAreas())); + const scalarField noMagSf(mag(noPp.faceAreas())); + + forAll(magSf, faceI) + { + scalar ratio = mag(magSf[faceI]/(noMagSf[faceI] + ROOTVSMALL)); + + if (ratio - 1 > tolerance_) + { + ok = false; + break; + } + } + } + else + { + ok = false; + } + + if (!ok) + { + FatalErrorIn + ( + "Foam::label " + "Foam::cyclicACMIPolyPatch::nonOverlapPatchID() const" + ) << "Inconsistent ACMI patches " << name() << " and " + << noPp.name() << ". Patches should have identical topology" + << exit(FatalError); + } + } + + return nonOverlapPatchID_; +} + + +void Foam::cyclicACMIPolyPatch::calcGeometry +( + const primitivePatch& referPatch, + const pointField& thisCtrs, + const vectorField& thisAreas, + const pointField& thisCc, + const pointField& nbrCtrs, + const vectorField& nbrAreas, + const pointField& nbrCc +) +{ + cyclicAMIPolyPatch::calcGeometry + ( + referPatch, + thisCtrs, + thisAreas, + thisCc, + nbrCtrs, + nbrAreas, + nbrCc + ); +} + + +void Foam::cyclicACMIPolyPatch::initOrder +( + PstreamBuffers& pBufs, + const primitivePatch& pp +) const +{ + cyclicAMIPolyPatch::initOrder(pBufs, pp); +} + + +bool Foam::cyclicACMIPolyPatch::order +( + PstreamBuffers& pBufs, + const primitivePatch& pp, + labelList& faceMap, + labelList& rotation +) const +{ + return cyclicAMIPolyPatch::order(pBufs, pp, faceMap, rotation); +} + + +void Foam::cyclicACMIPolyPatch::write(Ostream& os) const +{ + cyclicAMIPolyPatch::write(os); + + os.writeKeyword("nonOverlapPatch") << nonOverlapPatchName_ + << token::END_STATEMENT << nl; +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H new file mode 100644 index 0000000000000000000000000000000000000000..b092c14f0430caaab58d3f39e99bc8a1e51561a7 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H @@ -0,0 +1,349 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cyclicACMIPolyPatch + +Description + Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI) + +SourceFiles + cyclicACMIPolyPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cyclicACMIPolyPatch_H +#define cyclicACMIPolyPatch_H + +#include "cyclicAMIPolyPatch.H" +#include "AMIPatchToPatchInterpolation.H" +#include "polyBoundaryMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cyclicACMIPolyPatch Declaration +\*---------------------------------------------------------------------------*/ + +class cyclicACMIPolyPatch +: + public cyclicAMIPolyPatch +{ + +private: + + // Private data + + //- Copy of the original patch face areas + mutable vectorField faceAreas0_; + + //- Name of non-overlapping patch + const word nonOverlapPatchName_; + + //- Index of non-overlapping patch + mutable label nonOverlapPatchID_; + + //- Flag to indicate that AMI has been updated + mutable bool updated_; + + +protected: + + static const scalar tolerance_; + + + // Protected Member Functions + + //- Initialise patch face areas + virtual void initPatchFaceAreas() const; + + //- Reset the AMI interpolator + virtual void resetAMI + ( + const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod = + AMIPatchToPatchInterpolation::imFaceAreaWeight + ) const; + + //- Set neighbour ACMI patch areas + virtual void setNeighbourFaceAreas() const; + + //- Initialise the calculation of the patch geometry + virtual void initGeometry(PstreamBuffers&); + + //- Calculate the patch geometry + virtual void calcGeometry(PstreamBuffers&); + + //- Initialise the patches for moving points + virtual void initMovePoints(PstreamBuffers& pBufs, const pointField&); + + //- Correct patches after moving points + virtual void movePoints(PstreamBuffers& pBufs, const pointField&); + + //- Initialise the update of the patch topology + virtual void initUpdateMesh(PstreamBuffers&); + + //- Update of the patch topology + virtual void updateMesh(PstreamBuffers&); + + //- Clear geometry + virtual void clearGeom(); + + +public: + + //- Runtime type information + TypeName("cyclicACMI"); + + + // Constructors + + //- Construct from (base couped patch) components + cyclicACMIPolyPatch + ( + const word& name, + const label size, + const label start, + const label index, + const polyBoundaryMesh& bm, + const word& patchType, + const transformType transform = UNKNOWN + ); + + //- Construct from dictionary + cyclicACMIPolyPatch + ( + const word& name, + const dictionary& dict, + const label index, + const polyBoundaryMesh& bm, + const word& patchType + ); + + //- Construct as copy, resetting the boundary mesh + cyclicACMIPolyPatch + ( + const cyclicACMIPolyPatch&, + const polyBoundaryMesh& + ); + + //- Construct given the original patch and resetting the + // face list and boundary mesh information + cyclicACMIPolyPatch + ( + const cyclicACMIPolyPatch& pp, + const polyBoundaryMesh& bm, + const label index, + const label newSize, + const label newStart, + const word& nbrPatchName, + const word& nonOverlapPatchName + ); + + //- Construct given the original patch and a map + cyclicACMIPolyPatch + ( + const cyclicACMIPolyPatch& pp, + const polyBoundaryMesh& bm, + const label index, + const labelUList& mapAddressing, + const label newStart + ); + + + //- Construct and return a clone, resetting the boundary mesh + virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const + { + return autoPtr<polyPatch>(new cyclicACMIPolyPatch(*this, bm)); + } + + //- Construct and return a clone, resetting the face list + // and boundary mesh + virtual autoPtr<polyPatch> clone + ( + const polyBoundaryMesh& bm, + const label index, + const label newSize, + const label newStart + ) const + { + return autoPtr<polyPatch> + ( + new cyclicACMIPolyPatch + ( + *this, + bm, + index, + newSize, + newStart, + neighbPatchName(), + nonOverlapPatchName_ + ) + ); + } + + //- Construct and return a clone, resetting the face list + // and boundary mesh + virtual autoPtr<polyPatch> clone + ( + const polyBoundaryMesh& bm, + const label index, + const labelUList& mapAddressing, + const label newStart + ) const + { + return autoPtr<polyPatch> + ( + new cyclicACMIPolyPatch + ( + *this, + bm, + index, + mapAddressing, + newStart + ) + ); + } + + + //- Destructor + virtual ~cyclicACMIPolyPatch(); + + + // Member Functions + + // Access + + //- Reset the updated flag + inline void setUpdated(bool flag) const; + + //- Return access to the updated flag + inline bool updated() const; + + //- Return access to the original patch face areas + inline const vectorField& faceAreas0() const; + + //- Non-overlapping patch name + inline const word& nonOverlapPatchName() const; + + //- Non-overlapping patch ID + virtual label nonOverlapPatchID() const; + + //- Return a const reference to the non-overlapping patch + inline const polyPatch& nonOverlapPatch() const; + + //- Return a reference to the non-overlapping patch + inline polyPatch& nonOverlapPatch(); + + //- Mask field where 1 = overlap, 0 = no-overlap + inline const scalarField& mask() const; + + + // Interpolations + + //- Interpolate field + template<class Type> + tmp<Field<Type> > interpolate + ( + const Field<Type>& fldCouple, + const Field<Type>& fldNonOverlap + ) const; + + //- Interpolate tmp field + template<class Type> + tmp<Field<Type> > interpolate + ( + const tmp<Field<Type> >& tFldCouple, + const tmp<Field<Type> >& tFldNonOverlap + ) const; + + //- Low-level interpolate List + template<class Type, class CombineOp> + void interpolate + ( + const UList<Type>& fldCouple, + const UList<Type>& fldNonOverlap, + const CombineOp& cop, + List<Type>& result + ) const; + + + //- Calculate the patch geometry + virtual void calcGeometry + ( + const primitivePatch& referPatch, + const pointField& thisCtrs, + const vectorField& thisAreas, + const pointField& thisCc, + const pointField& nbrCtrs, + const vectorField& nbrAreas, + const pointField& nbrCc + ); + + //- Initialize ordering for primitivePatch. Does not + // refer to *this (except for name() and type() etc.) + virtual void initOrder + ( + PstreamBuffers&, + const primitivePatch& + ) const; + + //- Return new ordering for primitivePatch. + // Ordering is -faceMap: for every face + // index of the new face -rotation:for every new face the clockwise + // shift of the original face. Return false if nothing changes + // (faceMap is identity, rotation is 0), true otherwise. + virtual bool order + ( + PstreamBuffers&, + const primitivePatch&, + labelList& faceMap, + labelList& rotation + ) const; + + //- Write the polyPatch data as a dictionary + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "cyclicACMIPolyPatchI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "cyclicACMIPolyPatchTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H new file mode 100644 index 0000000000000000000000000000000000000000..a245f779c03a0c2391f8e4ed93841b00f9ec0f4c --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +inline void Foam::cyclicACMIPolyPatch::setUpdated(const bool flag) const +{ + updated_ = flag; +} + + +inline bool Foam::cyclicACMIPolyPatch::updated() const +{ + return updated_; +} + + +inline const Foam::vectorField& Foam::cyclicACMIPolyPatch::faceAreas0() const +{ + return faceAreas0_; +} + + +inline const Foam::word& Foam::cyclicACMIPolyPatch::nonOverlapPatchName() const +{ + return nonOverlapPatchName_; +} + + +inline const Foam::polyPatch& Foam::cyclicACMIPolyPatch::nonOverlapPatch() const +{ + // note: use nonOverlapPatchID() as opposed to patch name to initialise + // demand-driven data + + return this->boundaryMesh()[nonOverlapPatchID()]; +} + + +inline Foam::polyPatch& Foam::cyclicACMIPolyPatch::nonOverlapPatch() +{ + // note: use nonOverlapPatchID() as opposed to patch name to initialise + // demand-driven data + + return const_cast<polyPatch&>(this->boundaryMesh()[nonOverlapPatchID()]); +} + + +inline const Foam::scalarField& Foam::cyclicACMIPolyPatch::mask() const +{ + if (owner()) + { + return AMI().srcWeightsSum(); + } + else + { + return neighbPatch().AMI().tgtWeightsSum(); + } +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..127085ac44e58a75cc612d7f7a7ca40a29665592 --- /dev/null +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchTemplates.C @@ -0,0 +1,91 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +Foam::tmp<Foam::Field<Type> > Foam::cyclicACMIPolyPatch::interpolate +( + const Field<Type>& fldCouple, + const Field<Type>& fldNonOverlap +) const +{ + if (owner()) + { + const scalarField& w = AMI().srcWeightsSum(); + + return + w*AMI().interpolateToSource(fldCouple) + + (1.0 - w)*fldNonOverlap; + } + else + { + const scalarField& w = neighbPatch().AMI().tgtWeightsSum(); + + return + w*neighbPatch().AMI().interpolateToTarget(fldCouple) + + (1.0 - w)*fldNonOverlap; + } +} + + +template<class Type> +Foam::tmp<Foam::Field<Type> > Foam::cyclicACMIPolyPatch::interpolate +( + const tmp<Field<Type> >& tFldCouple, + const tmp<Field<Type> >& tFldNonOverlap +) const +{ + return interpolate(tFldCouple(), tFldNonOverlap()); +} + + +template<class Type, class CombineOp> +void Foam::cyclicACMIPolyPatch::interpolate +( + const UList<Type>& fldCouple, + const UList<Type>& fldNonOverlap, + const CombineOp& cop, + List<Type>& result +) const +{ + if (owner()) + { + const scalarField& w = AMI().srcWeightsSum(); + + AMI().interpolateToSource(fldCouple, cop, result); + result = w*result + (1.0 - w)*fldNonOverlap; + } + else + { + const scalarField& w = neighbPatch().AMI().tgtWeightsSum(); + + neighbPatch().AMI().interpolateToTarget(fldCouple, cop, result); + result = w*result + (1.0 - w)*fldNonOverlap; + } +} + + +// ************************************************************************* // diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterface.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterface.C similarity index 95% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterface.C rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterface.C index 863013080fb838682aea623694ec585ff774af35..19afeced6325b3c1dee2fb128efe6f963934187d 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterface.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterface.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterface.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterface.H similarity index 97% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterface.H rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterface.H index 0bcbf3a4ef3fc592ec760f35ad49d63baf941f27..55ecbf55146f0fb8c508c2d5902359727945a8fd 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterface.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterface.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C similarity index 96% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C index 0752825b563b4c3c6f5d698c3feac94c570aa4e2..d3b5a52b6b6c5a556dee7ad7b9d410fdfdcfba47 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H similarity index 98% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H index 533437df0806f6abde904b38b2ec1fe508ecbfa4..ad0a4e66ac5e2189a42cfcf990f79192377f1ace 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatch/cyclicAMIPointPatch.C similarity index 97% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.C rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatch/cyclicAMIPointPatch.C index fec146018df0fde5c1c87b54cbdd18d451ef3992..2b4e6b8ad3bf5c6cec6c8dcef011140fcae93b29 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatch/cyclicAMIPointPatch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatch/cyclicAMIPointPatch.H similarity index 98% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.H rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatch/cyclicAMIPointPatch.H index 477892745e4ab35fb30e7c84ccfd3599af529a8d..3cbe4c29f683f28034d4656c05ff7c83122f50a4 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatch/cyclicAMIPointPatch.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchField.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchField.C similarity index 98% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchField.C rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchField.C index 8aa29db5cb183163728a43778c11804b4e88f609..1bf86bea351b6c3374e985c5b1498d6fe5261501 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchField.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchField.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchField.H similarity index 98% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchField.H rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchField.H index 845ecb46a21d6e8e101e7ca7242425967c48b41d..e9f9212eab03e25239789f77e789d80f34d6c58b 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchField.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C similarity index 95% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C index 56e1aef4053ac1241009365caf60d5459cc4885f..889d4f73a3a016509b8755955874fe6baee9183b 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.H similarity index 95% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.H rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.H index 0fb94a64c7e8049ded2878d935e0f8989ae5bd2c..e85dfa4d3d5df27862bd7fae648ae93059f7bb98 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C similarity index 99% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C index 0458dad9dee1edb6e0c8180dba59b4f1162a618c..6632fdb6d2a653daa8923da06587e148adf317dd 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C @@ -232,7 +232,12 @@ void Foam::cyclicAMIPolyPatch::calcTransforms } -void Foam::cyclicAMIPolyPatch::resetAMI() const +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::cyclicAMIPolyPatch::resetAMI +( + const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod +) const { if (owner()) { @@ -283,7 +288,7 @@ void Foam::cyclicAMIPolyPatch::resetAMI() const nbrPatch0, surfPtr(), faceAreaIntersect::tmMesh, - AMIPatchToPatchInterpolation::imFaceAreaWeight, + AMIMethod, AMIReverse_ ) ); @@ -301,8 +306,6 @@ void Foam::cyclicAMIPolyPatch::resetAMI() const } -// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // - void Foam::cyclicAMIPolyPatch::initGeometry(PstreamBuffers& pBufs) { polyPatch::initGeometry(pBufs); diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H similarity index 97% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H index 45aef519524ab8278e788771162f0f9399f21f26..51a9c1dc0d2fab5d7a2cc2cdbc56afff15f7aade 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -108,14 +108,18 @@ private: const vectorField& half1Areas ); - //- Reset the AMI interpolator - void resetAMI() const; - protected: // Protected Member Functions + //- Reset the AMI interpolator + virtual void resetAMI + ( + const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod = + AMIPatchToPatchInterpolation::imFaceAreaWeight + ) const; + //- Recalculate the transformation tensors virtual void calcTransforms(); diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H similarity index 96% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H index 6d726e9df7a679208168c58f3feb6683693bacf1..66a273e0c7a61d3771e8c5f5b3a0ae8ab9f4b77f 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C similarity index 97% rename from src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C rename to src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C index bf4507ff8e0161adefb595974282f8072b559eb4..3c5fc6e02754cddcaebb266fc0e1e6fdbb751931 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index 91bbbc11fd2ea7df9c1a0fec04b4dc37ded5b369..ab78000ffc079dbb05d8a37af200dee1d88528eb 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -43,6 +43,9 @@ patchWave = $(algorithms)/PatchEdgeFaceWave $(patchWave)/PatchEdgeFaceWaveName.C $(patchWave)/patchEdgeFaceInfo.C $(patchWave)/patchPatchDist.C +$(patchWave)/patchEdgeFaceRegion.C +$(patchWave)/patchEdgeFaceRegions.C + meshWave = $(algorithms)/MeshWave $(meshWave)/MeshWaveName.C @@ -113,7 +116,6 @@ $(faceSources)/boundaryToFace/boundaryToFace.C $(faceSources)/zoneToFace/zoneToFace.C $(faceSources)/boxToFace/boxToFace.C $(faceSources)/regionToFace/regionToFace.C -$(faceSources)/regionToFace/patchEdgeFaceRegion.C pointSources = sets/pointSources $(pointSources)/labelToPoint/labelToPoint.C @@ -175,14 +177,23 @@ $(AMI)/AMIInterpolation/AMIPatchToPatchInterpolation.C $(AMI)/faceAreaIntersect/faceAreaIntersect.C $(AMI)/GAMG/interfaces/cyclicAMIGAMGInterface/cyclicAMIGAMGInterface.C $(AMI)/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C +$(AMI)/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.C +$(AMI)/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C -AMICycPatches=$(AMI)/patches/cyclic +AMICycPatches=$(AMI)/patches/cyclicAMI $(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterface.C $(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C $(AMICycPatches)/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C $(AMICycPatches)/cyclicAMIPointPatch/cyclicAMIPointPatch.C $(AMICycPatches)/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C +ACMICycPatches=$(AMI)/patches/cyclicACMI +$(ACMICycPatches)/cyclicACMILduInterfaceField/cyclicACMILduInterface.C +$(ACMICycPatches)/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C +$(ACMICycPatches)/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C +$(ACMICycPatches)/cyclicACMIPointPatch/cyclicACMIPointPatch.C +$(ACMICycPatches)/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.C + mappedPatches/mappedPolyPatch/mappedPatchBase.C mappedPatches/mappedPolyPatch/mappedPolyPatch.C mappedPatches/mappedPolyPatch/mappedWallPolyPatch.C diff --git a/src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegion.C b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegion.C similarity index 95% rename from src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegion.C rename to src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegion.C index 91e9b4c331919fd0c0a6e6e4097d0801c828aacd..eaac9a864a0beb43dd2702a8a76dfb3c7aac398b 100644 --- a/src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegion.C +++ b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegion.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegion.H b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegion.H similarity index 98% rename from src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegion.H rename to src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegion.H index 6c0b65f2d7525a2c6cdeb490978dac48dd88c824..48ced2899bf1c7c616fc6f6cd228e97d83661342 100644 --- a/src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegion.H +++ b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegion.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegionI.H b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegionI.H similarity index 100% rename from src/meshTools/sets/faceSources/regionToFace/patchEdgeFaceRegionI.H rename to src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegionI.H diff --git a/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegions.C b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegions.C new file mode 100644 index 0000000000000000000000000000000000000000..72050034aa22fbf5f36daed1b1926fe4b232f958 --- /dev/null +++ b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegions.C @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "patchEdgeFaceRegions.H" + +// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // + +Foam::Ostream& Foam::operator<< +( + Foam::Ostream& os, + const Foam::patchEdgeFaceRegions& wDist +) +{ + return os << wDist.regions_; +} + + +Foam::Istream& Foam::operator>> +( + Foam::Istream& is, + Foam::patchEdgeFaceRegions& wDist +) +{ + return is >> wDist.regions_; +} + + +// ************************************************************************* // diff --git a/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegions.H b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegions.H new file mode 100644 index 0000000000000000000000000000000000000000..a60a38ce45794dcb0a3f5ba1dd96652b248e3adb --- /dev/null +++ b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegions.H @@ -0,0 +1,173 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::patchEdgeFaceRegions + +Description + Transport of regions for use in PatchEdgeFaceWave. + + Set element to -1 to denote blocked. + +SourceFiles + patchEdgeFaceRegionsI.H + patchEdgeFaceRegions.C + +\*---------------------------------------------------------------------------*/ + +#ifndef patchEdgeFaceRegions_H +#define patchEdgeFaceRegions_H + +#include "labelList.H" +#include "scalar.H" +#include "tensor.H" +#include "labelPair.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class polyMesh; + +/*---------------------------------------------------------------------------*\ + Class patchEdgeFaceRegions Declaration +\*---------------------------------------------------------------------------*/ + +class patchEdgeFaceRegions +{ + // Private data + + //- region per point + labelList regions_; + +public: + + // Constructors + + //- Construct null + inline patchEdgeFaceRegions(); + + //- Construct from regions + inline patchEdgeFaceRegions(const labelList&); + + //- Construct from regions (on edge) + inline patchEdgeFaceRegions(const labelPair&); + + + // Member Functions + + // Access + + inline const labelList& regions() const; + + + // Needed by meshWave + + //- Check whether origin has been changed at all or + // still contains original (invalid) value. + template<class TrackingData> + inline bool valid(TrackingData& td) const; + + //- Apply rotation matrix + template<class Patch, class TrackingData> + inline void transform + ( + const polyMesh& mesh, + const Patch& patch, + const tensor& rotTensor, + const scalar tol, + TrackingData& td + ); + + //- Influence of face on edge + template<class Patch, class TrackingData> + inline bool updateEdge + ( + const polyMesh& mesh, + const Patch& patch, + const label edgeI, + const label faceI, + const patchEdgeFaceRegions& faceInfo, + const scalar tol, + TrackingData& td + ); + + //- New information for edge (from e.g. coupled edge) + template<class Patch, class TrackingData> + inline bool updateEdge + ( + const polyMesh& mesh, + const Patch& patch, + const patchEdgeFaceRegions& edgeInfo, + const bool sameOrientation, + const scalar tol, + TrackingData& td + ); + + //- Influence of edge on face. + template<class Patch, class TrackingData> + inline bool updateFace + ( + const polyMesh& mesh, + const Patch& patch, + const label faceI, + const label edgeI, + const patchEdgeFaceRegions& edgeInfo, + const scalar tol, + TrackingData& td + ); + + //- Same (like operator==) + template<class TrackingData> + inline bool equal(const patchEdgeFaceRegions&, TrackingData&) const; + + + // Member Operators + + // Needed for List IO + inline bool operator==(const patchEdgeFaceRegions&) const; + inline bool operator!=(const patchEdgeFaceRegions&) const; + + + // IOstream Operators + + friend Ostream& operator<<(Ostream&, const patchEdgeFaceRegions&); + friend Istream& operator>>(Istream&, patchEdgeFaceRegions&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "patchEdgeFaceRegionsI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegionsI.H b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegionsI.H new file mode 100644 index 0000000000000000000000000000000000000000..f39488a018fa4153168a0a082475c0591d755b48 --- /dev/null +++ b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceRegionsI.H @@ -0,0 +1,282 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "polyMesh.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +inline Foam::patchEdgeFaceRegions::patchEdgeFaceRegions() +{} + + +inline Foam::patchEdgeFaceRegions::patchEdgeFaceRegions +( + const labelList& regions +) +: + regions_(regions) +{} + + +inline Foam::patchEdgeFaceRegions::patchEdgeFaceRegions +( + const labelPair& regions +) +: + regions_(2) +{ + regions_[0] = regions[0]; + regions_[1] = regions[1]; +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline const Foam::labelList& Foam::patchEdgeFaceRegions::regions() const +{ + return regions_; +} + + +template<class TrackingData> +inline bool Foam::patchEdgeFaceRegions::valid(TrackingData& td) const +{ + return regions_.size() && (findIndex(regions_, labelMax) == -1); +} + + +template<class Patch, class TrackingData> +inline void Foam::patchEdgeFaceRegions::transform +( + const polyMesh& mesh, + const Patch& patch, + const tensor& rotTensor, + const scalar tol, + TrackingData& td +) +{} + + +template<class Patch, class TrackingData> +inline bool Foam::patchEdgeFaceRegions::updateEdge +( + const polyMesh& mesh, + const Patch& patch, + const label edgeI, + const label faceI, + const patchEdgeFaceRegions& faceInfo, + const scalar tol, + TrackingData& td +) +{ + const face& f = patch.localFaces()[faceI]; + const edge& e = patch.edges()[edgeI]; + + label index = findIndex(patch.faceEdges()[faceI], edgeI); + bool sameOrientation = (f[index] == e.start()); + + // Get information in edge-order + edge orientedInfo + ( + faceInfo.regions_[index], + faceInfo.regions_[f.fcIndex(index)] + ); + if (!sameOrientation) + { + orientedInfo.flip(); + } + + if (!faceInfo.valid(td)) + { + FatalErrorIn("patchEdgeFaceRegions::updateEdge(..)") + << "problem." << abort(FatalError); + } + + if ((findIndex(orientedInfo, -1) != -1) || (findIndex(regions_, -1) != -1)) + { + // Blocked edge/face + return false; + } + + + bool changed = false; + + regions_.setSize(orientedInfo.size(), labelMax); + forAll(orientedInfo, i) + { + if (orientedInfo[i] != -1 && orientedInfo[i] < regions_[i]) + { + regions_[i] = orientedInfo[i]; + changed = true; + } + } + return changed; +} + + +template<class Patch, class TrackingData> +inline bool Foam::patchEdgeFaceRegions::updateEdge +( + const polyMesh& mesh, + const Patch& patch, + const patchEdgeFaceRegions& edgeInfo, + const bool sameOrientation, + const scalar tol, + TrackingData& td +) +{ + // Get information in edge-order + edge orientedInfo(edgeInfo.regions_[0], edgeInfo.regions_[1]); + if (!sameOrientation) + { + orientedInfo.flip(); + } + + + if (!edgeInfo.valid(td)) + { + FatalErrorIn("patchEdgeFaceRegions::updateEdge(..)") + << "problem." << abort(FatalError); + } + + if ((findIndex(orientedInfo, -1) != -1) || (findIndex(regions_, -1) != -1)) + { + // Blocked edge/face + return false; + } + + + bool changed = false; + + regions_.setSize(orientedInfo.size(), labelMax); + forAll(orientedInfo, i) + { + if (orientedInfo[i] != -1 && orientedInfo[i] < regions_[i]) + { + regions_[i] = orientedInfo[i]; + changed = true; + } + } + return changed; +} + + +template<class Patch, class TrackingData> +inline bool Foam::patchEdgeFaceRegions::updateFace +( + const polyMesh& mesh, + const Patch& patch, + const label faceI, + const label edgeI, + const patchEdgeFaceRegions& edgeInfo, + const scalar tol, + TrackingData& td +) +{ + const face& f = patch.localFaces()[faceI]; + const edge& e = patch.edges()[edgeI]; + + // Find starting point of edge on face. + label index0 = findIndex(patch.faceEdges()[faceI], edgeI); + label index1 = f.fcIndex(index0); + bool sameOrientation = (f[index0] == e.start()); + + + // Get information in face-order + edge orientedInfo + ( + edgeInfo.regions_[0], + edgeInfo.regions_[1] + ); + if (!sameOrientation) + { + orientedInfo.flip(); + } + + if (!edgeInfo.valid(td)) + { + FatalErrorIn("patchEdgeFaceRegions::updateFace(..)") + << "problem." << abort(FatalError); + } + + if ((findIndex(orientedInfo, -1) != -1) || (findIndex(regions_, -1) != -1)) + { + // Blocked edge/face + return false; + } + + + bool changed = false; + + // Scale if needed + regions_.setSize(f.size(), labelMax); + + if (orientedInfo[0] < regions_[index0]) + { + regions_[index0] = orientedInfo[0]; + changed = true; + } + if (orientedInfo[1] < regions_[index1]) + { + regions_[index1] = orientedInfo[1]; + changed = true; + } + + return changed; +} + + +template<class TrackingData> +inline bool Foam::patchEdgeFaceRegions::equal +( + const patchEdgeFaceRegions& rhs, + TrackingData& td +) const +{ + return operator==(rhs); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +inline bool Foam::patchEdgeFaceRegions::operator== +( + const Foam::patchEdgeFaceRegions& rhs +) const +{ + return regions() == rhs.regions(); +} + + +inline bool Foam::patchEdgeFaceRegions::operator!= +( + const Foam::patchEdgeFaceRegions& rhs +) const +{ + return !(*this == rhs); +} + + +// ************************************************************************* // diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.C b/src/meshTools/searchableSurface/triSurfaceMesh.C index 22229817932e31a1704fbc6608975d6e8b65ec48..6009ec66703b5bac8e523cf7f8773d1ea8a8f89e 100644 --- a/src/meshTools/searchableSurface/triSurfaceMesh.C +++ b/src/meshTools/searchableSurface/triSurfaceMesh.C @@ -433,24 +433,28 @@ Foam::triSurfaceMesh::edgeTree() const + nInternalEdges() ); - treeBoundBox bb; - label nPoints; - PatchTools::calcBounds - ( - static_cast<const triSurface&>(*this), - bb, - nPoints - ); + treeBoundBox bb(vector::zero, vector::zero); + + if (bEdges.size()) + { + label nPoints; + PatchTools::calcBounds + ( + static_cast<const triSurface&>(*this), + bb, + nPoints + ); - // Random number generator. Bit dodgy since not exactly random ;-) - Random rndGen(65431); + // Random number generator. Bit dodgy since not exactly random ;-) + Random rndGen(65431); - // Slightly extended bb. Slightly off-centred just so on symmetric - // geometry there are less face/edge aligned items. + // Slightly extended bb. Slightly off-centred just so on symmetric + // geometry there are less face/edge aligned items. - bb = bb.extend(rndGen, 1e-4); - bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb = bb.extend(rndGen, 1e-4); + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + } scalar oldTol = indexedOctree<treeDataEdge>::perturbTol(); indexedOctree<treeDataEdge>::perturbTol() = tolerance(); diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C index 738cb8dcdd183a5a4e9ecdc0f603bae68b73d855..34dc89f920b3115d402eb211c490062cfcdfa5ed 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C @@ -121,33 +121,40 @@ Foam::triSurfaceRegionSearch::treeByRegion() const ); // Calculate bb without constructing local point numbering. - treeBoundBox bb; - label nPoints; - PatchTools::calcBounds - ( - indirectRegionPatches_[regionI], - bb, - nPoints - ); + treeBoundBox bb(vector::zero, vector::zero); + + if (indirectRegionPatches_[regionI].size()) + { + label nPoints; + PatchTools::calcBounds + ( + indirectRegionPatches_[regionI], + bb, + nPoints + ); -// if (nPoints != surface().points().size()) -// { -// WarningIn("triSurfaceRegionSearch::treeByRegion() const") -// << "Surface does not have compact point numbering. " -// << "Of " << surface().points().size() -// << " only " << nPoints -// << " are used. This might give problems in some routines." -// << endl; -// } - - // Random number generator. Bit dodgy since not exactly random ;-) - Random rndGen(65431); - - // Slightly extended bb. Slightly off-centred just so on symmetric - // geometry there are fewer face/edge aligned items. - bb = bb.extend(rndGen, 1e-4); - bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + // if (nPoints != surface().points().size()) + // { + // WarningIn("triSurfaceRegionSearch::treeByRegion() const") + // << "Surface does not have compact point numbering. " + // << "Of " << surface().points().size() + // << " only " << nPoints + // << " are used." + // << " This might give problems in some routines." + // << endl; + // } + + // Random number generator. Bit dodgy since not exactly + // random ;-) + Random rndGen(65431); + + // Slightly extended bb. Slightly off-centred just so + // on symmetric geometry there are fewer face/edge + // aligned items. + bb = bb.extend(rndGen, 1e-4); + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + } treeByRegion_.set ( diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C index fbff791040fe3d9bf6f617cc36859b2cf4ffb589..43877e3393e588a44edc49f3283110950358b593 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C @@ -200,27 +200,32 @@ Foam::triSurfaceSearch::tree() const if (treePtr_.empty()) { // Calculate bb without constructing local point numbering. - treeBoundBox bb; - label nPoints; - PatchTools::calcBounds(surface(), bb, nPoints); + treeBoundBox bb(vector::zero, vector::zero); - if (nPoints != surface().points().size()) + if (surface().size()) { - WarningIn("triSurfaceSearch::tree() const") - << "Surface does not have compact point numbering." - << " Of " << surface().points().size() << " only " << nPoints - << " are used. This might give problems in some routines." - << endl; - } + label nPoints; + PatchTools::calcBounds(surface(), bb, nPoints); - // Random number generator. Bit dodgy since not exactly random ;-) - Random rndGen(65431); + if (nPoints != surface().points().size()) + { + WarningIn("triSurfaceSearch::tree() const") + << "Surface does not have compact point numbering." + << " Of " << surface().points().size() + << " only " << nPoints + << " are used. This might give problems in some routines." + << endl; + } - // Slightly extended bb. Slightly off-centred just so on symmetric - // geometry there are less face/edge aligned items. - bb = bb.extend(rndGen, 1e-4); - bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + // Random number generator. Bit dodgy since not exactly random ;-) + Random rndGen(65431); + + // Slightly extended bb. Slightly off-centred just so on symmetric + // geometry there are less face/edge aligned items. + bb = bb.extend(rndGen, 1e-4); + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + } scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; diff --git a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C index 80308fac5e61a0a47fd36bf5f7bac05c399e72a7..7c80bd1a5694c6aec91244888117d33e604448f3 100644 --- a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C +++ b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C @@ -2360,10 +2360,28 @@ bool Foam::distributedTriSurfaceMesh::writeObject // Make sure dictionary goes to same directory as surface const_cast<fileName&>(dict_.instance()) = searchableSurface::instance(); + // Copy of triSurfaceMesh::writeObject except for the sorting of + // triangles by region. This is done so we preserve region names, + // even if locally we have zero triangles. + { + fileName fullPath(searchableSurface::objectPath()); + + if (!mkDir(fullPath.path())) + { + return false; + } + + // Important: preserve any zero-sized patches + triSurface::write(fullPath, true); + + if (!isFile(fullPath)) + { + return false; + } + } + // Dictionary needs to be written in ascii - binary output not supported. - return - triSurfaceMesh::writeObject(fmt, ver, cmp) - && dict_.writeObject(IOstream::ASCII, ver, cmp); + return dict_.writeObject(IOstream::ASCII, ver, cmp); } diff --git a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.H b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.H index 32a062a573810878fb46473e6af9f5c036bf5458..7e4d27ef0c6f43378518afac74617161d1e72d68 100644 --- a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.H +++ b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -446,6 +446,10 @@ public: // regIOobject implementation //- Write using given format, version and compression + // Do not use the triSurfaceMesh::writeObject since it + // would filter out empty regions. These need to be preserved + // in case we want to make decisions based on the number of + // regions. virtual bool writeObject ( IOstream::streamFormat fmt, diff --git a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H index f4bd97bd36842bfe75f16806fed65a989f99701a..014d4ce90c9d4b5679f6be776bb01507a99e136f 100644 --- a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H +++ b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -38,7 +38,7 @@ Description type writeRegisteredObject; functionObjectLibs ("libIOFunctionObjects.so"); ... - objectNames (obj1 obj2); + objectNames (obj1 obj2); } \endverbatim diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C index d714747310f6a2fdbdd4fd4ae998fbdf8e3d4b14..5a73765f938ece8322d5524196b30163dcacbc7a 100644 --- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C +++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C @@ -68,12 +68,6 @@ void Foam::fieldAverage::initialize() resetFields(prime2MeanScalarFields_); resetFields(prime2MeanSymmTensorFields_); - totalIter_.clear(); - totalIter_.setSize(faItems_.size(), 1); - - totalTime_.clear(); - totalTime_.setSize(faItems_.size(), obr_.time().deltaTValue()); - // Add mean fields to the field lists forAll(faItems_, fieldI) @@ -150,11 +144,21 @@ void Foam::fieldAverage::initialize() } } } + + // ensure first averaging works unconditionally + prevTimeIndex_ = -1; + + initialised_ = true; } void Foam::fieldAverage::calcAverages() { + if (!initialised_) + { + initialize(); + } + const label currentTimeIndex = static_cast<const fvMesh&>(obr_).time().timeIndex(); @@ -248,6 +252,12 @@ void Foam::fieldAverage::writeAveragingProperties() const void Foam::fieldAverage::readAveragingProperties() { + totalIter_.clear(); + totalIter_.setSize(faItems_.size(), 1); + + totalTime_.clear(); + totalTime_.setSize(faItems_.size(), obr_.time().deltaTValue()); + if (resetOnRestart_) { Info<< "fieldAverage: starting averaging at time " @@ -258,7 +268,7 @@ void Foam::fieldAverage::readAveragingProperties() IOobject propsDictHeader ( "fieldAveragingProperties", - obr_.time().timeName(), + obr_.time().timeName(obr_.time().startTime().value()), "uniform", obr_, IOobject::MUST_READ_IF_MODIFIED, @@ -290,6 +300,7 @@ void Foam::fieldAverage::readAveragingProperties() << " time = " << totalTime_[fieldI] << endl; } } + Info<< endl; } } @@ -311,6 +322,7 @@ Foam::fieldAverage::fieldAverage prevTimeIndex_(-1), resetOnRestart_(false), resetOnOutput_(false), + initialised_(false), faItems_(), meanScalarFields_(), meanVectorFields_(), @@ -357,15 +369,13 @@ void Foam::fieldAverage::read(const dictionary& dict) { if (active_) { + initialised_ = false; + dict.readIfPresent("resetOnRestart", resetOnRestart_); dict.readIfPresent("resetOnOutput", resetOnOutput_); dict.lookup("fields") >> faItems_; - initialize(); readAveragingProperties(); - - // ensure first averaging works unconditionally - prevTimeIndex_ = -1; } } diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H index f8b689757dce8d3804491e558962289682a7e950..4a6d75e06b8b380d59af35b0b48a0ec814a6574a 100644 --- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H +++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H @@ -171,6 +171,9 @@ protected: //- Reset the averaging process on output flag Switch resetOnOutput_; + //- Initialised flag + bool initialised_; + //- List of field average items, describing what averages to be // calculated and output List<fieldAverageItem> faItems_; diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C index 3d7977c488db8b7a3807bec026378c201edfeeb4..595c16084d6f4af93065a9766be4bfdc2e685507 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C +++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -222,11 +222,22 @@ void Foam::fieldValues::cellSource::write() forAll(fields_, i) { - writeValues<scalar>(fields_[i]); - writeValues<vector>(fields_[i]); - writeValues<sphericalTensor>(fields_[i]); - writeValues<symmTensor>(fields_[i]); - writeValues<tensor>(fields_[i]); + const word& fieldName = fields_[i]; + bool processed = false; + + processed = processed || writeValues<scalar>(fieldName); + processed = processed || writeValues<vector>(fieldName); + processed = processed || writeValues<sphericalTensor>(fieldName); + processed = processed || writeValues<symmTensor>(fieldName); + processed = processed || writeValues<tensor>(fieldName); + + if (!processed) + { + WarningIn("void Foam::fieldValues::cellSource::write()") + << "Requested field " << fieldName + << " not found in database and not processed" + << endl; + } } if (Pstream::master()) diff --git a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C index dd54de718ac14619f3ee231427bc5a22a3828148..ee3b62656285b0d9932119948c71f78309365717 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C +++ b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C @@ -630,11 +630,22 @@ void Foam::fieldValues::faceSource::write() forAll(fields_, i) { - writeValues<scalar>(fields_[i]); - writeValues<vector>(fields_[i]); - writeValues<sphericalTensor>(fields_[i]); - writeValues<symmTensor>(fields_[i]); - writeValues<tensor>(fields_[i]); + const word& fieldName = fields_[i]; + bool processed = false; + + processed = processed || writeValues<scalar>(fieldName); + processed = processed || writeValues<vector>(fieldName); + processed = processed || writeValues<sphericalTensor>(fieldName); + processed = processed || writeValues<symmTensor>(fieldName); + processed = processed || writeValues<tensor>(fieldName); + + if (!processed) + { + WarningIn("void Foam::fieldValues::faceSource::write()") + << "Requested field " << fieldName + << " not found in database and not processed" + << endl; + } } if (Pstream::master()) diff --git a/src/postProcessing/functionObjects/forces/forces/forces.C b/src/postProcessing/functionObjects/forces/forces/forces.C index c159b652e833cd30c04edfa5584d3e63d177f931..e38208963b322289bbb713a2fd4639790816a5ef 100644 --- a/src/postProcessing/functionObjects/forces/forces/forces.C +++ b/src/postProcessing/functionObjects/forces/forces/forces.C @@ -28,16 +28,12 @@ License #include "dictionary.H" #include "Time.H" #include "wordReList.H" - -#include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H" -#include "incompressible/RAS/RASModel/RASModel.H" -#include "incompressible/LES/LESModel/LESModel.H" - -#include "fluidThermo.H" -#include "compressible/RAS/RASModel/RASModel.H" -#include "compressible/LES/LESModel/LESModel.H" - +#include "fvcGrad.H" #include "porosityModel.H" +#include "fluidThermo.H" +#include "incompressible/turbulenceModel/turbulenceModel.H" +#include "compressible/turbulenceModel/turbulenceModel.H" +#include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -70,38 +66,27 @@ void Foam::forces::writeFileHeader(const label i) Foam::tmp<Foam::volSymmTensorField> Foam::forces::devRhoReff() const { - if (obr_.foundObject<compressible::RASModel>("RASProperties")) - { - const compressible::RASModel& ras - = obr_.lookupObject<compressible::RASModel>("RASProperties"); - - return ras.devRhoReff(); - } - else if (obr_.foundObject<incompressible::RASModel>("RASProperties")) - { - const incompressible::RASModel& ras - = obr_.lookupObject<incompressible::RASModel>("RASProperties"); + typedef compressible::turbulenceModel cmpTurbModel; + typedef incompressible::turbulenceModel icoTurbModel; - return rho()*ras.devReff(); - } - else if (obr_.foundObject<compressible::LESModel>("LESProperties")) + if (obr_.foundObject<cmpTurbModel>(cmpTurbModel::typeName)) { - const compressible::LESModel& les = - obr_.lookupObject<compressible::LESModel>("LESProperties"); + const cmpTurbModel& turb = + obr_.lookupObject<cmpTurbModel>(cmpTurbModel::typeName); - return les.devRhoReff(); + return turb.devRhoReff(); } - else if (obr_.foundObject<incompressible::LESModel>("LESProperties")) + else if (obr_.foundObject<icoTurbModel>(icoTurbModel::typeName)) { - const incompressible::LESModel& les - = obr_.lookupObject<incompressible::LESModel>("LESProperties"); + const incompressible::turbulenceModel& turb = + obr_.lookupObject<icoTurbModel>(icoTurbModel::typeName); - return rho()*les.devReff(); + return rho()*turb.devReff(); } - else if (obr_.foundObject<fluidThermo>("thermophysicalProperties")) + else if (obr_.foundObject<fluidThermo>(fluidThermo::typeName)) { const fluidThermo& thermo = - obr_.lookupObject<fluidThermo>("thermophysicalProperties"); + obr_.lookupObject<fluidThermo>(fluidThermo::typeName); const volVectorField& U = obr_.lookupObject<volVectorField>(UName_); @@ -438,7 +423,13 @@ Foam::forces::forces binPoints_(), binFormat_("undefined"), binCumulative_(true) -{} +{ + forAll(force_, i) + { + force_[i].setSize(nBin_); + moment_[i].setSize(nBin_); + } +} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // diff --git a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C index 607d52e5034eb046d30ceedc1803376a120a23ca..014aefd8a0be47911bfb7a448c79a5a4189f98a1 100644 --- a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C +++ b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C @@ -70,7 +70,7 @@ Foam::dimensionedScalar Foam::pressureTools::rhoScale } else { - return dimensionedScalar("rhoRef", dimDensity, rhoRef_); + return dimensionedScalar("rhoRef", dimDensity, rhoInf_); } } @@ -100,7 +100,7 @@ Foam::tmp<Foam::volScalarField> Foam::pressureTools::rho IOobject::NO_WRITE ), p.mesh(), - dimensionedScalar("zero", dimDensity, rhoRef_) + dimensionedScalar("zero", dimDensity, rhoInf_) ) ); } @@ -193,7 +193,6 @@ Foam::pressureTools::pressureTools pName_("p"), UName_("U"), rhoName_("rho"), - rhoRef_(1.0), calcTotal_(false), pRef_(0.0), calcCoeff_(false), @@ -219,6 +218,37 @@ Foam::pressureTools::pressureTools } read(dict); + + if (active_) + { + dimensionSet pDims(dimPressure); + + if (calcCoeff_) + { + pDims /= dimPressure; + } + + const fvMesh& mesh = refCast<const fvMesh>(obr_); + + volScalarField* pPtr + ( + new volScalarField + ( + IOobject + ( + pName(), + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedScalar("0", pDims, 0.0) + ) + ); + + mesh.objectRegistry::store(pPtr); + } } @@ -242,7 +272,7 @@ void Foam::pressureTools::read(const dictionary& dict) if (p.dimensions() != dimPressure) { - dict.lookup("rhoRef") >> rhoRef_; + dict.lookup("rhoRef") >> rhoInf_; } dict.lookup("calcTotal") >> calcTotal_; @@ -280,17 +310,13 @@ void Foam::pressureTools::write() { const volScalarField& p = obr_.lookupObject<volScalarField>(pName_); - volScalarField pResult - ( - IOobject + volScalarField& pResult = + const_cast<volScalarField&> ( - pName(), - obr_.time().timeName(), - obr_, - IOobject::NO_READ - ), - convertToCoeff(rhoScale(p)*p + pDyn(p) + pRef()) - ); + obr_.lookupObject<volScalarField>(pName()) + ); + + pResult == convertToCoeff(rhoScale(p)*p + pDyn(p) + pRef()); pResult.write(); } diff --git a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H index 11f490429d25f11630a0aaf1ce387886c26df1ce..82a44921edeb921703ee87e07be63c3ecfe83960 100644 --- a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H +++ b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -92,7 +92,6 @@ Description \table Property | Description | Required | Default value type | type name: pressureTools| yes | - rhoRef | Reference density for incompressible cases | no | 1 calcTotal | Calculate total coefficient | yes | pRef | Reference pressure for total pressure | no | 0.0 calcCoeff | Calculate pressure coefficient | yes | @@ -150,9 +149,6 @@ class pressureTools //- Name of density field, default is "rho" word rhoName_; - //- Reference density employed for incompressible cases - scalar rhoRef_; - // Total pressure calculation diff --git a/src/regionModels/surfaceFilmModels/Make/files b/src/regionModels/surfaceFilmModels/Make/files index 1151e2f7fd380386fc5c10bd64f921f3e068f24c..f14a789338dbe5a52075ee7a324ca3074f85eb86 100644 --- a/src/regionModels/surfaceFilmModels/Make/files +++ b/src/regionModels/surfaceFilmModels/Make/files @@ -24,6 +24,10 @@ $(KINEMATICMODELS)/injectionModel/drippingInjection/drippingInjection.C $(KINEMATICMODELS)/injectionModel/removeInjection/removeInjection.C $(KINEMATICMODELS)/injectionModel/curvatureSeparation/curvatureSeparation.C +$(KINEMATICMODELS)/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C +$(KINEMATICMODELS)/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C +$(KINEMATICMODELS)/filmTurbulenceModel/laminar/laminar.C + THERMOMODELS=submodels/thermo $(THERMOMODELS)/phaseChangeModel/phaseChangeModel/phaseChangeModel.C $(THERMOMODELS)/phaseChangeModel/phaseChangeModel/phaseChangeModelNew.C diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C index fecefcd2e367be8dd1a5ffb064cd8239b0c2d533..00a3ac39afb533c847fa1fe63fbdd88fa131567d 100644 --- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C +++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C @@ -163,7 +163,7 @@ tmp<volScalarField> kinematicSingleLayer::pu() ( IOobject ( - "pu", + typeName + ":pu", time_.timeName(), regionMesh(), IOobject::NO_READ, @@ -185,7 +185,7 @@ tmp<volScalarField> kinematicSingleLayer::pp() ( IOobject ( - "pp", + typeName + ":pp", time_.timeName(), regionMesh(), IOobject::NO_READ, @@ -216,6 +216,8 @@ void kinematicSingleLayer::updateSubmodels() // Update source fields const dimensionedScalar deltaT = time().deltaT(); rhoSp_ += cloudMassTrans_/magSf()/deltaT; + + turbulence_->correct(); } @@ -282,9 +284,7 @@ void kinematicSingleLayer::updateSurfaceVelocities() Uw_ -= nHat()*(Uw_ & nHat()); Uw_.correctBoundaryConditions(); - // apply quadratic profile to surface velocity (scale by sqrt(2)) - Us_ = 1.414*U_; - Us_.correctBoundaryConditions(); + Us_ = turbulence_->Us(); } @@ -309,6 +309,7 @@ tmp<Foam::fvVectorMatrix> kinematicSingleLayer::solveMomentum // - fvm::SuSp(rhoSp_, U_) - rhoSp_*U_ + forces_.correct(U_) + + turbulence_->Su(U_) ); fvVectorMatrix& UEqn = tUEqn(); @@ -779,6 +780,8 @@ kinematicSingleLayer::kinematicSingleLayer injection_(*this, coeffs_), + turbulence_(filmTurbulenceModel::New(*this, coeffs_)), + forces_(*this, coeffs_), addedMassTotal_(0.0) @@ -1020,7 +1023,7 @@ tmp<volScalarField> kinematicSingleLayer::primaryMassTrans() const ( IOobject ( - "kinematicSingleLayer::primaryMassTrans", + typeName + ":primaryMassTrans", time().timeName(), primaryMesh(), IOobject::NO_READ, @@ -1075,7 +1078,7 @@ tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Srho() const ( IOobject ( - "kinematicSingleLayer::Srho", + typeName + ":Srho", time().timeName(), primaryMesh(), IOobject::NO_READ, @@ -1100,7 +1103,7 @@ tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Srho ( IOobject ( - "kinematicSingleLayer::Srho(" + Foam::name(i) + ")", + typeName + ":Srho(" + Foam::name(i) + ")", time().timeName(), primaryMesh(), IOobject::NO_READ, @@ -1122,7 +1125,7 @@ tmp<DimensionedField<scalar, volMesh> > kinematicSingleLayer::Sh() const ( IOobject ( - "kinematicSingleLayer::Sh", + typeName + ":Sh", time().timeName(), primaryMesh(), IOobject::NO_READ, diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H index 079999d0cd4e835674f5aef5839a91cc61666e5d..2c9e1020a3b8f75a7c5f332ec75118293eba3368 100644 --- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H +++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,6 +43,7 @@ SourceFiles #include "injectionModelList.H" #include "forceList.H" +#include "filmTurbulenceModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -197,6 +198,9 @@ protected: //- Cloud injection injectionModelList injection_; + //- Turbulence model + autoPtr<filmTurbulenceModel> turbulence_; + //- List of film forces forceList forces_; @@ -444,6 +448,9 @@ public: //- Injection inline injectionModelList& injection(); + //- Turbulence + inline const filmTurbulenceModel& turbulence() const; + // Helper functions diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H index 6a77b614bcad146deb45f56c7546e9d208bbf9ee..15f6398ad8f33bcd99cad7593c3dfeeabc51f277 100644 --- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H +++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -169,6 +169,12 @@ inline injectionModelList& kinematicSingleLayer::injection() } +inline const filmTurbulenceModel& kinematicSingleLayer::turbulence() const +{ + return turbulence_(); +} + + inline tmp<volScalarField> kinematicSingleLayer::mass() const { return rho_*delta_*magSf(); diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C new file mode 100644 index 0000000000000000000000000000000000000000..a77307e881a5800bb649a9bd00c9d0cd7486cfa3 --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.C @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "filmTurbulenceModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(filmTurbulenceModel, 0); +defineRunTimeSelectionTable(filmTurbulenceModel, dictionary); + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +filmTurbulenceModel::filmTurbulenceModel(const surfaceFilmModel& owner) +: + subModelBase(owner) +{} + + +filmTurbulenceModel::filmTurbulenceModel +( + const word& type, + const surfaceFilmModel& owner, + const dictionary& dict +) +: + subModelBase(type, owner, dict) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +filmTurbulenceModel::~filmTurbulenceModel() +{} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H new file mode 100644 index 0000000000000000000000000000000000000000..571bf83e8d1c12faefd6df2348f24b4403a586b1 --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModel.H @@ -0,0 +1,148 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::regionModels::surfaceFilmModels::filmTurbulenceModel + +Description + Base class for film turbulence models + +SourceFiles + filmTurbulenceModel.C + filmTurbulenceModelNew.C + +\*---------------------------------------------------------------------------*/ + +#ifndef filmTurbulenceModel_H +#define filmTurbulenceModel_H + +#include "subModelBase.H" +#include "runTimeSelectionTables.H" +#include "fvMatricesFwd.H" +#include "volFieldsFwd.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +/*---------------------------------------------------------------------------*\ + Class filmTurbulenceModel Declaration +\*---------------------------------------------------------------------------*/ + +class filmTurbulenceModel +: + public subModelBase +{ +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + filmTurbulenceModel(const filmTurbulenceModel&); + + //- Disallow default bitwise assignment + void operator=(const filmTurbulenceModel&); + + +public: + + //- Runtime type information + TypeName("filmTurbulenceModel"); + + + // Declare runtime constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + filmTurbulenceModel, + dictionary, + ( + const surfaceFilmModel& owner, + const dictionary& dict + ), + (owner, dict) + ); + + // Constructors + + //- Construct null + filmTurbulenceModel(const surfaceFilmModel& owner); + + //- Construct from type name, dictionary and surface film model + filmTurbulenceModel + ( + const word& type, + const surfaceFilmModel& owner, + const dictionary& dict + ); + + + // Selectors + + //- Return a reference to the selected injection model + static autoPtr<filmTurbulenceModel> New + ( + const surfaceFilmModel& owner, + const dictionary& dict + ); + + + //- Destructor + virtual ~filmTurbulenceModel(); + + + // Member Functions + + // Evolution + + //- Return the film surface velocity + virtual tmp<volVectorField> Us() const = 0; + + //- Return the film turbulence viscosity + virtual tmp<volScalarField> mut() const = 0; + + //- Correct/update the model + virtual void correct() = 0; + + //- Return the source for the film momentum equation + virtual tmp<fvVectorMatrix> Su(volVectorField& U) const = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C new file mode 100644 index 0000000000000000000000000000000000000000..ba939ef798953794745d1f24b735f171390a6207 --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/filmTurbulenceModel/filmTurbulenceModelNew.C @@ -0,0 +1,77 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "filmTurbulenceModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +autoPtr<filmTurbulenceModel> filmTurbulenceModel::New +( + const surfaceFilmModel& model, + const dictionary& dict +) +{ + const word modelType(dict.lookup("turbulence")); + + Info<< " " << modelType << endl; + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(modelType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorIn + ( + "filmTurbulenceModel::New" + "(" + "const surfaceFilmModel&, " + "const dictionary&" + ")" + ) << "Unknown filmTurbulenceModel type " << modelType + << nl << nl << "Valid filmTurbulenceModel types are:" << nl + << dictionaryConstructorTablePtr_->toc() + << exit(FatalError); + } + + return autoPtr<filmTurbulenceModel>(cstrIter()(model, dict)); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/laminar/laminar.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/laminar/laminar.C new file mode 100644 index 0000000000000000000000000000000000000000..108109702b03dcb1170006f4a681afe4ea7012c3 --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/laminar/laminar.C @@ -0,0 +1,160 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "laminar.H" +#include "addToRunTimeSelectionTable.H" +#include "fvMesh.H" +#include "fvMatrices.H" +#include "Time.H" +#include "volFields.H" +#include "fvmSup.H" +#include "kinematicSingleLayer.H" +#include "zeroGradientFvPatchFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(laminar, 0); +addToRunTimeSelectionTable(filmTurbulenceModel, laminar, dictionary); + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +laminar::laminar +( + const surfaceFilmModel& owner, + const dictionary& dict +) +: + filmTurbulenceModel(type(), owner, dict), + Cf_(readScalar(coeffs_.lookup("Cf"))) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +laminar::~laminar() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +tmp<volVectorField> laminar::Us() const +{ + tmp<volVectorField> tUs + ( + new volVectorField + ( + IOobject + ( + typeName + ".Us", + owner_.regionMesh().time().timeName(), + owner_.regionMesh(), + IOobject::NO_READ, + IOobject::NO_WRITE + ), + owner_.regionMesh(), + dimensionedVector("zero", dimVelocity, vector::zero), + zeroGradientFvPatchVectorField::typeName + ) + ); + + // apply quadratic profile + tUs() = Foam::sqrt(2.0)*owner_.U(); + tUs().correctBoundaryConditions(); + + return tUs; +} + + +tmp<volScalarField> laminar::mut() const +{ + return tmp<volScalarField> + ( + new volScalarField + ( + IOobject + ( + typeName + ".mut", + owner_.regionMesh().time().timeName(), + owner_.regionMesh(), + IOobject::NO_READ, + IOobject::NO_WRITE + ), + owner_.regionMesh(), + dimensionedScalar("zero", dimMass/dimLength/dimTime, 0.0) + ) + ); +} + + +void laminar::correct() +{ + // do nothing +} + +tmp<fvVectorMatrix> laminar::Su(volVectorField& U) const +{ + // local reference to film model + const kinematicSingleLayer& film = + static_cast<const kinematicSingleLayer&>(owner_); + + // local references to film fields + const volScalarField& mu = film.mu(); + const volVectorField& Uw = film.Uw(); + const volVectorField& Us = film.Us(); + const volScalarField& delta = film.delta(); + const volVectorField& Up = film.UPrimary(); + const volScalarField& rhop = film.rhoPrimary(); + + // employ simple coeff-based model + volScalarField Cs("Cs", Cf_*rhop*mag(Up - Us)); + + dimensionedScalar d0("SMALL", delta.dimensions(), SMALL); + volScalarField Cw("Cw", mu/(0.3333*(delta + d0))); + Cw.min(5000.0); + + return + ( + - fvm::Sp(Cs, U) + Cs*Us // surface contribution + - fvm::Sp(Cw, U) + Cw*Uw // wall contribution + ); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/laminar/laminar.H b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/laminar/laminar.H new file mode 100644 index 0000000000000000000000000000000000000000..397030efffca63b7d15b53f817dae0af0e97b45e --- /dev/null +++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/filmTurbulenceModel/laminar/laminar.H @@ -0,0 +1,118 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::regionModels::surfaceFilmModels::laminar + +Description + Film laminar turbulence model. + +SourceFiles + laminar.C + +\*---------------------------------------------------------------------------*/ + +#ifndef laminar_H +#define laminar_H + +#include "filmTurbulenceModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace regionModels +{ +namespace surfaceFilmModels +{ + +/*---------------------------------------------------------------------------*\ + Class laminar Declaration +\*---------------------------------------------------------------------------*/ + +class laminar +: + public filmTurbulenceModel +{ +private: + + // Private Data + + //- Surface roughness coefficient + scalar Cf_; + + + // Private member functions + + //- Disallow default bitwise copy construct + laminar(const laminar&); + + //- Disallow default bitwise assignment + void operator=(const laminar&); + + +public: + + //- Runtime type information + TypeName("laminar"); + + + // Constructors + + //- Construct from surface film model + laminar(const surfaceFilmModel& owner, const dictionary& dict); + + + //- Destructor + virtual ~laminar(); + + + // Member Functions + + // Evolution + + //- Return the film surface velocity + virtual tmp<volVectorField> Us() const; + + //- Return the film turbulence viscosity + virtual tmp<volScalarField> mut() const; + + //- Correct/update the model + virtual void correct(); + + //- Return the source for the film momentum equation + virtual tmp<fvVectorMatrix> Su(volVectorField& U) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceFilmModels +} // End namespace regionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayerI.H b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayerI.H index 659a315f4916487eedfe0a8ce0db10f32705c50d..0905176adf59b8866781b522920d89e056d7097a 100644 --- a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayerI.H +++ b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayerI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,6 +25,7 @@ License #include "thermoSingleLayer.H" #include "heatTransferModel.H" +#include "filmRadiationModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/renumber/renumberMethods/structuredRenumber/structuredRenumber.C b/src/renumber/renumberMethods/structuredRenumber/structuredRenumber.C index b0a13a83997061bddae86c0c2520c82d8071ea01..289adba5c93ec095120110e26340468e3d0e87c8 100644 --- a/src/renumber/renumberMethods/structuredRenumber/structuredRenumber.C +++ b/src/renumber/renumberMethods/structuredRenumber/structuredRenumber.C @@ -202,7 +202,7 @@ Foam::labelList Foam::structuredRenumber::renumber if (depthFirst_) { orderedToOld[nLayers*cellData[cellI].data()+layerI] = cellI; - } + } else { orderedToOld[cellData[cellI].data()+nLayers*layerI] = cellI; diff --git a/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C b/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C index 5817279076fcbbf90e12553acbfa81d6377e9fd2..52b3192c6dbfca73d197a307c48672ca474313e8 100644 --- a/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C +++ b/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -189,51 +189,40 @@ updateCoeffs() } scalarField& Iw = *this; - const vectorField n(patch().Sf()/patch().magSf()); + const vectorField n(patch().nf()); radiativeIntensityRay& ray = const_cast<radiativeIntensityRay&>(dom.IRay(rayId)); - ray.Qr().boundaryField()[patchI] += Iw*(n & ray.dAve()); + const scalarField nAve(n & ray.dAve()); - scalarField temissivity = emissivity(); + ray.Qr().boundaryField()[patchI] += Iw*nAve; - forAll(Iw, faceI) - { - scalar Ir = 0.0; + const scalarField temissivity = emissivity(); - for (label rayI=0; rayI < dom.nRay(); rayI++) - { - const vector& d = dom.IRay(rayI).d(); + scalarField& Qem = ray.Qem().boundaryField()[patchI]; + scalarField& Qin = ray.Qin().boundaryField()[patchI]; - const scalarField& IFace = - dom.IRay(rayI).ILambda(lambdaId).boundaryField()[patchI]; + const vector& myRayId = dom.IRay(rayId).d(); - if ((-n[faceI] & d) < 0.0) - { - // q into the wall - const vector& dAve = dom.IRay(rayI).dAve(); - Ir += IFace[faceI]*mag(n[faceI] & dAve); - } - } + const scalarField& Ir = dom.Qin(); - const vector& d = dom.IRay(rayId).d(); - - if ((-n[faceI] & d) > 0.0) + forAll(Iw, faceI) + { + if ((-n[faceI] & myRayId) > 0.0) { // direction out of the wall refGrad()[faceI] = 0.0; valueFraction()[faceI] = 1.0; refValue()[faceI] = ( - Ir*(scalar(1.0) - temissivity[faceI]) + Ir[faceI]*(scalar(1.0) - temissivity[faceI]) + temissivity[faceI]*physicoChemical::sigma.value() * pow4(Tp[faceI]) )/pi; - // Emmited heat flux from this ray direction - ray.Qem().boundaryField()[patchI][faceI] = - refValue()[faceI]*(n[faceI] & ray.dAve()); + // Emmited heat flux from this ray direction + Qem[faceI] = refValue()[faceI]*nAve[faceI]; } else { @@ -242,9 +231,8 @@ updateCoeffs() refGrad()[faceI] = 0.0; refValue()[faceI] = 0.0; //not used - // Incident heat flux on this ray direction - ray.Qin().boundaryField()[patchI][faceI] = - Iw[faceI]*(n[faceI] & ray.dAve()); + // Incident heat flux on this ray direction + Qin[faceI] = Iw[faceI]*nAve[faceI]; } } diff --git a/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H b/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H index f1a38077e0acb383c0b83fae37fe654a4ce1dcd5..8f8b1aef171c51d782633773bfba00bcc7dc5a15 100644 --- a/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H +++ b/src/thermophysicalModels/radiationModels/derivedFvPatchFields/greyDiffusiveRadiation/greyDiffusiveRadiationMixedFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.C b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.C index 10961db0322bafbb097bc7a3eb4c9536bf67f0fc..4217231ce8e9409d03e61deed8aed8fe9a4f575c 100644 --- a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.C +++ b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -27,6 +27,7 @@ License #include "absorptionEmissionModel.H" #include "scatterModel.H" #include "constants.H" +#include "fvm.H" using namespace Foam::constant; using namespace Foam::constant::mathematical; @@ -172,10 +173,39 @@ void Foam::radiation::fvDOM::initialise() Info<< "fvDOM : Allocated " << IRay_.size() << " rays with average orientation:" << nl; - forAll(IRay_, i) + if (cacheDiv_) { - Info<< '\t' << IRay_[i].I().name() - << '\t' << IRay_[i].dAve() << nl; + Info<< "Caching div fvMatrix..."<< endl; + for (label lambdaI = 0; lambdaI < nLambda_; lambdaI++) + { + fvRayDiv_[lambdaI].setSize(nRay_); + + forAll(IRay_, rayId) + { + const surfaceScalarField Ji(IRay_[rayId].dAve() & mesh_.Sf()); + const volScalarField& iRayLambdaI = + IRay_[rayId].ILambda(lambdaI); + + fvRayDiv_[lambdaI].set + ( + rayId, + new fvScalarMatrix + ( + fvm::div(Ji, iRayLambdaI, "div(Ji,Ii_h)") + ) + ); + } + } + } + + forAll(IRay_, rayId) + { + if (omegaMax_ < IRay_[rayId].omega()) + { + omegaMax_ = IRay_[rayId].omega(); + } + Info<< '\t' << IRay_[rayId].I().name() << " : " << "omega : " + << '\t' << IRay_[rayId].omega() << nl; } Info<< endl; @@ -194,7 +224,7 @@ Foam::radiation::fvDOM::fvDOM(const volScalarField& T) "G", mesh_.time().timeName(), mesh_, - IOobject::READ_IF_PRESENT, + IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh_, @@ -247,7 +277,7 @@ Foam::radiation::fvDOM::fvDOM(const volScalarField& T) mesh_.time().timeName(), mesh_, IOobject::NO_READ, - IOobject::NO_WRITE + IOobject::AUTO_WRITE ), mesh_, dimensionedScalar("a", dimless/dimLength, 0.0) @@ -260,7 +290,10 @@ Foam::radiation::fvDOM::fvDOM(const volScalarField& T) blackBody_(nLambda_, T), IRay_(0), convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)), - maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)) + maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)), + fvRayDiv_(nLambda_), + cacheDiv_(coeffs_.lookupOrDefault<bool>("cacheDiv", false)), + omegaMax_(0) { initialise(); } @@ -346,7 +379,10 @@ Foam::radiation::fvDOM::fvDOM blackBody_(nLambda_, T), IRay_(0), convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)), - maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)) + maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)), + fvRayDiv_(nLambda_), + cacheDiv_(coeffs_.lookupOrDefault<bool>("cacheDiv", false)), + omegaMax_(0) { initialise(); } @@ -364,7 +400,6 @@ bool Foam::radiation::fvDOM::read() if (radiationModel::read()) { // Only reading solution parameters - not changing ray geometry - coeffs_.readIfPresent("convergence", convergence_); coeffs_.readIfPresent("maxIter", maxIter_); @@ -383,19 +418,30 @@ void Foam::radiation::fvDOM::calculate() updateBlackBodyEmission(); + // Set rays convergence false + List<bool> rayIdConv(nRay_, false); + scalar maxResidual = 0.0; label radIter = 0; do { + Info<< "Radiation solver iter: " << radIter << endl; + radIter++; + maxResidual = 0.0; forAll(IRay_, rayI) { - maxResidual = 0.0; - scalar maxBandResidual = IRay_[rayI].correct(); - maxResidual = max(maxBandResidual, maxResidual); - } + if (!rayIdConv[rayI]) + { + scalar maxBandResidual = IRay_[rayI].correct(); + maxResidual = max(maxBandResidual, maxResidual); - Info<< "Radiation solver iter: " << radIter << endl; + if (maxBandResidual < convergence_) + { + rayIdConv[rayI] = true; + } + } + } } while (maxResidual > convergence_ && radIter < maxIter_); @@ -433,7 +479,7 @@ Foam::radiation::fvDOM::Ru() const const DimensionedField<scalar, volMesh> E = absorptionEmission_->ECont()().dimensionedInternalField(); const DimensionedField<scalar, volMesh> a = - a_.dimensionedInternalField(); //absorptionEmission_->aCont()() + a_.dimensionedInternalField(); return a*G - E; } diff --git a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.H b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.H index 48efae9ee66fba47173a47635bd3e349e8bd9d7d..3d9950db4c7debf5b1c9d607e999838b9f4d36f5 100644 --- a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.H +++ b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOM.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -30,6 +30,7 @@ Description directions in a participating media, not including scatter. Available absorption models: + constantAbsorptionEmission greyMeanAbsoprtionEmission wideBandAbsorptionEmission @@ -37,9 +38,15 @@ Description \verbatim fvDOMCoeffs { - nPhi 1; // azimuthal angles in PI/2 on X-Y.(from Y to X) - nTheta 2; // polar angles in PI (from Z to X-Y plane) - convergence 1e-4; // convergence criteria for radiation iteration + nPhi 4; // azimuthal angles in PI/2 on X-Y. + //(from Y to X) + nTheta 0; // polar angles in PI (from Z to X-Y plane) + convergence 1e-3; // convergence criteria for radiation + //iteration + maxIter 4; // maximum number of iterations + cacheDiv true; // cache the div of the RTE equation. + //NOTE: Caching div is "only" accurate if the upwind scheme is used + //in div(Ji,Ii_h) } solverFreq 1; // Number of flow iterations per radiation iteration @@ -61,6 +68,7 @@ SourceFiles #include "radiativeIntensityRay.H" #include "radiationModel.H" +#include "fvMatrices.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -79,6 +87,7 @@ class fvDOM { // Private data + //- Incident radiation [W/m2] volScalarField G_; @@ -121,6 +130,15 @@ class fvDOM //- Maximum number of iterations scalar maxIter_; + //- List of cached fvMatrices for rays + List<PtrList<fvScalarMatrix> >fvRayDiv_; + + //- Cache convection div matrix + bool cacheDiv_; + + //- Maximum omega weight + scalar omegaMax_; + // Private Member Functions @@ -229,6 +247,19 @@ public: //- Const access to black body inline const blackBodyEmission& blackBody() const; + + //- Const access to cached fvMatrix + inline const fvScalarMatrix& fvRayDiv + ( + const label lambdaI, + const label rayId + ) const; + + //- Caching div(Ji, Ilamda) + inline bool cacheDiv() const; + + //- Return omegaMax + inline scalar omegaMax() const; }; diff --git a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOMI.H b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOMI.H index de6e44f523c0c00f3ef47b0b2ce493609559692c..8bc9c6425e8655dbabdaca41e7cd2bd295d51745 100644 --- a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOMI.H +++ b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/fvDOM/fvDOMI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -102,6 +102,7 @@ inline const Foam::volScalarField& Foam::radiation::fvDOM::Qem() const return Qem_; } + inline const Foam::radiation::blackBodyEmission& Foam::radiation::fvDOM::blackBody() const { @@ -109,4 +110,26 @@ Foam::radiation::fvDOM::blackBody() const } +inline const Foam::fvScalarMatrix& Foam::radiation::fvDOM::fvRayDiv +( + const label rayId, + const label lambdaI +) const +{ + return fvRayDiv_[lambdaI][rayId]; +} + + +inline bool Foam::radiation::fvDOM::cacheDiv() const +{ + return cacheDiv_; +} + + +inline Foam::scalar Foam::radiation::fvDOM::omegaMax() const +{ + return omegaMax_; +} + + // ************************************************************************* // diff --git a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.C b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.C index 947e3e50300487d25068ce6b215bbaadfad52d01..28644026a4c6f219db81e7d81ada8c3ba066963a 100644 --- a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.C +++ b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -113,7 +113,8 @@ Foam::radiation::radiativeIntensityRay::radiativeIntensityRay phi_(phi), omega_(0.0), nLambda_(nLambda), - ILambda_(nLambda) + ILambda_(nLambda), + myRayId_(rayId) { scalar sinTheta = Foam::sin(theta); scalar cosTheta = Foam::cos(theta); @@ -135,7 +136,6 @@ Foam::radiation::radiativeIntensityRay::radiativeIntensityRay 0.5*deltaPhi*Foam::sin(2.0*theta)*Foam::sin(deltaTheta) ); - autoPtr<volScalarField> IDefaultPtr; forAll(ILambda_, lambdaI) @@ -213,29 +213,51 @@ Foam::scalar Foam::radiation::radiativeIntensityRay::correct() { const volScalarField& k = dom_.aLambda(lambdaI); - const surfaceScalarField Ji(dAve_ & mesh_.Sf()); + tmp<fvScalarMatrix> IiEq; - fvScalarMatrix IiEq - ( - fvm::div(Ji, ILambda_[lambdaI], "div(Ji,Ii_h)") - + fvm::Sp(k*omega_, ILambda_[lambdaI]) - == - 1.0/constant::mathematical::pi*omega_ - *( - k*blackBody_.bLambda(lambdaI) - + absorptionEmission_.ECont(lambdaI)/4 - ) - ); + if (!dom_.cacheDiv()) + { + const surfaceScalarField Ji(dAve_ & mesh_.Sf()); - IiEq.relax(); + IiEq = + ( + fvm::div(Ji, ILambda_[lambdaI], "div(Ji,Ii_h)") + + fvm::Sp(k*omega_, ILambda_[lambdaI]) + == + 1.0/constant::mathematical::pi*omega_ + * ( + k*blackBody_.bLambda(lambdaI) + + absorptionEmission_.ECont(lambdaI)/4 + ) + ); + } + else + { + IiEq = + ( + dom_.fvRayDiv(myRayId_, lambdaI) + + fvm::Sp(k*omega_, ILambda_[lambdaI]) + == + 1.0/constant::mathematical::pi*omega_ + * ( + k*blackBody_.bLambda(lambdaI) + + absorptionEmission_.ECont(lambdaI)/4 + ) + ); + } - scalar eqnResidual = solve + IiEq().relax(); + + const solverPerformance ILambdaSol = solve ( - IiEq, + IiEq(), mesh_.solver("Ii") - ).initialResidual(); + ); + + const scalar initialRes = + ILambdaSol.initialResidual()*omega_/dom_.omegaMax(); - maxResidual = max(eqnResidual, maxResidual); + maxResidual = max(initialRes, maxResidual); } return maxResidual; diff --git a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.H b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.H index 83eed35d996eef0721f76b9abc22c457db8a4b6e..25f363044e03aa5689b79a94778e25ee2194348a 100644 --- a/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.H +++ b/src/thermophysicalModels/radiationModels/radiationModel/fvDOM/radiativeIntensityRay/radiativeIntensityRay.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -38,6 +38,7 @@ SourceFiles #include "absorptionEmissionModel.H" #include "blackBodyEmission.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam @@ -111,6 +112,9 @@ private: //- Global ray id - incremented in constructor static label rayId; + //- My ray Id + label myRayId_; + // Private Member Functions @@ -209,6 +213,7 @@ public: //- Return the radiative intensity for a given wavelength inline const volScalarField& ILambda(const label lambdaI) const; + }; diff --git a/src/thermophysicalModels/radiationModels/submodels/absorptionEmissionModel/absorptionEmissionModel/absorptionEmissionModel.C b/src/thermophysicalModels/radiationModels/submodels/absorptionEmissionModel/absorptionEmissionModel/absorptionEmissionModel.C index 982c7e31370107bc4d04164a8f0614f02cb9a6d1..563b46727fe2de82f56de3176e2dc6a3b01085fd 100644 --- a/src/thermophysicalModels/radiationModels/submodels/absorptionEmissionModel/absorptionEmissionModel/absorptionEmissionModel.C +++ b/src/thermophysicalModels/radiationModels/submodels/absorptionEmissionModel/absorptionEmissionModel/absorptionEmissionModel.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -252,8 +252,8 @@ void Foam::radiation::absorptionEmissionModel::correct PtrList<volScalarField>& aj ) const { - a.internalField() = this->a(); - aj[0].internalField() = a.internalField(); + a = this->a(); + aj[0] = a; } diff --git a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C index 6994f926e37dc402a4702d850ca1f6a441d99306..324d857a31950c2aba3aa74e2662729f80497c37 100644 --- a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C +++ b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -63,20 +63,51 @@ tmp<volScalarField> SpalartAllmaras::fv1() const tmp<volScalarField> SpalartAllmaras::fv2() const { - return 1.0/pow3(scalar(1) + rho()*nuTilda_/(mu()*Cv2_)); + if (ashfordCorrection_) + { + return 1.0/pow3(scalar(1) + rho()*nuTilda_/(mu()*Cv2_)); + } + else + { + const volScalarField chi("chi", rho()*nuTilda_/mu()); + return 1.0 - chi/(1.0 + chi*fv1()); + } } tmp<volScalarField> SpalartAllmaras::fv3() const { - volScalarField chi(rho()*nuTilda_/mu()); - volScalarField chiByCv2((1/Cv2_)*chi); - - return - (scalar(1) + chi*fv1()) - *(1/Cv2_) - *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) - /pow3(scalar(1) + chiByCv2); + if (ashfordCorrection_) + { + volScalarField chi(rho()*nuTilda_/mu()); + volScalarField chiByCv2((1/Cv2_)*chi); + + return + (scalar(1) + chi*fv1()) + *(1/Cv2_) + *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) + /pow3(scalar(1) + chiByCv2); + } + else + { + return tmp<volScalarField> + ( + new volScalarField + ( + IOobject + ( + "fv3", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + dimensionedScalar("fv3", dimless, 1), + zeroGradientFvPatchScalarField::typeName + ) + ); + } } @@ -222,6 +253,8 @@ SpalartAllmaras::SpalartAllmaras ) ), + ashfordCorrection_(coeffDict_.lookupOrDefault("ashfordCorrection", true)), + nuTilda_ ( IOobject @@ -265,6 +298,11 @@ SpalartAllmaras::SpalartAllmaras updateSubGridScaleFields(); printCoeffs(); + + if (ashfordCorrection_) + { + Info<< " Employing Ashford correction" << endl; + } } @@ -344,16 +382,19 @@ bool SpalartAllmaras::read() { sigmaNut_.readIfPresent(coeffDict()); Prt_.readIfPresent(coeffDict()); + Cb1_.readIfPresent(coeffDict()); Cb2_.readIfPresent(coeffDict()); - Cw1_ = Cb1_/sqr(kappa_) + (1.0 + Cb2_)/sigmaNut_; - Cw2_.readIfPresent(coeffDict()); - Cw3_.readIfPresent(coeffDict()); Cv1_.readIfPresent(coeffDict()); Cv2_.readIfPresent(coeffDict()); CDES_.readIfPresent(coeffDict()); ck_.readIfPresent(coeffDict()); kappa_.readIfPresent(*this); + Cw1_ = Cb1_/sqr(kappa_) + (1.0 + Cb2_)/sigmaNut_; + Cw2_.readIfPresent(coeffDict()); + Cw3_.readIfPresent(coeffDict()); + + ashfordCorrection_.readIfPresent("ashfordCorrection", coeffDict()); return true; } diff --git a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H index 18975789422911059336d189d54f3fae1b3feb44..11d24d3388c593b3e34469ba9894f5ee36d60fe6 100644 --- a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H +++ b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -30,6 +30,15 @@ Group Description SpalartAllmaras for compressible flows + Extended according to + \verbatim + "An Unstructured Grid Generation and Adaptive Solution Technique + for High Reynolds Number Compressible Flows" + G.A. Ashford, + Ph.D. thesis, University of Michigan, 1996. + \endverbatim + by using the optional flag \c ashfordCorrection + SourceFiles SpalartAllmaras.C @@ -77,12 +86,16 @@ class SpalartAllmaras dimensionedScalar Cw3_; - // Fields + //- Optional flag to activate the Ashford correction + Switch ashfordCorrection_; + + + // Fields - volScalarField nuTilda_; - volScalarField dTilda_; - volScalarField muSgs_; - volScalarField alphaSgs_; + volScalarField nuTilda_; + volScalarField dTilda_; + volScalarField muSgs_; + volScalarField alphaSgs_; // Private Member Functions diff --git a/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C index 6c5f3aae0c8d7a2396497b5406b77e4fd948772b..9e5cf2d11fb9e3271acb29bfcc644510cb55adb8 100644 --- a/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C +++ b/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -63,7 +63,14 @@ tmp<volScalarField> SpalartAllmaras::fv2 const volScalarField& fv1 ) const { - return 1.0/pow3(scalar(1) + chi/Cv2_); + if (ashfordCorrection_) + { + return 1.0/pow3(scalar(1) + chi/Cv2_); + } + else + { + return 1.0 - chi/(1.0 + chi*fv1); + } } @@ -73,13 +80,36 @@ tmp<volScalarField> SpalartAllmaras::fv3 const volScalarField& fv1 ) const { - const volScalarField chiByCv2((1/Cv2_)*chi); + if (ashfordCorrection_) + { + const volScalarField chiByCv2((1/Cv2_)*chi); - return - (scalar(1) + chi*fv1) - *(1/Cv2_) - *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) - /pow3(scalar(1) + chiByCv2); + return + (scalar(1) + chi*fv1) + *(1/Cv2_) + *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) + /pow3(scalar(1) + chiByCv2); + } + else + { + return tmp<volScalarField> + ( + new volScalarField + ( + IOobject + ( + "fv3", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + dimensionedScalar("fv3", dimless, 1), + zeroGradientFvPatchScalarField::typeName + ) + ); + } } @@ -252,6 +282,11 @@ SpalartAllmaras::SpalartAllmaras alphat_.correctBoundaryConditions(); printCoeffs(); + + if (ashfordCorrection_) + { + Info<< " Employing Ashford correction" << endl; + } } @@ -372,6 +407,8 @@ bool SpalartAllmaras::read() Cv1_.readIfPresent(coeffDict()); Cv2_.readIfPresent(coeffDict()); + ashfordCorrection_.readIfPresent("ashfordCorrection", coeffDict()); + return true; } else diff --git a/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.H b/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.H index ea829fc88dfbe69502c2346ec6723a84df45a952..ce1054c482eb3842869b621bbbe097075a61ee60 100644 --- a/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.H +++ b/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,14 +37,16 @@ Description P.R. Spalart, S.R. Allmaras, La Recherche Aerospatiale, No. 1, 1994, pp. 5-21. + \endverbatim - Extended according to: - + Extended according to: + \verbatim "An Unstructured Grid Generation and Adaptive Solution Technique for High Reynolds Number Compressible Flows" G.A. Ashford, Ph.D. thesis, University of Michigan, 1996. \endverbatim + by using the optional flag \c ashfordCorrection The default model coefficients correspond to the following: \verbatim @@ -110,6 +112,10 @@ protected: dimensionedScalar Cv2_; + //- Optional flag to activate the Ashford correction + Switch ashfordCorrection_; + + // Fields volScalarField nuTilda_; diff --git a/src/turbulenceModels/compressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C b/src/turbulenceModels/compressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C index 55434df625a5b4588e9034d58805c53ec89d5b71..7846bec820854630a76ec920f6fe76564c2f099a 100644 --- a/src/turbulenceModels/compressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C +++ b/src/turbulenceModels/compressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,6 +25,7 @@ License #include "backwardsCompatibilityWallFunctions.H" +#include "volFields.H" #include "calculatedFvPatchField.H" #include "alphatWallFunctionFvPatchScalarField.H" #include "mutkWallFunctionFvPatchScalarField.H" diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C index 84762e6beb400c93c25feae964dba067d2198489..d079c811ea9c211cd1d82b87e9581411f78d2882 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C @@ -55,6 +55,67 @@ scalar epsilonLowReWallFunctionFvPatchScalarField::yPlusLam } +void epsilonLowReWallFunctionFvPatchScalarField::calculate +( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon +) +{ + const label patchI = patch.index(); + + const scalarField& y = turbulence.y()[patchI]; + + const scalar Cmu25 = pow025(Cmu_); + const scalar Cmu75 = pow(Cmu_, 0.75); + + const tmp<volScalarField> tk = turbulence.k(); + const volScalarField& k = tk(); + + const tmp<volScalarField> tmu = turbulence.mu(); + const scalarField& muw = tmu().boundaryField()[patchI]; + + const tmp<volScalarField> tmut = turbulence.mut(); + const volScalarField& mut = tmut(); + const scalarField& mutw = mut.boundaryField()[patchI]; + + const scalarField& rhow = turbulence.rho().boundaryField()[patchI]; + + const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + + const scalarField magGradUw(mag(Uw.snGrad())); + + // Set epsilon and G + forAll(mutw, faceI) + { + label cellI = patch.faceCells()[faceI]; + + scalar yPlus = Cmu25*sqrt(k[cellI])*y[faceI]/muw[faceI]/rhow[faceI]; + + scalar w = cornerWeights[faceI]; + + if (yPlus > yPlusLam_) + { + epsilon[cellI] = w*Cmu75*pow(k[cellI], 1.5)/(kappa_*y[faceI]); + } + else + { + epsilon[cellI] = + w*2.0*k[cellI]*muw[faceI]/rhow[faceI]/sqr(y[faceI]); + } + + G[cellI] = + w + *(mutw[faceI] + muw[faceI]) + *magGradUw[faceI] + *Cmu25*sqrt(k[cellI]) + /(kappa_*y[faceI]); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // epsilonLowReWallFunctionFvPatchScalarField:: @@ -119,84 +180,6 @@ epsilonLowReWallFunctionFvPatchScalarField {} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void epsilonLowReWallFunctionFvPatchScalarField::updateCoeffs() -{ - if (updated()) - { - return; - } - - const label patchI = patch().index(); - - const turbulenceModel& turbulence = - db().lookupObject<turbulenceModel>("turbulenceModel"); - const scalarField& y = turbulence.y()[patchI]; - - volScalarField& G = - const_cast<volScalarField&> - ( - db().lookupObject<volScalarField> - ( - turbulence.GName() - ) - ); - - DimensionedField<scalar, volMesh>& epsilon = - const_cast<DimensionedField<scalar, volMesh>&> - ( - dimensionedInternalField() - ); - - const tmp<volScalarField> tk = turbulence.k(); - const volScalarField& k = tk(); - - const tmp<volScalarField> tmu = turbulence.mu(); - const scalarField& muw = tmu().boundaryField()[patchI]; - - const tmp<volScalarField> tmut = turbulence.mut(); - const volScalarField& mut = tmut(); - const scalarField& mutw = mut.boundaryField()[patchI]; - - const scalarField& rhow = turbulence.rho().boundaryField()[patchI]; - - const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; - const scalarField magGradUw(mag(Uw.snGrad())); - - const scalar Cmu25 = pow025(Cmu_); - const scalar Cmu75 = pow(Cmu_, 0.75); - - // Set epsilon and G - forAll(mutw, faceI) - { - label faceCellI = patch().faceCells()[faceI]; - - scalar yPlus = Cmu25*sqrt(k[faceCellI])*y[faceI]/muw[faceI]/rhow[faceI]; - - if (yPlus > yPlusLam_) - { - epsilon[faceCellI] = Cmu75*pow(k[faceCellI], 1.5)/(kappa_*y[faceI]); - } - else - { - epsilon[faceCellI] = - 2.0*k[faceCellI]*muw[faceI]/rhow[faceI]/sqr(y[faceI]); - } - - G[faceCellI] = - (mutw[faceI] + muw[faceI]) - *magGradUw[faceI] - *Cmu25*sqrt(k[faceCellI]) - /(kappa_*y[faceI]); - } - - fixedInternalValueFvPatchField<scalar>::updateCoeffs(); - - // TODO: perform averaging for cells sharing more than one boundary face -} - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // makePatchTypeField diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H index 61434c29b5020f24de8cca75004ce0ff4cb8c7c3..c2f7cf178fef5fb8fe29aec389f93783856666be 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -97,6 +97,16 @@ protected: //- Calculate the Y+ at the edge of the laminar sublayer scalar yPlusLam(const scalar kappa, const scalar E); + //- Calculate the epsilon and G + virtual void calculate + ( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon + ); + public: @@ -165,14 +175,6 @@ public: new epsilonLowReWallFunctionFvPatchScalarField(*this, iF) ); } - - - // Member functions - - // Evaluation functions - - //- Update the coefficients associated with the patch field - virtual void updateCoeffs(); }; diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C index dc6296f2ed64ad746fb3cc2e68fbaaff2312ecbf..5e78e48c9732566b7e4f029181e577a2dd4c25ad 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C @@ -26,10 +26,10 @@ License #include "epsilonWallFunctionFvPatchScalarField.H" #include "compressible/turbulenceModel/turbulenceModel.H" #include "fvPatchFieldMapper.H" +#include "fvMatrix.H" #include "volFields.H" -#include "addToRunTimeSelectionTable.H" -#include "mutWallFunctionFvPatchScalarField.H" #include "wallFvPatch.H" +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -62,6 +62,193 @@ void epsilonWallFunctionFvPatchScalarField::writeLocalEntries(Ostream& os) const } +void epsilonWallFunctionFvPatchScalarField::setMaster() +{ + if (master_ != -1) + { + return; + } + + const volScalarField& epsilon = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = epsilon.boundaryField(); + + label master = -1; + forAll(bf, patchI) + { + if (isA<epsilonWallFunctionFvPatchScalarField>(bf[patchI])) + { + epsilonWallFunctionFvPatchScalarField& epf = epsilonPatch(patchI); + + if (master == -1) + { + master = patchI; + } + + epf.master() = master; + } + } +} + + +void epsilonWallFunctionFvPatchScalarField::createAveragingWeights() +{ + if (initialised_) + { + return; + } + + const volScalarField& epsilon = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = epsilon.boundaryField(); + + const fvMesh& mesh = epsilon.mesh(); + + volScalarField weights + ( + IOobject + ( + "weights", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // do not register + ), + mesh, + dimensionedScalar("zero", dimless, 0.0) + ); + + DynamicList<label> epsilonPatches(bf.size()); + forAll(bf, patchI) + { + if (isA<epsilonWallFunctionFvPatchScalarField>(bf[patchI])) + { + epsilonPatches.append(patchI); + + const labelUList& faceCells = bf[patchI].patch().faceCells(); + forAll(faceCells, i) + { + label cellI = faceCells[i]; + weights[cellI]++; + } + } + } + + cornerWeights_.setSize(bf.size()); + forAll(epsilonPatches, i) + { + label patchI = epsilonPatches[i]; + const fvPatchField& wf = weights.boundaryField()[patchI]; + cornerWeights_[patchI] = 1.0/wf.patchInternalField(); + } + + G_.setSize(dimensionedInternalField().size(), 0.0); + epsilon_.setSize(dimensionedInternalField().size(), 0.0); + + initialised_ = true; +} + + +epsilonWallFunctionFvPatchScalarField& +epsilonWallFunctionFvPatchScalarField::epsilonPatch(const label patchI) +{ + const volScalarField& epsilon = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = epsilon.boundaryField(); + + const epsilonWallFunctionFvPatchScalarField& epf = + refCast<const epsilonWallFunctionFvPatchScalarField>(bf[patchI]); + + return const_cast<epsilonWallFunctionFvPatchScalarField&>(epf); +} + + +void epsilonWallFunctionFvPatchScalarField::calculateTurbulenceFields +( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& epsilon0 +) +{ + // accumulate all of the G and epsilon contributions + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + epsilonWallFunctionFvPatchScalarField& epf = epsilonPatch(patchI); + + const List<scalar>& w = cornerWeights_[patchI]; + + epf.calculate(turbulence, w, epf.patch(), G0, epsilon0); + } + } + + // apply zero-gradient condition for epsilon + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + epsilonWallFunctionFvPatchScalarField& epf = epsilonPatch(patchI); + + epf == scalarField(epsilon0, epf.patch().faceCells()); + } + } +} + + +void epsilonWallFunctionFvPatchScalarField::calculate +( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon +) +{ + const label patchI = patch.index(); + + const scalarField& y = turbulence.y()[patchI]; + + const scalar Cmu25 = pow025(Cmu_); + const scalar Cmu75 = pow(Cmu_, 0.75); + + const tmp<volScalarField> tk = turbulence.k(); + const volScalarField& k = tk(); + + const tmp<volScalarField> tmu = turbulence.mu(); + const scalarField& muw = tmu().boundaryField()[patchI]; + + const tmp<volScalarField> tmut = turbulence.mut(); + const volScalarField& mut = tmut(); + const scalarField& mutw = mut.boundaryField()[patchI]; + + const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + + const scalarField magGradUw(mag(Uw.snGrad())); + + // Set epsilon and G + forAll(mutw, faceI) + { + label cellI = patch.faceCells()[faceI]; + + scalar w = cornerWeights[faceI]; + + epsilon[cellI] = w*Cmu75*pow(k[cellI], 1.5)/(kappa_*y[faceI]); + + G[cellI] = + w + *(mutw[faceI] + muw[faceI]) + *magGradUw[faceI] + *Cmu25*sqrt(k[cellI]) + /(kappa_*y[faceI]); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField @@ -70,10 +257,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(p, iF), + fixedValueFvPatchField<scalar>(p, iF), Cmu_(0.09), kappa_(0.41), - E_(9.8) + E_(9.8), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -87,10 +279,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const fvPatchFieldMapper& mapper ) : - fixedInternalValueFvPatchField<scalar>(ptf, p, iF, mapper), + fixedValueFvPatchField<scalar>(ptf, p, iF, mapper), Cmu_(ptf.Cmu_), kappa_(ptf.kappa_), - E_(ptf.E_) + E_(ptf.E_), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -103,10 +300,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const dictionary& dict ) : - fixedInternalValueFvPatchField<scalar>(p, iF, dict), + fixedValueFvPatchField<scalar>(p, iF, dict), Cmu_(dict.lookupOrDefault<scalar>("Cmu", 0.09)), kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)), - E_(dict.lookupOrDefault<scalar>("E", 9.8)) + E_(dict.lookupOrDefault<scalar>("E", 9.8)), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -117,10 +319,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const epsilonWallFunctionFvPatchScalarField& ewfpsf ) : - fixedInternalValueFvPatchField<scalar>(ewfpsf), + fixedValueFvPatchField<scalar>(ewfpsf), Cmu_(ewfpsf.Cmu_), kappa_(ewfpsf.kappa_), - E_(ewfpsf.E_) + E_(ewfpsf.E_), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -132,10 +339,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(ewfpsf, iF), + fixedValueFvPatchField<scalar>(ewfpsf, iF), Cmu_(ewfpsf.Cmu_), kappa_(ewfpsf.kappa_), - E_(ewfpsf.E_) + E_(ewfpsf.E_), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -143,6 +355,38 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +scalarField& epsilonWallFunctionFvPatchScalarField::G(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + G_ = 0.0; + } + + return G_; + } + + return epsilonPatch(master_).G(); +} + + +scalarField& epsilonWallFunctionFvPatchScalarField::epsilon(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + epsilon_ = 0.0; + } + + return epsilon_; + } + + return epsilonPatch(master_).epsilon(init); +} + + void epsilonWallFunctionFvPatchScalarField::updateCoeffs() { if (updated()) @@ -150,76 +394,168 @@ void epsilonWallFunctionFvPatchScalarField::updateCoeffs() return; } - const label patchI = patch().index(); - const turbulenceModel& turbulence = - db().lookupObject<turbulenceModel>("turbulenceModel"); + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); - const scalar Cmu25 = pow025(Cmu_); - const scalar Cmu75 = pow(Cmu_, 0.75); + setMaster(); - const scalarField& y = turbulence.y()[patchI]; + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), epsilon(true)); + } - volScalarField& G = - const_cast<volScalarField&> - ( - db().lookupObject<volScalarField> - ( - turbulence.GName() - ) - ); + const scalarField& G0 = this->G(); + const scalarField& epsilon0 = this->epsilon(); - DimensionedField<scalar, volMesh>& epsilon = - const_cast<DimensionedField<scalar, volMesh>&> + typedef DimensionedField<scalar, volMesh> FieldType; + + FieldType& G = + const_cast<FieldType&> ( - dimensionedInternalField() + db().lookupObject<FieldType>(turbulence.GName()) ); - const tmp<volScalarField> tk = turbulence.k(); - const volScalarField& k = tk(); + FieldType& epsilon = const_cast<FieldType&>(dimensionedInternalField()); - const scalarField& muw = turbulence.mu().boundaryField()[patchI]; + forAll(*this, faceI) + { + label cellI = patch().faceCells()[faceI]; - const tmp<volScalarField> tmut = turbulence.mut(); - const volScalarField& mut = tmut(); - const scalarField& mutw = mut.boundaryField()[patchI]; + G[cellI] = G0[cellI]; + epsilon[cellI] = epsilon0[cellI]; + } - const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + fvPatchField<scalar>::updateCoeffs(); +} - const scalarField magGradUw(mag(Uw.snGrad())); - // Set epsilon and G - forAll(mutw, faceI) +void epsilonWallFunctionFvPatchScalarField::updateCoeffs +( + const scalarField& weights +) +{ + if (updated()) { - label faceCellI = patch().faceCells()[faceI]; + return; + } - epsilon[faceCellI] = Cmu75*pow(k[faceCellI], 1.5)/(kappa_*y[faceI]); + const turbulenceModel& turbulence = + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); - G[faceCellI] = - (mutw[faceI] + muw[faceI]) - *magGradUw[faceI] - *Cmu25*sqrt(k[faceCellI]) - /(kappa_*y[faceI]); + setMaster(); + + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), epsilon(true)); } - fixedInternalValueFvPatchField<scalar>::updateCoeffs(); + const scalarField& G0 = this->G(); + const scalarField& epsilon0 = this->epsilon(); + + typedef DimensionedField<scalar, volMesh> FieldType; + + FieldType& G = + const_cast<FieldType&> + ( + db().lookupObject<FieldType>(turbulence.GName()) + ); + + FieldType& epsilon = const_cast<FieldType&>(dimensionedInternalField()); + + // only set the values if the weights are < 1 - tolerance + forAll(weights, faceI) + { + scalar w = weights[faceI]; + + if (w < 1.0 - 1e-6) + { + label cellI = patch().faceCells()[faceI]; + + G[cellI] = w*G[cellI] + (1.0 - w)*G0[cellI]; + epsilon[cellI] = w*epsilon[cellI] + (1.0 - w)*epsilon0[cellI]; + } + } - // TODO: perform averaging for cells sharing more than one boundary face + fvPatchField<scalar>::updateCoeffs(); } -void epsilonWallFunctionFvPatchScalarField::evaluate +void epsilonWallFunctionFvPatchScalarField::manipulateMatrix ( - const Pstream::commsTypes commsType + fvMatrix<scalar>& matrix ) { - fixedInternalValueFvPatchField<scalar>::evaluate(commsType); + if (manipulatedMatrix()) + { + return; + } + + matrix.setValues(patch().faceCells(), patchInternalField()); + + fvPatchField<scalar>::manipulateMatrix(matrix); +} + + +void epsilonWallFunctionFvPatchScalarField::manipulateMatrix +( + fvMatrix<scalar>& matrix, + const Field<scalar>& weights +) +{ + if (manipulatedMatrix()) + { + return; + } + + // filter weights so that we only apply the constraint where the + // weight > SMALL + DynamicList<label> constraintCells(weights.size()); + DynamicList<scalar> constraintEpsilon(weights.size()); + const labelUList& faceCells = patch().faceCells(); + + const DimensionedField<scalar, volMesh>& epsilon + = dimensionedInternalField(); + + label nConstrainedCells = 0; + + + forAll(weights, faceI) + { + // only set the values if the weights are < 1 - tolerance + if (weights[faceI] < (1.0 - 1e-6)) + { + nConstrainedCells++; + + label cellI = faceCells[faceI]; + + constraintCells.append(cellI); + constraintEpsilon.append(epsilon[cellI]); + } + } + + if (debug) + { + Pout<< "Patch: " << patch().name() + << ": number of constrained cells = " << nConstrainedCells + << " out of " << patch().size() + << endl; + } + + matrix.setValues + ( + constraintCells, + scalarField(constraintEpsilon.xfer()) + ); + + fvPatchField<scalar>::manipulateMatrix(matrix); } void epsilonWallFunctionFvPatchScalarField::write(Ostream& os) const { - fixedInternalValueFvPatchField<scalar>::write(os); + fixedValueFvPatchField<scalar>::write(os); writeLocalEntries(os); writeEntry("value", os); } diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H index 9975348d0be53acb86dc2765eb872df90f4634f8..9eefc78620e6e6a00ba2f589731d04ceaba0727e 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -71,7 +71,7 @@ SourceFiles #ifndef compressibleEpsilonWallFunctionFvPatchScalarField_H #define compressibleEpsilonWallFunctionFvPatchScalarField_H -#include "fixedInternalValueFvPatchField.H" +#include "fixedValueFvPatchField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -80,13 +80,15 @@ namespace Foam namespace compressible { +class turbulenceModel; + /*---------------------------------------------------------------------------*\ Class epsilonWallFunctionFvPatchScalarField Declaration \*---------------------------------------------------------------------------*/ class epsilonWallFunctionFvPatchScalarField : - public fixedInternalValueFvPatchField<scalar> + public fixedValueFvPatchField<scalar> { protected: @@ -101,6 +103,21 @@ protected: //- E coefficient scalar E_; + //- Local copy of turbulence G field + scalarField G_; + + //- Local copy of turbulence epsilon field + scalarField epsilon_; + + //- Initialised flag + bool initialised_; + + //- Master patch ID + label master_; + + //- List of averaging corner weights + List<List<scalar> > cornerWeights_; + // Protected Member Functions @@ -110,6 +127,44 @@ protected: //- Write local wall function variables virtual void writeLocalEntries(Ostream&) const; + //- Set the master patch - master is responsible for updating all + // wall function patches + virtual void setMaster(); + + //- Create the averaging weights for cells which are bounded by + // multiple wall function faces + virtual void createAveragingWeights(); + + //- Helper function to return non-const access to an epsilon patch + virtual epsilonWallFunctionFvPatchScalarField& epsilonPatch + ( + const label patchI + ); + + //- Main driver to calculate the turbulence fields + virtual void calculateTurbulenceFields + ( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& epsilon0 + ); + + //- Calculate the epsilon and G + virtual void calculate + ( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon + ); + + //- Return non-const access to the master patch ID + virtual label& master() + { + return master_; + } + public: @@ -180,15 +235,39 @@ public: } + //- Destructor + virtual ~epsilonWallFunctionFvPatchScalarField() + {} + + // Member functions + // Access + + //- Return non-const access to the master's G field + scalarField& G(bool init = false); + + //- Return non-const access to the master's epsilon field + scalarField& epsilon(bool init = false); + + // Evaluation functions //- Update the coefficients associated with the patch field virtual void updateCoeffs(); - //- Evaluate the patchField - virtual void evaluate(const Pstream::commsTypes); + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(const scalarField& weights); + + //- Manipulate matrix + virtual void manipulateMatrix(fvMatrix<scalar>& matrix); + + //- Manipulate matrix with given weights + virtual void manipulateMatrix + ( + fvMatrix<scalar>& matrix, + const scalarField& weights + ); // I-O diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C index a826fdf5e3bc76bb9b013b03b4cfec6f63c367e6..fff165e15e3511d125b56fdc971b231e6631c335 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C @@ -26,10 +26,11 @@ License #include "omegaWallFunctionFvPatchScalarField.H" #include "compressible/turbulenceModel/turbulenceModel.H" #include "fvPatchFieldMapper.H" +#include "fvMatrix.H" #include "volFields.H" -#include "addToRunTimeSelectionTable.H" -#include "mutWallFunctionFvPatchScalarField.H" #include "wallFvPatch.H" +#include "mutWallFunctionFvPatchScalarField.H" +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -63,6 +64,198 @@ void omegaWallFunctionFvPatchScalarField::writeLocalEntries(Ostream& os) const } +void omegaWallFunctionFvPatchScalarField::setMaster() +{ + if (master_ != -1) + { + return; + } + + const volScalarField& omega = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = omega.boundaryField(); + + label master = -1; + forAll(bf, patchI) + { + if (isA<omegaWallFunctionFvPatchScalarField>(bf[patchI])) + { + omegaWallFunctionFvPatchScalarField& epf = omegaPatch(patchI); + + if (master == -1) + { + master = patchI; + } + + epf.master() = master; + } + } +} + + +void omegaWallFunctionFvPatchScalarField::createAveragingWeights() +{ + if (initialised_) + { + return; + } + + const volScalarField& omega = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = omega.boundaryField(); + + const fvMesh& mesh = omega.mesh(); + + volScalarField weights + ( + IOobject + ( + "weights", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // do not register + ), + mesh, + dimensionedScalar("zero", dimless, 0.0) + ); + + DynamicList<label> omegaPatches(bf.size()); + forAll(bf, patchI) + { + if (isA<omegaWallFunctionFvPatchScalarField>(bf[patchI])) + { + omegaPatches.append(patchI); + + const labelUList& faceCells = bf[patchI].patch().faceCells(); + forAll(faceCells, i) + { + label cellI = faceCells[i]; + weights[cellI]++; + } + } + } + + cornerWeights_.setSize(bf.size()); + forAll(omegaPatches, i) + { + label patchI = omegaPatches[i]; + const fvPatchField& wf = weights.boundaryField()[patchI]; + cornerWeights_[patchI] = 1.0/wf.patchInternalField(); + } + + G_.setSize(dimensionedInternalField().size(), 0.0); + omega_.setSize(dimensionedInternalField().size(), 0.0); + + initialised_ = true; +} + + +omegaWallFunctionFvPatchScalarField& +omegaWallFunctionFvPatchScalarField::omegaPatch(const label patchI) +{ + const volScalarField& omega = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = omega.boundaryField(); + + const omegaWallFunctionFvPatchScalarField& epf = + refCast<const omegaWallFunctionFvPatchScalarField>(bf[patchI]); + + return const_cast<omegaWallFunctionFvPatchScalarField&>(epf); +} + + +void omegaWallFunctionFvPatchScalarField::calculateTurbulenceFields +( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& omega0 +) +{ + // accumulate all of the G and omega contributions + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + omegaWallFunctionFvPatchScalarField& epf = omegaPatch(patchI); + + const List<scalar>& w = cornerWeights_[patchI]; + + epf.calculate(turbulence, w, epf.patch(), G0, omega0); + } + } + + // apply zero-gradient condition for omega + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + omegaWallFunctionFvPatchScalarField& epf = omegaPatch(patchI); + + epf == scalarField(omega0, epf.patch().faceCells()); + } + } +} + + +void omegaWallFunctionFvPatchScalarField::calculate +( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& omega +) +{ + const label patchI = patch.index(); + + const scalarField& y = turbulence.y()[patchI]; + + const scalar Cmu25 = pow025(Cmu_); + + const tmp<volScalarField> tk = turbulence.k(); + const volScalarField& k = tk(); + + const scalarField& rhow = turbulence.rho().boundaryField()[patchI]; + + const tmp<volScalarField> tmu = turbulence.mu(); + const scalarField& muw = tmu().boundaryField()[patchI]; + + const tmp<volScalarField> tmut = turbulence.mut(); + const volScalarField& mut = tmut(); + const scalarField& mutw = mut.boundaryField()[patchI]; + + const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + + const scalarField magGradUw(mag(Uw.snGrad())); + + // Set omega and G + forAll(mutw, faceI) + { + label cellI = patch.faceCells()[faceI]; + + scalar w = cornerWeights[faceI]; + + scalar omegaVis = 6.0*muw[faceI]/(rhow[faceI]*beta1_*sqr(y[faceI])); + + scalar omegaLog = sqrt(k[cellI])/(Cmu25*kappa_*y[faceI]); + + omega[cellI] = w*sqrt(sqr(omegaVis) + sqr(omegaLog)); + + G[cellI] = + w + *(mutw[faceI] + muw[faceI]) + *magGradUw[faceI] + *Cmu25*sqrt(k[cellI]) + /(kappa_*y[faceI]); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField @@ -71,13 +264,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(p, iF), + fixedValueFvPatchField<scalar>(p, iF), Cmu_(0.09), kappa_(0.41), E_(9.8), beta1_(0.075), - yPlusLam_(mutWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)) - + yPlusLam_(mutWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -91,12 +288,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const fvPatchFieldMapper& mapper ) : - fixedInternalValueFvPatchField<scalar>(ptf, p, iF, mapper), + fixedValueFvPatchField<scalar>(ptf, p, iF, mapper), Cmu_(ptf.Cmu_), kappa_(ptf.kappa_), E_(ptf.E_), beta1_(ptf.beta1_), - yPlusLam_(ptf.yPlusLam_) + yPlusLam_(ptf.yPlusLam_), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -109,12 +311,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const dictionary& dict ) : - fixedInternalValueFvPatchField<scalar>(p, iF, dict), + fixedValueFvPatchField<scalar>(p, iF, dict), Cmu_(dict.lookupOrDefault<scalar>("Cmu", 0.09)), kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)), E_(dict.lookupOrDefault<scalar>("E", 9.8)), beta1_(dict.lookupOrDefault<scalar>("beta1", 0.075)), - yPlusLam_(mutWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)) + yPlusLam_(mutWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -125,12 +332,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const omegaWallFunctionFvPatchScalarField& owfpsf ) : - fixedInternalValueFvPatchField<scalar>(owfpsf), + fixedValueFvPatchField<scalar>(owfpsf), Cmu_(owfpsf.Cmu_), kappa_(owfpsf.kappa_), E_(owfpsf.E_), beta1_(owfpsf.beta1_), - yPlusLam_(owfpsf.yPlusLam_) + yPlusLam_(owfpsf.yPlusLam_), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -142,13 +354,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(owfpsf, iF), + fixedValueFvPatchField<scalar>(owfpsf, iF), Cmu_(owfpsf.Cmu_), kappa_(owfpsf.kappa_), E_(owfpsf.E_), beta1_(owfpsf.beta1_), - yPlusLam_(owfpsf.yPlusLam_) - + yPlusLam_(owfpsf.yPlusLam_), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -156,6 +372,38 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +scalarField& omegaWallFunctionFvPatchScalarField::G(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + G_ = 0.0; + } + + return G_; + } + + return omegaPatch(master_).G(); +} + + +scalarField& omegaWallFunctionFvPatchScalarField::omega(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + omega_ = 0.0; + } + + return omega_; + } + + return omegaPatch(master_).omega(init); +} + + void omegaWallFunctionFvPatchScalarField::updateCoeffs() { if (updated()) @@ -163,68 +411,168 @@ void omegaWallFunctionFvPatchScalarField::updateCoeffs() return; } - const label patchI = patch().index(); - const turbulenceModel& turbulence = - db().lookupObject<turbulenceModel>("turbulenceModel"); - const scalarField& y = turbulence.y()[patch().index()]; + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); - const scalar Cmu25 = pow025(Cmu_); + setMaster(); + + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), omega(true)); + } + + const scalarField& G0 = this->G(); + const scalarField& omega0 = this->omega(); - volScalarField& G = const_cast<volScalarField&> + typedef DimensionedField<scalar, volMesh> FieldType; + + FieldType& G = + const_cast<FieldType&> ( - db().lookupObject<volScalarField> - ( - turbulence.GName() - ) + db().lookupObject<FieldType>(turbulence.GName()) ); - DimensionedField<scalar, volMesh>& omega = - const_cast<DimensionedField<scalar, volMesh>&> + FieldType& omega = const_cast<FieldType&>(dimensionedInternalField()); + + forAll(*this, faceI) + { + label cellI = patch().faceCells()[faceI]; + + G[cellI] = G0[cellI]; + omega[cellI] = omega0[cellI]; + } + + fvPatchField<scalar>::updateCoeffs(); +} + + +void omegaWallFunctionFvPatchScalarField::updateCoeffs +( + const scalarField& weights +) +{ + if (updated()) + { + return; + } + + const turbulenceModel& turbulence = + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); + + setMaster(); + + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), omega(true)); + } + + const scalarField& G0 = this->G(); + const scalarField& omega0 = this->omega(); + + typedef DimensionedField<scalar, volMesh> FieldType; + + FieldType& G = + const_cast<FieldType&> ( - dimensionedInternalField() + db().lookupObject<FieldType>(turbulence.GName()) ); - const tmp<volScalarField> tk = turbulence.k(); - const volScalarField& k = tk(); + FieldType& omega = const_cast<FieldType&>(dimensionedInternalField()); - const scalarField& rhow = turbulence.rho().boundaryField()[patchI]; + // only set the values if the weights are < 1 - tolerance + forAll(weights, faceI) + { + scalar w = weights[faceI]; - const scalarField& muw = turbulence.mu().boundaryField()[patchI]; + if (w < 1.0 - 1e-6) + { + label cellI = patch().faceCells()[faceI]; - const tmp<volScalarField> tmut = turbulence.mut(); - const volScalarField& mut = tmut(); - const scalarField& mutw = mut.boundaryField()[patchI]; + G[cellI] = w*G[cellI] + (1.0 - w)*G0[cellI]; + omega[cellI] = w*omega[cellI] + (1.0 - w)*omega0[cellI]; + } + } - const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + fvPatchField<scalar>::updateCoeffs(); +} - const scalarField magGradUw(mag(Uw.snGrad())); - // Set omega and G - forAll(mutw, faceI) +void omegaWallFunctionFvPatchScalarField::manipulateMatrix +( + fvMatrix<scalar>& matrix +) +{ + if (manipulatedMatrix()) + { + return; + } + + matrix.setValues(patch().faceCells(), patchInternalField()); + + fvPatchField<scalar>::manipulateMatrix(matrix); +} + + +void omegaWallFunctionFvPatchScalarField::manipulateMatrix +( + fvMatrix<scalar>& matrix, + const Field<scalar>& weights +) +{ + if (manipulatedMatrix()) { - label faceCellI = patch().faceCells()[faceI]; + return; + } - scalar omegaVis = 6.0*muw[faceI]/(rhow[faceI]*beta1_*sqr(y[faceI])); - scalar omegaLog = sqrt(k[faceCellI])/(Cmu25*kappa_*y[faceI]); - omega[faceCellI] = sqrt(sqr(omegaVis) + sqr(omegaLog)); + // filter weights so that we only apply the constraint where the + // weight > SMALL + DynamicList<label> constraintCells(weights.size()); + DynamicList<scalar> constraintomega(weights.size()); + const labelUList& faceCells = patch().faceCells(); - G[faceCellI] = - (mutw[faceI] + muw[faceI]) - *magGradUw[faceI] - *Cmu25*sqrt(k[faceCellI]) - /(kappa_*y[faceI]); + const DimensionedField<scalar, volMesh>& omega + = dimensionedInternalField(); + + label nConstrainedCells = 0; + + + forAll(weights, faceI) + { + // only set the values if the weights are < 1 - tolerance + if (weights[faceI] < (1.0 - 1e-6)) + { + nConstrainedCells++; + + label cellI = faceCells[faceI]; + + constraintCells.append(cellI); + constraintomega.append(omega[cellI]); + } + } + + if (debug) + { + Pout<< "Patch: " << patch().name() + << ": number of constrained cells = " << nConstrainedCells + << " out of " << patch().size() + << endl; } - fixedInternalValueFvPatchField<scalar>::updateCoeffs(); + matrix.setValues + ( + constraintCells, + scalarField(constraintomega.xfer()) + ); - // TODO: perform averaging for cells sharing more than one boundary face + fvPatchField<scalar>::manipulateMatrix(matrix); } void omegaWallFunctionFvPatchScalarField::write(Ostream& os) const { - fixedInternalValueFvPatchField<scalar>::write(os); + fixedValueFvPatchField<scalar>::write(os); writeLocalEntries(os); writeEntry("value", os); } diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H index 69fa8ee9cd06ea6ab759ef193a94c9c89a8e3f9f..9db8e32a8d6e7c3abcf127324d211114c97d64f1 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -76,7 +76,7 @@ SourceFiles #ifndef compressibleOmegaWallFunctionFvPatchScalarField_H #define compressibleOmegaWallFunctionFvPatchScalarField_H -#include "fixedInternalValueFvPatchField.H" +#include "fixedValueFvPatchField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -85,13 +85,15 @@ namespace Foam namespace compressible { +class turbulenceModel; + /*---------------------------------------------------------------------------*\ - Class omegaWallFunctionFvPatchScalarField Declaration + Class omegaWallFunctionFvPatchScalarField Declaration \*---------------------------------------------------------------------------*/ class omegaWallFunctionFvPatchScalarField : - public fixedInternalValueFvPatchField<scalar> + public fixedValueFvPatchField<scalar> { protected: @@ -112,6 +114,21 @@ protected: //- Y+ at the edge of the laminar sublayer scalar yPlusLam_; + //- Local copy of turbulence G field + scalarField G_; + + //- Local copy of turbulence omega field + scalarField omega_; + + //- Initialised flag + bool initialised_; + + //- Master patch ID + label master_; + + //- List of averaging corner weights + List<List<scalar> > cornerWeights_; + // Protected Member Functions @@ -121,6 +138,44 @@ protected: //- Write local wall function variables virtual void writeLocalEntries(Ostream&) const; + //- Set the master patch - master is responsible for updating all + // wall function patches + virtual void setMaster(); + + //- Create the averaging weights for cells which are bounded by + // multiple wall function faces + virtual void createAveragingWeights(); + + //- Helper function to return non-const access to an omega patch + virtual omegaWallFunctionFvPatchScalarField& omegaPatch + ( + const label patchI + ); + + //- Main driver to calculate the turbulence fields + virtual void calculateTurbulenceFields + ( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& omega0 + ); + + //- Calculate the omega and G + virtual void calculate + ( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& omega + ); + + //- Return non-const access to the master patch ID + virtual label& master() + { + return master_; + } + public: @@ -193,11 +248,33 @@ public: // Member functions + // Access + + //- Return non-const access to the master's G field + scalarField& G(bool init = false); + + //- Return non-const access to the master's omega field + scalarField& omega(bool init = false); + + // Evaluation functions //- Update the coefficients associated with the patch field virtual void updateCoeffs(); + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(const scalarField& weights); + + //- Manipulate matrix + virtual void manipulateMatrix(fvMatrix<scalar>& matrix); + + //- Manipulate matrix with given weights + virtual void manipulateMatrix + ( + fvMatrix<scalar>& matrix, + const scalarField& weights + ); + // I-O diff --git a/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchField.H b/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchField.H index a52e8e5b34fa2731631459a4be58c037d0a30fad..ed225757855f7c43f83089c298b93015d04b974a 100644 --- a/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchField.H +++ b/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -34,7 +34,7 @@ Description The porous baffle introduces a pressure jump defined by: \f[ - \Delta p = -(I \mu U + 0.5 D \rho |U|^2 L) + \Delta p = -(I \mu U + 0.5 D \rho |U|^2 )L \f] where diff --git a/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchFields.C b/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchFields.C index 08855fa7fb85c32612e5bfbf8f6903f6be39bb6f..32317c0ad16cbd2ba68c7ddaa1fa955b4e080f19 100644 --- a/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchFields.C +++ b/src/turbulenceModels/derivedFvPatchFields/porousBafflePressure/porousBafflePressureFvPatchFields.C @@ -78,7 +78,7 @@ void Foam::porousBafflePressureFvPatchField<Foam::scalar>::updateCoeffs() const scalarField nuEffw = turbModel.nuEff()().boundaryField()[patchI]; - jump_ = -sign(Un)*(I_*nuEffw + D_*0.5*magUn*length_)*magUn; + jump_ = -sign(Un)*(I_*nuEffw + D_*0.5*magUn)*magUn*length_; } else { @@ -95,7 +95,7 @@ void Foam::porousBafflePressureFvPatchField<Foam::scalar>::updateCoeffs() Un /= rhow; - jump_ = -sign(Un)*(I_*muEffw + D_*0.5*rhow*magUn*length_)*magUn; + jump_ = -sign(Un)*(I_*muEffw + D_*0.5*rhow*magUn)*magUn*length_; } if (debug) diff --git a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C index 4bbf67702af1f770995b91a71684cda821678f58..39afb02f3066330a47cd9f1c3c4f7784c50b05e1 100644 --- a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C +++ b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -60,20 +60,51 @@ tmp<volScalarField> SpalartAllmaras::fv1() const tmp<volScalarField> SpalartAllmaras::fv2() const { - return 1/pow3(scalar(1) + nuTilda_/(Cv2_*nu())); + if (ashfordCorrection_) + { + return 1/pow3(scalar(1) + nuTilda_/(Cv2_*nu())); + } + else + { + const volScalarField chi("chi", nuTilda_/nu()); + return 1.0 - chi/(1.0 + chi*fv1()); + } } tmp<volScalarField> SpalartAllmaras::fv3() const { - const volScalarField chi("chi", nuTilda_/nu()); - const volScalarField chiByCv2(chi/Cv2_); - - return - (scalar(1) + chi*fv1()) - *(1/Cv2_) - *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) - /pow3(scalar(1) + chiByCv2); + if (ashfordCorrection_) + { + const volScalarField chi("chi", nuTilda_/nu()); + const volScalarField chiByCv2(chi/Cv2_); + + return + (scalar(1) + chi*fv1()) + *(1/Cv2_) + *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) + /pow3(scalar(1) + chiByCv2); + } + else + { + return tmp<volScalarField> + ( + new volScalarField + ( + IOobject + ( + "fv3", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + dimensionedScalar("fv3", dimless, 1), + zeroGradientFvPatchScalarField::typeName + ) + ); + } } @@ -246,6 +277,8 @@ SpalartAllmaras::SpalartAllmaras ) ), + ashfordCorrection_(coeffDict_.lookupOrDefault("ashfordCorrection", true)), + y_(mesh_), nuTilda_ @@ -275,6 +308,11 @@ SpalartAllmaras::SpalartAllmaras ) { updateSubGridScaleFields(); + + if (ashfordCorrection_) + { + Info<< " Employing Ashford correction" << endl; + } } @@ -376,6 +414,7 @@ bool SpalartAllmaras::read() { sigmaNut_.readIfPresent(coeffDict()); kappa_.readIfPresent(*this); + Cb1_.readIfPresent(coeffDict()); Cb2_.readIfPresent(coeffDict()); Cv1_.readIfPresent(coeffDict()); @@ -386,6 +425,8 @@ bool SpalartAllmaras::read() Cw2_.readIfPresent(coeffDict()); Cw3_.readIfPresent(coeffDict()); + ashfordCorrection_.readIfPresent("ashfordCorrection", coeffDict()); + return true; } else diff --git a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H index fe4fe280f3186a44ca889d32ef19d2a1d0ea0f7a..3f3b39e12b179791dda688d6977eea5d6475bbf2 100644 --- a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H +++ b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -30,6 +30,15 @@ Group Description SpalartAllmaras DES (SA + LES) turbulence model for incompressible flows + Extended according to + \verbatim + "An Unstructured Grid Generation and Adaptive Solution Technique + for High Reynolds Number Compressible Flows" + G.A. Ashford, + Ph.D. thesis, University of Michigan, 1996. + \endverbatim + by using the optional flag \c ashfordCorrection + SourceFiles SpalartAllmaras.C @@ -90,6 +99,10 @@ protected: dimensionedScalar Cw3_; + //- Optional flag to activate the Ashford correction + Switch ashfordCorrection_; + + // Fields wallDist y_; diff --git a/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C index 76046a80e251195b106f9acbdad79b1ee803ece7..999978f3c92691297e717abb11964010ba613a19 100644 --- a/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C +++ b/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -61,7 +61,14 @@ tmp<volScalarField> SpalartAllmaras::fv2 const volScalarField& fv1 ) const { - return 1.0/pow3(scalar(1) + chi/Cv2_); + if (ashfordCorrection_) + { + return 1.0/pow3(scalar(1) + chi/Cv2_); + } + else + { + return 1.0 - chi/(1.0 + chi*fv1); + } } @@ -71,13 +78,36 @@ tmp<volScalarField> SpalartAllmaras::fv3 const volScalarField& fv1 ) const { - const volScalarField chiByCv2((1/Cv2_)*chi); + if (ashfordCorrection_) + { + const volScalarField chiByCv2((1/Cv2_)*chi); - return - (scalar(1) + chi*fv1) - *(1/Cv2_) - *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) - /pow3(scalar(1) + chiByCv2); + return + (scalar(1) + chi*fv1) + *(1/Cv2_) + *(3*(scalar(1) + chiByCv2) + sqr(chiByCv2)) + /pow3(scalar(1) + chiByCv2); + } + else + { + return tmp<volScalarField> + ( + new volScalarField + ( + IOobject + ( + "fv3", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + dimensionedScalar("fv3", dimless, 1), + zeroGradientFvPatchScalarField::typeName + ) + ); + } } @@ -195,6 +225,8 @@ SpalartAllmaras::SpalartAllmaras ) ), + ashfordCorrection_(coeffDict_.lookupOrDefault("ashfordCorrection", true)), + nuTilda_ ( IOobject @@ -224,6 +256,11 @@ SpalartAllmaras::SpalartAllmaras d_(mesh_) { printCoeffs(); + + if (ashfordCorrection_) + { + Info<< " Employing Ashford correction" << endl; + } } @@ -368,6 +405,8 @@ bool SpalartAllmaras::read() Cv1_.readIfPresent(coeffDict()); Cv2_.readIfPresent(coeffDict()); + ashfordCorrection_.readIfPresent("ashfordCorrection", coeffDict()); + return true; } else diff --git a/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.H b/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.H index d7479c2dd5b829c5b08e703682f730fbd33f3252..597b0859c41effd522c04624556e0a5c09c2bc9b 100644 --- a/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.H +++ b/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,14 +37,16 @@ Description P.R. Spalart, S.R. Allmaras, La Recherche Aerospatiale, No. 1, 1994, pp. 5-21. + \endverbatim - Extended according to: - + Extended according to + \verbatim "An Unstructured Grid Generation and Adaptive Solution Technique for High Reynolds Number Compressible Flows" G.A. Ashford, Ph.D. thesis, University of Michigan, 1996. \endverbatim + using the optional flag \c ashfordCorrection The default model coefficients correspond to the following: \verbatim @@ -82,7 +84,7 @@ namespace RASModels { /*---------------------------------------------------------------------------*\ - Class SpalartAllmaras Declaration + Class SpalartAllmaras Declaration \*---------------------------------------------------------------------------*/ class SpalartAllmaras @@ -108,6 +110,10 @@ protected: dimensionedScalar Cv2_; + //- Optional flag to activate the Ashford correction + Switch ashfordCorrection_; + + // Fields volScalarField nuTilda_; diff --git a/src/turbulenceModels/incompressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C b/src/turbulenceModels/incompressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C index 98514bb5bec842d5a97ded1ec85a49111afd9a0a..df20a315f840909a40f526197b773bb6355fa3c5 100644 --- a/src/turbulenceModels/incompressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C +++ b/src/turbulenceModels/incompressible/RAS/backwardsCompatibility/wallFunctions/backwardsCompatibilityWallFunctions.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,6 +25,7 @@ License #include "backwardsCompatibilityWallFunctions.H" +#include "volFields.H" #include "calculatedFvPatchField.H" #include "nutkWallFunctionFvPatchScalarField.H" #include "nutLowReWallFunctionFvPatchScalarField.H" diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C index 0191a90a8ccd02b814d1a3b4d704c0672a4ec7cf..d9898beda113f5acfa77adfa3e7d8eb013794708 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.C @@ -55,6 +55,64 @@ scalar epsilonLowReWallFunctionFvPatchScalarField::yPlusLam } +void epsilonLowReWallFunctionFvPatchScalarField::calculate +( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon +) +{ + const label patchI = patch.index(); + + const scalarField& y = turbulence.y()[patchI]; + + const scalar Cmu25 = pow025(Cmu_); + const scalar Cmu75 = pow(Cmu_, 0.75); + + const tmp<volScalarField> tk = turbulence.k(); + const volScalarField& k = tk(); + + const tmp<volScalarField> tnu = turbulence.nu(); + const scalarField& nuw = tnu().boundaryField()[patchI]; + + const tmp<volScalarField> tnut = turbulence.nut(); + const volScalarField& nut = tnut(); + const scalarField& nutw = nut.boundaryField()[patchI]; + + const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + + const scalarField magGradUw(mag(Uw.snGrad())); + + // Set epsilon and G + forAll(nutw, faceI) + { + label cellI = patch.faceCells()[faceI]; + + scalar yPlus = Cmu25*sqrt(k[cellI])*y[faceI]/nuw[faceI]; + + scalar w = cornerWeights[faceI]; + + if (yPlus > yPlusLam_) + { + epsilon[cellI] = w*Cmu75*pow(k[cellI], 1.5)/(kappa_*y[faceI]); + } + else + { + epsilon[cellI] = w*2.0*k[cellI]*nuw[faceI]/sqr(y[faceI]); + } + + G[cellI] = + w + *(nutw[faceI] + nuw[faceI]) + *magGradUw[faceI] + *Cmu25*sqrt(k[cellI]) + /(kappa_*y[faceI]); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // epsilonLowReWallFunctionFvPatchScalarField:: @@ -119,81 +177,6 @@ epsilonLowReWallFunctionFvPatchScalarField {} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void epsilonLowReWallFunctionFvPatchScalarField::updateCoeffs() -{ - if (updated()) - { - return; - } - - const label patchI = patch().index(); - - const turbulenceModel& turbulence = - db().lookupObject<turbulenceModel>("turbulenceModel"); - const scalarField& y = turbulence.y()[patchI]; - - volScalarField& G = - const_cast<volScalarField&> - ( - db().lookupObject<volScalarField> - ( - turbulence.GName() - ) - ); - - DimensionedField<scalar, volMesh>& epsilon = - const_cast<DimensionedField<scalar, volMesh>&> - ( - dimensionedInternalField() - ); - - const tmp<volScalarField> tk = turbulence.k(); - const volScalarField& k = tk(); - - const tmp<volScalarField> tnu = turbulence.nu(); - const scalarField& nuw = tnu().boundaryField()[patchI]; - - const tmp<volScalarField> tnut = turbulence.nut(); - const volScalarField& nut = tnut(); - const scalarField& nutw = nut.boundaryField()[patchI]; - - const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; - const scalarField magGradUw(mag(Uw.snGrad())); - - const scalar Cmu25 = pow025(Cmu_); - const scalar Cmu75 = pow(Cmu_, 0.75); - - // Set epsilon and G - forAll(nutw, faceI) - { - label faceCellI = patch().faceCells()[faceI]; - - scalar yPlus = Cmu25*sqrt(k[faceCellI])*y[faceI]/nuw[faceI]; - - if (yPlus > yPlusLam_) - { - epsilon[faceCellI] = Cmu75*pow(k[faceCellI], 1.5)/(kappa_*y[faceI]); - } - else - { - epsilon[faceCellI] = 2.0*k[faceCellI]*nuw[faceI]/sqr(y[faceI]); - } - - G[faceCellI] = - (nutw[faceI] + nuw[faceI]) - *magGradUw[faceI] - *Cmu25*sqrt(k[faceCellI]) - /(kappa_*y[faceI]); - } - - fixedInternalValueFvPatchField<scalar>::updateCoeffs(); - - // TODO: perform averaging for cells sharing more than one boundary face -} - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // makePatchTypeField diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H index b8cf09f0b7930d3da619f0fbd350089ff4b725f0..778fffcfd7b8e19c640be3170e417e17ee17ee6e 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonLowReWallFunction/epsilonLowReWallFunctionFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -97,6 +97,16 @@ protected: //- Calculate the Y+ at the edge of the laminar sublayer scalar yPlusLam(const scalar kappa, const scalar E); + //- Calculate the epsilon and G + virtual void calculate + ( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon + ); + public: @@ -166,13 +176,9 @@ public: ); } - - // Member functions - - // Evaluation functions - - //- Update the coefficients associated with the patch field - virtual void updateCoeffs(); + //- Destructor + virtual ~epsilonLowReWallFunctionFvPatchScalarField() + {} }; diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C index 9435962e6abdfa8d3d670a60760ceb2fe2644938..7fb6fcfb96e1ebe727a59ffff566480f1f347d7c 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C @@ -26,11 +26,10 @@ License #include "epsilonWallFunctionFvPatchScalarField.H" #include "incompressible/turbulenceModel/turbulenceModel.H" #include "fvPatchFieldMapper.H" +#include "fvMatrix.H" #include "volFields.H" -#include "addToRunTimeSelectionTable.H" #include "wallFvPatch.H" -#include "nutkWallFunctionFvPatchScalarField.H" - +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -39,7 +38,7 @@ namespace Foam namespace incompressible { -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // void epsilonWallFunctionFvPatchScalarField::checkType() { @@ -63,6 +62,193 @@ void epsilonWallFunctionFvPatchScalarField::writeLocalEntries(Ostream& os) const } +void epsilonWallFunctionFvPatchScalarField::setMaster() +{ + if (master_ != -1) + { + return; + } + + const volScalarField& epsilon = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = epsilon.boundaryField(); + + label master = -1; + forAll(bf, patchI) + { + if (isA<epsilonWallFunctionFvPatchScalarField>(bf[patchI])) + { + epsilonWallFunctionFvPatchScalarField& epf = epsilonPatch(patchI); + + if (master == -1) + { + master = patchI; + } + + epf.master() = master; + } + } +} + + +void epsilonWallFunctionFvPatchScalarField::createAveragingWeights() +{ + if (initialised_) + { + return; + } + + const volScalarField& epsilon = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = epsilon.boundaryField(); + + const fvMesh& mesh = epsilon.mesh(); + + volScalarField weights + ( + IOobject + ( + "weights", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // do not register + ), + mesh, + dimensionedScalar("zero", dimless, 0.0) + ); + + DynamicList<label> epsilonPatches(bf.size()); + forAll(bf, patchI) + { + if (isA<epsilonWallFunctionFvPatchScalarField>(bf[patchI])) + { + epsilonPatches.append(patchI); + + const labelUList& faceCells = bf[patchI].patch().faceCells(); + forAll(faceCells, i) + { + label cellI = faceCells[i]; + weights[cellI]++; + } + } + } + + cornerWeights_.setSize(bf.size()); + forAll(epsilonPatches, i) + { + label patchI = epsilonPatches[i]; + const fvPatchField& wf = weights.boundaryField()[patchI]; + cornerWeights_[patchI] = 1.0/wf.patchInternalField(); + } + + G_.setSize(dimensionedInternalField().size(), 0.0); + epsilon_.setSize(dimensionedInternalField().size(), 0.0); + + initialised_ = true; +} + + +epsilonWallFunctionFvPatchScalarField& +epsilonWallFunctionFvPatchScalarField::epsilonPatch(const label patchI) +{ + const volScalarField& epsilon = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = epsilon.boundaryField(); + + const epsilonWallFunctionFvPatchScalarField& epf = + refCast<const epsilonWallFunctionFvPatchScalarField>(bf[patchI]); + + return const_cast<epsilonWallFunctionFvPatchScalarField&>(epf); +} + + +void epsilonWallFunctionFvPatchScalarField::calculateTurbulenceFields +( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& epsilon0 +) +{ + // accumulate all of the G and epsilon contributions + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + epsilonWallFunctionFvPatchScalarField& epf = epsilonPatch(patchI); + + const List<scalar>& w = cornerWeights_[patchI]; + + epf.calculate(turbulence, w, epf.patch(), G0, epsilon0); + } + } + + // apply zero-gradient condition for epsilon + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + epsilonWallFunctionFvPatchScalarField& epf = epsilonPatch(patchI); + + epf == scalarField(epsilon0, epf.patch().faceCells()); + } + } +} + + +void epsilonWallFunctionFvPatchScalarField::calculate +( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon +) +{ + const label patchI = patch.index(); + + const scalarField& y = turbulence.y()[patchI]; + + const scalar Cmu25 = pow025(Cmu_); + const scalar Cmu75 = pow(Cmu_, 0.75); + + const tmp<volScalarField> tk = turbulence.k(); + const volScalarField& k = tk(); + + const tmp<volScalarField> tnu = turbulence.nu(); + const scalarField& nuw = tnu().boundaryField()[patchI]; + + const tmp<volScalarField> tnut = turbulence.nut(); + const volScalarField& nut = tnut(); + const scalarField& nutw = nut.boundaryField()[patchI]; + + const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + + const scalarField magGradUw(mag(Uw.snGrad())); + + // Set epsilon and G + forAll(nutw, faceI) + { + label cellI = patch.faceCells()[faceI]; + + scalar w = cornerWeights[faceI]; + + epsilon[cellI] += w*Cmu75*pow(k[cellI], 1.5)/(kappa_*y[faceI]); + + G[cellI] += + w + *(nutw[faceI] + nuw[faceI]) + *magGradUw[faceI] + *Cmu25*sqrt(k[cellI]) + /(kappa_*y[faceI]); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField @@ -71,10 +257,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(p, iF), + fixedValueFvPatchField<scalar>(p, iF), Cmu_(0.09), kappa_(0.41), - E_(9.8) + E_(9.8), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -88,10 +279,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const fvPatchFieldMapper& mapper ) : - fixedInternalValueFvPatchField<scalar>(ptf, p, iF, mapper), + fixedValueFvPatchField<scalar>(ptf, p, iF, mapper), Cmu_(ptf.Cmu_), kappa_(ptf.kappa_), - E_(ptf.E_) + E_(ptf.E_), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -104,10 +300,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const dictionary& dict ) : - fixedInternalValueFvPatchField<scalar>(p, iF, dict), + fixedValueFvPatchField<scalar>(p, iF, dict), Cmu_(dict.lookupOrDefault<scalar>("Cmu", 0.09)), kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)), - E_(dict.lookupOrDefault<scalar>("E", 9.8)) + E_(dict.lookupOrDefault<scalar>("E", 9.8)), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -118,10 +319,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const epsilonWallFunctionFvPatchScalarField& ewfpsf ) : - fixedInternalValueFvPatchField<scalar>(ewfpsf), + fixedValueFvPatchField<scalar>(ewfpsf), Cmu_(ewfpsf.Cmu_), kappa_(ewfpsf.kappa_), - E_(ewfpsf.E_) + E_(ewfpsf.E_), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -133,10 +339,15 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(ewfpsf, iF), + fixedValueFvPatchField<scalar>(ewfpsf, iF), Cmu_(ewfpsf.Cmu_), kappa_(ewfpsf.kappa_), - E_(ewfpsf.E_) + E_(ewfpsf.E_), + G_(), + epsilon_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -144,6 +355,38 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +scalarField& epsilonWallFunctionFvPatchScalarField::G(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + G_ = 0.0; + } + + return G_; + } + + return epsilonPatch(master_).G(); +} + + +scalarField& epsilonWallFunctionFvPatchScalarField::epsilon(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + epsilon_ = 0.0; + } + + return epsilon_; + } + + return epsilonPatch(master_).epsilon(init); +} + + void epsilonWallFunctionFvPatchScalarField::updateCoeffs() { if (updated()) @@ -151,76 +394,168 @@ void epsilonWallFunctionFvPatchScalarField::updateCoeffs() return; } - const label patchI = patch().index(); - const turbulenceModel& turbulence = - db().lookupObject<turbulenceModel>("turbulenceModel"); - const scalarField& y = turbulence.y()[patchI]; + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); - const scalar Cmu25 = pow025(Cmu_); - const scalar Cmu75 = pow(Cmu_, 0.75); + setMaster(); - volScalarField& G = - const_cast<volScalarField&> - ( - db().lookupObject<volScalarField> - ( - turbulence.GName() - ) - ); + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), epsilon(true)); + } + + const scalarField& G0 = this->G(); + const scalarField& epsilon0 = this->epsilon(); - DimensionedField<scalar, volMesh>& epsilon = - const_cast<DimensionedField<scalar, volMesh>&> + typedef DimensionedField<scalar, volMesh> FieldType; + + FieldType& G = + const_cast<FieldType&> ( - dimensionedInternalField() + db().lookupObject<FieldType>(turbulence.GName()) ); - const tmp<volScalarField> tk = turbulence.k(); - const volScalarField& k = tk(); + FieldType& epsilon = const_cast<FieldType&>(dimensionedInternalField()); - const tmp<volScalarField> tnu = turbulence.nu(); - const scalarField& nuw = tnu().boundaryField()[patchI]; + forAll(*this, faceI) + { + label cellI = patch().faceCells()[faceI]; - const tmp<volScalarField> tnut = turbulence.nut(); - const volScalarField& nut = tnut(); - const scalarField& nutw = nut.boundaryField()[patchI]; + G[cellI] = G0[cellI]; + epsilon[cellI] = epsilon0[cellI]; + } - const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + fvPatchField<scalar>::updateCoeffs(); +} - const scalarField magGradUw(mag(Uw.snGrad())); - // Set epsilon and G - forAll(nutw, faceI) +void epsilonWallFunctionFvPatchScalarField::updateCoeffs +( + const scalarField& weights +) +{ + if (updated()) { - label faceCellI = patch().faceCells()[faceI]; + return; + } + + const turbulenceModel& turbulence = + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); - epsilon[faceCellI] = Cmu75*pow(k[faceCellI], 1.5)/(kappa_*y[faceI]); + setMaster(); - G[faceCellI] = - (nutw[faceI] + nuw[faceI]) - *magGradUw[faceI] - *Cmu25*sqrt(k[faceCellI]) - /(kappa_*y[faceI]); + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), epsilon(true)); } - fixedInternalValueFvPatchField<scalar>::updateCoeffs(); + const scalarField& G0 = this->G(); + const scalarField& epsilon0 = this->epsilon(); + + typedef DimensionedField<scalar, volMesh> FieldType; + + FieldType& G = + const_cast<FieldType&> + ( + db().lookupObject<FieldType>(turbulence.GName()) + ); + + FieldType& epsilon = const_cast<FieldType&>(dimensionedInternalField()); - // TODO: perform averaging for cells sharing more than one boundary face + // only set the values if the weights are < 1 - tolerance + forAll(weights, faceI) + { + scalar w = weights[faceI]; + + if (w < 1.0 - 1e-6) + { + label cellI = patch().faceCells()[faceI]; + + G[cellI] = w*G[cellI] + (1.0 - w)*G0[cellI]; + epsilon[cellI] = w*epsilon[cellI] + (1.0 - w)*epsilon0[cellI]; + } + } + + fvPatchField<scalar>::updateCoeffs(); } -void epsilonWallFunctionFvPatchScalarField::evaluate +void epsilonWallFunctionFvPatchScalarField::manipulateMatrix ( - const Pstream::commsTypes commsType + fvMatrix<scalar>& matrix ) { - fixedInternalValueFvPatchField<scalar>::evaluate(commsType); + if (manipulatedMatrix()) + { + return; + } + + matrix.setValues(patch().faceCells(), patchInternalField()); + + fvPatchField<scalar>::manipulateMatrix(matrix); +} + + +void epsilonWallFunctionFvPatchScalarField::manipulateMatrix +( + fvMatrix<scalar>& matrix, + const Field<scalar>& weights +) +{ + if (manipulatedMatrix()) + { + return; + } + + // filter weights so that we only apply the constraint where the + // weight > SMALL + DynamicList<label> constraintCells(weights.size()); + DynamicList<scalar> constraintEpsilon(weights.size()); + const labelUList& faceCells = patch().faceCells(); + + const DimensionedField<scalar, volMesh>& epsilon + = dimensionedInternalField(); + + label nConstrainedCells = 0; + + + forAll(weights, faceI) + { + // only set the values if the weights are < 1 - tolerance + if (weights[faceI] < (1.0 - 1e-6)) + { + nConstrainedCells++; + + label cellI = faceCells[faceI]; + + constraintCells.append(cellI); + constraintEpsilon.append(epsilon[cellI]); + } + } + + if (debug) + { + Pout<< "Patch: " << patch().name() + << ": number of constrained cells = " << nConstrainedCells + << " out of " << patch().size() + << endl; + } + + matrix.setValues + ( + constraintCells, + scalarField(constraintEpsilon.xfer()) + ); + + fvPatchField<scalar>::manipulateMatrix(matrix); } void epsilonWallFunctionFvPatchScalarField::write(Ostream& os) const { - fixedInternalValueFvPatchField<scalar>::write(os); + fixedValueFvPatchField<scalar>::write(os); writeLocalEntries(os); writeEntry("value", os); } diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H index 9ff7b7acb544341bc1a46a8d1ef9d9ce20cb7f31..61de72a385f2e73a8fd19be6bbcd90b46767157f 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -71,7 +71,7 @@ SourceFiles #ifndef epsilonWallFunctionFvPatchScalarField_H #define epsilonWallFunctionFvPatchScalarField_H -#include "fixedInternalValueFvPatchField.H" +#include "fixedValueFvPatchField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -80,13 +80,15 @@ namespace Foam namespace incompressible { +class turbulenceModel; + /*---------------------------------------------------------------------------*\ Class epsilonWallFunctionFvPatchScalarField Declaration \*---------------------------------------------------------------------------*/ class epsilonWallFunctionFvPatchScalarField : - public fixedInternalValueFvPatchField<scalar> + public fixedValueFvPatchField<scalar> { protected: @@ -101,6 +103,21 @@ protected: //- E coefficient scalar E_; + //- Local copy of turbulence G field + scalarField G_; + + //- Local copy of turbulence epsilon field + scalarField epsilon_; + + //- Initialised flag + bool initialised_; + + //- Master patch ID + label master_; + + //- List of averaging corner weights + List<List<scalar> > cornerWeights_; + // Protected Member Functions @@ -110,6 +127,44 @@ protected: //- Write local wall function variables virtual void writeLocalEntries(Ostream&) const; + //- Set the master patch - master is responsible for updating all + // wall function patches + virtual void setMaster(); + + //- Create the averaging weights for cells which are bounded by + // multiple wall function faces + virtual void createAveragingWeights(); + + //- Helper function to return non-const access to an epsilon patch + virtual epsilonWallFunctionFvPatchScalarField& epsilonPatch + ( + const label patchI + ); + + //- Main driver to calculate the turbulence fields + virtual void calculateTurbulenceFields + ( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& epsilon0 + ); + + //- Calculate the epsilon and G + virtual void calculate + ( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& epsilon + ); + + //- Return non-const access to the master patch ID + virtual label& master() + { + return master_; + } + public: @@ -179,16 +234,39 @@ public: ); } + //- Destructor + virtual ~epsilonWallFunctionFvPatchScalarField() + {} + // Member functions + // Access + + //- Return non-const access to the master's G field + scalarField& G(bool init = false); + + //- Return non-const access to the master's epsilon field + scalarField& epsilon(bool init = false); + + // Evaluation functions //- Update the coefficients associated with the patch field virtual void updateCoeffs(); - //- Evaluate the patchField - virtual void evaluate(const Pstream::commsTypes); + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(const scalarField& weights); + + //- Manipulate matrix + virtual void manipulateMatrix(fvMatrix<scalar>& matrix); + + //- Manipulate matrix with given weights + virtual void manipulateMatrix + ( + fvMatrix<scalar>& matrix, + const scalarField& weights + ); // I-O diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C index a78e0bdb84ed3c9d046dec62bb596c24cd4bc144..554c18542d9fd800d7d52ac0fd4892d4e8ec2e91 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C @@ -26,11 +26,11 @@ License #include "omegaWallFunctionFvPatchScalarField.H" #include "incompressible/turbulenceModel/turbulenceModel.H" #include "fvPatchFieldMapper.H" +#include "fvMatrix.H" #include "volFields.H" -#include "addToRunTimeSelectionTable.H" #include "wallFvPatch.H" #include "nutkWallFunctionFvPatchScalarField.H" - +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -64,6 +64,196 @@ void omegaWallFunctionFvPatchScalarField::writeLocalEntries(Ostream& os) const } +void omegaWallFunctionFvPatchScalarField::setMaster() +{ + if (master_ != -1) + { + return; + } + + const volScalarField& omega = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = omega.boundaryField(); + + label master = -1; + forAll(bf, patchI) + { + if (isA<omegaWallFunctionFvPatchScalarField>(bf[patchI])) + { + omegaWallFunctionFvPatchScalarField& epf = omegaPatch(patchI); + + if (master == -1) + { + master = patchI; + } + + epf.master() = master; + } + } +} + + +void omegaWallFunctionFvPatchScalarField::createAveragingWeights() +{ + if (initialised_) + { + return; + } + + const volScalarField& omega = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = omega.boundaryField(); + + const fvMesh& mesh = omega.mesh(); + + volScalarField weights + ( + IOobject + ( + "weights", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // do not register + ), + mesh, + dimensionedScalar("zero", dimless, 0.0) + ); + + DynamicList<label> omegaPatches(bf.size()); + forAll(bf, patchI) + { + if (isA<omegaWallFunctionFvPatchScalarField>(bf[patchI])) + { + omegaPatches.append(patchI); + + const labelUList& faceCells = bf[patchI].patch().faceCells(); + forAll(faceCells, i) + { + label cellI = faceCells[i]; + weights[cellI]++; + } + } + } + + cornerWeights_.setSize(bf.size()); + forAll(omegaPatches, i) + { + label patchI = omegaPatches[i]; + const fvPatchField& wf = weights.boundaryField()[patchI]; + cornerWeights_[patchI] = 1.0/wf.patchInternalField(); + } + + G_.setSize(dimensionedInternalField().size(), 0.0); + omega_.setSize(dimensionedInternalField().size(), 0.0); + + initialised_ = true; +} + + +omegaWallFunctionFvPatchScalarField& +omegaWallFunctionFvPatchScalarField::omegaPatch(const label patchI) +{ + const volScalarField& omega = + static_cast<const volScalarField&>(this->dimensionedInternalField()); + + const volScalarField::GeometricBoundaryField& bf = omega.boundaryField(); + + const omegaWallFunctionFvPatchScalarField& epf = + refCast<const omegaWallFunctionFvPatchScalarField>(bf[patchI]); + + return const_cast<omegaWallFunctionFvPatchScalarField&>(epf); +} + + +void omegaWallFunctionFvPatchScalarField::calculateTurbulenceFields +( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& omega0 +) +{ + // accumulate all of the G and omega contributions + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + omegaWallFunctionFvPatchScalarField& epf = omegaPatch(patchI); + + const List<scalar>& w = cornerWeights_[patchI]; + + epf.calculate(turbulence, w, epf.patch(), G0, omega0); + } + } + + // apply zero-gradient condition for omega + forAll(cornerWeights_, patchI) + { + if (!cornerWeights_[patchI].empty()) + { + omegaWallFunctionFvPatchScalarField& epf = omegaPatch(patchI); + + epf == scalarField(omega0, epf.patch().faceCells()); + } + } +} + + +void omegaWallFunctionFvPatchScalarField::calculate +( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& omega +) +{ + const label patchI = patch.index(); + + const scalarField& y = turbulence.y()[patchI]; + + const scalar Cmu25 = pow025(Cmu_); + + const tmp<volScalarField> tk = turbulence.k(); + const volScalarField& k = tk(); + + const tmp<volScalarField> tnu = turbulence.nu(); + const scalarField& nuw = tnu().boundaryField()[patchI]; + + const tmp<volScalarField> tnut = turbulence.nut(); + const volScalarField& nut = tnut(); + const scalarField& nutw = nut.boundaryField()[patchI]; + + const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + + const scalarField magGradUw(mag(Uw.snGrad())); + + // Set omega and G + forAll(nutw, faceI) + { + label cellI = patch.faceCells()[faceI]; + + scalar w = cornerWeights[faceI]; + + scalar omegaVis = 6.0*nuw[faceI]/(beta1_*sqr(y[faceI])); + + scalar omegaLog = sqrt(k[cellI])/(Cmu25*kappa_*y[faceI]); + + omega[cellI] = w*sqrt(sqr(omegaVis) + sqr(omegaLog)); + + G[cellI] = + w + *(nutw[faceI] + nuw[faceI]) + *magGradUw[faceI] + *Cmu25*sqrt(k[cellI]) + /(kappa_*y[faceI]); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField @@ -72,12 +262,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(p, iF), + fixedValueFvPatchField<scalar>(p, iF), Cmu_(0.09), kappa_(0.41), E_(9.8), beta1_(0.075), - yPlusLam_(nutkWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)) + yPlusLam_(nutkWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -91,12 +286,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const fvPatchFieldMapper& mapper ) : - fixedInternalValueFvPatchField<scalar>(ptf, p, iF, mapper), + fixedValueFvPatchField<scalar>(ptf, p, iF, mapper), Cmu_(ptf.Cmu_), kappa_(ptf.kappa_), E_(ptf.E_), beta1_(ptf.beta1_), - yPlusLam_(ptf.yPlusLam_) + yPlusLam_(ptf.yPlusLam_), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -109,12 +309,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const dictionary& dict ) : - fixedInternalValueFvPatchField<scalar>(p, iF, dict), + fixedValueFvPatchField<scalar>(p, iF, dict), Cmu_(dict.lookupOrDefault<scalar>("Cmu", 0.09)), kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)), E_(dict.lookupOrDefault<scalar>("E", 9.8)), beta1_(dict.lookupOrDefault<scalar>("beta1", 0.075)), - yPlusLam_(nutkWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)) + yPlusLam_(nutkWallFunctionFvPatchScalarField::yPlusLam(kappa_, E_)), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -125,12 +330,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const omegaWallFunctionFvPatchScalarField& owfpsf ) : - fixedInternalValueFvPatchField<scalar>(owfpsf), + fixedValueFvPatchField<scalar>(owfpsf), Cmu_(owfpsf.Cmu_), kappa_(owfpsf.kappa_), E_(owfpsf.E_), beta1_(owfpsf.beta1_), - yPlusLam_(owfpsf.yPlusLam_) + yPlusLam_(owfpsf.yPlusLam_), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -142,12 +352,17 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField const DimensionedField<scalar, volMesh>& iF ) : - fixedInternalValueFvPatchField<scalar>(owfpsf, iF), + fixedValueFvPatchField<scalar>(owfpsf, iF), Cmu_(owfpsf.Cmu_), kappa_(owfpsf.kappa_), E_(owfpsf.E_), beta1_(owfpsf.beta1_), - yPlusLam_(owfpsf.yPlusLam_) + yPlusLam_(owfpsf.yPlusLam_), + G_(), + omega_(), + initialised_(false), + master_(-1), + cornerWeights_() { checkType(); } @@ -155,6 +370,38 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +scalarField& omegaWallFunctionFvPatchScalarField::G(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + G_ = 0.0; + } + + return G_; + } + + return omegaPatch(master_).G(); +} + + +scalarField& omegaWallFunctionFvPatchScalarField::omega(bool init) +{ + if (patch().index() == master_) + { + if (init) + { + omega_ = 0.0; + } + + return omega_; + } + + return omegaPatch(master_).omega(init); +} + + void omegaWallFunctionFvPatchScalarField::updateCoeffs() { if (updated()) @@ -162,70 +409,168 @@ void omegaWallFunctionFvPatchScalarField::updateCoeffs() return; } - const label patchI = patch().index(); - const turbulenceModel& turbulence = - db().lookupObject<turbulenceModel>("turbulenceModel"); - const scalarField& y = turbulence.y()[patchI]; + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); - const scalar Cmu25 = pow025(Cmu_); + setMaster(); + + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), omega(true)); + } + + const scalarField& G0 = this->G(); + const scalarField& omega0 = this->omega(); + + typedef DimensionedField<scalar, volMesh> FieldType; - volScalarField& G = - const_cast<volScalarField&> + FieldType& G = + const_cast<FieldType&> ( - db().lookupObject<volScalarField> - ( - turbulence.GName() - ) + db().lookupObject<FieldType>(turbulence.GName()) ); - DimensionedField<scalar, volMesh>& omega = - const_cast<DimensionedField<scalar, volMesh>&> + FieldType& omega = const_cast<FieldType&>(dimensionedInternalField()); + + forAll(*this, faceI) + { + label cellI = patch().faceCells()[faceI]; + + G[cellI] = G0[cellI]; + omega[cellI] = omega0[cellI]; + } + + fvPatchField<scalar>::updateCoeffs(); +} + + +void omegaWallFunctionFvPatchScalarField::updateCoeffs +( + const scalarField& weights +) +{ + if (updated()) + { + return; + } + + const turbulenceModel& turbulence = + db().lookupObject<turbulenceModel>(turbulenceModel::typeName); + + setMaster(); + + if (patch().index() == master_) + { + createAveragingWeights(); + calculateTurbulenceFields(turbulence, G(true), omega(true)); + } + + const scalarField& G0 = this->G(); + const scalarField& omega0 = this->omega(); + + typedef DimensionedField<scalar, volMesh> FieldType; + + FieldType& G = + const_cast<FieldType&> ( - dimensionedInternalField() + db().lookupObject<FieldType>(turbulence.GName()) ); - const tmp<volScalarField> tk = turbulence.k(); - const volScalarField& k = tk(); + FieldType& omega = const_cast<FieldType&>(dimensionedInternalField()); - const tmp<volScalarField> tnu = turbulence.nu(); - const scalarField& nuw = tnu().boundaryField()[patchI]; + // only set the values if the weights are < 1 - tolerance + forAll(weights, faceI) + { + scalar w = weights[faceI]; - const tmp<volScalarField> tnut = turbulence.nut(); - const volScalarField& nut = tnut(); - const scalarField& nutw = nut.boundaryField()[patchI]; + if (w < 1.0 - 1e-6) + { + label cellI = patch().faceCells()[faceI]; - const fvPatchVectorField& Uw = turbulence.U().boundaryField()[patchI]; + G[cellI] = w*G[cellI] + (1.0 - w)*G0[cellI]; + omega[cellI] = w*omega[cellI] + (1.0 - w)*omega0[cellI]; + } + } - const scalarField magGradUw(mag(Uw.snGrad())); + fvPatchField<scalar>::updateCoeffs(); +} - // Set omega and G - forAll(nutw, faceI) + +void omegaWallFunctionFvPatchScalarField::manipulateMatrix +( + fvMatrix<scalar>& matrix +) +{ + if (manipulatedMatrix()) { - label faceCellI = patch().faceCells()[faceI]; + return; + } - scalar omegaVis = 6.0*nuw[faceI]/(beta1_*sqr(y[faceI])); + matrix.setValues(patch().faceCells(), patchInternalField()); - scalar omegaLog = sqrt(k[faceCellI])/(Cmu25*kappa_*y[faceI]); + fvPatchField<scalar>::manipulateMatrix(matrix); +} - omega[faceCellI] = sqrt(sqr(omegaVis) + sqr(omegaLog)); - G[faceCellI] = - (nutw[faceI] + nuw[faceI]) - *magGradUw[faceI] - *Cmu25*sqrt(k[faceCellI]) - /(kappa_*y[faceI]); +void omegaWallFunctionFvPatchScalarField::manipulateMatrix +( + fvMatrix<scalar>& matrix, + const Field<scalar>& weights +) +{ + if (manipulatedMatrix()) + { + return; + } + + // filter weights so that we only apply the constraint where the + // weight > SMALL + DynamicList<label> constraintCells(weights.size()); + DynamicList<scalar> constraintomega(weights.size()); + const labelUList& faceCells = patch().faceCells(); + + const DimensionedField<scalar, volMesh>& omega + = dimensionedInternalField(); + + label nConstrainedCells = 0; + + + forAll(weights, faceI) + { + // only set the values if the weights are < 1 - tolerance + if (weights[faceI] < (1.0 - 1e-6)) + { + nConstrainedCells++; + + label cellI = faceCells[faceI]; + + constraintCells.append(cellI); + constraintomega.append(omega[cellI]); + } + } + + if (debug) + { + Pout<< "Patch: " << patch().name() + << ": number of constrained cells = " << nConstrainedCells + << " out of " << patch().size() + << endl; } - fixedInternalValueFvPatchField<scalar>::updateCoeffs(); + matrix.setValues + ( + constraintCells, + scalarField(constraintomega.xfer()) + ); - // TODO: perform averaging for cells sharing more than one boundary face + fvPatchField<scalar>::manipulateMatrix(matrix); } void omegaWallFunctionFvPatchScalarField::write(Ostream& os) const { - fixedInternalValueFvPatchField<scalar>::write(os); + fixedValueFvPatchField<scalar>::write(os); writeLocalEntries(os); writeEntry("value", os); } diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H index 9ee99bd6c6927e76a57325b96fbeb8b1be76d1a1..957d0f945eed05607aa6ba122c42714395d24ebb 100644 --- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H +++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -76,7 +76,7 @@ SourceFiles #ifndef omegaWallFunctionFvPatchScalarField_H #define omegaWallFunctionFvPatchScalarField_H -#include "fixedInternalValueFvPatchField.H" +#include "fixedValueFvPatchField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -85,13 +85,15 @@ namespace Foam namespace incompressible { +class turbulenceModel; + /*---------------------------------------------------------------------------*\ - Class omegaWallFunctionFvPatchScalarField Declaration + Class omegaWallFunctionFvPatchScalarField Declaration \*---------------------------------------------------------------------------*/ class omegaWallFunctionFvPatchScalarField : - public fixedInternalValueFvPatchField<scalar> + public fixedValueFvPatchField<scalar> { protected: @@ -112,6 +114,21 @@ protected: //- Y+ at the edge of the laminar sublayer scalar yPlusLam_; + //- Local copy of turbulence G field + scalarField G_; + + //- Local copy of turbulence omega field + scalarField omega_; + + //- Initialised flag + bool initialised_; + + //- Master patch ID + label master_; + + //- List of averaging corner weights + List<List<scalar> > cornerWeights_; + // Protected Member Functions @@ -121,6 +138,44 @@ protected: //- Write local wall function variables virtual void writeLocalEntries(Ostream&) const; + //- Set the master patch - master is responsible for updating all + // wall function patches + virtual void setMaster(); + + //- Create the averaging weights for cells which are bounded by + // multiple wall function faces + virtual void createAveragingWeights(); + + //- Helper function to return non-const access to an omega patch + virtual omegaWallFunctionFvPatchScalarField& omegaPatch + ( + const label patchI + ); + + //- Main driver to calculate the turbulence fields + virtual void calculateTurbulenceFields + ( + const turbulenceModel& turbulence, + scalarField& G0, + scalarField& omega0 + ); + + //- Calculate the omega and G + virtual void calculate + ( + const turbulenceModel& turbulence, + const List<scalar>& cornerWeights, + const fvPatch& patch, + scalarField& G, + scalarField& omega + ); + + //- Return non-const access to the master patch ID + virtual label& master() + { + return master_; + } + public: @@ -193,11 +248,33 @@ public: // Member functions + // Access + + //- Return non-const access to the master's G field + scalarField& G(bool init = false); + + //- Return non-const access to the master's omega field + scalarField& omega(bool init = false); + + // Evaluation functions //- Update the coefficients associated with the patch field virtual void updateCoeffs(); + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(const scalarField& weights); + + //- Manipulate matrix + virtual void manipulateMatrix(fvMatrix<scalar>& matrix); + + //- Manipulate matrix with given weights + virtual void manipulateMatrix + ( + fvMatrix<scalar>& matrix, + const scalarField& weights + ); + // I-O diff --git a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/0/G b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/0/G new file mode 100644 index 0000000000000000000000000000000000000000..fd53ea0248aaf4a8606f7279ed40389e74d99863 --- /dev/null +++ b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/0/G @@ -0,0 +1,41 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object G; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 0 -3 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + ".*" + { + type MarshakRadiation; + T T; + emissivityMode lookup; + emissivity uniform 1.0; + value uniform 0; + } + + "(region0_to.*)" + { + type MarshakRadiation; + T T; + emissivityMode solidRadiation; + value uniform 0; + } +} + +// ************************************************************************* // diff --git a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/constant/radiationProperties b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/constant/radiationProperties index 89ee652071b09e14ed05d12e58017422f461b891..ae6091de4dcfec007b306990ac6d633ec38b5e58 100644 --- a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/constant/radiationProperties +++ b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/constant/radiationProperties @@ -24,21 +24,24 @@ fvDOMCoeffs { nPhi 3; // azimuthal angles in PI/2 on X-Y.(from Y to X) nTheta 6; // polar angles in PI (from Z to X-Y plane) - convergence 1e-4; // convergence criteria for radiation iteration - maxIter 2; // maximum number of iterations + convergence 0.05; // convergence criteria for radiation iteration + maxIter 3; // maximum number of iterations + cacheDiv true; // cache the div of the RTE equation. + +// NOTE: Caching div is "only" accurate if the upwind scheme is used in +// div(Ji,Ii_h) } // Number of flow iterations per radiation iteration solverFreq 10; absorptionEmissionModel constantAbsorptionEmission; -//absorptionEmissionModel greyMeanAbsorptionEmission; constantAbsorptionEmissionCoeffs { - absorptivity absorptivity [ 0 -1 0 0 0 0 0 ] 0.01; - emissivity emissivity [ 0 -1 0 0 0 0 0 ] 0.01; - E E [ 1 -1 -3 0 0 0 0 ] 0; + absorptivity absorptivity [ m^-1 ] 0.01; + emissivity emissivity [ m^-1 ] 0.01; + E E [ kg m^-1 s^-3 ] 0; } greyMeanAbsorptionEmissionCoeffs @@ -49,7 +52,7 @@ greyMeanAbsorptionEmissionCoeffs CO2 { - Tcommon 300; //Common Temp + Tcommon 200; //Common Temp invTemp true; //Is the polynomio using inverse temperature. Tlow 200; //Low Temp Thigh 2500; //High Temp @@ -77,7 +80,7 @@ greyMeanAbsorptionEmissionCoeffs H2O { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; @@ -104,7 +107,7 @@ greyMeanAbsorptionEmissionCoeffs C3H8//CH4 { - Tcommon 300; + Tcommon 200; Tlow 200; Thigh 2000; invTemp false; @@ -131,7 +134,7 @@ greyMeanAbsorptionEmissionCoeffs O2 { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; @@ -159,7 +162,7 @@ greyMeanAbsorptionEmissionCoeffs N2 { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; diff --git a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/controlDict b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/controlDict index 3efab07aeb899a9b83c1b1eb4c4559be420e6014..eb03206ed18647528b92f04611ece51f9ea7910b 100644 --- a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/controlDict +++ b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/controlDict @@ -16,7 +16,7 @@ FoamFile application fireFoam; -startFrom startTime; +startFrom latestTime; startTime 0; @@ -28,11 +28,11 @@ deltaT 0.03; writeControl adjustableRunTime; -writeInterval 1; +writeInterval 0.5; purgeWrite 0; -writeFormat ascii; +writeFormat binary; writePrecision 12; diff --git a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/fvSolution b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/fvSolution index 3a3bd03c733c99653bfb82a6a92388c591eb7cef..7345991f719934ed54e9b6a34755aa9a6b6722ac 100644 --- a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/fvSolution +++ b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/fvSolution @@ -34,7 +34,7 @@ solvers p_rgh { solver GAMG; - tolerance 1e-5; + tolerance 1e-7; relTol 0.01; smoother GaussSeidel; cacheAgglomeration true; @@ -45,28 +45,25 @@ solvers p_rghFinal { - solver GAMG; - tolerance 1e-6; + $p_rgh; + tolerance 1e-7; relTol 0; - smoother GaussSeidel; - cacheAgglomeration true; - nCellsInCoarsestLevel 10; - agglomerator faceAreaPair; - mergeLevels 1; }; - "(U|k)" + "(U|Yi|k|h|omega)" { solver PBiCG; preconditioner DILU; - tolerance 1e-6; - relTol 0.01; + tolerance 1e-7; + relTol 0.1; + nSweeps 1; }; - "(U|k)Final" + "(U|Yi|k|h|omega)Final" { $U; + tolerance 1e-7; relTol 0; }; @@ -84,18 +81,21 @@ solvers solver GAMG; tolerance 1e-4; relTol 0; - smoother DILU; + smoother symGaussSeidel; cacheAgglomeration true; nCellsInCoarsestLevel 10; agglomerator faceAreaPair; - mergeLevels 1; + mergeLevels 1; + maxIter 1; + nPreSweeps 0; + nPostSweeps 1; } - G + "(G)Final" { solver PCG; preconditioner DIC; - tolerance 1e-06; + tolerance 1e-04; relTol 0; } @@ -104,8 +104,8 @@ solvers PIMPLE { momentumPredictor yes; - nOuterCorrectors 2; - nCorrectors 1; + nOuterCorrectors 1; + nCorrectors 3; nNonOrthogonalCorrectors 0; } @@ -117,7 +117,7 @@ relaxationFactors equations { "(U|k).*" 1; - "(C3H8|O2|H2O|CO2|h).*" 1; + "(C3H8|O2|H2O|CO2|h).*" 1; } } diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/radiationProperties b/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/radiationProperties index 9ff932edc968e52371342354df72737247a45635..62b677bd775af3f7a73f4d4a4ab1676cdb3fe089 100644 --- a/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/radiationProperties +++ b/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/radiationProperties @@ -19,10 +19,14 @@ radiationModel fvDOM; fvDOMCoeffs { - nPhi 4; // azimuthal angles in PI/2 on X-Y.(from Y to X) - nTheta 0; // polar angles in PI (from Z to X-Y plane) - convergence 1e-3; // convergence criteria for radiation iteration - maxIter 1; // maximum number of iterations + nPhi 4; // azimuthal angles in PI/2 on X-Y.(from Y to X) + nTheta 0; // polar angles in PI (from Z to X-Y plane) + convergence 1e-2; // convergence criteria for radiation iteration + maxIter 4; // maximum number of iterations + cacheDiv true; // cache the div of the RTE equation. + +// NOTE: Caching div is "only" accurate if the upwind scheme is used in +// div(Ji,Ii_h) } // Number of flow iterations per radiation iteration @@ -32,9 +36,9 @@ absorptionEmissionModel greyMeanAbsorptionEmission; constantAbsorptionEmissionCoeffs { - absorptivity absorptivity [ 0 -1 0 0 0 0 0 ] 0.1; - emissivity emissivity [ 0 -1 0 0 0 0 0 ] 0.1; - E E [ 1 -1 -3 0 0 0 0 ] 0; + absorptivity absorptivity [ m^-1 ] 0.01; + emissivity emissivity [ m^-1 ] 0.01; + E E [ kg m^-1 s^-3 ] 0; } greyMeanAbsorptionEmissionCoeffs @@ -45,7 +49,7 @@ greyMeanAbsorptionEmissionCoeffs CO2 { - Tcommon 300; //Common Temp + Tcommon 200; //Common Temp invTemp true; //Is the polynomio using inverse temperature. Tlow 200; //Low Temp Thigh 2500; //High Temp @@ -73,7 +77,7 @@ greyMeanAbsorptionEmissionCoeffs H2O { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; @@ -100,7 +104,7 @@ greyMeanAbsorptionEmissionCoeffs CH4 { - Tcommon 300; + Tcommon 200; Tlow 200; Thigh 2500; invTemp false; @@ -127,7 +131,7 @@ greyMeanAbsorptionEmissionCoeffs O2 { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; @@ -155,7 +159,7 @@ greyMeanAbsorptionEmissionCoeffs N2 { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/controlDict b/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/controlDict index 8420fc7598c8fc8217824029f4e054a0b5960f1c..689f2a866c0150d38aabd2aac6e0fb69c440f208 100644 --- a/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/controlDict +++ b/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/controlDict @@ -48,8 +48,6 @@ runTimeModifiable yes; adjustTimeStep yes; -maxCo 0.25; - -maxDeltaT 0.1; +maxCo 0.5; // ************************************************************************* // diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/fvSolution b/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/fvSolution index d7bebcf0bb6fd329e5553f4b14b9e0a02ab8087d..fba625916d732884fb300bf1acc071c296dcfc19 100644 --- a/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/fvSolution +++ b/tutorials/combustion/fireFoam/les/smallPoolFire2D/system/fvSolution @@ -72,21 +72,24 @@ solvers Ii { - solver GAMG; + solver GAMG; tolerance 1e-4; - relTol 0; - smoother DILU; + relTol 0.1; + smoother symGaussSeidel; cacheAgglomeration true; nCellsInCoarsestLevel 10; - agglomerator faceAreaPair; - mergeLevels 1; + agglomerator faceAreaPair; + mergeLevels 1; + maxIter 3; + nPreSweeps 0; + nPostSweeps 1; } G { solver PCG; preconditioner DIC; - tolerance 1e-06; + tolerance 1e-04; relTol 0; } @@ -108,7 +111,7 @@ relaxationFactors equations { "(U|k).*" 1; - "(C3H8|O2|H2O|CO2|h).*" 0.9; + "(C3H8|O2|H2O|CO2|h).*" 1; } } diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire3D/0/IDefault b/tutorials/combustion/fireFoam/les/smallPoolFire3D/0/IDefault index e70bf3dec049007f0f422f82e0a9cab1950acdec..1da0ef50b95b0471f73122f9ac4d9627c93d363b 100644 --- a/tutorials/combustion/fireFoam/les/smallPoolFire3D/0/IDefault +++ b/tutorials/combustion/fireFoam/les/smallPoolFire3D/0/IDefault @@ -25,7 +25,7 @@ boundaryField type greyDiffusiveRadiation; T T; emissivityMode lookup; - emissivity uniform 1.0; + emissivity uniform 1; value uniform 0; } } diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire3D/constant/radiationProperties b/tutorials/combustion/fireFoam/les/smallPoolFire3D/constant/radiationProperties index 513c11e7dbc0b37023670e0818edc186ded83394..63e3de884c06d497ea1cfffd4d1bb240b77b8675 100644 --- a/tutorials/combustion/fireFoam/les/smallPoolFire3D/constant/radiationProperties +++ b/tutorials/combustion/fireFoam/les/smallPoolFire3D/constant/radiationProperties @@ -20,10 +20,14 @@ radiationModel fvDOM; fvDOMCoeffs { - nPhi 2; // azimuthal angles in PI/2 on X-Y.(from Y to X) - nTheta 2; // polar angles in PI (from Z to X-Y plane) - convergence 1e-3; // convergence criteria for radiation iteration - maxIter 10; // maximum number of iterations + nPhi 2; // azimuthal angles in PI/2 on X-Y.(from Y to X) + nTheta 2; // polar angles in PI (from Z to X-Y plane) + convergence 1e-1; // convergence criteria for radiation iteration + maxIter 1; // maximum number of iterations + cacheDiv true; // cache the div of the RTE equation. + +// NOTE: Caching div is "only" accurate if the upwind scheme is used in +// div(Ji,Ii_h) } // Number of flow iterations per radiation iteration @@ -33,9 +37,9 @@ absorptionEmissionModel greyMeanAbsorptionEmission; constantAbsorptionEmissionCoeffs { - absorptivity absorptivity [ 0 -1 0 0 0 0 0 ] 0.01; - emissivity emissivity [ 0 -1 0 0 0 0 0 ] 0.01; - E E [ 1 -1 -3 0 0 0 0 ] 0; + absorptivity absorptivity [ m^-1 ] 0.01; + emissivity emissivity [ m^-1 ] 0.01; + E E [ kg m^-1 s^-3 ] 0; } greyMeanAbsorptionEmissionCoeffs @@ -46,7 +50,7 @@ greyMeanAbsorptionEmissionCoeffs CO2 { - Tcommon 300; //Common Temp + Tcommon 200; //Common Temp invTemp true; //Is the polynomio using inverse temperature. Tlow 200; //Low Temp Thigh 2500; //High Temp @@ -74,7 +78,7 @@ greyMeanAbsorptionEmissionCoeffs H2O { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; @@ -101,7 +105,7 @@ greyMeanAbsorptionEmissionCoeffs CH4 { - Tcommon 300; + Tcommon 200; Tlow 200; Thigh 2500; invTemp false; @@ -128,7 +132,7 @@ greyMeanAbsorptionEmissionCoeffs O2 { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; @@ -156,7 +160,7 @@ greyMeanAbsorptionEmissionCoeffs N2 { - Tcommon 300; + Tcommon 200; invTemp true; Tlow 200; Thigh 2500; diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/controlDict b/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/controlDict index 6a45d3a30f8de04795c0e6652202f2ab4a9f0d5d..6f9c9cf1e6a0546c76a75310af3c93b32d63cef3 100644 --- a/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/controlDict +++ b/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/controlDict @@ -22,13 +22,13 @@ startTime 0.0; stopAt endTime; -endTime 2.75; +endTime 0.75; deltaT 0.001; writeControl adjustableRunTime; -writeInterval 0.05; +writeInterval 0.5; purgeWrite 0; @@ -48,7 +48,7 @@ runTimeModifiable yes; adjustTimeStep yes; -maxCo 0.2; +maxCo 0.5; maxDeltaT 0.1; diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/fvSolution b/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/fvSolution index 829f7a4a7ac112b1bd25f30ef358e2dba5b6542a..11cfaf95bd913ff7dbf038cf31a316dc7f6a008a 100644 --- a/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/fvSolution +++ b/tutorials/combustion/fireFoam/les/smallPoolFire3D/system/fvSolution @@ -66,12 +66,14 @@ solvers solver GAMG; tolerance 1e-4; relTol 0; - smoother DILU; + smoother symGaussSeidel; cacheAgglomeration true; nCellsInCoarsestLevel 10; - agglomerator faceAreaPair; - mergeLevels 1; - maxIter 20; + agglomerator faceAreaPair; + mergeLevels 1; + maxIter 1; + nPreSweeps 0; + nPostSweeps 1; } G @@ -88,7 +90,7 @@ PIMPLE { momentumPredictor yes; nOuterCorrectors 1; - nCorrectors 2; + nCorrectors 3; nNonOrthogonalCorrectors 0; } diff --git a/tutorials/discreteMethods/dsmcFoam/freeSpacePeriodic/system/controlDict b/tutorials/discreteMethods/dsmcFoam/freeSpacePeriodic/system/controlDict index 6ec357331862a0b44c0f15b0dfa15a544488c7da..28634ee885d278b59e768d1e02e825d7b646eb29 100644 --- a/tutorials/discreteMethods/dsmcFoam/freeSpacePeriodic/system/controlDict +++ b/tutorials/discreteMethods/dsmcFoam/freeSpacePeriodic/system/controlDict @@ -49,13 +49,6 @@ adjustTimeStep no; functions { - dsmcFields1 - { - type dsmcFields; - functionObjectLibs ( "libutilityFunctionObjects.so" ); - enabled true; - outputControl outputTime; - } fieldAverage1 { type fieldAverage; @@ -121,6 +114,13 @@ functions } ); } + dsmcFields1 + { + type dsmcFields; + functionObjectLibs ( "libutilityFunctionObjects.so" ); + enabled true; + outputControl outputTime; + } } // ************************************************************************* // diff --git a/tutorials/discreteMethods/dsmcFoam/freeSpaceStream/system/controlDict b/tutorials/discreteMethods/dsmcFoam/freeSpaceStream/system/controlDict index 9cd736a161d43ce6dd11100323095f872ad8d006..2f17c188c0921d18d65c39d536d42a356f02fc2e 100644 --- a/tutorials/discreteMethods/dsmcFoam/freeSpaceStream/system/controlDict +++ b/tutorials/discreteMethods/dsmcFoam/freeSpaceStream/system/controlDict @@ -49,13 +49,6 @@ adjustTimeStep no; functions { - dsmcFields1 - { - type dsmcFields; - functionObjectLibs ( "libutilityFunctionObjects.so" ); - enabled true; - outputControl outputTime; - } fieldAverage1 { type fieldAverage; @@ -121,6 +114,13 @@ functions } ); } + dsmcFields1 + { + type dsmcFields; + functionObjectLibs ( "libutilityFunctionObjects.so" ); + enabled true; + outputControl outputTime; + } } // ************************************************************************* // diff --git a/tutorials/discreteMethods/dsmcFoam/supersonicCorner/system/controlDict b/tutorials/discreteMethods/dsmcFoam/supersonicCorner/system/controlDict index f87019fc7a729e598882109e499fc8f099c29e68..8045c73096f54c4abd88d45bbf6997439156c3a9 100644 --- a/tutorials/discreteMethods/dsmcFoam/supersonicCorner/system/controlDict +++ b/tutorials/discreteMethods/dsmcFoam/supersonicCorner/system/controlDict @@ -49,13 +49,6 @@ adjustTimeStep no; functions { - dsmcFields1 - { - type dsmcFields; - functionObjectLibs ( "libutilityFunctionObjects.so" ); - enabled true; - outputControl outputTime; - } fieldAverage1 { type fieldAverage; @@ -121,6 +114,13 @@ functions } ); } + dsmcFields1 + { + type dsmcFields; + functionObjectLibs ( "libutilityFunctionObjects.so" ); + enabled true; + outputControl outputTime; + } } // ************************************************************************* // diff --git a/tutorials/discreteMethods/dsmcFoam/wedge15Ma5/system/controlDict b/tutorials/discreteMethods/dsmcFoam/wedge15Ma5/system/controlDict index ebbcdcf9a67a90fdfe4b0aea29dadddc6735de7c..00dd9e1e857dad35e623f6a4eb3c5018cce6d591 100644 --- a/tutorials/discreteMethods/dsmcFoam/wedge15Ma5/system/controlDict +++ b/tutorials/discreteMethods/dsmcFoam/wedge15Ma5/system/controlDict @@ -49,14 +49,6 @@ adjustTimeStep no; functions { - dsmcFields1 - { - type dsmcFields; - functionObjectLibs ( "libutilityFunctionObjects.so" ); - enabled true; - outputControl outputTime; - } - fieldAverage1 { type fieldAverage; @@ -123,6 +115,14 @@ functions ); } + dsmcFields1 + { + type dsmcFields; + functionObjectLibs ( "libutilityFunctionObjects.so" ); + enabled true; + outputControl outputTime; + } + forces1 { type forces; diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/U b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/U new file mode 100644 index 0000000000000000000000000000000000000000..72f38fd6dd13d8d895aeeae8ab2386356e6a8f84 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/U @@ -0,0 +1,67 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + inlet + { + type fixedValue; + value uniform (1 0 0); + } + outlet + { + type pressureInletOutletVelocity; + value uniform (0 0 0); + } + walls + { +// type fixedValue; + type movingWallVelocity; + value uniform (0 0 0); + } + defaultFaces + { + type empty; + } + ACMI1_blockage + { + type fixedValue; + value uniform (0 0 0); + } + ACMI1_couple + { + type cyclicACMI; + value uniform (0 0 0); + } + ACMI2_blockage + { + type fixedValue; + value uniform (0 0 0); + } + ACMI2_couple + { + type cyclicACMI; + value uniform (0 0 0); + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/epsilon b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/epsilon new file mode 100644 index 0000000000000000000000000000000000000000..36447c10794044c40dbe85991c9ec4e5b9e7e9c4 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/epsilon @@ -0,0 +1,67 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 1.8e-3; + +boundaryField +{ + inlet + { + type fixedValue; + value $internalField; + } + outlet + { + type inletOutlet; + inletValue $internalField; + value $internalField; + } + walls + { + type epsilonWallFunction; + value $internalField; + } + defaultFaces + { + type empty; + } + ACMI1_blockage + { + type epsilonWallFunction; + value $internalField; + } + ACMI1_couple + { + type cyclicACMI; + value $internalField; + } + ACMI2_blockage + { + type epsilonWallFunction; + value $internalField; + } + ACMI2_couple + { + type cyclicACMI; + value $internalField; + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/k b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/k new file mode 100644 index 0000000000000000000000000000000000000000..286cdf4e26884e862ac702a183614c8fbfdbe4dc --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/k @@ -0,0 +1,67 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 3.75e-3; + +boundaryField +{ + inlet + { + type fixedValue; + value $internalField; + } + outlet + { + type inletOutlet; + inletValue $internalField; + value $internalField; + } + walls + { + type kqRWallFunction; + value $internalField; + } + defaultFaces + { + type empty; + } + ACMI1_blockage + { + type kqRWallFunction; + value $internalField; + } + ACMI1_couple + { + type cyclicACMI; + value $internalField; + } + ACMI2_blockage + { + type kqRWallFunction; + value $internalField; + } + ACMI2_couple + { + type cyclicACMI; + value $internalField; + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/p b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/p new file mode 100644 index 0000000000000000000000000000000000000000..6a9c955b27a1b52c9f276a9d4fe80ffaccab1aca --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/0.org/p @@ -0,0 +1,70 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + inlet + { + type zeroGradient; + } + outlet + { + type fixedValue; + value uniform 0; + } + walls + { + type zeroGradient; + } + couple1 + { + type zeroGradient; + } + couple2 + { + type zeroGradient; + } + defaultFaces + { + type empty; + } + ACMI1_blockage + { + type zeroGradient; + } + ACMI1_couple + { + type cyclicACMI; + value uniform 0; + } + ACMI2_blockage + { + type zeroGradient; + } + ACMI2_couple + { + type cyclicACMI; + value uniform 0; + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allclean b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..fa0925adb5c730ed7946332470451289ce0fdf43 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allclean @@ -0,0 +1,9 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + +# Source tutorial clean functions +. $WM_PROJECT_DIR/bin/tools/CleanFunctions + +cleanCase + +rm -rf 0 diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..26008d23c09402ed650e9864248e7bb4029a8d94 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun @@ -0,0 +1,9 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +./Allrun.pre + +runApplication $(getApplication) diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun-parallel b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun-parallel new file mode 100755 index 0000000000000000000000000000000000000000..ef154f057dfdfd6fd260cd857d5c386251e53eef --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun-parallel @@ -0,0 +1,13 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +./Allrun.pre + +runApplication decomposePar + +runParallel $(getApplication) 4 + +runApplication reconstructPar diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun.pre b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun.pre new file mode 100755 index 0000000000000000000000000000000000000000..07707e449578cca76706230c7ea303785fe6cd0c --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/Allrun.pre @@ -0,0 +1,17 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +runApplication blockMesh + +runApplication topoSet -constant + +# split the mesh to generate the ACMI coupled patches +runApplication createBaffles -overwrite + +# remove zero-sized patches +runApplication createPatch -overwrite + +cp -rf 0.org 0 diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/README b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/README new file mode 100644 index 0000000000000000000000000000000000000000..7871c1303e3a609d1fa632dd0c514db81e3de0f8 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/README @@ -0,0 +1,104 @@ +oscillatingInletACMI2D + +This tutorial case gives an example of the Arbitrarily Coupled Mesh Interface +(ACMI) usage. The mesh is composed of two mesh regions: an inlet channel which +oscillates in the +/- Y-direction, and a fixed mesh region. + +Each ACMI patch requires the specification of a 'non-overlapping' patch. In +this example, the non-overlapping patches are described as walls, e.g. taken +from the constant/polyMesh/boundary file: + + 1. First ACMI poatch pair applied to the inlet channel outlet + + ACMI1_blockage + { + type wall; + nFaces 40; + startFace 43680; + } + ACMI1_couple + { + type cyclicACMI; + nFaces 40; + startFace 43720; + matchTolerance 0.0001; + transform noOrdering; + neighbourPatch ACMI2_couple; + nonOverlapPatch ACMI1_blockage; + } + + + 1. Second ACMI poatch pair applied to the fixed mesh region inlet + + ACMI2_blockage + { + type wall; + nFaces 96; + startFace 43760; + } + ACMI2_couple + { + type cyclicACMI; + nFaces 96; + startFace 43856; + matchTolerance 0.0001; + transform noOrdering; + neighbourPatch ACMI1_couple; + nonOverlapPatch ACMI2_blockage; + } + + +In the above, the ACMI1_blockage and ACMI1_couple patches occupy the same space, +with duplicate points, edges and faces. The ACMI2_blockage and ACMI2_couple +patches are created similarly. + +The duplicate patches are initially created using the createBaffles utility. +Firstly, the original (non-duplicated) patch faces are collected into zones +using the topoSet utility. + +Each ACMI/no-overlapping patch pair is specified using a master-slave approach. +However, since we are generating boundary patches (which are always master +patches) the slave patches are simply defined using 'dummy' entries, e.g.: + + type faceZone; + zoneName couple1Faces; + + patches + { + // create blockage patch + master + { + //- Master side patch + name ACMI1_blockage; + type wall; + } + slave1 // dummy entries only + { + //- Slave side patch + name ACMI1_blockage; + type wall; + } + + // create cyclic ACMI patch + master2 + { + //- Master side patch + name ACMI1_couple; + type cyclicACMI; + matchTolerance 0.0001; + neighbourPatch ACMI2_couple; + nonOverlapPatch ACMI1_blockage; + transform noOrdering; + } + slave2 // dummy entries only + { + //- Slave side patch + name ACMI1_couple; + type patch; + } + } + +Boundary conditions must then be applied to all geometric patches in the usual, +manner, and the cases can be executed in parallel (as shown when running the +Allrun-parallel script) without any speacial treatment, i.e. the case set-up is +the same as when operating in serial mode. diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/RASProperties b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/RASProperties new file mode 100644 index 0000000000000000000000000000000000000000..a4937b503a46850b2626f0d301e4a07b9f691507 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/RASProperties @@ -0,0 +1,25 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +RASModel kEpsilon; + +turbulence on; + +printCoeffs on; + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/dynamicMeshDict b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/dynamicMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..ae204c40bcb4d535ea4c98712615de0063211cf4 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/dynamicMeshDict @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object dynamicMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dynamicFvMesh solidBodyMotionFvMesh; + +motionSolverLibs ( "libfvMotionSolvers.so" ); + +solidBodyMotionFvMeshCoeffs +{ + cellZone inletChannel; + + solidBodyMotionFunction oscillatingLinearMotion; + + oscillatingLinearMotionCoeffs + { + amplitude (0 0.5 0); + omega 3.14; // rad/s (.5 rps) + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/polyMesh/blockMeshDict b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/polyMesh/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..638f67494708b5c9fbcaca1ed1b14cb9dead9fdf --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/polyMesh/blockMeshDict @@ -0,0 +1,103 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +convertToMeters 1; + +vertices +( + (0 0.3 0) + (1 0.3 0) + (1 0.7 0) + (0 0.7 0) + (0 0.3 0.1) + (1 0.3 0.1) + (1 0.7 0.1) + (0 0.7 0.1) + + (1 0 0) + (3 0 0) + (3 1 0) + (1 1 0) + (1 0 0.1) + (3 0 0.1) + (3 1 0.1) + (1 1 0.1) +); + +blocks +( +// hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1) +// hex (8 9 10 11 12 13 14 15) (40 48 1) simpleGrading (1 1 1) + hex (0 1 2 3 4 5 6 7) (80 40 1) simpleGrading (1 1 1) + hex (8 9 10 11 12 13 14 15) (80 96 1) simpleGrading (1 1 1) +); + +edges +( +); + +boundary +( + inlet + { + type patch; + faces + ( + (0 4 7 3) + ); + } + outlet + { + type patch; + faces + ( + (10 14 13 9) + ); + } + walls + { + type wall; + faces + ( + (3 7 6 2) + (1 5 4 0) + (11 15 14 10) + (9 13 12 8) + ); + } + couple1 + { + type patch; + faces + ( + (2 6 5 1) + ); + } + couple2 + { + type patch; + faces + ( + (8 12 15 11) + ); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/polyMesh/boundary b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/polyMesh/boundary new file mode 100644 index 0000000000000000000000000000000000000000..f6e6726c6bc2912dada27f59fca03ea17e1b68d8 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/polyMesh/boundary @@ -0,0 +1,81 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class polyBoundaryMesh; + location "constant/polyMesh"; + object boundary; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +8 +( + inlet + { + type patch; + nFaces 40; + startFace 21464; + } + outlet + { + type patch; + nFaces 96; + startFace 21504; + } + walls + { + type wall; + nFaces 320; + startFace 21600; + } + defaultFaces + { + type empty; + inGroups 1(empty); + nFaces 21760; + startFace 21920; + } + ACMI1_blockage + { + type wall; + nFaces 40; + startFace 43680; + } + ACMI1_couple + { + type cyclicACMI; + inGroups 1(cyclicACMI); + nFaces 40; + startFace 43720; + matchTolerance 0.0001; + transform noOrdering; + neighbourPatch ACMI2_couple; + nonOverlapPatch ACMI1_blockage; + } + ACMI2_blockage + { + type wall; + nFaces 96; + startFace 43760; + } + ACMI2_couple + { + type cyclicACMI; + inGroups 1(cyclicACMI); + nFaces 96; + startFace 43856; + matchTolerance 0.0001; + transform noOrdering; + neighbourPatch ACMI1_couple; + nonOverlapPatch ACMI2_blockage; + } +) + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/transportProperties b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/transportProperties new file mode 100644 index 0000000000000000000000000000000000000000..5f2e87ebefb9f23138b331d9088e3af55931eaa9 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/transportProperties @@ -0,0 +1,22 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object transportProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +transportModel Newtonian; + +nu nu [ 0 2 -1 0 0 0 0 ] 1e-6; + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/turbulenceProperties b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..3721a46a2ead37eb2bf10434bcde59afa9fe9bf6 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType RASModel; + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/controlDict b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..3521d07583e44c95b22ff9a001e030b066be2bca --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/controlDict @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application pimpleDyMFoam; + +startFrom latestTime; + +startTime 0; + +stopAt endTime; + +endTime 5; + +deltaT 0.005; + +writeControl adjustableRunTime; + +writeInterval 0.05; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression off; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable true; + +adjustTimeStep true; + +maxCo 0.5; + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/createBafflesDict b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/createBafflesDict new file mode 100644 index 0000000000000000000000000000000000000000..54e2ab822b05bf116fcc5bbde637f8bf4770f2c5 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/createBafflesDict @@ -0,0 +1,111 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object createBafflesDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Whether to convert internal faces only (so leave boundary faces intact). +// This is only relevant if your face selection type can pick up boundary +// faces. +internalFacesOnly false; + + +// Baffles to create. +baffles +{ + // NOTE: cyclicAMI patches MUST BE defined PRIOR to their associted + // blockage patches + + ACMI1 + { + //- Use predefined faceZone to select faces and orientation. + type faceZone; + zoneName couple1Faces; + + patches + { + master + { + //- Master side patch + name ACMI1_couple; + type cyclicACMI; + matchTolerance 0.0001; + neighbourPatch ACMI2_couple; + nonOverlapPatch ACMI1_blockage; + transform noOrdering; + } + slave // not used since we're manipulating a boundary patch + { + //- Slave side patch + name ACMI1_couple; + type patch; + } + + master2 + { + //- Master side patch + name ACMI1_blockage; + type wall; + } + slave2 // not used since we're manipulating a boundary patch + { + //- Slave side patch + name ACMI1_blockage; + type wall; + } + + } + } + ACMI2 + { + //- Use predefined faceZone to select faces and orientation. + type faceZone; + zoneName couple2Faces; + + patches + { + master + { + //- Master side patch + name ACMI2_couple; + type cyclicACMI; + matchTolerance 0.0001; + neighbourPatch ACMI1_couple; + nonOverlapPatch ACMI2_blockage; + transform noOrdering; + } + slave // not used since we're manipulating a boundary patch + { + //- Slave side patch + name ACMI2_couple; + type patch; + } + + master2 + { + //- Master side patch + name ACMI2_blockage; + type wall; + } + slave2 // not used since we're manipulating a boundary patch + { + //- Slave side patch + name ACMI2_blockage; + type wall; + } + } + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/createPatchDict b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/createPatchDict new file mode 100644 index 0000000000000000000000000000000000000000..cbfab2fa08f08fa817d48a44dc0dfbdbca722b57 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/createPatchDict @@ -0,0 +1,54 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object createPatchDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// This application/dictionary controls: +// - optional: create new patches from boundary faces (either given as +// a set of patches or as a faceSet) +// - always: order faces on coupled patches such that they are opposite. This +// is done for all coupled faces, not just for any patches created. +// - optional: synchronise points on coupled patches. + +// 1. Create cyclic: +// - specify where the faces should come from +// - specify the type of cyclic. If a rotational specify the rotationAxis +// and centre to make matching easier +// - always create both halves in one invocation with correct 'neighbourPatch' +// setting. +// - optionally pointSync true to guarantee points to line up. + +// 2. Correct incorrect cyclic: +// This will usually fail upon loading: +// "face 0 area does not match neighbour 2 by 0.0100005%" +// " -- possible face ordering problem." +// - in polyMesh/boundary file: +// - loosen matchTolerance of all cyclics to get case to load +// - or change patch type from 'cyclic' to 'patch' +// and regenerate cyclic as above + + +// Do a synchronisation of coupled points after creation of any patches. +// Note: this does not work with points that are on multiple coupled patches +// with transformations (i.e. cyclics). +pointSync false; + +// Patches to create. +patches +( + // none +); + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/decomposeParDict b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..8b22fc9971e21eafcf4b6de1596f380ec7e0cd9e --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/decomposeParDict @@ -0,0 +1,30 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object decomposeParDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 4; + +method scotch; + +hierarchicalCoeffs +{ + n (1 4 1); + delta 0.001; + order xyz; +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/fvSchemes b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..b6ae74a4e93443b0987df7ae5831866b36b37584 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/fvSchemes @@ -0,0 +1,63 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; + grad(U) cellLimited Gauss linear 1; +} + +divSchemes +{ + default none; +// div(phi,U) Gauss upwind; + div(phi,U) Gauss linearUpwind grad(U); + div(phi,k) Gauss upwind; + div(phi,epsilon) Gauss upwind; + div((nuEff*dev(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear limited corrected 0.33; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default limited corrected 0.33; +} + +fluxRequired +{ + default no; + pcorr ; + p ; +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/fvSolution b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..61da672625587417385d65d2b2dfc378340dd6a4 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/fvSolution @@ -0,0 +1,80 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + pcorr + { + solver GAMG; + tolerance 1e-2; + relTol 0; + smoother GaussSeidel; + cacheAgglomeration no; + nCellsInCoarsestLevel 10; + agglomerator faceAreaPair; + mergeLevels 1; + maxIter 50; + } + + p + { + $pcorr; + tolerance 1e-5; + relTol 0.01; + } + + pFinal + { + $p; + tolerance 1e-6; + relTol 0; + } + + "(U|k|epsilon)" + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-6; + relTol 0.1; + } + + "(U|k|epsilon)Final" + { + $U; + tolerance 1e-6; + relTol 0; + } +} + +PIMPLE +{ + correctPhi no; + nOuterCorrectors 1; + nCorrectors 2; + nNonOrthogonalCorrectors 0; +} + +relaxationFactors +{ +// "(U|k|epsilon).*" 1; +} + +cache +{ + grad(U); +} + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/topoSetDict b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/topoSetDict new file mode 100644 index 0000000000000000000000000000000000000000..814bded7d0ac8c538056e65c606400931ef43b40 --- /dev/null +++ b/tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/system/topoSetDict @@ -0,0 +1,89 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: dev | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object topoSetDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +actions +( + // Get both sides of ami + // ~~~~~~~~~~~~~~~~~~~~~ + + // Create faceZone for patch couple1 + { + name couple1Faces; + type faceSet; + action new; + source patchToFace; + sourceInfo + { + name couple1; + } + } + { + name couple1Faces; + type faceZoneSet; + action new; + source setToFaceZone; + sourceInfo + { + faceSet couple1Faces; + } + } + + // Create faceZone for patch couple2 + { + name couple2Faces; + type faceSet; + action new; + source patchToFace; + sourceInfo + { + name couple2; + } + } + { + name couple2Faces; + type faceZoneSet; + action new; + source setToFaceZone; + sourceInfo + { + faceSet couple2Faces; + } + } + + // Create cellZone for moving cells in inlet channel + { + name inletChannel; + type cellSet; + action new; + source boxToCell; + sourceInfo + { + box (-100 -100 -100) (1.0001 100 100); + } + } + { + name inletChannel; + type cellZoneSet; + action new; + source setToCellZone; + sourceInfo + { + set inletChannel; + } + } +); + +// ************************************************************************* // diff --git a/tutorials/incompressible/simpleFoam/turbineSiting/constant/RASProperties b/tutorials/incompressible/simpleFoam/turbineSiting/constant/RASProperties index 4e7382cf5e151250218639000c12e07cc5d6b520..e8f2fd50229c5a78420b2d020728e8d0b09ed730 100644 --- a/tutorials/incompressible/simpleFoam/turbineSiting/constant/RASProperties +++ b/tutorials/incompressible/simpleFoam/turbineSiting/constant/RASProperties @@ -25,10 +25,11 @@ kEpsilonCoeffs Cmu 0.09; C1 1.44; C2 1.92; - C3 -0.33; - sigmak 1.0; sigmaEps 1.11; //Original value:1.44 - Prt 1.0; + //NOTE: See "On the use of the k-Epsilon model in commercial CFD software + // to model the neutral atmospheric boundary layer". J. of wind engineering + // and inductrial aerodymanics 95(2007) 355-269 by + // D.M. Hargreaves and N.G. Wright } // ************************************************************************* // diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/reactingCloud1Properties index 45ae8875b737fc122940315d9d3ff594744a9512..b0104d35d2b976835e587057431dd0cc4ba94b09 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/reactingCloud1Properties @@ -88,6 +88,7 @@ subModels inputFile "parcelInjectionProperties"; duration 20.0; parcelsPerSecond 50; + randomise true; } } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/surfaceFilmProperties b/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/surfaceFilmProperties index e327a829599ca9d90206d28ee6bcfd5a96bfeea9..407db73fc3d69f33057a68e513196643d37520cf 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/surfaceFilmProperties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/constant/surfaceFilmProperties @@ -29,17 +29,17 @@ thermoSingleLayerCoeffs deltaWet 1e-4; hydrophilic no; + turbulence laminar; + laminarCoeffs + { + Cf 0.005; + } + forces ( - surfaceShear thermocapillary ); - surfaceShearCoeffs - { - Cf 0.005; - } - injectionModels (); phaseChangeModel none; diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties index c6a1bcbfc12755dbb3c9ceaebedd23538a5877d0..40b719099c46597b9ac3f369b03aad66228a3b78 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/constant/surfaceFilmProperties @@ -33,6 +33,12 @@ thermoSingleLayerCoeffs radiationModel none; + turbulence laminar; + laminarCoeffs + { + Cf 0.005; + } + upperSurfaceModels { /* @@ -56,16 +62,10 @@ thermoSingleLayerCoeffs forces ( - surfaceShear thermocapillary contactAngle ); - surfaceShearCoeffs - { - Cf 0.005; - } - contactAngleCoeffs { Ccf 0.085; diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/constant/surfaceFilmProperties b/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/constant/surfaceFilmProperties index 90792e87a65dd11e012ec03693cbbf1afa48d57b..01e2f58fef34271b2ecc0ae4c34d1f3d3790ae58 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/constant/surfaceFilmProperties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/constant/surfaceFilmProperties @@ -33,14 +33,18 @@ kinematicSingleLayerCoeffs injectionModels (); + turbulence laminar; + laminarCoeffs + { + Cf 0.001; + } + forces ( contactAngle - surfaceShear thermocapillary ); - contactAngleCoeffs { Ccf 1; @@ -58,9 +62,4 @@ kinematicSingleLayerCoeffs zeroForcePatches (); } - - surfaceShearCoeffs - { - Cf 0.001; - } } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/reactingCloud1Properties index c25468b554f13ea9ffe18c18a972fb1a5538385a..9c0d5fdcac2e25d767a7315be752ffcbc45fa685 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/reactingCloud1Properties @@ -88,6 +88,7 @@ subModels inputFile "parcelInjectionProperties"; duration 10.0; parcelsPerSecond 200; + randomise true; } } diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/surfaceFilmProperties b/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/surfaceFilmProperties index 8335fadfc218d46a36d4c93c882f0e40738d7b69..c6b9dd1841a8b0506a7e3ff31587e3ea459d5699 100644 --- a/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/surfaceFilmProperties +++ b/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/constant/surfaceFilmProperties @@ -30,17 +30,17 @@ thermoSingleLayerCoeffs deltaWet 1e-4; hydrophilic no; + turbulence laminar; + laminarCoeffs + { + Cf 0.005; + } + forces ( - surfaceShear thermocapillary ); - surfaceShearCoeffs - { - Cf 0.005; - } - injectionModels (); diff --git a/tutorials/lagrangian/reactingParcelFoam/filter/constant/reactingCloud1Properties b/tutorials/lagrangian/reactingParcelFoam/filter/constant/reactingCloud1Properties index 5a1582cead67ec7a347edce8a3fc920e365ef92b..47aa8cf33caccf59a43760d451931dcd2dc3c49b 100644 --- a/tutorials/lagrangian/reactingParcelFoam/filter/constant/reactingCloud1Properties +++ b/tutorials/lagrangian/reactingParcelFoam/filter/constant/reactingCloud1Properties @@ -93,6 +93,7 @@ subModels inputFile "parcelInjectionProperties"; duration 1.0; parcelsPerSecond 250; + randomise true; } } diff --git a/tutorials/lagrangian/sprayFoam/aachenBomb/constant/sprayCloudProperties b/tutorials/lagrangian/sprayFoam/aachenBomb/constant/sprayCloudProperties index dc08a39d09b9ecbab2837cc9282400335c5b5ef0..62775863dfde602df14efa3dd47a19cfba06e048 100644 --- a/tutorials/lagrangian/sprayFoam/aachenBomb/constant/sprayCloudProperties +++ b/tutorials/lagrangian/sprayFoam/aachenBomb/constant/sprayCloudProperties @@ -56,9 +56,11 @@ constantProperties { T0 320; - // place holders for rho0 and Cp0 - reset from liquid props using T0 + // place holders for rho0, Cp0 and sigma0 + // - reset from liquid props using T0 rho0 1000; Cp0 4187; + sigma0 0.02; youngsModulus 1e9; poissonsRatio 0.35;