All Classes Namespaces Files Functions Variables Typedefs Friends Macros Groups
interQHDFoam.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019 OpenCFD Ltd.
10  Copyright (C) 2016-2019 ISP RAS (www.ispras.ru) UniCFD Group (www.unicfd.ru)
11 -------------------------------------------------------------------------------
12 License
13  This file is part of QGDsolver library, based on OpenFOAM+.
14 
15  OpenFOAM is free software: you can redistribute it and/or modify it
16  under the terms of the GNU General Public License as published by
17  the Free Software Foundation, either version 3 of the License, or
18  (at your option) any later version.
19 
20  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27 
28 Application
29  QHDFoam
30 
31 Description
32  Solver for unsteady 3D turbulent flow of 2 incompressible immisicible
33  fluids governed by quasi-hydrodynamic dynamic (QHD) equations.
34 
35  QHD system of equations has been developed by scientific group from
36  Keldysh Institute of Applied Mathematics,
37  see http://elizarova.imamod.ru/selection-of-papers.html
38 
39  A comprehensive description of QGD equations and their applications
40  can be found here:
41  \verbatim
42  Elizarova, T.G.
43  "Quasi-Gas Dynamic equations"
44  Springer, 2009
45  \endverbatim
46 
47  A brief of theory on QGD and QHD system of equations:
48  \verbatim
49  Elizarova, T.G. and Sheretov, Y.V.
50  "Theoretical and numerical analysis of quasi-gasdynamic and quasi-hydrodynamic
51  equations"
52  J. Computational Mathematics and Mathematical Physics, vol. 41, no. 2, pp 219-234,
53  2001
54  \endverbatim
55 
56  Developed by UniCFD group (www.unicfd.ru) of ISP RAS (www.ispras.ru).
57 
58 
59 \*---------------------------------------------------------------------------*/
60 
61 #include "fvCFD.H"
62 #include "wallFvPatch.H"
63 #include "fvsc.H"
64 #include "twoPhaseIcoQGDThermo.H"
65 #include "QGDInterpolate.H"
66 #include "MULES.H"
67 #include "fvcSmooth.H"
68 
69 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
70 
71 int main(int argc, char *argv[])
72 {
73  argList::addOption("smoothAlpha");
74  argList::addOption("nSmoothIters");
75  argList::addOption("smoothCoeff");
76  #define NO_CONTROL
77  #include "postProcess.H"
78 
79  #include "setRootCase.H"
80 
81  #include "createTime.H"
82  #include "createMesh.H"
83  #include "createFields.H"
84  #include "createFaceFields.H"
85  #include "createFaceFluxes.H"
86  #include "createTimeControls.H"
87 
88  #include "smoothSolution.H"
89 
90  // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
91 
92  // Courant numbers used to adjust the time-step
93  scalar CoNum = 0.0;
94  scalar meanCoNum = 0.0;
95 
96  Info<< "\nStarting time loop\n" << endl;
97 
98  while (runTime.run())
99  {
100  /*
101  *
102  * Update physical properties
103  *
104  */
105  thermo.correct();
106  //turbulence.correct();
107 
108  /*
109  *
110  * Update fields
111  *
112  */
113  #include "updateFields.H"
114 
115  /*
116  *
117  * Update fluxes
118  *
119  */
120  #include "updateFluxes.H"
121  /*
122  *
123  * Update time step
124  *
125  */
126  #include "readTimeControls.H"
127  #include "QHDCourantNo.H"
128  #include "setDeltaT-QGDQHD.H"
129 
130  runTime++;
131  Info<< "Time = " << runTime.timeName() << nl << endl;
132 
133  // --- Store old time values
134  U.oldTime();
135  alpha1.oldTime();
136  rho.oldTime();
137 
138  //Continuity equation
140  surfaceScalarField tphi = phiu*da1dtf*(Tau1-Tau2);
141  tphi.setOriented(true);
142  phiwm += tphi;
143  coeffp = alpha1f*Tau1/rho1 + alpha2f*Tau2/rho2;
144  p.correctBoundaryConditions();
145 
146  //solve for pressure
147  {
148  fvScalarMatrix pEqn1
149  (
150  -fvm::laplacian(Tau1/rho1,p)
151  );
152  fvScalarMatrix pEqn2
153  (
154  -fvm::laplacian(Tau2/rho2,p)
155  );
156  fvScalarMatrix pEqn
157  (
158  fvc::div(phiu)
159  +fvc::div(phiwm)
160  -fvm::laplacian(coeffp,p)
161  );
162  pEqn.setReference(pRefCell, getRefCellValue(p, pRefCell));
163  pEqn.solve();
164 
165  phiw1 = phiwo1 - pEqn1.flux();
166  phiw2 = phiwo2 - pEqn2.flux();
167  phi1 = phiu - phiw1;
168  phi2 = phiu - phiw2;
169 
170  phi = phiu+phiwm+pEqn.flux();
171  }
172 
173  gradpf = fvsc::grad(p);
174  //W1 = ((Uf & gradUf) + (1./rho1)*gradpf - g)*Tau1;
175  //W2 = ((Uf & gradUf) + (1./rho2)*gradpf - g)*Tau2;
176  W1 = ((Uf & gradUf) + (1./rho1)*gradpf - g - linearInterpolate(cFrc)/rho1/*cFrcf/rho1*/)*Tau1;
177  W2 = ((Uf & gradUf) + (1./rho2)*gradpf - g - linearInterpolate(cFrc)/rho2/*cFrcf/rho2*/)*Tau2;
178 
179  phiWr =
180  qgdFlux
181  (
182  -phiw2+phiw1,
183  alpha2,
184  alpha2f,
185  "div(phi,alpha1)"
186  );
187  phiAlpha1f =
188  qgdFlux
189  (
190  phi,
191  alpha1,
192  alpha1f,
193  "div(phi,alpha1)"
194  )
195  +
196  //add qgd terms from Wr
197  qgdFlux
198  (
199  -phiWr,
200  alpha1,
201  alpha1f,
202  "div(phi,alpha1)"
203  );
204 
205  //add terms from da1dt
206  {
207  surfaceScalarField DeltaTauFlux =
208  phiu*da1dtf*(Tau1 - alpha1f*(Tau1-Tau2));
209  //phiu*da1dtf*Tau1;
210  DeltaTauFlux.setOriented(true);
211  phiAlpha1f += DeltaTauFlux;
212  }
213 
214  //apply compressive fluxes and MULES limiter
215  if (thermo.cAlpha() > SMALL)
216  {
217  surfaceScalarField phic(thermo.cAlpha()*mag(phi/mesh.magSf()));
218 
219  // Do not compress interface at non-coupled boundary faces
220  // (inlets, outlets etc.)
221  {
222  surfaceScalarField::Boundary& phicBf =
223  phic.boundaryFieldRef();
224 
225  forAll(phic.boundaryField(), patchi)
226  {
227  fvsPatchScalarField& phicp = phicBf[patchi];
228 
229  if (!phicp.coupled())
230  {
231  phicp == 0;
232  }
233  }
234  }
235  surfaceScalarField phir(phic*thermo.nHatf());
236 
237  phiAlpha1f +=
238  fvc::flux
239  (
240  -fvc::flux(-phir, alpha2, "div(phir,alphar)"),
241  alpha1,
242  "div(phir,alphar)"
243  );
244 
245  //limit flux with MULES limiter
246  MULES::limit
247  (
248  1.0 / runTime.deltaTValue(),
249  geometricOneField(),
250  alpha1,
251  phi,
252  phiAlpha1f,
253  zeroField(),
254  zeroField(),
255  oneField(),
256  zeroField(),
257  false //return total flux
258  );
259  }
260 
261  // --- Solve for volume fraction
262  {
263 
264  solve
265  (
266  fvm::ddt(alpha1)
267  + fvc::div(phiAlpha1f)
268  );
269  //
270  Info << "max/min alpha1: " << max(alpha1).value() << "/" << min(alpha1).value() << endl;
271  alpha1 = max(min(alpha1,1.0),0.0);
272  alpha2 = 1.0 - alpha1;
273  }
274 
275  // --- Update density field
276  rho = thermo.rho();
277 
278  // --- Update mass fluxes
279  {
281  rhoPhi = phiAlpha1f*rho1 + phiAlpha2f*rho2;
282 
283  phiRhofWf = phiu*(alpha1f*rho1*W1 + alpha2f*rho2*W2);
284  phiRhofWf.setOriented(true);
286  (
287  rhoPhi,
288  U,
289  Uf
290  )
291  -
292  phiRhofWf;
293  }
294 
295  // --- Solve U
296  if (implicitDiffusion)
297  {
298  solve
299  (
300  fvm::ddt(rho,U)
301  +
303  -
304  fvm::laplacian(muf,U)
305  -
306  fvc::div(muf*mesh.Sf() & qgdInterpolate(Foam::T(fvc::grad(U))))
307  -
308  BdFrc
309  //+
310  //(
311  // fvc::grad(p)
312  // -
313  // cFrc
314  //)*(1.0 + da1dt*(Tau1-Tau2))
315  +
316  (
317  fvc::reconstruct
318  (
319  fvc::snGrad(p)*mesh.magSf()
320  )
321  -
322  cFrc
323  )*(1.0 + da1dt*(Tau1-Tau2))
324  );
325  }
326  else
327  {
328  solve
329  (
330  fvm::ddt(rho,U)
331  +
333  +
334  fvc::grad(p)
335  *(1.0 + da1dt*(Tau1-Tau2))
336  -
337  fvc::laplacian(muf,U)
338  -
339  fvc::div(muf*mesh.Sf() & qgdInterpolate(Foam::T(fvc::grad(U))))
340  -
341  BdFrc
342  -
343  cFrc*(1.0 + da1dt*(Tau1-Tau2))
344  );
345  }
346 
347  runTime.write();
348 
349  Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
350  << " ClockTime = " << runTime.elapsedClockTime() << " s"
351  << nl << endl;
352 
353  }
354 
355  Info<< "End\n" << endl;
356 
357  return 0;
358 }
359 
360 
361 // ************************************************************************* //
surfaceScalarField phiAlpha1f("phiAlpha1f", phi *alpha1f)
surfaceScalarField phi1("phi1", mesh.Sf()&linearInterpolate(U))
tmp< GeometricField< T, Foam::fvsPatchField, Foam::surfaceMesh > > qgdFlux(const GeometricField< scalar, Foam::fvsPatchField, Foam::surfaceMesh > &flux, const GeometricField< T, Foam::fvPatchField, Foam::volMesh > &psi, const GeometricField< T, Foam::fvsPatchField, Foam::surfaceMesh > &psif, const word fluxName)
Calculates the mean and maximum wave speed based Courant Numbers.
surfaceScalarField phiw2("phiw2", phi *alpha1f)
Creates interpolation instances templated for QGD solver.
surfaceScalarField phiw1("phiw1", phi *alpha1f)
Creates the face fields: linear interpolation of fields from volumes to face centers.
muf
Definition: updateFields.H:38
int main(int argc, char *argv[])
volVectorField U(IOobject("U", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE), mesh)
Switch implicitDiffusion(thermo.implicitDiffusion())
surfaceVectorField phiRhofWf("phiUf", phi *Uf *rho1)
EEqn solve()
gradUf
Definition: updateFields.H:34
phiwo2
Definition: updateFluxes.H:43
surfaceScalarField phi2("phi2", mesh.Sf()&linearInterpolate(U))
phiwo1
Definition: updateFluxes.H:42
surfaceVectorField phiUfRhof("phiUf", phi *Uf *rho1)
tmp< GeometricField< T, Foam::fvsPatchField, Foam::surfaceMesh > > qgdInterpolate(const GeometricField< T, Foam::fvPatchField, Foam::volMesh > &psi)
Reset the timestep to maintain a constant maximum courant Number. Reduction of time-step is immediate...
surfaceScalarField phiwm("phiwm", phiwo1 *0.0)
surfaceVectorField gradpf("gradpf", fvsc::grad(p))
forAll(Y, i)
Definition: QGDYEqn.H:36
BdFrc
Definition: updateFields.H:35
Creates the face-flux fields.
tmp< surfaceScalarField > div(const volVectorField &vF)
rhoQGDThermo & thermo
Definition: createFields.H:47
surfaceScalarField rhoPhi("rhoPhi", rho1 *phi)
Updates fields.
surfaceScalarField alpha1f("alpha1f",)
Uf
Definition: updateFields.H:30
volScalarField rho(IOobject("rho", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), thermo.rho())
surfaceVectorField W1("Wf", linearInterpolate(U)*0.0)
phiu
——–Start———
Definition: updateFluxes.H:33
surfaceScalarField alpha2f("alpha2f", 1.0-alpha1f)
surfaceScalarField phiWr("phiWr", phiwo1 *0.0)
volScalarField & T
Definition: createFields.H:53
tmp< surfaceVectorField > grad(const volScalarField &vF)
fvScalarMatrix pEqn(fvc::div(phiu)-fvc::div(phiwo)-fvm::laplacian(taubyrhof, p))
surfaceVectorField W2("Wf", linearInterpolate(U)*0.0)
surfaceScalarField phiAlpha2f("phiAlpha2f", phi *alpha1f)
Updates fluxes for continuity equation.
surfaceScalarField coeffp("coeffp",)
volScalarField & p
Definition: createFields.H:52