1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Martin Beaudoin, Hydro-Quebec, 2009. All rights reserved
28 \*---------------------------------------------------------------------------*/
30 #include "mixingPlaneCheckFunctionObject.H"
31 #include "addToRunTimeSelectionTable.H"
32 #include "mixingPlaneFvsPatchFields.H"
33 #include "surfaceFields.H"
34 #include "mixingPlanePolyPatch.H"
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 defineTypeNameAndDebug(mixingPlaneCheckFunctionObject, 0);
42 addToRunTimeSelectionTable
45 mixingPlaneCheckFunctionObject,
51 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
53 Foam::mixingPlaneCheckFunctionObject::mixingPlaneCheckFunctionObject
57 const dictionary& dict
62 regionName_(polyMesh::defaultRegion),
63 phiName_(dict.lookup("phi"))
65 if (dict.found("region"))
67 dict.lookup("region") >> regionName_;
70 Info << "Creating mixingPlane check functionObject" << endl;
74 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
76 bool Foam::mixingPlaneCheckFunctionObject::start()
82 bool Foam::mixingPlaneCheckFunctionObject::execute()
84 const polyMesh& mesh =
85 time_.lookupObject<polyMesh>(regionName_);
87 boolList visited(mesh.boundaryMesh().size(), false);
89 forAll (mesh.boundaryMesh(), patchI)
92 isA<mixingPlanePolyPatch>(mesh.boundaryMesh()[patchI]) &&
93 mesh.boundaryMesh()[patchI].size()
98 visited[patchI] = true;
100 const mixingPlanePolyPatch& mixingMaster =
101 refCast<const mixingPlanePolyPatch>
103 mesh.boundaryMesh()[patchI]
106 const label shadowPatchI = mixingMaster.shadowIndex();
108 visited[shadowPatchI] = true;
110 const mixingPlanePolyPatch& mixingShadow =
111 mixingMaster.shadow();
113 // Get access to the mixing plane patch
114 const standAlonePatch& mixingPlanePatch =
115 mixingMaster.patchToPatch().mixingPlanePatch();
117 // Calculate areas of the mixing patch
118 scalarField mixingPlanePatchAreas(mixingPlanePatch.size());
119 const vectorField& mixingPlanePatchPoints =
120 mixingPlanePatch.points();
122 forAll (mixingPlanePatch, faceI)
124 mixingPlanePatchAreas[faceI] =
125 mixingPlanePatch[faceI].mag(mixingPlanePatchPoints);
128 const scalarField masterAreas = mag(mixingMaster.faceAreas());
129 const scalarField shadowAreas = mag(mixingShadow.faceAreas());
131 // Until the mixingPlane is fully parallelized, we stick with
132 // the serial version of sum. The interface is residing on a
133 // single processor when running in parallel
134 scalar sumMasterAreas = sum(masterAreas);
135 scalar sumShadowAreas = sum(shadowAreas);
136 // scalar sumMixingAreas = sum(mixingPlanePatchAreas);
138 #if 0 // Remove this for now
139 Info<< "Mixing plane functionObject: area check " << nl
140 << " " << "Master " << mixingMaster.name()
141 << " = " << sumMasterAreas << nl
142 << " " << "Shadow " << mixingMaster.shadow().name()
143 << " = " << sumShadowAreas << nl
144 << " " << "Mixing = " << sumMixingAreas << nl
145 << " " << "mixingPlanePatchAreas = " << mixingPlanePatchAreas
146 //<< " " << "mixingPlanePatchPoints = " << mixingPlanePatchPoints
150 // Calculate master to strip sum
151 scalarField masterToStripsAreas(mixingPlanePatch.size(), 0);
153 const labelListList& mppAddr =
154 mixingMaster.patchToPatch().masterProfileToPatchAddr();
156 const scalarListList& mppWeights =
157 mixingMaster.patchToPatch().masterProfileToPatchWeights();
159 forAll (masterAreas, masterI)
161 const labelList& curMppAddr = mppAddr[masterI];
162 const scalarList& curMppWeights = mppWeights[masterI];
164 forAll (curMppAddr, i)
166 masterToStripsAreas[curMppAddr[i]] +=
167 curMppWeights[i]*masterAreas[masterI];
172 // Does not work when in cylindrical coordinates
173 Info<< "Master scaling = "
174 << mixingPlanePatchAreas/masterToStripsAreas << endl;
177 // Calculate shadow to strip sum
178 scalarField shadowToStripsAreas(mixingPlanePatch.size(), 0);
180 const labelListList& sppAddr =
181 mixingMaster.patchToPatch().slaveProfileToPatchAddr();
183 const scalarListList& sppWeights =
184 mixingMaster.patchToPatch().slaveProfileToPatchWeights();
186 forAll (shadowAreas, shadowI)
188 const labelList& curSppAddr = sppAddr[shadowI];
189 const scalarList& curSppWeights = sppWeights[shadowI];
191 forAll (curSppAddr, i)
193 shadowToStripsAreas[curSppAddr[i]] +=
194 curSppWeights[i]*shadowAreas[shadowI];
199 // Does not work when in cylindrical coordinates
200 Info<< "Shadow scaling = "
201 << mixingPlanePatchAreas/shadowToStripsAreas << endl;
204 // Old way of computing phi balance
206 if( mesh.foundObject<surfaceScalarField>(phiName_) )
208 const surfaceScalarField& phi =
209 mesh.lookupObject<surfaceScalarField>(phiName_);
211 // Calculate local and shadow flux
212 scalar masterPatchScaleFactor_ = 1.0;
213 scalar shadowPatchScaleFactor_ = sumMasterAreas/sumShadowAreas;
214 scalar localFlux = masterPatchScaleFactor_ * sum(phi.boundaryField()[patchI]);
215 scalar localFluxMag = mag(localFlux);
217 scalar shadowFlux = shadowPatchScaleFactor_ * sum(phi.boundaryField()[shadowPatchI]);
218 // scalar shadowFluxMag = mag(shadowFlux);
220 Info<< "Mixing plane pair "
221 << "(" << mixingMaster.name() << ", "
222 << mixingMaster.shadow().name() << ") : "
223 << localFlux << " " << shadowFlux
224 << " Diff = " << localFlux + shadowFlux << " or "
225 << mag(localFlux + shadowFlux)/(localFluxMag + SMALL)*100
234 // word patchName = phi.boundaryField()[patchI].patch().name();
236 // if (patchName == masterPatchName_ && !visited[patchI])
238 // visited[patchI] = true;
240 // // Calculate local and shadow flux
241 // scalar localFlux = masterPatchScaleFactor_ * sum(phi.boundaryField()[patchI]);
242 // //scalar localFluxMag = masterPatchScaleFactor_ * sumMag(phi.boundaryField()[patchI]);
243 // scalar localFluxMag = mag(localFlux);
245 // const mixingPlanePolyPatch& mixingPlanePatch =
246 // refCast<const mixingPlanePolyPatch>
248 // phi.boundaryField()[patchI].patch().patch()
251 // const label shadowPatchI = mixingPlanePatch.shadowIndex();
253 // visited[shadowPatchI] = true;
255 // scalar shadowFlux = shadowPatchScaleFactor_ * sum(phi.boundaryField()[shadowPatchI]);
256 // //scalar shadowFluxMag = shadowPatchScaleFactor_ * sumMag(phi.boundaryField()[shadowPatchI]);
257 // scalar shadowFluxMag = mag(shadowFlux);
259 // Info<< "mixingPlane pair " << name_ << " (" << mixingPlanePatch.name() << ", " << mixingPlanePatch.shadow().name() << ") : "
260 // << " flux: " << localFlux << " " << shadowFlux
261 // << " : mag: " << localFluxMag << " " << shadowFluxMag
262 // << " Diff = " << localFlux + shadowFlux << " or "
263 // << mag(localFlux + shadowFlux)/(localFluxMag + SMALL)*100
273 bool Foam::mixingPlaneCheckFunctionObject::read(const dictionary& dict)
279 // ************************************************************************* //