eReactingFoam copy of plasmaReactingFoam
This commit is contained in:
commit
9949acea5e
17 changed files with 1386 additions and 0 deletions
7
Allwmake
Executable file
7
Allwmake
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # run from this directory
|
||||
set -x
|
||||
|
||||
wmake
|
||||
|
||||
# ----------------------------------------------------------------- end-of-file
|
||||
36
EEqn.H
Normal file
36
EEqn.H
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
volScalarField& he = thermo.he();
|
||||
|
||||
fvScalarMatrix EEqn
|
||||
(
|
||||
fvm::ddt(rho, he) + fvm::div(phi, he, "div(phi,Yi_h)")
|
||||
+ fvc::ddt(rho, K) + fvc::div(phi, K)
|
||||
+ (
|
||||
he.name() == "e"
|
||||
? fvc::div
|
||||
(
|
||||
fvc::absolute(phi/fvc::interpolate(rho), U),
|
||||
p,
|
||||
"div(phiv,p)"
|
||||
)
|
||||
: -dpdt
|
||||
)
|
||||
- fvm::laplacian(turbulence->alphaEff(), he)
|
||||
==
|
||||
reaction->Sh()
|
||||
+ fvOptions(rho, he)
|
||||
);
|
||||
|
||||
EEqn.relax();
|
||||
|
||||
fvOptions.constrain(EEqn);
|
||||
|
||||
EEqn.solve();
|
||||
|
||||
fvOptions.correct(he);
|
||||
|
||||
thermo.correct();
|
||||
|
||||
Info<< "min/max(T) = "
|
||||
<< min(T).value() << ", " << max(T).value() << endl;
|
||||
}
|
||||
3
Make/files
Normal file
3
Make/files
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
eReactingFoam.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/eReactingFoam
|
||||
27
Make/options
Normal file
27
Make/options
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/fvOptions/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
|
||||
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/chemistryModel/lnInclude \
|
||||
-I$(LIB_SRC)/ODE/lnInclude \
|
||||
-I$(LIB_SRC)/combustionModels/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lfvOptions \
|
||||
-lmeshTools \
|
||||
-lsampling \
|
||||
-lcompressibleTurbulenceModel \
|
||||
-lcompressibleRASModels \
|
||||
-lcompressibleLESModels \
|
||||
-lreactionThermophysicalModels \
|
||||
-lspecie \
|
||||
-lfluidThermophysicalModels \
|
||||
-lchemistryModel \
|
||||
-lODE \
|
||||
-lcombustionModels
|
||||
19
PhiEqn.H
Normal file
19
PhiEqn.H
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
rhoq = (rho * qc) - (eCharge * ne);
|
||||
|
||||
solve
|
||||
(
|
||||
fvm::laplacian(Phi)
|
||||
+ rhoq/epsilon0
|
||||
);
|
||||
|
||||
E = -fvc::grad(Phi);
|
||||
snE = -fvc::snGrad(Phi);
|
||||
|
||||
tmp<volScalarField> tMagE (mag(E));
|
||||
const volScalarField &magE = tMagE();
|
||||
|
||||
magE.writeMinMax(Info);
|
||||
|
||||
En = magE / (ng);
|
||||
}
|
||||
24
UEqn.H
Normal file
24
UEqn.H
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
fvVectorMatrix UEqn
|
||||
(
|
||||
fvm::ddt(rho, U)
|
||||
+ fvm::div(phi, U)
|
||||
+ turbulence->divDevRhoReff(U)
|
||||
==
|
||||
rho*g
|
||||
+ rhoq*E
|
||||
+ fvOptions(rho, U)
|
||||
);
|
||||
|
||||
UEqn.relax();
|
||||
|
||||
fvOptions.constrain(UEqn);
|
||||
|
||||
if (pimple.momentumPredictor())
|
||||
{
|
||||
solve(UEqn == -fvc::grad(p));
|
||||
|
||||
fvOptions.correct(U);
|
||||
K = 0.5*magSqr(U);
|
||||
}
|
||||
|
||||
q = linearInterpolate(U) & mesh.Sf();
|
||||
181
YEqn.H
Normal file
181
YEqn.H
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
tmp<fv::convectionScheme<scalar> > mvConvection
|
||||
(
|
||||
fv::convectionScheme<scalar>::New
|
||||
(
|
||||
mesh,
|
||||
fields,
|
||||
phi,
|
||||
mesh.divScheme("div(phi,Yi_h)")
|
||||
)
|
||||
);
|
||||
*/
|
||||
|
||||
{
|
||||
label inertIndex = -1;
|
||||
volScalarField Yt(0.0*Y[0]);
|
||||
|
||||
composition.calculateDiffusivities(p, T);
|
||||
|
||||
const surfaceScalarField &msf = mesh.magSf();
|
||||
const surfaceVectorField &sf = mesh.Sf();
|
||||
|
||||
forAll(ions, k) // ion-neutral pair
|
||||
{
|
||||
const word nIon(ions[k]);
|
||||
|
||||
const volScalarField& Di = composition.D(nIon);
|
||||
const scalar z(composition.z(composition.species()[nIon]));
|
||||
|
||||
// P_Reflex list for the ion
|
||||
const scalarList &rK = reflexes[k];
|
||||
|
||||
surfaceScalarField::GeometricBoundaryField&
|
||||
bfIonFlux = ionFluxBFs[k];
|
||||
bfIonFlux = phi.boundaryField();
|
||||
|
||||
// Adding drift flux to boundary patches
|
||||
forAll (bfIonFlux, pidx)
|
||||
{
|
||||
Info << "Adding drift flux to boundary patches" << pidx << endl;
|
||||
|
||||
bfIonFlux[pidx] +=
|
||||
snE.boundaryField()[pidx]
|
||||
* msf.boundaryField()[pidx]
|
||||
* rho.boundaryField()[pidx]
|
||||
* Di.boundaryField()[pidx]
|
||||
/ T.boundaryField()[pidx]
|
||||
* (eCharge*z/kB).value();
|
||||
}
|
||||
|
||||
const scalar WIon(composition.W(composition.species()[nIon]));
|
||||
const scalar MIon(WIon / NA.value() / 1000.0);
|
||||
|
||||
const volScalarField& Yion = composition.Y(nIon);
|
||||
|
||||
const hashedWordList &targets = targetList[k];
|
||||
|
||||
forAll (targets, tidx)
|
||||
{
|
||||
const word &nNeu(targets[tidx]);
|
||||
|
||||
surfaceScalarField::GeometricBoundaryField &
|
||||
bfNeuFlux = neutralFluxBFs[neutrals[nNeu]];
|
||||
bfNeuFlux = phi.boundaryField();
|
||||
|
||||
const scalar WNeu(composition.W(composition.species()[nNeu]));
|
||||
const scalar MNeu(WNeu / NA.value() / 1000.0);
|
||||
|
||||
const volScalarField& Yneu = composition.Y(nNeu);
|
||||
|
||||
forAll(wallPatcheIDs, pidx) // loop over wall patches
|
||||
{
|
||||
const label patchID = wallPatcheIDs[pidx];
|
||||
|
||||
// Probability of ion reflex
|
||||
const scalar pReflex = max(min(rK[pidx],1.0),0.0);
|
||||
|
||||
scalarField &wallFluxIon = bfIonFlux[patchID];
|
||||
|
||||
const scalarField &wallMSf = msf.boundaryField()[patchID];
|
||||
const scalarField &wallT = T.boundaryField()[patchID];
|
||||
const scalarField &wallYion = Yion.boundaryField()[patchID];
|
||||
|
||||
const scalarField vt(sqrt(8.0*kB.value()/pi/MIon*wallT) / 4.0);
|
||||
|
||||
// remove negative wallFlux value (flux from wall)
|
||||
wallFluxIon = max(wallFluxIon, 0.0);
|
||||
|
||||
// add flux by thermal velocity
|
||||
wallFluxIon += vt * wallMSf;
|
||||
wallFluxIon *= (1.0 - pReflex);
|
||||
|
||||
// add flux by ion neutralization
|
||||
scalarField &wallFluxNeu = bfNeuFlux[patchID];
|
||||
|
||||
const scalarField &wallYneu = Yneu.boundaryField()[patchID];
|
||||
|
||||
wallFluxNeu -= wallFluxIon * wallYion / wallYneu
|
||||
/ (WIon / WNeu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forAll(Y, i)
|
||||
{
|
||||
volScalarField& Yi = Y[i];
|
||||
|
||||
const volScalarField& Di = D[i];
|
||||
|
||||
if (Y[i].name() == electronSpecie)
|
||||
{
|
||||
}
|
||||
else if (Y[i].name() != inertSpecie)
|
||||
{
|
||||
const scalar z(composition.z(i));
|
||||
const label nCharge(z);
|
||||
|
||||
if (nCharge != 0)
|
||||
{
|
||||
phis[i] = phi;
|
||||
phis[i] += fvc::interpolate((rho*Di/T*(eCharge*z/kB))*E) & mesh.Sf();
|
||||
|
||||
if (relaxDrift < 1.0 && relaxDrift > 0.0)
|
||||
{
|
||||
phis[i] *= relaxDrift;
|
||||
}
|
||||
}
|
||||
|
||||
if (ions.contains(Y[i].name()))
|
||||
{
|
||||
const label ibc = ions[Y[i].name()];
|
||||
// phis[i] updated
|
||||
phis[i].boundaryField() = ionFluxBFs[ibc];
|
||||
}
|
||||
else if (neutrals.contains(Y[i].name()))
|
||||
{
|
||||
const label ibc = neutrals[Y[i].name()];
|
||||
// update phis[i]
|
||||
phis[i].internalField() = phi.internalField();
|
||||
phis[i].boundaryField() = neutralFluxBFs[ibc];
|
||||
}
|
||||
|
||||
|
||||
fvScalarMatrix YiEqn
|
||||
(
|
||||
fvm::ddt(rho, Yi)
|
||||
+
|
||||
( nCharge != 0
|
||||
? fvm::div(phis[i], Yi, "div(phi,Yi_h)")
|
||||
: ( neutrals.contains(Y[i].name())
|
||||
? fvm::div(phis[i], Yi, "div(phi,Yi_h)")
|
||||
: fvm::div(phi, Yi, "div(phi,Yi_h)")
|
||||
)
|
||||
)
|
||||
// - fvm::laplacian(turbulence->muEff(), Yi)
|
||||
- fvm::laplacian(rho*Di, Yi)
|
||||
==
|
||||
reaction->R(Yi)
|
||||
+ fvOptions(rho, Yi)
|
||||
);
|
||||
|
||||
YiEqn.relax();
|
||||
|
||||
fvOptions.constrain(YiEqn);
|
||||
|
||||
YiEqn.solve(mesh.solver("Yi"));
|
||||
|
||||
fvOptions.correct(Yi);
|
||||
|
||||
Yi.max(0.0);
|
||||
Yt += Yi;
|
||||
}
|
||||
else
|
||||
{
|
||||
inertIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
Y[inertIndex] = scalar(1) - Yt;
|
||||
Y[inertIndex].max(0.0);
|
||||
}
|
||||
548
createFields.H
Normal file
548
createFields.H
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
Info<< "Reading physicalProperties\n" << endl;
|
||||
|
||||
IOdictionary physicalProperties
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"physicalProperties",
|
||||
runTime.constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
scalar relaxDrift
|
||||
(
|
||||
physicalProperties.lookupOrDefault("relaxDrift", 1.0)
|
||||
);
|
||||
|
||||
dimensionedScalar epsilon0
|
||||
(
|
||||
physicalProperties.lookup("epsilon0")
|
||||
);
|
||||
|
||||
Switch mobility_f_of_Te = physicalProperties.lookupOrDefault("mobility_f_of_Te", false);
|
||||
|
||||
Switch calculateDe = physicalProperties.lookupOrDefault("calculateDe", false);
|
||||
|
||||
// Convert E/n in SI unit to table unit.
|
||||
// Default V m^2 => Td
|
||||
scalar TeToTableUnit (
|
||||
physicalProperties.lookupOrDefault("TeToTableUnit", 1.0)
|
||||
);
|
||||
|
||||
// Convert E/n in SI unit to table unit.
|
||||
// Default V m^2 => Td
|
||||
scalar EnToTableUnit (
|
||||
physicalProperties.lookupOrDefault("EnToTableUnit", 1.0e21)
|
||||
);
|
||||
|
||||
|
||||
autoPtr< DataEntry< scalar > > pmueN (
|
||||
DataEntry<scalar>::New("mueN", physicalProperties));
|
||||
const DataEntry<scalar> &mueN(pmueN());
|
||||
|
||||
// Convert mu_e * n_g value from table into SI unit.
|
||||
scalar mueNFac (
|
||||
physicalProperties.lookupOrDefault("mueNFac", 1.0)
|
||||
);
|
||||
|
||||
|
||||
autoPtr< DataEntry< scalar > > pDeN (
|
||||
DataEntry<scalar>::New("DeN", physicalProperties));
|
||||
const DataEntry<scalar> &DeN(pDeN());
|
||||
|
||||
// Convert D_e * n_g value from table into SI unit.
|
||||
scalar DeNFac (
|
||||
physicalProperties.lookupOrDefault("DeNFac", 1.0)
|
||||
);
|
||||
|
||||
|
||||
autoPtr< DataEntry< scalar > > pTeOfEn(
|
||||
DataEntry<scalar>::New ("TeOfEn", physicalProperties));
|
||||
const DataEntry<scalar> &TeOfEn(pTeOfEn());
|
||||
|
||||
// Convert T_e value from table into SI unit.
|
||||
scalar TeFac (
|
||||
physicalProperties.lookupOrDefault("TeFac", 1.0)
|
||||
);
|
||||
|
||||
|
||||
Info<< "Reading field Phi\n" << endl;
|
||||
volScalarField Phi
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"Phi",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
Info<< "Creating field electric field\n" << endl;
|
||||
volVectorField E
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"E",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
-fvc::grad(Phi)
|
||||
);
|
||||
|
||||
surfaceScalarField snE
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"snE",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
-fvc::snGrad(Phi)
|
||||
);
|
||||
|
||||
|
||||
Info<< "Creating reaction model\n" << endl;
|
||||
|
||||
autoPtr<combustionModels::psiCombustionModel> reaction
|
||||
(
|
||||
combustionModels::psiCombustionModel::New(mesh)
|
||||
);
|
||||
|
||||
psiReactionThermo& thermo = reaction->thermo();
|
||||
thermo.validate(args.executable(), "h", "e");
|
||||
|
||||
volScalarField& qc = thermo.qc();
|
||||
basicMultiComponentMixture& composition = thermo.composition();
|
||||
|
||||
//- Electron mass (default in [kg])
|
||||
const dimensionedScalar eMass = constant::atomic::me;
|
||||
|
||||
//- Elementary charge (default in [C])
|
||||
const dimensionedScalar eCharge = constant::electromagnetic::e;
|
||||
|
||||
//- Avogadro number (default in [1/mol])
|
||||
const dimensionedScalar NA = constant::physicoChemical::NA;
|
||||
|
||||
//- Universal gas constant (default in [J/mol/K])
|
||||
const dimensionedScalar R = constant::physicoChemical::R;
|
||||
|
||||
//- Boltzmann constant
|
||||
const dimensionedScalar kB = constant::physicoChemical::k;
|
||||
|
||||
//- Pi
|
||||
const scalar pi = constant::mathematical::pi;
|
||||
|
||||
PtrList<volScalarField>& Y = composition.Y();
|
||||
const PtrList<volScalarField>& D = composition.D();
|
||||
|
||||
word inertSpecie(thermo.lookup("inertSpecie"));
|
||||
word electronSpecie("E-");
|
||||
|
||||
volScalarField rho
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"rho",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
thermo.rho()
|
||||
);
|
||||
|
||||
Info<< "Reading field U\n" << endl;
|
||||
volVectorField U
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"U",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
|
||||
volScalarField& p = thermo.p();
|
||||
const volScalarField& psi = thermo.psi();
|
||||
const volScalarField& T = thermo.T();
|
||||
|
||||
#include "compressibleCreatePhi.H"
|
||||
|
||||
surfaceScalarField q
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"q",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
linearInterpolate(U) & mesh.Sf()
|
||||
);
|
||||
|
||||
Info << "Creating turbulence model.\n" << nl;
|
||||
autoPtr<compressible::turbulenceModel> turbulence
|
||||
(
|
||||
compressible::turbulenceModel::New
|
||||
(
|
||||
rho,
|
||||
U,
|
||||
phi,
|
||||
thermo
|
||||
)
|
||||
);
|
||||
|
||||
// Set the turbulence into the reaction model
|
||||
reaction->setTurbulence(turbulence());
|
||||
|
||||
|
||||
Info<< "Creating field dpdt\n" << endl;
|
||||
volScalarField dpdt
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dpdt",
|
||||
runTime.timeName(),
|
||||
mesh
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("dpdt", p.dimensions()/dimTime, 0)
|
||||
);
|
||||
|
||||
Info<< "Creating field kinetic energy K\n" << endl;
|
||||
volScalarField K("K", 0.5*magSqr(U));
|
||||
|
||||
|
||||
multivariateSurfaceInterpolationScheme<scalar>::fieldTable fields;
|
||||
|
||||
forAll(Y, i)
|
||||
{
|
||||
fields.add(Y[i]);
|
||||
}
|
||||
fields.add(thermo.he());
|
||||
|
||||
volScalarField dQ
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dQ",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("dQ", dimEnergy/dimTime, 0.0)
|
||||
);
|
||||
|
||||
Info<< "Creating field electron number density\n" << endl;
|
||||
volScalarField ne
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"ne",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
|
||||
Info<< "Creating field charge density\n" << endl;
|
||||
volScalarField rhoq
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"rhoq",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
// (rho * qc) - (eCharge * ne)
|
||||
);
|
||||
|
||||
Info<< "Creating field gas number density\n" << endl;
|
||||
volScalarField ng("ng", p / R / T * NA);
|
||||
|
||||
Info<< "Creating field reduced electric field\n" << endl;
|
||||
volScalarField En ("En", mag(E) / (ng));
|
||||
scalarField EnTd(En.internalField() * EnToTableUnit);
|
||||
|
||||
Info<< "Creating field electron mobility\n" << endl;
|
||||
volScalarField mue
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"mue",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
Info<< "Creating field electron diffusivity\n" << endl;
|
||||
volScalarField De
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"De",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
Info<< "Creating field electron temperature\n" << endl;
|
||||
volScalarField Te
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"Te",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
BE_IX::Bolos bolos;
|
||||
|
||||
bolos.readCollisions("./LXCat-June2013.txt");
|
||||
|
||||
bolos.presolve();
|
||||
{
|
||||
bolos.maxwellian(2);
|
||||
forAll(rho, celli)
|
||||
{
|
||||
De[celli] = bolos.diffusivity();
|
||||
mue[celli] = bolos.mobility();
|
||||
}
|
||||
De.correctBoundaryConditions();
|
||||
mue.correctBoundaryConditions();
|
||||
}
|
||||
*/
|
||||
|
||||
Info<< "Calculating face flux field ve\n" << endl;
|
||||
volVectorField Udrift
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"Udrift",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
- (mue*E/ng)
|
||||
);
|
||||
|
||||
volVectorField Uthermal
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"Uthermal",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
- ((De/ng/Te)*fvc::grad(Te))
|
||||
);
|
||||
|
||||
surfaceScalarField ve
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"ve",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
linearInterpolate(Udrift+Uthermal) & mesh.Sf()
|
||||
);
|
||||
|
||||
|
||||
surfaceScalarField phi_drift
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"phi_drift",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
phi
|
||||
);
|
||||
|
||||
|
||||
surfaceScalarField phi_neutral
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"phi_neutral",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
phi
|
||||
);
|
||||
|
||||
|
||||
PtrList<surfaceScalarField> phis (composition.species().size());
|
||||
|
||||
forAll (composition.species(), isp)
|
||||
{
|
||||
const scalar z(composition.z(isp));
|
||||
const label nCharge(z);
|
||||
|
||||
if (nCharge != 0)
|
||||
{
|
||||
phis.set(isp,
|
||||
new surfaceScalarField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"phi." + composition.species()[isp],
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
phi
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// plasmaWallFluxes
|
||||
Info<< "Reading plasma wall flux bc control\n" << endl;
|
||||
|
||||
// electron wall flux
|
||||
dictionary wallElectronFlux
|
||||
(
|
||||
physicalProperties.subDict("wallElectronFlux")
|
||||
);
|
||||
|
||||
word TeName(wallElectronFlux.lookup("TeName"));
|
||||
|
||||
wordList wallPatcheNames (wallElectronFlux.lookup("wallPatches"));
|
||||
labelList wallPatcheIDs (wallPatcheNames.size(), 0);
|
||||
scalarList wallReflexes (wallElectronFlux.lookup("wallReflexes"));
|
||||
|
||||
forAll (wallPatcheNames, pi)
|
||||
{
|
||||
const word patchName = wallPatcheNames[pi];
|
||||
wallPatcheIDs[pi]
|
||||
= mesh.boundaryMesh().findPatchID(patchName);
|
||||
}
|
||||
|
||||
Info<< "plasma walls are \n" << wallPatcheNames << endl;
|
||||
|
||||
// ion wall flux
|
||||
|
||||
dictionary wallIonFluxes
|
||||
(
|
||||
physicalProperties.subDict("wallIonFluxes")
|
||||
);
|
||||
|
||||
const label nMaxTargets = 5;
|
||||
const hashedWordList ions(wordList(wallIonFluxes.lookup("ions")));
|
||||
wordList neutrals_ (ions.size()*nMaxTargets);
|
||||
PtrList<hashedWordList> targetList (ions.size());
|
||||
PtrList<scalarList> reflexes (ions.size());
|
||||
PtrList<surfaceScalarField::GeometricBoundaryField> ionFluxBFs (ions.size());
|
||||
|
||||
Info<< ions.size() << " ions are \n" << ions << endl;
|
||||
|
||||
label nTargets = 0;
|
||||
|
||||
forAll (ions, iidx)
|
||||
{
|
||||
const dictionary &wallIonFlux = wallIonFluxes.subDict(ions[iidx]);
|
||||
|
||||
const Switch noTarget (wallIonFlux.lookupOrDefault("noTarget", false));
|
||||
|
||||
const wordList targets (wallIonFlux.lookupOrDefault("neutrals", wordList()));
|
||||
|
||||
if (noTarget)
|
||||
{
|
||||
targetList.set(iidx, new hashedWordList());
|
||||
}
|
||||
else if (targets.empty())
|
||||
{
|
||||
word neutralName(wallIonFlux.lookup("neutral"));
|
||||
neutrals_[nTargets] = neutralName;
|
||||
nTargets += 1;
|
||||
|
||||
targetList.set(iidx, new hashedWordList(wordList(1, neutralName)));
|
||||
}
|
||||
else
|
||||
{
|
||||
wordList::subList sub (neutrals_, targets.size(), nTargets);
|
||||
forAll (targets, tidx)
|
||||
{
|
||||
sub[tidx] = targets[tidx];
|
||||
}
|
||||
nTargets += targets.size();;
|
||||
|
||||
targetList.set(iidx, new hashedWordList(targets));
|
||||
}
|
||||
|
||||
reflexes.set(iidx, new scalarList(wallIonFlux.lookup("wallReflexes")));
|
||||
|
||||
ionFluxBFs.set(iidx,
|
||||
new surfaceScalarField::GeometricBoundaryField(phi.boundaryField()));
|
||||
}
|
||||
|
||||
hashedWordList neutrals;
|
||||
|
||||
label nNeutrals = 0;
|
||||
|
||||
for (label nidx = 0; nidx < nTargets; nidx++)
|
||||
{
|
||||
const word n(neutrals_[nidx]);
|
||||
|
||||
if (!neutrals.contains(n))
|
||||
{
|
||||
neutrals.append(n);
|
||||
nNeutrals += 1;
|
||||
}
|
||||
}
|
||||
|
||||
PtrList<surfaceScalarField::GeometricBoundaryField> neutralFluxBFs (neutrals.size());
|
||||
|
||||
forAll (neutrals, iidx)
|
||||
{
|
||||
neutralFluxBFs.set(iidx,
|
||||
new surfaceScalarField::GeometricBoundaryField (phi.boundaryField()));
|
||||
}
|
||||
120
eReactingFoam.C
Normal file
120
eReactingFoam.C
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
reactingFoam
|
||||
|
||||
Description
|
||||
Solver for combustion with chemical reactions.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "subCycle.H"
|
||||
#include "turbulenceModel.H"
|
||||
#include "psiCombustionModel.H"
|
||||
#include "multivariateScheme.H"
|
||||
#include "pimpleControl.H"
|
||||
#include "fvIOoptionList.H"
|
||||
|
||||
#include "CSV.H"
|
||||
|
||||
// #include "bolos.h"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
#include "readGravitationalAcceleration.H"
|
||||
#include "createFields.H"
|
||||
#include "createFvOptions.H"
|
||||
#include "initContinuityErrs.H"
|
||||
#include "readTimeControls.H"
|
||||
#include "compressibleCourantNo.H"
|
||||
#include "setInitialDeltaT.H"
|
||||
|
||||
pimpleControl pimple(mesh);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
while (runTime.run())
|
||||
{
|
||||
#include "readTimeControls.H"
|
||||
#include "compressibleCourantNo.H"
|
||||
#include "electronCourantNo.H"
|
||||
#include "setDeltaT.H"
|
||||
|
||||
runTime++;
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
|
||||
#include "rhoEqn.H"
|
||||
|
||||
while (pimple.loop())
|
||||
{
|
||||
#include "numberDensity.H"
|
||||
#include "PhiEqn.H"
|
||||
|
||||
#include "UEqn.H"
|
||||
|
||||
reaction->correct();
|
||||
dQ = reaction->dQ();
|
||||
|
||||
#include "neControls.H"
|
||||
#include "neEqnSubCycle.H"
|
||||
// #include "neEqn.H"
|
||||
|
||||
#include "YEqn.H"
|
||||
#include "EEqn.H"
|
||||
|
||||
// --- Pressure corrector loop
|
||||
while (pimple.correct())
|
||||
{
|
||||
#include "pEqn.H"
|
||||
}
|
||||
|
||||
if (pimple.turbCorr())
|
||||
{
|
||||
turbulence->correct();
|
||||
}
|
||||
}
|
||||
|
||||
runTime.write();
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
51
electronCourantNo.H
Normal file
51
electronCourantNo.H
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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/>.
|
||||
|
||||
Global
|
||||
CourantNo
|
||||
|
||||
Description
|
||||
Calculates and outputs the mean and maximum Courant Numbers from electron flux.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
scalar CoNumVe = 0.0;
|
||||
scalar meanCoNumVe = 0.0;
|
||||
|
||||
if (mesh.nInternalFaces())
|
||||
{
|
||||
scalarField sumPhi
|
||||
(
|
||||
fvc::surfaceSum(mag(ve))().internalField()
|
||||
);
|
||||
|
||||
CoNumVe = 0.5*gMax(sumPhi/mesh.V().field())*runTime.deltaTValue();
|
||||
|
||||
meanCoNumVe =
|
||||
0.5*(gSum(sumPhi)/gSum(mesh.V().field()))*runTime.deltaTValue();
|
||||
}
|
||||
|
||||
Info<< "Electron Courant Number mean: " << meanCoNumVe
|
||||
<< " max: " << CoNumVe << endl;
|
||||
|
||||
// ************************************************************************* //
|
||||
4
neControls.H
Normal file
4
neControls.H
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
const dictionary& neControls = mesh.solverDict(ne.name());
|
||||
|
||||
label nNeSubCycles(readLabel(neControls.lookup("nNeSubCycles")));
|
||||
|
||||
96
neEqn.H
Normal file
96
neEqn.H
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
// Electron swarm parameter
|
||||
|
||||
EnTd = En.internalField();
|
||||
EnTd *= EnToTableUnit;
|
||||
|
||||
Te.internalField() = TeOfEn.value(EnTd) * TeFac;
|
||||
forAll(rho, celli)
|
||||
{
|
||||
Te[celli] = max(Te[celli], T[celli]);
|
||||
}
|
||||
Te.correctBoundaryConditions();
|
||||
|
||||
if (mobility_f_of_Te)
|
||||
{
|
||||
EnTd = Te.internalField();
|
||||
EnTd *= TeToTableUnit;
|
||||
}
|
||||
|
||||
mue.internalField() = mueN.value(EnTd) * mueNFac;
|
||||
|
||||
if (calculateDe)
|
||||
{
|
||||
De = mue * Te * (kB / eCharge);
|
||||
}
|
||||
else
|
||||
{
|
||||
De.internalField() = DeN.value(EnTd) * DeNFac;
|
||||
}
|
||||
|
||||
mue.correctBoundaryConditions();
|
||||
De.correctBoundaryConditions();
|
||||
|
||||
|
||||
Udrift = -(mue/ng)*E;
|
||||
if (relaxDrift < 1.0 && relaxDrift > 0.0)
|
||||
{
|
||||
Udrift *= relaxDrift;
|
||||
}
|
||||
Uthermal = -((De/ng/Te)*fvc::grad(Te));
|
||||
ve = (linearInterpolate(Udrift+Uthermal) & mesh.Sf()) + q;
|
||||
|
||||
const surfaceScalarField &msf = mesh.magSf();
|
||||
|
||||
// Wall electron flux correction
|
||||
forAll (wallPatcheIDs, pidx)
|
||||
{
|
||||
label patchID = wallPatcheIDs[pidx];
|
||||
// Probability of electron reflex
|
||||
scalar pReflex = wallReflexes[pidx];
|
||||
pReflex = max(min(pReflex,1.0),0.0);
|
||||
|
||||
fvsPatchScalarField &wallFlux = ve.boundaryField()[patchID];
|
||||
const fvsPatchScalarField &wallMSf = msf.boundaryField()[patchID];
|
||||
const fvPatchScalarField &wallTe = Te.boundaryField()[patchID];
|
||||
|
||||
scalarField vt(sqrt(8.0*kB.value()/pi/eMass.value()*wallTe) / 4.0);
|
||||
|
||||
// remove negative wallFlux value (flux from wall)
|
||||
wallFlux = max(wallFlux, 0.0);
|
||||
|
||||
// add flux by thermal velocity
|
||||
wallFlux += vt * wallMSf;
|
||||
wallFlux *= (1.0-pReflex);
|
||||
}
|
||||
|
||||
|
||||
volScalarField& Yi = composition.Y(electronSpecie);
|
||||
|
||||
tmp<fvScalarMatrix> electronR(
|
||||
new fvScalarMatrix(ne, ne.dimensions()*dimVol/dimTime)
|
||||
);
|
||||
electronR->source() = reaction->R(Yi)->source();
|
||||
|
||||
fvScalarMatrix neEqn
|
||||
(
|
||||
fvm::ddt(ne)
|
||||
+ fvm::div(ve, ne)
|
||||
- fvm::laplacian(De/ng, ne)
|
||||
==
|
||||
electronR
|
||||
+ fvOptions(ne)
|
||||
);
|
||||
|
||||
neEqn.relax();
|
||||
|
||||
fvOptions.constrain(neEqn);
|
||||
|
||||
neEqn.solve(mesh.solver("ne"));
|
||||
|
||||
fvOptions.correct(ne);
|
||||
|
||||
ne.writeMinMax(Info);
|
||||
|
||||
ne.max(0.0);
|
||||
}
|
||||
22
neEqnSubCycle.H
Normal file
22
neEqnSubCycle.H
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
if (nNeSubCycles > 1)
|
||||
{
|
||||
dimensionedScalar totalDeltaT = runTime.deltaT();
|
||||
|
||||
for
|
||||
(
|
||||
subCycle<volScalarField> neSubCycle(ne, nNeSubCycles);
|
||||
!(++neSubCycle).end();
|
||||
)
|
||||
{
|
||||
#include "neEqn.H"
|
||||
#include "PhiEqn.H"
|
||||
// rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi;
|
||||
}
|
||||
|
||||
// rhoPhi = rhoPhiSum;
|
||||
}
|
||||
else
|
||||
{
|
||||
#include "neEqn.H"
|
||||
#include "PhiEqn.H"
|
||||
}
|
||||
3
numberDensity.H
Normal file
3
numberDensity.H
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
ng = p / T * (NA / R);
|
||||
}
|
||||
90
pEqn.H
Normal file
90
pEqn.H
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
rho = thermo.rho();
|
||||
|
||||
volScalarField rAU(1.0/UEqn.A());
|
||||
surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho*rAU));
|
||||
|
||||
volVectorField HbyA("HbyA", U);
|
||||
HbyA = rAU*UEqn.H();
|
||||
|
||||
if (pimple.transonic())
|
||||
{
|
||||
surfaceScalarField phid
|
||||
(
|
||||
"phid",
|
||||
fvc::interpolate(psi)
|
||||
*(
|
||||
(fvc::interpolate(rho*HbyA) & mesh.Sf())
|
||||
+ rhorAUf*fvc::ddtCorr(rho, U, phi)
|
||||
)/fvc::interpolate(rho)
|
||||
);
|
||||
|
||||
fvOptions.makeRelative(fvc::interpolate(psi), phid);
|
||||
|
||||
while (pimple.correctNonOrthogonal())
|
||||
{
|
||||
fvScalarMatrix pEqn
|
||||
(
|
||||
fvm::ddt(psi, p)
|
||||
+ fvm::div(phid, p)
|
||||
- fvm::laplacian(rho*rAU, p)
|
||||
==
|
||||
fvOptions(psi, p, rho.name())
|
||||
);
|
||||
|
||||
fvOptions.constrain(pEqn);
|
||||
|
||||
pEqn.solve(mesh.solver(p.select(pimple.finalInnerIter())));
|
||||
|
||||
if (pimple.finalNonOrthogonalIter())
|
||||
{
|
||||
phi == pEqn.flux();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
surfaceScalarField phiHbyA
|
||||
(
|
||||
"phiHbyA",
|
||||
(
|
||||
(fvc::interpolate(rho*HbyA) & mesh.Sf())
|
||||
+ rhorAUf*fvc::ddtCorr(rho, U, phi)
|
||||
)
|
||||
);
|
||||
|
||||
fvOptions.makeRelative(fvc::interpolate(rho), phiHbyA);
|
||||
|
||||
while (pimple.correctNonOrthogonal())
|
||||
{
|
||||
fvScalarMatrix pEqn
|
||||
(
|
||||
fvm::ddt(psi, p)
|
||||
+ fvc::div(phiHbyA)
|
||||
- fvm::laplacian(rho*rAU, p)
|
||||
==
|
||||
fvOptions(psi, p, rho.name())
|
||||
);
|
||||
|
||||
fvOptions.constrain(pEqn);
|
||||
|
||||
pEqn.solve(mesh.solver(p.select(pimple.finalInnerIter())));
|
||||
|
||||
if (pimple.finalNonOrthogonalIter())
|
||||
{
|
||||
phi = phiHbyA + pEqn.flux();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "rhoEqn.H"
|
||||
#include "compressibleContinuityErrs.H"
|
||||
|
||||
U = HbyA - rAU*fvc::grad(p);
|
||||
U.correctBoundaryConditions();
|
||||
fvOptions.correct(U);
|
||||
K = 0.5*magSqr(U);
|
||||
|
||||
if (thermo.dpdt())
|
||||
{
|
||||
dpdt = fvc::ddt(p);
|
||||
}
|
||||
70
readTimeControls.H
Normal file
70
readTimeControls.H
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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/>.
|
||||
|
||||
Global
|
||||
readTimeControls
|
||||
|
||||
Description
|
||||
Read the control parameters used by setDeltaT
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
const bool adjustTimeStep =
|
||||
runTime.controlDict().lookupOrDefault("adjustTimeStep", false);
|
||||
|
||||
scalar maxCo =
|
||||
runTime.controlDict().lookupOrDefault<scalar>("maxCo", 1.0);
|
||||
|
||||
scalar maxDeltaT =
|
||||
runTime.controlDict().lookupOrDefault<scalar>("maxDeltaT", GREAT);
|
||||
|
||||
|
||||
|
||||
|
||||
const dictionary pulseTimeStepDict = runTime.controlDict().subOrEmptyDict("pulseTimeStep");
|
||||
|
||||
const bool pulseTimeStep = !pulseTimeStepDict.empty();
|
||||
|
||||
const scalar pulseFrequency = // default 20 kHz
|
||||
pulseTimeStepDict.lookupOrDefault<scalar>("pulseFrequency", 20e3);
|
||||
|
||||
const scalar pulseDuration = // default 12 ns
|
||||
pulseTimeStepDict.lookupOrDefault<scalar>("pulseDuration", 12e-9);
|
||||
|
||||
const label nStepPulse = // default 1
|
||||
ceil(pulseTimeStepDict.lookupOrDefault<scalar>("nStepPulse", 1));
|
||||
|
||||
const label nStepIdle = // default 1
|
||||
ceil(pulseTimeStepDict.lookupOrDefault<scalar>("nStepIdle", 1));
|
||||
|
||||
const scalar pulsePeriod = 1 / pulseFrequency;
|
||||
const scalar pulseTime = 2*pulseDuration;
|
||||
const scalar idleTime = pulsePeriod - pulseTime;
|
||||
|
||||
const scalar deltaTpulse = pulseTime / nStepPulse;
|
||||
const scalar deltaTidle = idleTime / nStepIdle;
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
85
setDeltaT.H
Normal file
85
setDeltaT.H
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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/>.
|
||||
|
||||
Global
|
||||
setDeltaT
|
||||
|
||||
Description
|
||||
Reset the timestep to maintain a constant maximum courant Number.
|
||||
Reduction of time-step is immediate, but increase is damped to avoid
|
||||
unstable oscillations.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
if (pulseTimeStep)
|
||||
{
|
||||
const scalar t = runTime.timeOutputValue();
|
||||
const scalar T = pulsePeriod;
|
||||
const scalar neg_saw_t = (t - floor(t/T+1.)*T);
|
||||
|
||||
const bool inPulse = neg_saw_t >= -pulseTime;
|
||||
|
||||
if (inPulse)
|
||||
{
|
||||
runTime.setDeltaT (deltaTpulse);
|
||||
Info<< "deltaT to proceed the pulse time " << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
const scalar eta = - pulseTime - neg_saw_t;
|
||||
|
||||
if (eta >= deltaTidle)
|
||||
{
|
||||
runTime.setDeltaT (deltaTidle);
|
||||
Info<< "deltaT to proceed the idle time " << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
runTime.setDeltaT (deltaTpulse);
|
||||
Info<< "deltaT to the start of the pulse " << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Info<< "deltaT = " << runTime.deltaTValue() << endl;
|
||||
}
|
||||
else if (adjustTimeStep)
|
||||
{
|
||||
CoNum = max(CoNum, CoNumVe);
|
||||
scalar maxDeltaTFact = maxCo/(CoNum + SMALL);
|
||||
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
|
||||
|
||||
runTime.setDeltaT
|
||||
(
|
||||
min
|
||||
(
|
||||
deltaTFact*runTime.deltaTValue(),
|
||||
maxDeltaT
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "deltaT = " << runTime.deltaTValue() << endl;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
Loading…
Add table
Reference in a new issue