1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 Martin Beaudoin, Hydro-Quebec, 2009. All rights reserved
27 \*---------------------------------------------------------------------------*/
29 #include "mixingPlaneCheckFunctionObject.H"
30 #include "addToRunTimeSelectionTable.H"
31 #include "mixingPlaneFvsPatchFields.H"
32 #include "surfaceFields.H"
33 #include "mixingPlanePolyPatch.H"
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(mixingPlaneCheckFunctionObject, 0);
41 addToRunTimeSelectionTable
44 mixingPlaneCheckFunctionObject,
50 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
52 Foam::mixingPlaneCheckFunctionObject::mixingPlaneCheckFunctionObject
56 const dictionary& dict
61 regionName_(polyMesh::defaultRegion),
62 phiName_(dict.lookup("phi"))
64 if (dict.found("region"))
66 dict.lookup("region") >> regionName_;
69 Info << "Creating mixingPlane check functionObject" << endl;
73 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
75 bool Foam::mixingPlaneCheckFunctionObject::start()
81 bool Foam::mixingPlaneCheckFunctionObject::execute()
83 const polyMesh& mesh =
84 time_.lookupObject<polyMesh>(regionName_);
86 boolList visited(mesh.boundaryMesh().size(), false);
88 forAll (mesh.boundaryMesh(), patchI)
91 isA<mixingPlanePolyPatch>(mesh.boundaryMesh()[patchI]) &&
92 mesh.boundaryMesh()[patchI].size()
97 visited[patchI] = true;
99 const mixingPlanePolyPatch& mixingMaster =
100 refCast<const mixingPlanePolyPatch>
102 mesh.boundaryMesh()[patchI]
105 const label shadowPatchI = mixingMaster.shadowIndex();
107 visited[shadowPatchI] = true;
109 const mixingPlanePolyPatch& mixingShadow =
110 mixingMaster.shadow();
112 // Get access to the mixing plane patch
113 const standAlonePatch& mixingPlanePatch =
114 mixingMaster.patchToPatch().mixingPlanePatch();
116 // Calculate areas of the mixing patch
117 scalarField mixingPlanePatchAreas(mixingPlanePatch.size());
118 const vectorField& mixingPlanePatchPoints =
119 mixingPlanePatch.points();
121 forAll (mixingPlanePatch, faceI)
123 mixingPlanePatchAreas[faceI] =
124 mixingPlanePatch[faceI].mag(mixingPlanePatchPoints);
127 const scalarField masterAreas = mag(mixingMaster.faceAreas());
128 const scalarField shadowAreas = mag(mixingShadow.faceAreas());
130 // Until the mixingPlane is fully parallelized, we stick with
131 // the serial version of sum. The interface is residing on a
132 // single processor when running in parallel
133 scalar sumMasterAreas = sum(masterAreas);
134 scalar sumShadowAreas = sum(shadowAreas);
135 // scalar sumMixingAreas = sum(mixingPlanePatchAreas);
137 #if 0 // Remove this for now
138 Info<< "Mixing plane functionObject: area check " << nl
139 << " " << "Master " << mixingMaster.name()
140 << " = " << sumMasterAreas << nl
141 << " " << "Shadow " << mixingMaster.shadow().name()
142 << " = " << sumShadowAreas << nl
143 << " " << "Mixing = " << sumMixingAreas << nl
144 << " " << "mixingPlanePatchAreas = " << mixingPlanePatchAreas
145 //<< " " << "mixingPlanePatchPoints = " << mixingPlanePatchPoints
149 // Calculate master to strip sum
150 scalarField masterToStripsAreas(mixingPlanePatch.size(), 0);
152 const labelListList& mppAddr =
153 mixingMaster.patchToPatch().masterProfileToPatchAddr();
155 const scalarListList& mppWeights =
156 mixingMaster.patchToPatch().masterProfileToPatchWeights();
158 forAll (masterAreas, masterI)
160 const labelList& curMppAddr = mppAddr[masterI];
161 const scalarList& curMppWeights = mppWeights[masterI];
163 forAll (curMppAddr, i)
165 masterToStripsAreas[curMppAddr[i]] +=
166 curMppWeights[i]*masterAreas[masterI];
171 // Does not work when in cylindrical coordinates
172 Info<< "Master scaling = "
173 << mixingPlanePatchAreas/masterToStripsAreas << endl;
176 // Calculate shadow to strip sum
177 scalarField shadowToStripsAreas(mixingPlanePatch.size(), 0);
179 const labelListList& sppAddr =
180 mixingMaster.patchToPatch().slaveProfileToPatchAddr();
182 const scalarListList& sppWeights =
183 mixingMaster.patchToPatch().slaveProfileToPatchWeights();
185 forAll (shadowAreas, shadowI)
187 const labelList& curSppAddr = sppAddr[shadowI];
188 const scalarList& curSppWeights = sppWeights[shadowI];
190 forAll (curSppAddr, i)
192 shadowToStripsAreas[curSppAddr[i]] +=
193 curSppWeights[i]*shadowAreas[shadowI];
198 // Does not work when in cylindrical coordinates
199 Info<< "Shadow scaling = "
200 << mixingPlanePatchAreas/shadowToStripsAreas << endl;
203 // Old way of computing phi balance
205 if( mesh.foundObject<surfaceScalarField>(phiName_) )
207 const surfaceScalarField& phi =
208 mesh.lookupObject<surfaceScalarField>(phiName_);
210 // Calculate local and shadow flux
211 scalar masterPatchScaleFactor_ = 1.0;
212 scalar shadowPatchScaleFactor_ = sumMasterAreas/sumShadowAreas;
213 scalar localFlux = masterPatchScaleFactor_ * sum(phi.boundaryField()[patchI]);
214 scalar localFluxMag = mag(localFlux);
216 scalar shadowFlux = shadowPatchScaleFactor_ * sum(phi.boundaryField()[shadowPatchI]);
217 // scalar shadowFluxMag = mag(shadowFlux);
219 Info<< "Mixing plane pair "
220 << "(" << mixingMaster.name() << ", "
221 << mixingMaster.shadow().name() << ") : "
222 << localFlux << " " << shadowFlux
223 << " Diff = " << localFlux + shadowFlux << " or "
224 << mag(localFlux + shadowFlux)/(localFluxMag + SMALL)*100
233 // word patchName = phi.boundaryField()[patchI].patch().name();
235 // if (patchName == masterPatchName_ && !visited[patchI])
237 // visited[patchI] = true;
239 // // Calculate local and shadow flux
240 // scalar localFlux = masterPatchScaleFactor_ * sum(phi.boundaryField()[patchI]);
241 // //scalar localFluxMag = masterPatchScaleFactor_ * sumMag(phi.boundaryField()[patchI]);
242 // scalar localFluxMag = mag(localFlux);
244 // const mixingPlanePolyPatch& mixingPlanePatch =
245 // refCast<const mixingPlanePolyPatch>
247 // phi.boundaryField()[patchI].patch().patch()
250 // const label shadowPatchI = mixingPlanePatch.shadowIndex();
252 // visited[shadowPatchI] = true;
254 // scalar shadowFlux = shadowPatchScaleFactor_ * sum(phi.boundaryField()[shadowPatchI]);
255 // //scalar shadowFluxMag = shadowPatchScaleFactor_ * sumMag(phi.boundaryField()[shadowPatchI]);
256 // scalar shadowFluxMag = mag(shadowFlux);
258 // Info<< "mixingPlane pair " << name_ << " (" << mixingPlanePatch.name() << ", " << mixingPlanePatch.shadow().name() << ") : "
259 // << " flux: " << localFlux << " " << shadowFlux
260 // << " : mag: " << localFluxMag << " " << shadowFluxMag
261 // << " Diff = " << localFlux + shadowFlux << " or "
262 // << mag(localFlux + shadowFlux)/(localFluxMag + SMALL)*100
272 bool Foam::mixingPlaneCheckFunctionObject::read(const dictionary& dict)
278 // ************************************************************************* //