How to address a certain region in solver?
Hello,
say I create a simple mesh with blockMesh. Then I use topoSet and splitMeshRegions to create two regions Reg1 and Reg2. Now, I would like to calculate a certain parameter, but differently for each region. Is there a way to "tell" the solver that for region Reg1 he should use a certain equation and for region Reg2 he should use a different one?
I know that multiple regions are used in chtMultiRegionFoam tutorial. The solver handles it in a very sophisticated way:
Code:
forAll(fluidRegions, i)
{ ...
I have tried to understand this tutorial and to use something similar in my case but sadly, I have not been successful. I do not have C++ language knowledge, but it is my impression that this case is connected to the heat transfer case very strongly. I have not been able to understand, how exactly should I create fields. The solver does it via #include "createFields.H", which includes the creation of fluid and solid fields.
The createFluidFields.H file looks like this:
Code:
// Initialise fluid field pointer lists
PtrList<rhoThermo> thermoFluid(fluidRegions.size());
PtrList<volScalarField> rhoFluid(fluidRegions.size());
PtrList<volVectorField> UFluid(fluidRegions.size());
PtrList<surfaceScalarField> phiFluid(fluidRegions.size());
PtrList<uniformDimensionedVectorField> gFluid(fluidRegions.size());
PtrList<uniformDimensionedScalarField> hRefFluid(fluidRegions.size());
PtrList<volScalarField> ghFluid(fluidRegions.size());
PtrList<surfaceScalarField> ghfFluid(fluidRegions.size());
PtrList<compressible::turbulenceModel> turbulence(fluidRegions.size());
PtrList<volScalarField> p_rghFluid(fluidRegions.size());
PtrList<radiation::radiationModel> radiation(fluidRegions.size());
List<scalar> initialMassFluid(fluidRegions.size());
List<label> pRefCellFluid(fluidRegions.size(), 0);
List<scalar> pRefValueFluid(fluidRegions.size(), 0.0);
List<bool> frozenFlowFluid(fluidRegions.size(), false);
PtrList<dimensionedScalar> rhoMax(fluidRegions.size());
PtrList<dimensionedScalar> rhoMin(fluidRegions.size());
PtrList<IOMRFZoneList> MRFfluid(fluidRegions.size());
PtrList<fv::options> fluidFvOptions(fluidRegions.size());
// Populate fluid field pointer lists
forAll(fluidRegions, i)
{
Info<< "*** Reading fluid mesh thermophysical properties for region "
<< fluidRegions[i].name() << nl << endl;
Info<< " Adding to thermoFluid\n" << endl;
thermoFluid.set
(
i,
rhoThermo::New(fluidRegions[i]).ptr()
);
Info<< " Adding to rhoFluid\n" << endl;
rhoFluid.set
(
i,
new volScalarField
(
IOobject
(
"rho",
runTime.timeName(),
fluidRegions[i],
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
thermoFluid[i].rho()
)
);
Info<< " Adding to UFluid\n" << endl;
UFluid.set
(
i,
new volVectorField
(
IOobject
(
"U",
runTime.timeName(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluidRegions[i]
)
);
Info<< " Adding to phiFluid\n" << endl;
phiFluid.set
(
i,
new surfaceScalarField
(
IOobject
(
"phi",
runTime.timeName(),
fluidRegions[i],
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
linearInterpolate(rhoFluid[i]*UFluid[i])
& fluidRegions[i].Sf()
)
);
Info<< " Adding to gFluid\n" << endl;
gFluid.set
(
i,
new uniformDimensionedVectorField
(
IOobject
(
"g",
runTime.constant(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
Info<< " Adding to hRefFluid\n" << endl;
hRefFluid.set
(
i,
new uniformDimensionedScalarField
(
IOobject
(
"hRef",
runTime.constant(),
fluidRegions[i],
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
dimensionedScalar("hRef", dimLength, 0)
)
);
dimensionedScalar ghRef
(
mag(gFluid[i].value()) > SMALL
? gFluid[i]
& (cmptMag(gFluid[i].value())/mag(gFluid[i].value()))*hRefFluid[i]
: dimensionedScalar("ghRef", gFluid[i].dimensions()*dimLength, 0)
);
Info<< " Adding to ghFluid\n" << endl;
ghFluid.set
(
i,
new volScalarField
(
"gh",
(gFluid[i] & fluidRegions[i].C()) - ghRef
)
);
Info<< " Adding to ghfFluid\n" << endl;
ghfFluid.set
(
i,
new surfaceScalarField
(
"ghf",
(gFluid[i] & fluidRegions[i].Cf()) - ghRef
)
);
Info<< " Adding to turbulence\n" << endl;
turbulence.set
(
i,
compressible::turbulenceModel::New
(
rhoFluid[i],
UFluid[i],
phiFluid[i],
thermoFluid[i]
).ptr()
);
p_rghFluid.set
(
i,
new volScalarField
(
IOobject
(
"p_rgh",
runTime.timeName(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluidRegions[i]
)
);
// Force p_rgh to be consistent with p
p_rghFluid[i] = thermoFluid[i].p() - rhoFluid[i]*ghFluid[i];
fluidRegions[i].setFluxRequired(p_rghFluid[i].name());
radiation.set
(
i,
radiation::radiationModel::New(thermoFluid[i].T())
);
initialMassFluid[i] = fvc::domainIntegrate(rhoFluid[i]).value();
const dictionary& simpleDict =
fluidRegions[i].solutionDict().subDict("SIMPLE");
setRefCell
(
thermoFluid[i].p(),
p_rghFluid[i],
simpleDict,
pRefCellFluid[i],
pRefValueFluid[i]
);
simpleDict.readIfPresent("frozenFlow", frozenFlowFluid[i]);
rhoMax.set
(
i,
new dimensionedScalar
(
dimensionedScalar::lookupOrDefault
(
"rhoMax",
simpleDict,
dimDensity,
GREAT
)
)
);
rhoMin.set
(
i,
new dimensionedScalar
(
dimensionedScalar::lookupOrDefault
(
"rhoMin",
simpleDict,
dimDensity,
0
)
)
);
Info<< " Adding MRF\n" << endl;
MRFfluid.set
(
i,
new IOMRFZoneList(fluidRegions[i])
);
Info<< " Adding fvOptions\n" << endl;
fluidFvOptions.set
(
i,
new fv::options(fluidRegions[i])
);
turbulence[i].validate();
}
Right at the beginning, all the lists are created using functions pretty specific for the heat transfer case. I do not know how could I include something similar in my case.
My question is, is there a way around this? My case is much simpler, I just need two, maximum three, regions. Is there a way I could just assign equations to a specific region?
Thanks for reading!
mizo
|