immersedBoundaryAdjustPhi.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
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 -------------------------------------------------------------------------------
8 License
9  This file is part of foam-extend.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "volFields.H"
28 #include "surfaceFields.H"
32 #include "fvc.H"
33 
34 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
35 
37 (
40 )
41 {
42  const fvMesh& mesh = phi.mesh();
43 
44  // If the mesh is moving, adjustment needs to be calculated on
45  // relative fluxes. HJ, 13/Feb/2009
46  if (mesh.moving())
47  {
49  }
50 
51  forAll (phi.boundaryField(), patchI)
52  {
53  const fvPatchVectorField& Up = U.boundaryField()[patchI];
54 
55  if (isA<immersedBoundaryFvPatchVectorField>(Up))
56  {
57  if (Up.fixesValue())
58  {
59  // Found immersed boundary path which fixes value.
60  // Correction is necessary
61 
62  // Cast into immersedBoundary types
63  const immersedBoundaryFvPatchVectorField& ibU =
64  refCast<const immersedBoundaryFvPatchVectorField>(Up);
65 
66  const immersedBoundaryFvPatch& ibPatch = ibU.ibPatch();
67 
68  // Complete immersed boundary triangular surface is present
69  // on all processors: no need for parallel reduction
70 
71  // Sum the flux through the immersed boundary
72  const scalar triFlux = sum(ibU.refValue() & ibPatch.triSf());
73 
74  scalarField& phiInternal = phi.internalField();
75 
76  scalar fluxIn = 0;
77  scalar fluxOut = 0;
78  scalar fixedFlux = 0;
79 
80  // Get all IB faces
81  const labelList& ibFaces = ibPatch.ibFaces();
82  const boolList& ibFaceFlips = ibPatch.ibFaceFlips();
83 
84  forAll (ibFaces, faceI)
85  {
86  const label curFace = ibFaces[faceI];
87  const bool curFlip = ibFaceFlips[faceI];
88 
89  if (mesh.isInternalFace(curFace))
90  {
91  const scalar curFlux = phiInternal[curFace];
92 
93  if (!curFlip)
94  {
95  // Face points out of the live cell
96  if (curFlux >= 0)
97  {
98  // Flux out of the live cell
99  fluxOut += curFlux;
100  }
101  else
102  {
103  // Flux into the live cell
104  fluxIn -= curFlux;
105  }
106  }
107  else
108  {
109  // Face points into the live cell: flip it
110  if (curFlux >= 0)
111  {
112  // Flux into of the live cell
113  fluxIn += curFlux;
114  }
115  else
116  {
117  // Flux out the live cell
118  fluxOut -= curFlux;
119  }
120  }
121  }
122  else
123  {
124  const label patchID =
125  mesh.boundaryMesh().whichPatch(curFace);
126  const label faceID =
127  mesh.boundaryMesh()[patchID].whichFace(curFace);
128 
129  const scalar curFlux =
130  phi.boundaryField()[patchID][faceID];
131 
132  // Note: only coupled patches may carry flux
133  // In order to avoid double summation and
134  // inconsistencies in the correction,
135  // coupled face fluxes will NOT be corrected,
136  // but only accounted for in the summation.
137  if (mesh.boundaryMesh()[patchID].coupled())
138  {
139  // Only do the master side; slave will
140  // be handled on the other side of the couple
141  if (!curFlip)
142  {
143  fixedFlux += curFlux;
144  }
145  }
146  }
147  }
148 
149  reduce(fluxIn, sumOp<scalar>());
150  reduce(fluxOut, sumOp<scalar>());
151  reduce(fixedFlux, sumOp<scalar>());
152 
153  scalar imbalance = (fluxIn - fluxOut + fixedFlux) - triFlux;
154 
155  if (fvMesh::debug)
156  {
157  Info<< "triFlux = " << triFlux
158  << " fluxIn = " << fluxIn << " fluxOut = " << fluxOut
159  << " fixedFlux = " << fixedFlux
160  << " imbalance = " << imbalance
161  << endl;
162  }
163 
164  scalar massCorr = 1.0;
165 
166  if (mag(imbalance) > SMALL)
167  {
168  // Scaling required: scale to match the smaller of two
169  // fluxes
170  if (fluxIn > fluxOut)
171  {
172  // Scale down incoming flux
173  // Note change of sign: imbalance is negative
174  massCorr = 1 - imbalance/(fluxIn + SMALL);
175 
176  if (fvMesh::debug)
177  {
178  Info<< "Scaling down incoming flux with factor = "
179  << massCorr << endl;
180  }
181 
182  scalar newFluxIn = 0;
183 
184  // Visit all incoming flux faces and re-scale the flux
185  forAll (ibFaces, faceI)
186  {
187  const label curFace = ibFaces[faceI];
188  const bool curFlip = ibFaceFlips[faceI];
189 
190  if (mesh.isInternalFace(curFace))
191  {
192  // Take reference to current flux
193  scalar& curFlux = phiInternal[curFace];
194 
195  if (!curFlip)
196  {
197  // Face points out of the live cell
198  if (curFlux < 0)
199  {
200  // Flux out of the live cell
201  curFlux *= massCorr;
202  newFluxIn -= curFlux;
203  }
204  }
205  else
206  {
207  // Face points into the live cell: flip it
208  if (curFlux >= 0)
209  {
210  // Flux out the live cell
211  curFlux *= massCorr;
212  newFluxIn += curFlux;
213  }
214  }
215  }
216  }
217  }
218  else
219  {
220  // Scale down outgoing flux
221  massCorr = 1 + imbalance/(fluxOut + SMALL);
222 
223  if (fvMesh::debug)
224  {
225  Info<< "Scaling down outgoing flux with factor = "
226  << massCorr << endl;
227  }
228 
229  scalar newFluxOut = 0;
230 
231  // Visit all outgoing flux faces and re-scale the flux
232  forAll (ibFaces, faceI)
233  {
234  const label curFace = ibFaces[faceI];
235  const bool curFlip = ibFaceFlips[faceI];
236 
237  if (mesh.isInternalFace(curFace))
238  {
239  // Take reference to current flux
240  scalar& curFlux = phiInternal[curFace];
241 
242  if (!curFlip)
243  {
244  // Face points out of the live cell
245  if (curFlux >= 0)
246  {
247  // Flux out of the live cell
248  curFlux *= massCorr;
249  newFluxOut += curFlux;
250  }
251  }
252  else
253  {
254  // Face points into the live cell: flip it
255  if (curFlux < 0)
256  {
257  // Flux out the live cell
258  curFlux *= massCorr;
259  newFluxOut -= curFlux;
260  }
261  }
262  }
263  }
264  }
265  }
266  }
267  }
268  }
269 
270 
271  // If the mesh is moving, adjustment needs to be calculated on
272  // relative fluxes. Now reverting to absolute fluxes. HJ, 13/Feb/2009
273  if (mesh.moving())
274  {
276  }
277 }
278 
279 
280 // ************************************************************************* //
Foam::fvPatchField
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:65
volFields.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::immersedBoundaryFvPatch::triSf
const vectorField & triSf() const
Return triangular surface face area vectors.
Definition: immersedBoundaryFvPatch.C:2558
phi
surfaceScalarField & phi
Definition: setRegionFluidFields.H:8
Foam::immersedBoundaryAdjustPhi
void immersedBoundaryAdjustPhi(surfaceScalarField &phi, volVectorField &U)
Adjust the fluxes on immersed boundary to obey continuity.
Definition: immersedBoundaryAdjustPhi.C:37
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
surfaceFields.H
Foam::surfaceFields.
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::fvPatchField::fixesValue
virtual bool fixesValue() const
Return true if this patch field fixes a value.
Definition: fvPatchField.H:336
U
U
Definition: pEqn.H:46
Foam::fvc::makeRelative
void makeRelative(surfaceScalarField &phi, const volVectorField &U)
Make the given flux relative.
Definition: fvcMeshPhi.C:74
Foam::immersedBoundaryFvPatch::ibFaces
const labelList & ibFaces() const
Return list of faces for which one neighbour is an IB cell.
Definition: immersedBoundaryFvPatch.C:2300
immersedBoundaryAdjustPhi.H
Adjust immersed boundary fluxes to obey continuity.
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::immersedBoundaryFvPatch
Immersed boundary FV patch.
Definition: immersedBoundaryFvPatch.H:66
Foam::Info
messageStream Info
immersedBoundaryFvPatchFields.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Foam::immersedBoundaryFvPatch::ibFaceFlips
const boolList & ibFaceFlips() const
Return list of IB face flip:
Definition: immersedBoundaryFvPatch.C:2322
Foam::sumOp
Definition: ops.H:162
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:333
fvc.H
Foam::fvc::makeAbsolute
void makeAbsolute(surfaceScalarField &phi, const volVectorField &U)
Make the given flux absolute.
Definition: fvcMeshPhi.C:113
Foam::GeometricField
Generic GeometricField class.
Definition: surfaceFieldsFwd.H:52
inletOutletFvPatchFields.H
immersedBoundaryFvsPatchFields.H