Merge branch 'feature-finiteArea-postProcessing' into 'develop'

finite area integration

See merge request Development/OpenFOAM-plus!179
This commit is contained in:
Andrew Heather
2017-12-18 11:44:02 +00:00
452 changed files with 94480 additions and 603 deletions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,6 +39,7 @@ The available solvers are grouped into the following categories:
- \ref grpLagrangianSolvers
- \ref grpMultiphaseSolvers
- \ref grpStressAnalysisSolvers
- \ref grpFiniteAreaSolvers
\*---------------------------------------------------------------------------*/

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,4 +34,10 @@ License
This group contains moving mesh solvers solvers
@}
\defgroup grpFiniteAreaSolvers Finite area solvers
@{
\ingroup grpSolvers
This group contains finite area solvers
@}
\*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,3 @@
liquidFilmFoam.C
EXE = $(FOAM_APPBIN)/liquidFilmFoam

View File

@ -0,0 +1,10 @@
EXE_INC = \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/cfdTools/general/lnInclude
EXE_LIBS = \
-lfiniteArea \
-lfiniteVolume \
-lmeshTools

View File

@ -0,0 +1,7 @@
{
// Stabilisation of friction factor calculation
// Friction factor is defined with standard gravity
frictionFactor.primitiveFieldRef() =
mag(2*9.81*sqr(manningField.primitiveField())/
pow(mag(h.primitiveField()) + 1e-7, 1.0/3.0));
}

View File

@ -0,0 +1,13 @@
{
scalar CoNumSigma = max
(
sqrt
(
2*M_PI*sigma*sqr(aMesh.edgeInterpolation::deltaCoeffs())
*aMesh.edgeInterpolation::deltaCoeffs()
/rhol
)
).value()*runTime.deltaT().value();
Info<< "Max Capillary Courant Number = " << CoNumSigma << '\n' << endl;
}

View File

@ -0,0 +1,158 @@
Info<< "Reading field h" << endl;
areaScalarField h
(
IOobject
(
"h",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
aMesh
);
Info<< "Reading field Us" << endl;
areaVectorField Us
(
IOobject
(
"Us",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
aMesh
);
edgeScalarField phis
(
IOobject
(
"phis",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fac::interpolate(Us) & aMesh.Le()
);
edgeScalarField phi2s
(
IOobject
(
"phi2s",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fac::interpolate(h*Us) & aMesh.Le()
);
const areaVectorField& Ns = aMesh.faceAreaNormals();
areaVectorField Gs(g - Ns*(Ns & g));
areaScalarField Gn(mag(g - Gs));
// Mass source
areaScalarField Sm
(
IOobject
(
"Sm",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
aMesh,
dimensionedScalar("Sm", dimLength/dimTime, 0)
);
// Mass sink
areaScalarField Sd
(
IOobject
(
"Sd",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
aMesh,
dimensionedScalar("Sd", dimLength/dimTime, 0)
);
areaVectorField Ug
(
IOobject
(
"Sg",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
aMesh,
dimensionedVector("Ug", dimVelocity, vector::zero)
);
// Surface pressure
areaScalarField ps
(
IOobject
(
"ps",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
rhol*Gn*h - sigma*fac::laplacian(h)
);
// Friction factor
areaScalarField dotProduct
(
aMesh.faceAreaNormals() & (g/mag(g))
);
Info<< "View factor: min = " << min(dotProduct.internalField())
<< " max = " << max(dotProduct.internalField()) << endl;
areaScalarField manningField
(
IOobject
(
"manningField",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
aMesh
);
areaScalarField frictionFactor
(
IOobject
(
"frictionFactor",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
aMesh,
dimensionedScalar("one", dimless, 0.01)
);
aMesh.setFluxRequired("h");

View File

@ -0,0 +1,31 @@
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector("0", dimVelocity, vector::zero)
);
volScalarField H
(
IOobject
(
"H",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("0", dimLength, 0)
);
// Create volume-to surface mapping object
volSurfaceMapping vsm(aMesh);

View File

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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
liquidFilmFoam
Group
grpFiniteAreaSolvers
Description
Transient solver for incompressible, laminar flow of Newtonian fluids in
liquid film formulation.
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "faCFD.H"
#include "loopControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFaMesh.H"
#include "readGravitationalAcceleration.H"
#include "readTransportProperties.H"
#include "createFaFields.H"
#include "createFvFields.H"
#include "createTimeControls.H"
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readSolutionControls.H"
#include "readTimeControls.H"
#include "surfaceCourantNo.H"
#include "capillaryCourantNo.H"
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
while (iters.loop())
{
phi2s = fac::interpolate(h)*phis;
#include "calcFrictionFactor.H"
faVectorMatrix UsEqn
(
fam::ddt(h, Us)
+ fam::div(phi2s, Us)
+ fam::Sp(0.0125*frictionFactor*mag(Us), Us)
==
Gs*h
- fam::Sp(Sd, Us)
);
UsEqn.relax();
solve(UsEqn == - fac::grad(ps*h)/rhol + ps*fac::grad(h)/rhol);
areaScalarField UsA(UsEqn.A());
Us = UsEqn.H()/UsA;
Us.correctBoundaryConditions();
phis =
(fac::interpolate(Us) & aMesh.Le())
- fac::interpolate(1.0/(rhol*UsA))*fac::lnGrad(ps*h)*aMesh.magLe()
+ fac::interpolate(ps/(rhol*UsA))*fac::lnGrad(h)*aMesh.magLe();
faScalarMatrix hEqn
(
fam::ddt(h)
+ fam::div(phis, h)
==
Sm
- fam::Sp
(
Sd/(h + dimensionedScalar("small", dimLength, SMALL)),
h
)
);
hEqn.relax();
hEqn.solve();
phi2s = hEqn.flux();
// Bound h
h.primitiveFieldRef() = max
(
max
(
h.primitiveField(),
fac::average(max(h, h0))().primitiveField()
*pos(h0.value() - h.primitiveField())
),
h0.value()
);
ps = rhol*Gn*h - sigma*fac::laplacian(h);
ps.correctBoundaryConditions();
Us -= (1.0/(rhol*UsA))*fac::grad(ps*h)
- (ps/(rhol*UsA))*fac::grad(h);
Us.correctBoundaryConditions();
}
if (runTime.outputTime())
{
vsm.mapToVolume(h, H.boundaryFieldRef());
vsm.mapToVolume(Us, U.boundaryFieldRef());
runTime.write();
}
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1 @@
loopControl iters(runTime, aMesh.solutionDict(), "solution");

View File

@ -0,0 +1,41 @@
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar mug
(
transportProperties.lookup("mug")
);
dimensionedScalar mul
(
transportProperties.lookup("mul")
);
dimensionedScalar sigma
(
transportProperties.lookup("sigma")
);
dimensionedScalar rhol
(
transportProperties.lookup("rhol")
);
dimensionedScalar rhog
(
transportProperties.lookup("rhog")
);
dimensionedScalar h0
(
transportProperties.lookup("h0")
);

View File

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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
surfaceCourantNo
Author
Hrvoje Jasak, Wikki Ltd.
Description
Calculates and outputs the mean and maximum Courant Numbers for the
Finite Area method.
\*---------------------------------------------------------------------------*/
scalar CoNum = 0.0;
scalar meanCoNum = 0.0;
scalar velMag = 0.0;
if (aMesh.nInternalEdges())
{
edgeScalarField SfUfbyDelta
(
aMesh.edgeInterpolation::deltaCoeffs()*mag(phis)
);
CoNum = max(SfUfbyDelta/aMesh.magLe())
.value()*runTime.deltaT().value();
meanCoNum = (sum(SfUfbyDelta)/sum(aMesh.magLe()))
.value()*runTime.deltaT().value();
velMag = max(mag(phis)/aMesh.magLe()).value();
}
Info<< "Courant Number mean: " << meanCoNum
<< " max: " << CoNum
<< " velocity magnitude: " << velMag << endl;
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
surfactantFoam.C
EXE = $(FOAM_USER_APPBIN)/sphereSurfactantFoam

View File

@ -0,0 +1,10 @@
EXE_INC = \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/cfdTools/general/lnInclude
EXE_LIBS = \
-lfiniteArea \
-lfiniteVolume \
-lmeshTools

View File

@ -0,0 +1,78 @@
Info<< "Reading field Cs" << endl;
areaScalarField Cs
(
IOobject
(
"Cs",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
aMesh
);
dimensioned<scalar> Cs0
(
"Cs0",
dimensionSet(1, -2, 0, 0, 0, 0, 0),
1.0
);
const areaVectorField& R = aMesh.areaCentres();
Cs = Cs0*(1.0 + R.component(vector::X)/mag(R));
dimensioned<scalar> Ds
(
"Ds",
dimensionSet(0, 2, -1, 0, 0, 0, 0),
1.0
);
areaVectorField Us
(
IOobject
(
"Us",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
aMesh,
dimensioned<vector>("Us", dimVelocity, vector::zero)
);
dimensioned<scalar> Uinf("Uinf", dimVelocity, 1.0);
forAll (Us, faceI)
{
Us[faceI].x() =
Uinf.value()*(0.25*(3.0 + sqr(R[faceI].x()/mag(R[faceI]))) - 1.0);
Us[faceI].y() =
Uinf.value()*0.25*R[faceI].x()*R[faceI].y()/sqr(mag(R[faceI]));
Us[faceI].z() =
Uinf.value()*0.25*R[faceI].x()*R[faceI].z()/sqr(mag(R[faceI]));
}
Us -= aMesh.faceAreaNormals()*(aMesh.faceAreaNormals() & Us);
edgeScalarField phis
(
IOobject
(
"phis",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
linearEdgeInterpolate(Us) & aMesh.Le()
);

View File

@ -0,0 +1,2 @@
// Create Finite Area mesh
faMesh aMesh(mesh);

View File

@ -0,0 +1,36 @@
// Create volume-to surface mapping object
volSurfaceMapping vsm(aMesh);
volScalarField Cvf
(
IOobject
(
"Cvf",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("0", dimless/dimLength, 0)
);
vsm.mapToVolume(Cs, Cvf.boundaryFieldRef());
Cvf.write();
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector("zero", dimVelocity, vector::zero)
);
vsm.mapToVolume(Us, U.boundaryFieldRef());
U.write();

View File

@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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
surfactantFoam for sphere transport
Group
grpFiniteAreaSolvers
Description
Passive scalar transport equation solver on a sphere
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "faCFD.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFaMesh.H"
#include "createFaFields.H"
#include "createVolFields.H"
Info<< "Total mass of surfactant: "
<< sum(Cs.internalField()*aMesh.S()) << endl;
Info<< "\nStarting time loop\n" << endl;
while (runTime.loop())
{
Info<< "Time = " << runTime.value() << endl;
faScalarMatrix CsEqn
(
fam::ddt(Cs)
+ fam::div(phis, Cs)
- fam::laplacian(Ds, Cs)
);
CsEqn.solve();
if (runTime.writeTime())
{
vsm.mapToVolume(Cs, Cvf.boundaryFieldRef());
runTime.write();
}
Info<< "Total mass of surfactant: "
<< sum(Cs.internalField()*aMesh.S()) << endl;
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
surfactantFoam.C
EXE = $(FOAM_APPBIN)/surfactantFoam

View File

@ -0,0 +1,10 @@
EXE_INC = \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/cfdTools/general/lnInclude
EXE_LIBS = \
-lfiniteArea \
-lfiniteVolume \
-lmeshTools

View File

@ -0,0 +1,63 @@
Info<< "Reading field Cs" << endl;
areaScalarField Cs
(
IOobject
(
"Cs",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
aMesh
);
Info<< "Reading transportProperties\n" << endl;
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
Info<< "Reading diffusivity D\n" << endl;
dimensionedScalar Ds
(
transportProperties.lookup("Ds")
);
areaVectorField Us
(
IOobject
(
"Us",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
),
aMesh
);
edgeScalarField phis
(
IOobject
(
"phis",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
linearEdgeInterpolate(Us) & aMesh.Le()
);

View File

@ -0,0 +1,2 @@
// Create Finite Area mesh
faMesh aMesh(mesh);

View File

@ -0,0 +1,36 @@
// Create volume-to surface mapping object
volSurfaceMapping vsm(aMesh);
volScalarField Cvf
(
IOobject
(
"Cvf",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("0", dimless/dimLength, 0)
);
vsm.mapToVolume(Cs, Cvf.boundaryFieldRef());
Cvf.write();
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector("zero", dimVelocity, vector::zero)
);
vsm.mapToVolume(Us, U.boundaryFieldRef());
U.write();

View File

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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
surfactantFoam
Group
grpFiniteAreaSolvers
Description
Passive scalar transport equation solver.
\heading Solver details
The equation is given by:
\f[
\ddt{Cs} + \div \left(\vec{U} Cs\right) - \div \left(D_T \grad Cs \right)
= 0
\f]
Where:
\vartable
Cs | Passive scalar
Ds | Diffusion coefficient
\endvartable
\heading Required fields
\plaintable
Cs | Passive scalar
Us | Velocity [m/s]
\endplaintable
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "faCFD.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFaMesh.H"
#include "createFaFields.H"
#include "createVolFields.H"
Info<< "Total mass of surfactant: "
<< sum(Cs.internalField()*aMesh.S()) << endl;
Info<< "\nStarting time loop\n" << endl;
while (runTime.loop())
{
Info<< "Time = " << runTime.value() << endl;
faScalarMatrix CsEqn
(
fam::ddt(Cs)
+ fam::div(phis, Cs)
- fam::laplacian(Ds, Cs)
);
CsEqn.solve();
if (runTime.writeTime())
{
vsm.mapToVolume(Cs, Cvf.boundaryFieldRef());
runTime.write();
}
Info<< "Total mass of surfactant: "
<< sum(Cs.internalField()*aMesh.S()) << endl;
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
checkFaMesh.C
EXE = $(FOAM_APPBIN)/checkFaMesh

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-lfiniteArea

View File

@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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
makeFaMesh
Description
Check a Finite Area mesh
Author
Zeljko Tukovic, FAMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "faCFD.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
# include "addRegionOption.H"
# include "setRootCase.H"
# include "createTime.H"
# include "createNamedMesh.H"
# include "createFaMesh.H"
Info<< "Time = " << runTime.timeName() << nl << endl;
// General mesh statistics
Info<< "Number of points: " << aMesh.nPoints() << nl
<< "Number of internal edges: " << aMesh.nInternalEdges() << nl
<< "Number of edges: " << aMesh.nEdges() << nl
<< "Number of faces: " << aMesh.nFaces() << nl
<< endl;
// Check geometry
Info<< "Face area: min = " << min(aMesh.S().field())
<< " max = " << max(aMesh.S().field()) << nl
<< "Internal edge length: min = "
<< min(aMesh.magLe().internalField()) << nl
<< " max = " << max(aMesh.magLe().internalField()) << nl
<< "Edge length: min = "
<< min(aMesh.magLe()).value() << nl
<< " max = " << max(aMesh.magLe()).value() << nl
<< "Face area normals: min = " << min(aMesh.faceAreaNormals().field())
<< " max = " << max(aMesh.faceAreaNormals().field()) << nl
<< endl;
return(0);
}
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
makeFaMesh.C
EXE = $(FOAM_APPBIN)/makeFaMesh

View File

@ -0,0 +1,8 @@
EXE_INC = \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/cfdTools/general/lnInclude
EXE_LIBS = \
-lfiniteArea \
-lfiniteVolume

View File

@ -0,0 +1,355 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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
makeFaMesh
Description
A mesh generator for finite area mesh.
Author
Zeljko Tukovic, FAMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#include "objectRegistry.H"
#include "Time.H"
#include "argList.H"
#include "OSspecific.H"
#include "faMesh.H"
#include "fvMesh.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
class faPatchData
{
public:
word name_;
word type_;
dictionary dict_;
label ownPolyPatchID_;
label ngbPolyPatchID_;
labelList edgeLabels_;
faPatchData()
:
name_(word::null),
type_(word::null),
ownPolyPatchID_(-1),
ngbPolyPatchID_(-1)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "addRegionOption.H"
argList::noParallel();
#include "setRootCase.H"
#include "createTime.H"
#include "createNamedMesh.H"
// Reading faMeshDefinition dictionary
IOdictionary faMeshDefinition
(
IOobject
(
"faMeshDefinition",
runTime.constant(),
"faMesh",
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
wordList polyMeshPatches
(
faMeshDefinition.lookup("polyMeshPatches")
);
const dictionary& bndDict = faMeshDefinition.subDict("boundary");
const wordList faPatchNames(bndDict.toc());
List<faPatchData> faPatches(faPatchNames.size()+1);
forAll(faPatchNames, patchI)
{
const dictionary& curPatchDict = bndDict.subDict(faPatchNames[patchI]);
faPatches[patchI].name_ = faPatchNames[patchI];
faPatches[patchI].type_ = word(curPatchDict.lookup("type"));
const word ownName = curPatchDict.lookup("ownerPolyPatch");
faPatches[patchI].ownPolyPatchID_ =
mesh.boundaryMesh().findPatchID(ownName);
if (faPatches[patchI].ownPolyPatchID_ < 0)
{
FatalErrorIn("makeFaMesh:")
<< "neighbourPolyPatch " << ownName << " does not exist"
<< exit(FatalError);
}
const word neiName = curPatchDict.lookup("neighbourPolyPatch");
faPatches[patchI].ngbPolyPatchID_ =
mesh.boundaryMesh().findPatchID(neiName);
if (faPatches[patchI].ngbPolyPatchID_ < 0)
{
FatalErrorIn("makeFaMesh:")
<< "neighbourPolyPatch " << neiName << " does not exist"
<< exit(FatalError);
}
}
// Setting faceLabels list size
label size = 0;
labelList patchIDs(polyMeshPatches.size(), -1);
forAll(polyMeshPatches, patchI)
{
patchIDs[patchI] =
mesh.boundaryMesh().findPatchID(polyMeshPatches[patchI]);
if (patchIDs[patchI] < 0)
{
FatalErrorIn("makeFaMesh:")
<< "Patch " << polyMeshPatches[patchI] << " does not exist"
<< exit(FatalError);
}
size += mesh.boundaryMesh()[patchIDs[patchI]].size();
}
labelList faceLabels(size, -1);
sort(patchIDs);
// Filling of faceLabels list
label faceI = -1;
forAll(polyMeshPatches, patchI)
{
label start = mesh.boundaryMesh()[patchIDs[patchI]].start();
label size = mesh.boundaryMesh()[patchIDs[patchI]].size();
for (label i = 0; i < size; ++i)
{
faceLabels[++faceI] = start + i;
}
}
// Creating faMesh
Info << "Create faMesh ... ";
faMesh areaMesh
(
mesh,
faceLabels
);
Info << "Done" << endl;
// Determination of faPatch ID for each boundary edge.
// Result is in the bndEdgeFaPatchIDs list
const indirectPrimitivePatch& patch = areaMesh.patch();
labelList faceCells(faceLabels.size(), -1);
forAll(faceCells, faceI)
{
label faceID = faceLabels[faceI];
faceCells[faceI] = mesh.faceOwner()[faceID];
}
labelList meshEdges =
patch.meshEdges
(
mesh.edges(),
mesh.cellEdges(),
faceCells
);
const labelListList& edgeFaces = mesh.edgeFaces();
const label nTotalEdges = patch.nEdges();
const label nInternalEdges = patch.nInternalEdges();
labelList bndEdgeFaPatchIDs(nTotalEdges - nInternalEdges, -1);
for (label edgeI = nInternalEdges; edgeI < nTotalEdges; ++edgeI)
{
label curMeshEdge = meshEdges[edgeI];
labelList curEdgePatchIDs(2, label(-1));
label patchI = -1;
forAll(edgeFaces[curMeshEdge], faceI)
{
label curFace = edgeFaces[curMeshEdge][faceI];
label curPatchID = mesh.boundaryMesh().whichPatch(curFace);
if (curPatchID != -1)
{
curEdgePatchIDs[++patchI] = curPatchID;
}
}
for (label pI = 0; pI < faPatches.size() - 1; ++pI)
{
if
(
(
curEdgePatchIDs[0] == faPatches[pI].ownPolyPatchID_
&& curEdgePatchIDs[1] == faPatches[pI].ngbPolyPatchID_
)
||
(
curEdgePatchIDs[1] == faPatches[pI].ownPolyPatchID_
&& curEdgePatchIDs[0] == faPatches[pI].ngbPolyPatchID_
)
)
{
bndEdgeFaPatchIDs[edgeI - nInternalEdges] = pI;
break;
}
}
}
// Set edgeLabels for each faPatch
for (label pI=0; pI<(faPatches.size()-1); ++pI)
{
SLList<label> tmpList;
forAll(bndEdgeFaPatchIDs, eI)
{
if (bndEdgeFaPatchIDs[eI] == pI)
{
tmpList.append(nInternalEdges + eI);
}
}
faPatches[pI].edgeLabels_ = tmpList;
}
// Check for undefined edges
SLList<label> tmpList;
forAll(bndEdgeFaPatchIDs, eI)
{
if (bndEdgeFaPatchIDs[eI] == -1)
{
tmpList.append(nInternalEdges + eI);
}
}
if (tmpList.size() > 0)
{
label pI = faPatches.size()-1;
faPatches[pI].name_ = "undefined";
faPatches[pI].type_ = "patch";
faPatches[pI].edgeLabels_ = tmpList;
}
// Add good patches to faMesh
SLList<faPatch*> faPatchLst;
for (label pI = 0; pI < faPatches.size(); ++pI)
{
faPatches[pI].dict_.add("type", faPatches[pI].type_);
faPatches[pI].dict_.add("edgeLabels", faPatches[pI].edgeLabels_);
faPatches[pI].dict_.add
(
"ngbPolyPatchIndex",
faPatches[pI].ngbPolyPatchID_
);
if(faPatches[pI].edgeLabels_.size() > 0)
{
faPatchLst.append
(
faPatch::New
(
faPatches[pI].name_,
faPatches[pI].dict_,
pI,
areaMesh.boundary()
).ptr()
);
}
}
if (args.optionFound("addEmptyPatch"))
{
word emptyPatchName(args.optionLookup("addEmptyPatch")());
dictionary emptyPatchDict;
emptyPatchDict.add("type", "empty");
emptyPatchDict.add("edgeLabels", labelList());
emptyPatchDict.add("ngbPolyPatchIndex", -1);
faPatchLst.append
(
faPatch::New
(
emptyPatchName,
emptyPatchDict,
faPatchLst.size(),
areaMesh.boundary()
).ptr()
);
}
Info << "Add faPatches ... ";
areaMesh.addFaPatches(List<faPatch*>(faPatchLst));
Info << "Done" << endl;
// Writing faMesh
Info << "Write finite area mesh ... ";
areaMesh.write();
Info << "Done" << endl;
return(0);
}
// ************************************************************************* //

View File

@ -4,6 +4,8 @@ domainDecompositionMesh.C
domainDecompositionDistribute.C
dimFieldDecomposer.C
pointFieldDecomposer.C
faMeshDecomposition.C
faFieldDecomposer.C
lagrangianFieldDecomposer.C
EXE = $(FOAM_APPBIN)/decomposePar

View File

@ -2,6 +2,7 @@ EXE_INC = \
-I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
@ -14,6 +15,7 @@ EXE_LIBS = \
-ldecompositionMethods \
-L$(FOAM_LIBBIN)/dummy \
-lkahipDecomp -lmetisDecomp -lscotchDecomp \
-lfiniteArea \
-llagrangian \
-ldynamicMesh \
-lregionModels

View File

@ -106,6 +106,11 @@ Usage
#include "decompositionModel.H"
#include "collatedFileOperation.H"
#include "faCFD.H"
#include "emptyFaPatch.H"
#include "faMeshDecomposition.H"
#include "faFieldDecomposer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -1239,6 +1244,178 @@ int main(int argc, char *argv[])
processorDbList.set(proci, nullptr);
}
}
// Finite area mesh and field decomposition
IOobject faMeshBoundaryIOobj
(
"faBoundary",
mesh.time().findInstance
(
mesh.dbDir()/polyMesh::meshSubDir,
"boundary"
),
faMesh::meshSubDir,
mesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
);
if (faMeshBoundaryIOobj.typeHeaderOk<faBoundaryMesh>(true))
{
Info << "\nFinite area mesh decomposition" << endl;
faMeshDecomposition aMesh(mesh);
aMesh.decomposeMesh();
aMesh.writeDecomposition();
// Construct the area fields
// ~~~~~~~~~~~~~~~~~~~~~~~~
PtrList<areaScalarField> areaScalarFields;
readFields(aMesh, objects, areaScalarFields);
PtrList<areaVectorField> areaVectorFields;
readFields(aMesh, objects, areaVectorFields);
PtrList<areaSphericalTensorField> areaSphericalTensorFields;
readFields(aMesh, objects, areaSphericalTensorFields);
PtrList<areaSymmTensorField> areaSymmTensorFields;
readFields(aMesh, objects, areaSymmTensorFields);
PtrList<areaTensorField> areaTensorFields;
readFields(aMesh, objects, areaTensorFields);
// Construct the edge fields
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PtrList<edgeScalarField> edgeScalarFields;
readFields(aMesh, objects, edgeScalarFields);
Info << endl;
// Split the fields over processors
for (label procI = 0; procI < mesh.nProcs(); procI++)
{
Info<< "Processor " << procI
<< ": finite area field transfer" << endl;
// open the database
Time processorDb
(
Time::controlDictName,
args.rootPath(),
args.caseName()/
fileName(word("processor") + name(procI))
);
processorDb.setTime(runTime);
// Read the mesh
fvMesh procFvMesh
(
IOobject
(
regionName,
processorDb.timeName(),
processorDb
)
);
faMesh procMesh(procFvMesh);
// // Does not work. HJ, 15/Aug/2017
// const labelIOList& faceProcAddressing =
// procAddressing
// (
// procMeshList,
// procI,
// "faceProcAddressing",
// faceProcAddressingList
// );
// const labelIOList& boundaryProcAddressing =
// procAddressing
// (
// procMeshList,
// procI,
// "boundaryProcAddressing",
// boundaryProcAddressingList
// );
labelIOList faceProcAddressing
(
IOobject
(
"faceProcAddressing",
"constant",
procMesh.meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
labelIOList boundaryProcAddressing
(
IOobject
(
"boundaryProcAddressing",
"constant",
procMesh.meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
// FA fields
if
(
areaScalarFields.size()
|| areaVectorFields.size()
|| areaSphericalTensorFields.size()
|| areaSymmTensorFields.size()
|| areaTensorFields.size()
|| edgeScalarFields.size()
)
{
labelIOList edgeProcAddressing
(
IOobject
(
"edgeProcAddressing",
"constant",
procMesh.meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
faFieldDecomposer fieldDecomposer
(
aMesh,
procMesh,
edgeProcAddressing,
faceProcAddressing,
boundaryProcAddressing
);
fieldDecomposer.decomposeFields(areaScalarFields);
fieldDecomposer.decomposeFields(areaVectorFields);
fieldDecomposer.decomposeFields(areaSphericalTensorFields);
fieldDecomposer.decomposeFields(areaSymmTensorFields);
fieldDecomposer.decomposeFields(areaTensorFields);
fieldDecomposer.decomposeFields(edgeScalarFields);
}
}
}
}
}
}

View File

@ -0,0 +1,238 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "faFieldDecomposer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
faFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
(
const label sizeBeforeMapping,
const labelUList& addressingSlice,
const label addressingOffset
)
:
sizeBeforeMapping_(sizeBeforeMapping),
directAddressing_(addressingSlice)
{
forAll (directAddressing_, i)
{
// Subtract one to align addressing.
// directAddressing_[i] -= addressingOffset + 1;
// ZT, 12/Nov/2010
directAddressing_[i] -= addressingOffset;
}
}
faFieldDecomposer::processorAreaPatchFieldDecomposer::
processorAreaPatchFieldDecomposer
(
const faMesh& mesh,
const labelUList& addressingSlice
)
:
sizeBeforeMapping_(mesh.nFaces()),
addressing_(addressingSlice.size()),
weights_(addressingSlice.size())
{
const scalarField& weights = mesh.weights().internalField();
const labelList& own = mesh.edgeOwner();
const labelList& neighb = mesh.edgeNeighbour();
forAll (addressing_, i)
{
// Subtract one to align addressing.
label ai = addressingSlice[i];
// label ai = mag(addressingSlice[i]) - 1;
if (ai < neighb.size())
{
// This is a regular edge. it has been an internal edge
// of the original mesh and now it has become a edge
// on the parallel boundary
addressing_[i].setSize(2);
weights_[i].setSize(2);
addressing_[i][0] = own[ai];
addressing_[i][1] = neighb[ai];
weights_[i][0] = weights[ai];
weights_[i][1] = 1.0 - weights[ai];
}
else
{
// This is a edge that used to be on a cyclic boundary
// but has now become a parallel patch edge. I cannot
// do the interpolation properly (I would need to look
// up the different (edge) list of data), so I will
// just grab the value from the owner face
//
addressing_[i].setSize(1);
weights_[i].setSize(1);
addressing_[i][0] = own[ai];
weights_[i][0] = 1.0;
}
}
}
faFieldDecomposer::processorEdgePatchFieldDecomposer::
processorEdgePatchFieldDecomposer
(
label sizeBeforeMapping,
const labelUList& addressingSlice
)
:
sizeBeforeMapping_(sizeBeforeMapping),
addressing_(addressingSlice.size()),
weights_(addressingSlice.size())
{
forAll (addressing_, i)
{
addressing_[i].setSize(1);
weights_[i].setSize(1);
addressing_[i][0] = mag(addressingSlice[i]) - 1;
weights_[i][0] = sign(addressingSlice[i]);
}
}
faFieldDecomposer::faFieldDecomposer
(
const faMesh& completeMesh,
const faMesh& procMesh,
const labelList& edgeAddressing,
const labelList& faceAddressing,
const labelList& boundaryAddressing
)
:
completeMesh_(completeMesh),
procMesh_(procMesh),
edgeAddressing_(edgeAddressing),
faceAddressing_(faceAddressing),
boundaryAddressing_(boundaryAddressing),
patchFieldDecomposerPtrs_
(
procMesh_.boundary().size(),
static_cast<patchFieldDecomposer*>(NULL)
),
processorAreaPatchFieldDecomposerPtrs_
(
procMesh_.boundary().size(),
static_cast<processorAreaPatchFieldDecomposer*>(NULL)
),
processorEdgePatchFieldDecomposerPtrs_
(
procMesh_.boundary().size(),
static_cast<processorEdgePatchFieldDecomposer*>(NULL)
)
{
forAll (boundaryAddressing_, patchi)
{
if (boundaryAddressing_[patchi] >= 0)
{
patchFieldDecomposerPtrs_[patchi] = new patchFieldDecomposer
(
completeMesh_.boundary()[boundaryAddressing_[patchi]].size(),
procMesh_.boundary()[patchi].patchSlice(edgeAddressing_),
// completeMesh_.boundaryMesh()
completeMesh_.boundary()
[
boundaryAddressing_[patchi]
].start()
);
}
else
{
processorAreaPatchFieldDecomposerPtrs_[patchi] =
new processorAreaPatchFieldDecomposer
(
completeMesh_,
procMesh_.boundary()[patchi].patchSlice(edgeAddressing_)
);
processorEdgePatchFieldDecomposerPtrs_[patchi] =
new processorEdgePatchFieldDecomposer
(
procMesh_.boundary()[patchi].size(),
static_cast<const labelUList&>
(
procMesh_.boundary()[patchi].patchSlice
(
edgeAddressing_
)
)
);
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
faFieldDecomposer::~faFieldDecomposer()
{
forAll (patchFieldDecomposerPtrs_, patchi)
{
if (patchFieldDecomposerPtrs_[patchi])
{
delete patchFieldDecomposerPtrs_[patchi];
}
}
forAll (processorAreaPatchFieldDecomposerPtrs_, patchi)
{
if (processorAreaPatchFieldDecomposerPtrs_[patchi])
{
delete processorAreaPatchFieldDecomposerPtrs_[patchi];
}
}
forAll (processorEdgePatchFieldDecomposerPtrs_, patchi)
{
if (processorEdgePatchFieldDecomposerPtrs_[patchi])
{
delete processorEdgePatchFieldDecomposerPtrs_[patchi];
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,319 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
faFieldDecomposer
Description
Finite Area area and edge field decomposer.
Author
Zeljko Tukovic, FSB Zagreb
Hrvoje Jasak, Wikki Ltd.
SourceFiles
faFieldDecomposer.C
faFieldDecomposerDecomposeFields.C
\*---------------------------------------------------------------------------*/
#ifndef faFieldDecomposer_H
#define faFieldDecomposer_H
#include "faMesh.H"
#include "faPatchFieldMapper.H"
#include "edgeFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class IOobjectList;
/*---------------------------------------------------------------------------*\
Class faFieldDecomposer Declaration
\*---------------------------------------------------------------------------*/
class faFieldDecomposer
{
public:
//- Patch field decomposer class
class patchFieldDecomposer
:
public faPatchFieldMapper
{
// Private data
label sizeBeforeMapping_;
labelList directAddressing_;
public:
// Constructors
//- Construct given addressing
patchFieldDecomposer
(
const label sizeBeforeMapping,
const labelUList& addressingSlice,
const label addressingOffset
);
// Member functions
label size() const
{
return directAddressing_.size();
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
bool direct() const
{
return true;
}
virtual bool hasUnmapped() const
{
return false;
}
const labelUList& directAddressing() const
{
return directAddressing_;
}
};
//- Processor patch field decomposer class
class processorAreaPatchFieldDecomposer
:
public faPatchFieldMapper
{
// Private data
label sizeBeforeMapping_;
labelListList addressing_;
scalarListList weights_;
public:
//- Construct given addressing
processorAreaPatchFieldDecomposer
(
const faMesh& mesh,
const labelUList& addressingSlice
);
// Member functions
label size() const
{
return addressing_.size();
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
bool direct() const
{
return false;
}
virtual bool hasUnmapped() const
{
return false;
}
const labelListList& addressing() const
{
return addressing_;
}
const scalarListList& weights() const
{
return weights_;
}
};
//- Processor patch field decomposer class
class processorEdgePatchFieldDecomposer
:
public faPatchFieldMapper
{
label sizeBeforeMapping_;
labelListList addressing_;
scalarListList weights_;
public:
//- Construct given addressing
processorEdgePatchFieldDecomposer
(
label sizeBeforeMapping,
const labelUList& addressingSlice
);
// Member functions
label size() const
{
return addressing_.size();
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
bool direct() const
{
return false;
}
virtual bool hasUnmapped() const
{
return false;
}
const labelListList& addressing() const
{
return addressing_;
}
const scalarListList& weights() const
{
return weights_;
}
};
private:
// Private data
//- Reference to complete mesh
const faMesh& completeMesh_;
//- Reference to processor mesh
const faMesh& procMesh_;
//- Reference to edge addressing
const labelList& edgeAddressing_;
//- Reference to face addressing
const labelList& faceAddressing_;
//- Reference to boundary addressing
const labelList& boundaryAddressing_;
//- List of patch field decomposers
List<patchFieldDecomposer*> patchFieldDecomposerPtrs_;
List<processorAreaPatchFieldDecomposer*>
processorAreaPatchFieldDecomposerPtrs_;
List<processorEdgePatchFieldDecomposer*>
processorEdgePatchFieldDecomposerPtrs_;
// Private Member Functions
//- Disallow default bitwise copy construct
faFieldDecomposer(const faFieldDecomposer&);
//- Disallow default bitwise assignment
void operator=(const faFieldDecomposer&);
public:
// Constructors
//- Construct from components
faFieldDecomposer
(
const faMesh& completeMesh,
const faMesh& procMesh,
const labelList& edgeAddressing,
const labelList& faceAddressing,
const labelList& boundaryAddressing
);
// Destructor
~faFieldDecomposer();
// Member Functions
//- Decompose area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh> >
decomposeField
(
const GeometricField<Type, faPatchField, areaMesh>& field
) const;
//- Decompose surface field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh> >
decomposeField
(
const GeometricField<Type, faePatchField, edgeMesh>& field
) const;
template<class GeoField>
void decomposeFields(const PtrList<GeoField>& fields) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "faFieldDecomposerDecomposeFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,237 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "faFieldDecomposer.H"
#include "processorFaPatchField.H"
#include "processorFaePatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh> >
faFieldDecomposer::decomposeField
(
const GeometricField<Type, faPatchField, areaMesh>& field
) const
{
// Create and map the internal field values
Field<Type> internalField(field.internalField(), faceAddressing_);
// Create and map the patch field values
PtrList<faPatchField<Type> > patchFields(boundaryAddressing_.size());
forAll (boundaryAddressing_, patchi)
{
if (boundaryAddressing_[patchi] >= 0)
{
patchFields.set
(
patchi,
faPatchField<Type>::New
(
field.boundaryField()[boundaryAddressing_[patchi]],
procMesh_.boundary()[patchi],
DimensionedField<Type, areaMesh>::null(),
*patchFieldDecomposerPtrs_[patchi]
)
);
}
else
{
patchFields.set
(
patchi,
new processorFaPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, areaMesh>::null(),
Field<Type>
(
field.internalField(),
*processorAreaPatchFieldDecomposerPtrs_[patchi]
)
)
);
}
}
// Create the field for the processor
return tmp<GeometricField<Type, faPatchField, areaMesh> >
(
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
field.name(),
procMesh_.time().timeName(),
procMesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
procMesh_,
field.dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh> >
faFieldDecomposer::decomposeField
(
const GeometricField<Type, faePatchField, edgeMesh>& field
) const
{
labelList mapAddr
(
labelList::subList
(
edgeAddressing_,
procMesh_.nInternalEdges()
)
);
forAll (mapAddr, i)
{
mapAddr[i] -= 1;
}
// Create and map the internal field values
Field<Type> internalField
(
field.internalField(),
mapAddr
);
// Problem with addressing when a processor patch picks up both internal
// edges and edges from cyclic boundaries. This is a bit of a hack, but
// I cannot find a better solution without making the internal storage
// mechanism for edgeFields correspond to the one of edges in polyMesh
// (i.e. using slices)
Field<Type> allEdgeField(field.mesh().nEdges());
forAll (field.internalField(), i)
{
allEdgeField[i] = field.internalField()[i];
}
forAll (field.boundaryField(), patchi)
{
const Field<Type> & p = field.boundaryField()[patchi];
const label patchStart = field.mesh().boundary()[patchi].start();
forAll (p, i)
{
allEdgeField[patchStart + i] = p[i];
}
}
// Create and map the patch field values
PtrList<faePatchField<Type> > patchFields(boundaryAddressing_.size());
forAll (boundaryAddressing_, patchi)
{
if (boundaryAddressing_[patchi] >= 0)
{
patchFields.set
(
patchi,
faePatchField<Type>::New
(
field.boundaryField()[boundaryAddressing_[patchi]],
procMesh_.boundary()[patchi],
DimensionedField<Type, edgeMesh>::null(),
*patchFieldDecomposerPtrs_[patchi]
)
);
}
else
{
patchFields.set
(
patchi,
new processorFaePatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, edgeMesh>::null(),
Field<Type>
(
allEdgeField,
*processorEdgePatchFieldDecomposerPtrs_[patchi]
)
)
);
}
}
// Create the field for the processor
return tmp<GeometricField<Type, faePatchField, edgeMesh> >
(
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
field.name(),
procMesh_.time().timeName(),
procMesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
procMesh_,
field.dimensions(),
internalField,
patchFields
)
);
}
template<class GeoField>
void faFieldDecomposer::decomposeFields
(
const PtrList<GeoField>& fields
) const
{
forAll (fields, fieldI)
{
decomposeField(fields[fieldI])().write();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,178 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
faMeshDecomposition
Description
Automatic faMesh decomposition class
Author
Zeljko Tukovic, FSB Zagreb
Hrvoje Jasak, Wikki Ltd.
SourceFiles
faMeshDecomposition.C
\*---------------------------------------------------------------------------*/
#ifndef faMeshDecomposition_H
#define faMeshDecomposition_H
#include "fvMesh.H"
#include "faMesh.H"
#include "labelList.H"
#include "SLList.H"
#include "PtrList.H"
#include "point.H"
#ifndef namespaceFoam
#define namespaceFoam
using namespace Foam;
#endif
/*---------------------------------------------------------------------------*\
Class faMeshDecomposition Declaration
\*---------------------------------------------------------------------------*/
class faMeshDecomposition
:
public faMesh
{
// Private data
//- Mesh decomposition control dictionary
IOdictionary decompositionDict_;
//- Number of processors in decomposition
label nProcs_;
//- Is the decomposition data to be distributed for each processor
bool distributed_;
//- Processor label for each cell
labelList faceToProc_;
//- Face labels for each processor mesh
labelListList procFaceLabels_;
//-
List<Map<label> > procMeshEdgesMap_;
//- Number of internal edges for each processor mesh
labelList procNInternalEdges_;
//- Edge labels for patches of processor meshes
List<List<List<label> > > procPatchEdgeLabels_;
//- Labels of points for each processor
labelListList procPatchPointAddressing_;
//- Labels of edges for each processor
labelListList procPatchEdgeAddressing_;
//- Labels of edges for each processor
labelListList procEdgeAddressing_;
//- Labels of faces for each processor
labelListList procFaceAddressing_;
//- Original patch index for every processor patch
labelListList procBoundaryAddressing_;
//- Sizes for processor mesh patches
// Excludes inter-processor boundaries
labelListList procPatchSize_;
//- Start indices for processor patches
// Excludes inter-processor boundaries
labelListList procPatchStartIndex_;
//- Neighbour processor ID for inter-processor boundaries
labelListList procNeighbourProcessors_;
//- Sizes for inter-processor patches
labelListList procProcessorPatchSize_;
//- Start indices for inter-processor patches
labelListList procProcessorPatchStartIndex_;
//- List of globally shared point labels
labelList globallySharedPoints_;
//- Are there cyclic-parallel faces
bool cyclicParallel_;
// Private Member Functions
void distributeFaces();
public:
// Constructors
//- Construct from fvMesh
faMeshDecomposition(const fvMesh& mesh);
// Destructor
~faMeshDecomposition();
// Member Functions
//- Number of processor in decomposition
label nProcs() const
{
return nProcs_;
}
//- Is the decomposition data to be distributed for each processor
bool distributed() const
{
return distributed_;
}
//- Decompose mesh
void decomposeMesh();
//- Write decomposition
bool writeDecomposition();
//- Cell-processor decomposition labels
const labelList& faceToProc() const
{
return faceToProc_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,3 +1,5 @@
processorFaMeshes.C
faFieldReconstructor.C
reconstructPar.C
EXE = $(FOAM_APPBIN)/reconstructPar

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
@ -10,6 +11,7 @@ EXE_LIBS = \
-lfiniteVolume \
-lgenericPatchFields \
-llagrangian \
-lfiniteArea \
-ldynamicMesh \
-lmeshTools \
-lreconstruct \

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "faFieldReconstructor.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faFieldReconstructor::faFieldReconstructor
(
faMesh& mesh,
const PtrList<faMesh>& procMeshes,
const PtrList<labelIOList>& edgeProcAddressing,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
)
:
mesh_(mesh),
procMeshes_(procMeshes),
edgeProcAddressing_(edgeProcAddressing),
faceProcAddressing_(faceProcAddressing),
boundaryProcAddressing_(boundaryProcAddressing)
{}
// ************************************************************************* //

View File

@ -0,0 +1,205 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
faFieldReconstructor
Description
FA area and edge field reconstructor.
Author
Zeljko Tukovic, FSB Zagreb
Hrvoje Jasak, Wikki Ltd.
SourceFiles
faFieldReconstructor.C
faFieldReconstructorReconstructFields.C
\*---------------------------------------------------------------------------*/
#ifndef faFieldReconstructor_H
#define faFieldReconstructor_H
#include "PtrList.H"
#include "faMesh.H"
#include "IOobjectList.H"
#include "faPatchFieldMapper.H"
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faFieldReconstructor Declaration
\*---------------------------------------------------------------------------*/
class faFieldReconstructor
{
// Private data
//- Reconstructed mesh reference
faMesh& mesh_;
//- List of processor meshes
const PtrList<faMesh>& procMeshes_;
//- List of processor edge addressing lists
const PtrList<labelIOList>& edgeProcAddressing_;
//- List of processor face addressing lists
const PtrList<labelIOList>& faceProcAddressing_;
//- List of processor boundary addressing lists
const PtrList<labelIOList>& boundaryProcAddressing_;
// Private Member Functions
//- Disallow default bitwise copy construct
faFieldReconstructor(const faFieldReconstructor&);
//- Disallow default bitwise assignment
void operator=(const faFieldReconstructor&);
public:
class faPatchFieldReconstructor
:
public faPatchFieldMapper
{
label size_;
label sizeBeforeMapping_;
public:
// Constructors
//- Construct given size
faPatchFieldReconstructor
(
const label size,
const label sizeBeforeMapping
)
:
size_(size),
sizeBeforeMapping_(sizeBeforeMapping)
{}
// Member functions
virtual label size() const
{
return size_;
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
virtual bool direct() const
{
return true;
}
virtual bool hasUnmapped() const
{
return false;
}
virtual const labelUList& directAddressing() const
{
return labelUList::null();
}
};
// Constructors
//- Construct from components
faFieldReconstructor
(
faMesh& mesh,
const PtrList<faMesh>& procMeshes,
const PtrList<labelIOList>& edgeProcAddressing,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
);
// Member Functions
//- Reconstruct area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh> >
reconstructFaAreaField
(
const IOobject& fieldIoObject
);
//- Reconstruct edge field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh> >
reconstructFaEdgeField
(
const IOobject& fieldIoObject
);
//- Reconstruct and write all area fields
template<class Type>
void reconstructFaAreaFields
(
const IOobjectList& objects
);
//- Reconstruct and write all area fields
template<class Type>
void reconstructFaEdgeFields
(
const IOobjectList& objects
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "faFieldReconstructorReconstructFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,642 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "faFieldReconstructor.H"
#include "Time.H"
#include "PtrList.H"
#include "faPatchFields.H"
#include "emptyFaPatch.H"
#include "emptyFaPatchField.H"
#include "emptyFaePatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh> >
Foam::faFieldReconstructor::reconstructFaAreaField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, faPatchField, areaMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nFaces());
// Create the patch fields
PtrList<faPatchField<Type> > patchFields(mesh_.boundary().size());
// Create global mesh patchs starts
labelList gStarts(mesh_.boundary().size(), -1);
if (mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i=1; i<mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i-1] + mesh_.boundary()[i-1].labelList::size();
}
forAll (procMeshes_, procI)
{
const GeometricField<Type, faPatchField, areaMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
internalField.rmap
(
procField.internalField(),
faceProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if(procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for(label i=1; i<procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i-1]
+ procMeshes_[procI].boundary()[i-1].labelList::size();
}
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// edgeProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, areaMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[edgeI] = cp[edgeI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// label curE = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch = mesh_.boundary().whichPatch(curE);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faPatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, areaMesh>::null()
)
);
}
// add the edge
// label curPatchEdge =
// mesh_.boundary()
// [curBPatch].whichEdge(curE);
label curPatchEdge = curE - gStarts[curBPatch];
patchFields[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
}
}
}
}
forAll(mesh_.boundary(), patchI)
{
// add empty patches
if
(
isA<emptyFaPatch>(mesh_.boundary()[patchI])
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
faPatchField<Type>::New
(
emptyFaPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, areaMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, faPatchField, areaMesh> >
(
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh> >
Foam::faFieldReconstructor::reconstructFaEdgeField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, faePatchField, edgeMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nInternalEdges());
// Create the patch fields
PtrList<faePatchField<Type> > patchFields(mesh_.boundary().size());
labelList gStarts(mesh_.boundary().size(), -1);
if(mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i=1; i<mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i-1] + mesh_.boundary()[i-1].labelList::size();
}
forAll (procMeshes_, procI)
{
const GeometricField<Type, faePatchField, edgeMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
//
{
labelList curAddr(edgeProcAddressing_[procI]);
// forAll (curAddr, addrI)
// {
// curAddr[addrI] -= 1;
// }
internalField.rmap
(
procField.internalField(),
curAddr
);
}
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if(procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for(label i=1; i<procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i-1]
+ procMeshes_[procI].boundary()[i-1].labelList::size();
}
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// faceProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faePatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, edgeMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, edgeI)
{
// label curF = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face turned the right side round
if (curE >= 0)
{
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch =
// mesh_.boundary().whichPatch(curF);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faePatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, edgeMesh>
::null()
)
);
}
// add the face
// label curPatchFace =
// mesh_.boundary()
// [curBPatch].whichEdge(curF);
label curPatchEdge = curE - gStarts[curBPatch];
patchFields[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
else
{
// Internal face
internalField[curE] = curProcPatch[edgeI];
}
}
}
}
}
}
forAll(mesh_.boundary(), patchI)
{
// add empty patches
if
(
isA<emptyFaPatch>(mesh_.boundary()[patchI])
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
faePatchField<Type>::New
(
emptyFaePatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, edgeMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, faePatchField, edgeMesh> >
(
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
// Reconstruct and write all area fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaAreaFields
(
const IOobjectList& objects
)
{
const word& fieldClassName =
GeometricField<Type, faPatchField, areaMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info << " " << fieldIter()->name() << endl;
reconstructFaAreaField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// Reconstruct and write all edge fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaEdgeFields
(
const IOobjectList& objects
)
{
const word& fieldClassName =
GeometricField<Type, faePatchField, edgeMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFaEdgeField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,260 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "processorFaMeshes.H"
#include "Time.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::processorFaMeshes::read()
{
forAll (fvMeshes_, procI)
{
meshes_.set
(
procI,
new faMesh(fvMeshes_[procI])
);
pointProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"pointProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"pointProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
edgeProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"edgeProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"edgeProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
faceProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"faceProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
boundaryProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"boundaryProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorFaMeshes::processorFaMeshes
(
const PtrList<fvMesh>& processorFvMeshes
)
:
fvMeshes_(processorFvMeshes),
meshes_(processorFvMeshes.size()),
pointProcAddressing_(processorFvMeshes.size()),
edgeProcAddressing_(processorFvMeshes.size()),
faceProcAddressing_(processorFvMeshes.size()),
boundaryProcAddressing_(processorFvMeshes.size())
{
read();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Foam::fvMesh::readUpdateState Foam::processorFaMeshes::readUpdate()
// {
// fvMesh::readUpdateState stat = fvMesh::UNCHANGED;
// forAll (databases_, procI)
// {
// // Check if any new meshes need to be read.
// fvMesh::readUpdateState procStat = meshes_[procI].readUpdate();
// /*
// if (procStat != fvMesh::UNCHANGED)
// {
// Info<< "Processor " << procI
// << " at time " << databases_[procI].timeName()
// << " detected mesh change " << procStat
// << endl;
// }
// */
// // Combine into overall mesh change status
// if (stat == fvMesh::UNCHANGED)
// {
// stat = procStat;
// }
// else
// {
// if (stat != procStat)
// {
// FatalErrorIn("processorFaMeshes::readUpdate()")
// << "Processor " << procI
// << " has a different polyMesh at time "
// << databases_[procI].timeName()
// << " compared to any previous processors." << nl
// << "Please check time " << databases_[procI].timeName()
// << " directories on all processors for consistent"
// << " mesh files."
// << exit(FatalError);
// }
// }
// }
// if
// (
// stat == fvMesh::TOPO_CHANGE
// || stat == fvMesh::TOPO_PATCH_CHANGE
// )
// {
// // Reread all meshes and addresssing
// read();
// }
// return stat;
// }
// void Foam::processorFaMeshes::reconstructPoints(fvMesh& mesh)
// {
// // Read the field for all the processors
// PtrList<pointIOField> procsPoints(meshes_.size());
// forAll (meshes_, procI)
// {
// procsPoints.set
// (
// procI,
// new pointIOField
// (
// IOobject
// (
// "points",
// meshes_[procI].time().timeName(),
// polyMesh::meshSubDir,
// meshes_[procI],
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// )
// );
// }
// // Create the new points
// vectorField newPoints(mesh.nPoints());
// forAll (meshes_, procI)
// {
// const vectorField& procPoints = procsPoints[procI];
// // Set the cell values in the reconstructed field
// const labelList& pointProcAddressingI = pointProcAddressing_[procI];
// if (pointProcAddressingI.size() != procPoints.size())
// {
// FatalErrorIn("processorFaMeshes")
// << "problem :"
// << " pointProcAddressingI:" << pointProcAddressingI.size()
// << " procPoints:" << procPoints.size()
// << abort(FatalError);
// }
// forAll(pointProcAddressingI, pointI)
// {
// newPoints[pointProcAddressingI[pointI]] = procPoints[pointI];
// }
// }
// mesh.movePoints(newPoints);
// mesh.write();
// }
// ************************************************************************* //

View File

@ -0,0 +1,142 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
processorFaMeshes
Description
Container for processor mesh addressing.
Author
Zeljko Tukovic, FSB Zagreb
SourceFiles
processorFaMeshes.C
\*---------------------------------------------------------------------------*/
#ifndef processorFaMeshes_H
#define processorFaMeshes_H
#include "PtrList.H"
#include "fvMesh.H"
#include "faMesh.H"
#include "IOobjectList.H"
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorFaMeshes Declaration
\*---------------------------------------------------------------------------*/
class processorFaMeshes
{
// Private data
//- List of processor finite volume meshes
const PtrList<fvMesh>& fvMeshes_;
//- List of processor finite area meshes
PtrList<faMesh> meshes_;
//- List of processor point addressing lists
PtrList<labelIOList> pointProcAddressing_;
//- List of processor face addressing lists
PtrList<labelIOList> edgeProcAddressing_;
//- List of processor cell addressing lists
PtrList<labelIOList> faceProcAddressing_;
//- List of processor boundary addressing lists
PtrList<labelIOList> boundaryProcAddressing_;
// Private Member Functions
//- Read all meshes
void read();
//- Disallow default bitwise copy construct
processorFaMeshes(const processorFaMeshes&);
//- Disallow default bitwise assignment
void operator=(const processorFaMeshes&);
public:
// Constructors
//- Construct from components
processorFaMeshes(const PtrList<fvMesh>& processorFvMeshes);
// Member Functions
//- Update the meshes based on the mesh files saved in
// time directories
// fvMesh::readUpdateState readUpdate();
//- Reconstruct point position after motion in parallel
// void reconstructPoints(faMesh& mesh);
PtrList<faMesh>& meshes()
{
return meshes_;
}
const PtrList<labelIOList>& pointProcAddressing() const
{
return pointProcAddressing_;
}
PtrList<labelIOList>& edgeProcAddressing()
{
return edgeProcAddressing_;
}
const PtrList<labelIOList>& faceProcAddressing() const
{
return faceProcAddressing_;
}
const PtrList<labelIOList>& boundaryProcAddressing() const
{
return boundaryProcAddressing_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -44,6 +44,11 @@ Description
#include "pointFieldReconstructor.H"
#include "reconstructLagrangian.H"
#include "faCFD.H"
#include "faMesh.H"
#include "processorFaMeshes.H"
#include "faFieldReconstructor.H"
#include "cellSet.H"
#include "faceSet.H"
#include "pointSet.H"
@ -710,6 +715,47 @@ int main(int argc, char *argv[])
}
// If there are any FA fields, reconstruct them
if
(
objects.lookupClass(areaScalarField::typeName).size()
|| objects.lookupClass(areaVectorField::typeName).size()
|| objects.lookupClass(areaSphericalTensorField::typeName).size()
|| objects.lookupClass(areaSymmTensorField::typeName).size()
|| objects.lookupClass(areaTensorField::typeName).size()
|| objects.lookupClass(edgeScalarField::typeName).size()
)
{
Info << "Reconstructing FA fields" << nl << endl;
faMesh aMesh(mesh);
processorFaMeshes procFaMeshes(procMeshes.meshes());
faFieldReconstructor faReconstructor
(
aMesh,
procFaMeshes.meshes(),
procFaMeshes.edgeProcAddressing(),
procFaMeshes.faceProcAddressing(),
procFaMeshes.boundaryProcAddressing()
);
faReconstructor.reconstructFaAreaFields<scalar>(objects);
faReconstructor.reconstructFaAreaFields<vector>(objects);
faReconstructor
.reconstructFaAreaFields<sphericalTensor>(objects);
faReconstructor.reconstructFaAreaFields<symmTensor>(objects);
faReconstructor.reconstructFaAreaFields<tensor>(objects);
faReconstructor.reconstructFaEdgeFields<scalar>(objects);
}
else
{
Info << "No FA fields" << nl << endl;
}
if (!noReconstructSets)
{
// Scan to find all sets

View File

@ -97,25 +97,6 @@ using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// file-scope helper
static bool inFileNameList
(
const fileNameList& nameList,
const word& name
)
{
forAll(nameList, i)
{
if (nameList[i] == name)
{
return true;
}
}
return false;
}
int main(int argc, char *argv[])
{
timeSelector::addOptions();
@ -641,7 +622,7 @@ int main(int argc, char *argv[])
Info<< "Write " << cloudName << " (";
bool cloudExists = inFileNameList(currentCloudDirs, cloudName);
bool cloudExists = currentCloudDirs.found(cloudName);
reduce(cloudExists, orOp<bool>());
{

View File

@ -3,11 +3,13 @@ EXE_INC = \
-I$(LIB_SRC)/conversion/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lconversion \
-ldynamicMesh \
-lfiniteArea \
-llagrangian \
-lgenericPatchFields

View File

@ -155,6 +155,7 @@ Note
#include "Cloud.H"
#include "passiveParticle.H"
#include "stringOps.H"
#include "areaFields.H"
#include "meshSubsetHelper.H"
#include "readFields.H"
@ -862,6 +863,119 @@ int main(int argc, char *argv[])
);
// Finite-area mesh and fields - need not exist
autoPtr<faMesh> aMeshPtr;
{
const bool throwing = FatalError.throwExceptions();
try
{
aMeshPtr.reset(new faMesh(meshRef.baseMesh()));
}
catch (Foam::error& err)
{
aMeshPtr.clear();
}
FatalError.throwExceptions(throwing);
}
if (aMeshPtr.valid())
{
// Construct the area fields
PtrList<const areaScalarField> aScalarFld;
PtrList<const areaVectorField> aVectorFld;
PtrList<const areaSphericalTensorField> aSphTensorf;
PtrList<const areaSymmTensorField> aSymTensorFld;
PtrList<const areaTensorField> aTensorFld;
const faMesh& aMesh = aMeshPtr();
if (!specifiedFields || selectedFields.size())
{
readFields
(
aMesh,
objects,
selectedFields,
aScalarFld
);
print(" areaScalar :", Info, aScalarFld);
readFields
(
aMesh,
objects,
selectedFields,
aVectorFld
);
print(" areaVector :", Info, aVectorFld);
readFields
(
aMesh,
objects,
selectedFields,
aSphTensorf
);
print(" areaSphericalTensor :", Info, aSphTensorf);
readFields
(
aMesh,
objects,
selectedFields,
aSymTensorFld
);
print(" areaSymmTensor :", Info, aSymTensorFld);
readFields
(
aMesh,
objects,
selectedFields,
aTensorFld
);
print(" areaTensor :", Info, aTensorFld);
}
const label nAreaFields =
(
aScalarFld.size()
+ aVectorFld.size()
+ aSphTensorf.size()
+ aSymTensorFld.size()
+ aTensorFld.size()
);
fileName outputName(fvPath/"finiteArea");
mkDir(outputName);
const auto& pp = aMesh.patch();
vtk::surfaceMeshWriter writer
(
pp,
aMesh.name(),
outputName/"finiteArea" + "_" + timeDesc,
fmtType
);
// Number of fields
writer.beginCellData(nAreaFields);
writer.write(aScalarFld);
writer.write(aVectorFld);
writer.write(aSphTensorf);
writer.write(aSymTensorFld);
writer.write(aTensorFld);
writer.endCellData();
writer.writeFooter();
}
PtrList<const pointScalarField> pScalarFld;
PtrList<const pointVectorField> pVectorFld;
PtrList<const pointSphericalTensorField> pSphTensorFld;

View File

@ -72,6 +72,38 @@ label readFields
}
template<class GeoField>
void readFields
(
const typename GeoField::Mesh& mesh,
const IOobjectList& objects,
const HashSet<word>& selectedFields,
PtrList<const GeoField>& fields
)
{
// Search list of objects for fields of type GeomField
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
// Construct the fields
fields.setSize(fieldObjects.size());
label nFields = 0;
forAllIters(fieldObjects, iter)
{
if (selectedFields.empty() || selectedFields.found(iter()->name()))
{
fields.set
(
nFields++,
new GeoField(*iter(), mesh)
);
}
}
fields.setSize(nFields);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -13,6 +13,7 @@ include_directories(
$ENV{WM_PROJECT_DIR}/src/OpenFOAM/lnInclude
$ENV{WM_PROJECT_DIR}/src/OSspecific/$ENV{WM_OSTYPE}/lnInclude
$ENV{WM_PROJECT_DIR}/src/conversion/lnInclude
$ENV{WM_PROJECT_DIR}/src/finiteArea/lnInclude
$ENV{WM_PROJECT_DIR}/src/finiteVolume/lnInclude
${PROJECT_SOURCE_DIR}/../foamPv
${PROJECT_SOURCE_DIR}/../vtkPVFoam
@ -66,6 +67,7 @@ target_link_libraries(
vtkPVFoam-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR}
foamPv-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR}
conversion
finiteArea
finiteVolume
OpenFOAM
)

View File

@ -309,16 +309,16 @@ int vtkPVFoamReader::RequestData
// Get the requested time step.
// We only support requests for a single time step
int nRequestTime = 0;
double requestTime[nInfo];
std::vector<double> requestTime;
requestTime.reserve(nInfo);
// taking port0 as the lead for other outputs would be nice, but fails when
// a filter is added - we need to check everything
// but since PREVIOUS_UPDATE_TIME_STEPS() is protected, relay the logic
// to the vtkPVFoam::setTime() method
for (int infoI = 0; infoI < nInfo; ++infoI)
for (int infoi = 0; infoi < nInfo; ++infoi)
{
vtkInformation *outInfo = outputVector->GetInformationObject(infoI);
vtkInformation *outInfo = outputVector->GetInformationObject(infoi);
const int nsteps =
outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
@ -329,7 +329,7 @@ int vtkPVFoamReader::RequestData
&& nsteps > 0
)
{
requestTime[nRequestTime] =
const double timeValue =
(
1 == nsteps
// Only one time-step available, UPDATE_TIME_STEP is unreliable
@ -337,16 +337,13 @@ int vtkPVFoamReader::RequestData
: outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())
);
// outInfo->Set(vtkDataObject::DATA_TIME_STEP(), requestTime[nRequestTime]);
// this->SetTimeValue(requestedTimeValue);
++nRequestTime;
// outInfo->Set(vtkDataObject::DATA_TIME_STEP(), timeValue);
// this->SetTimeValue(timeValue);
requestTime.push_back(timeValue);
}
}
if (nRequestTime)
{
backend_->setTime(nRequestTime, requestTime);
}
backend_->setTime(requestTime);
vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
(

View File

@ -25,9 +25,9 @@ Class
vtkPVFoamReader
Description
reads a dataset in OpenFOAM format
Reads a dataset in OpenFOAM format
vtkPVblockMeshReader creates an multiblock dataset.
vtkPVFoamReader creates an multiblock dataset.
It uses the OpenFOAM infrastructure (fvMesh, etc) to handle mesh and
field data.

View File

@ -43,6 +43,35 @@ namespace Foam
defineTypeNameAndDebug(foamPvCore, 0);
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::Ostream& Foam::foamPvCore::printDataArraySelection
(
Ostream& os,
vtkDataArraySelection* select
)
{
if (!select)
{
return os;
}
const int n = select->GetNumberOfArrays();
os << n << '(';
for (int i=0; i < n; ++i)
{
if (i) os << ' ';
os << select->GetArrayName(i) << '='
<< (select->GetArraySetting(i) ? 1 : 0);
}
os << ')';
return os;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::foamPvCore::addToBlock
@ -229,10 +258,8 @@ Foam::word Foam::foamPvCore::getFoamName(const std::string& str)
// Already checked for valid/invalid chars
return word(str.substr(beg, beg+end), false);
}
else
{
return word::null;
}
return word::null;
}

View File

@ -119,13 +119,51 @@ public:
setStart(startAt);
}
//- Increment the size
void operator+=(label n)
{
setSize(size() + n);
}
//- True if the labelRange intersects any key in the Map
template<class T>
bool intersects(const Map<T>& map) const
{
for (const label idx : *this)
{
if (map.found(idx))
{
return true;
}
}
return false;
}
//- The intersection ids with keys in the Map
template<class T>
List<label> intersection(const Map<T>& map) const
{
List<label> indices(Foam::min(map.size(), this->size()));
if (indices.size())
{
label n = 0;
for (const label idx : *this)
{
if (map.found(idx))
{
indices[n++] = idx;
}
}
indices.setSize(n);
}
return indices;
}
}; // End class arrayRange
@ -139,6 +177,7 @@ private:
//- Disallow default bitwise assignment
void operator=(const foamPvCore&) = delete;
public:
//- Static data members
@ -146,8 +185,15 @@ public:
//- Construct null
foamPvCore()
{}
foamPvCore() = default;
//- Print information about vtkDataArraySelection
static Ostream& printDataArraySelection
(
Ostream& os,
vtkDataArraySelection* select
);
//- Convenience method for the VTK multiblock API

View File

@ -152,7 +152,8 @@ void Foam::foamPvCore::setSelectedArrayEntries
)
{
const int n = select->GetNumberOfArrays();
// disable everything not explicitly enabled
// Disable everything not explicitly enabled
select->DisableAllArrays();
// Loop through entries, enabling as required

View File

@ -29,7 +29,7 @@ Description
#ifndef foamPvFields_H
#define foamPvFields_H
#include "volFields.H"
#include "symmTensor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -40,28 +40,18 @@ namespace Foam
Class foamPvFields Declaration
\*---------------------------------------------------------------------------*/
class foamPvFields
struct foamPvFields
{
// Private Member Functions
//- Disallow default bitwise copy construct
foamPvFields(const foamPvFields&) = delete;
//- Disallow default bitwise assignment
void operator=(const foamPvFields&) = delete;
public:
//- Remapping for some data types
template<class Type>
inline static void remapTuple(float vec[])
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
}; // End class foamPvFields
// Template specialization for symmTensor
template<>
inline void Foam::foamPvFields::remapTuple<Foam::symmTensor>(float vec[])

View File

@ -4,6 +4,7 @@ EXE_INC = \
${c++LESSWARN} \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
@ -14,6 +15,7 @@ EXE_INC = \
-I../PVFoamReader
LIB_LIBS = \
-lfiniteArea \
-ldynamicMesh \
-lconversion \
-lgenericPatchFields \

View File

@ -27,9 +27,12 @@ License
#include "vtkPVFoamReader.h"
// OpenFOAM includes
#include "areaFaMesh.H"
#include "faMesh.H"
#include "fvMesh.H"
#include "Time.H"
#include "patchZones.H"
#include "IOobjectList.H"
// VTK includes
#include "vtkDataArraySelection.h"
@ -108,7 +111,7 @@ void Foam::vtkPVFoam::resetCounters()
// Reset array range information (ids and sizes)
rangeVolume_.reset();
rangePatches_.reset();
rangeLagrangian_.reset();
rangeClouds_.reset();
rangeCellZones_.reset();
rangeFaceZones_.reset();
rangePointZones_.reset();
@ -131,50 +134,49 @@ bool Foam::vtkPVFoam::addOutputBlock
vtkSmartPointer<vtkMultiBlockDataSet> block;
int datasetNo = 0;
for (auto partId : selector)
const List<label> partIds = selector.intersection(selectedPartIds_);
for (const auto partId : partIds)
{
if (selectedPartIds_.found(partId))
const auto& longName = selectedPartIds_[partId];
const word shortName = getFoamName(longName);
auto iter = cache.find(longName);
if (iter.found() && iter.object().dataset)
{
const auto& longName = selectedPartIds_[partId];
const word shortName = getFoamName(longName);
auto dataset = iter.object().dataset;
auto iter = cache.find(longName);
if (iter.found() && iter.object().dataset)
if (singleDataset)
{
auto dataset = iter.object().dataset;
if (singleDataset)
{
output->SetBlock(blockNo, dataset);
output->GetMetaData(blockNo)->Set
(
vtkCompositeDataSet::NAME(),
shortName.c_str()
);
++datasetNo;
break;
}
else if (datasetNo == 0)
{
block = vtkSmartPointer<vtkMultiBlockDataSet>::New();
output->SetBlock(blockNo, block);
output->GetMetaData(blockNo)->Set
(
vtkCompositeDataSet::NAME(),
selector.name()
);
}
block->SetBlock(datasetNo, dataset);
block->GetMetaData(datasetNo)->Set
output->SetBlock(blockNo, dataset);
output->GetMetaData(blockNo)->Set
(
vtkCompositeDataSet::NAME(),
shortName.c_str()
);
++datasetNo;
break;
}
else if (datasetNo == 0)
{
block = vtkSmartPointer<vtkMultiBlockDataSet>::New();
output->SetBlock(blockNo, block);
output->GetMetaData(blockNo)->Set
(
vtkCompositeDataSet::NAME(),
selector.name()
);
}
block->SetBlock(datasetNo, dataset);
block->GetMetaData(datasetNo)->Set
(
vtkCompositeDataSet::NAME(),
shortName.c_str()
);
++datasetNo;
}
}
@ -182,17 +184,22 @@ bool Foam::vtkPVFoam::addOutputBlock
}
int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
int Foam::vtkPVFoam::setTime(const std::vector<double>& requestTimes)
{
if (requestTimes.empty())
{
return 0;
}
Time& runTime = dbPtr_();
// Get times list
instantList Times = runTime.times();
int nearestIndex = timeIndex_;
for (int requestI = 0; requestI < nRequest; ++requestI)
for (const double& timeValue : requestTimes)
{
int index = Time::findClosestTimeIndex(Times, requestTimes[requestI]);
const int index = Time::findClosestTimeIndex(Times, timeValue);
if (index >= 0 && index != timeIndex_)
{
nearestIndex = index;
@ -208,13 +215,15 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
if (debug)
{
Info<< "<beg> setTime(";
for (int requestI = 0; requestI < nRequest; ++requestI)
unsigned reqi = 0;
for (const double& timeValue : requestTimes)
{
if (requestI) Info<< ", ";
Info<< requestTimes[requestI];
if (reqi) Info<< ", ";
Info<< timeValue;
++reqi;
}
Info<< ") - previousIndex = " << timeIndex_
<< ", nearestIndex = " << nearestIndex << endl;
<< ", nearestIndex = " << nearestIndex << nl;
}
// See what has changed
@ -223,8 +232,13 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
timeIndex_ = nearestIndex;
runTime.setTime(Times[nearestIndex], nearestIndex);
// When the changes, so do the fields
meshState_ = meshPtr_ ? meshPtr_->readUpdate() : polyMesh::TOPO_CHANGE;
// When mesh changes, so do fields
meshState_ =
(
volMeshPtr_
? volMeshPtr_->readUpdate()
: polyMesh::TOPO_CHANGE
);
reader_->UpdateProgress(0.05);
@ -237,7 +251,7 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
Info<< "<end> setTime() - selectedTime="
<< Times[nearestIndex].name() << " index=" << timeIndex_
<< "/" << Times.size()
<< " meshUpdateState=" << updateStateName(meshState_) << endl;
<< " meshUpdateState=" << updateStateName(meshState_) << nl;
}
return nearestIndex;
@ -260,15 +274,17 @@ Foam::vtkPVFoam::vtkPVFoam
:
reader_(reader),
dbPtr_(nullptr),
meshPtr_(nullptr),
volMeshPtr_(nullptr),
areaMeshPtr_(nullptr),
meshRegion_(polyMesh::defaultRegion),
meshDir_(polyMesh::meshSubDir),
timeIndex_(-1),
decomposePoly_(false),
meshState_(polyMesh::TOPO_CHANGE),
rangeVolume_("unzoned"),
rangeVolume_("volMesh"),
rangeArea_("areaMesh"),
rangePatches_("patch"),
rangeLagrangian_("lagrangian"),
rangeClouds_("lagrangian"),
rangeCellZones_("cellZone"),
rangeFaceZones_("faceZone"),
rangePointZones_("pointZone"),
@ -278,7 +294,7 @@ Foam::vtkPVFoam::vtkPVFoam
{
if (debug)
{
Info<< "vtkPVFoam - " << FileName << endl;
Info<< "vtkPVFoam - " << FileName << nl;
printMemory();
}
@ -315,13 +331,13 @@ Foam::vtkPVFoam::vtkPVFoam
// could be stringent and insist the prefix match the directory name...
// Note: cannot use fileName::name() due to the embedded '{}'
string caseName(fileName(FileName).lessExt());
string::size_type beg = caseName.find_last_of("/{");
string::size_type end = caseName.find('}', beg);
const auto beg = caseName.find_last_of("/{");
const auto end = caseName.find('}', beg);
if
(
beg != string::npos && caseName[beg] == '{'
&& end != string::npos && end == caseName.size()-1
beg != std::string::npos && caseName[beg] == '{'
&& end != std::string::npos && end == caseName.size()-1
)
{
meshRegion_ = caseName.substr(beg+1, end-beg-1);
@ -343,7 +359,7 @@ Foam::vtkPVFoam::vtkPVFoam
Info<< "fullCasePath=" << fullCasePath << nl
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
<< "FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << nl
<< "region=" << meshRegion_ << endl;
<< "region=" << meshRegion_ << nl;
}
// Create time object
@ -369,10 +385,11 @@ Foam::vtkPVFoam::~vtkPVFoam()
{
if (debug)
{
Info<< "~vtkPVFoam" << endl;
Info<< "~vtkPVFoam" << nl;
}
delete meshPtr_;
delete volMeshPtr_;
delete areaMeshPtr_;
}
@ -383,64 +400,62 @@ void Foam::vtkPVFoam::updateInfo()
if (debug)
{
Info<< "<beg> updateInfo"
<< " [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "] timeIndex="
<< timeIndex_ << endl;
<< " [volMeshPtr=" << (volMeshPtr_ ? "set" : "nullptr")
<< "] timeIndex="
<< timeIndex_ << nl;
}
resetCounters();
vtkDataArraySelection* partSelection = reader_->GetPartSelection();
// there are two ways to ensure we have the correct list of parts:
// 1. remove everything and then set particular entries 'on'
// 2. build a 'char **' list and call SetArraysWithDefault()
//
// Nr. 2 has the potential advantage of not touching the modification
// time of the vtkDataArraySelection, but the qt/paraview proxy
// layer doesn't care about that anyhow.
HashSet<string> enabled;
if (!partSelection->GetNumberOfArrays() && !meshPtr_)
// Part selection
{
// Fake enable 'internalMesh' on the first call
enabled = { "internalMesh" };
}
else
{
// preserve the enabled selections
enabled = getSelectedArraySet(partSelection);
vtkDataArraySelection* select = reader_->GetPartSelection();
// There are two ways to ensure we have the correct list of parts:
// 1. remove everything and then set particular entries 'on'
// 2. build a 'char **' list and call SetArraysWithDefault()
//
// Nr. 2 has the potential advantage of not touching the modification
// time of the vtkDataArraySelection, but the qt/paraview proxy
// layer doesn't care about that anyhow.
HashSet<string> enabled;
if (!select->GetNumberOfArrays() && !volMeshPtr_)
{
// Fake enable 'internalMesh' on the first call
enabled = { "internalMesh" };
}
else
{
// Preserve the enabled selections
enabled = getSelectedArraySet(select);
}
select->RemoveAllArrays(); // Clear existing list
// Update mesh parts list - add Lagrangian at the bottom
updateInfoInternalMesh(select);
updateInfoPatches(select, enabled);
updateInfoSets(select);
updateInfoZones(select);
updateInfoAreaMesh(select);
updateInfoLagrangian(select);
setSelectedArrayEntries(select, enabled); // Adjust/restore selected
}
// Clear current mesh parts list
partSelection->RemoveAllArrays();
// Volume and area fields - includes save/restore of selected
updateInfoContinuumFields(reader_->GetVolFieldSelection());
// Update mesh parts list - add Lagrangian at the bottom
updateInfoInternalMesh(partSelection);
updateInfoPatches(partSelection, enabled);
updateInfoSets(partSelection);
updateInfoZones(partSelection);
updateInfoLagrangian(partSelection);
// Point fields - includes save/restore of selected
updateInfoPointFields(reader_->GetPointFieldSelection());
// Adjust/restore the enabled selections
setSelectedArrayEntries(partSelection, enabled);
// Update volume, point and lagrangian fields
updateInfoFields<fvPatchField, volMesh>
(
reader_->GetVolFieldSelection()
);
updateInfoFields<pointPatchField, pointMesh>
(
reader_->GetPointFieldSelection()
);
updateInfoLagrangianFields
(
reader_->GetLagrangianFieldSelection()
);
// Lagrangian fields - includes save/restore of selected
updateInfoLagrangianFields(reader_->GetLagrangianFieldSelection());
if (debug)
{
Info<< "<end> updateInfo" << endl;
Info<< "<end> updateInfo" << nl;
}
}
@ -531,26 +546,29 @@ void Foam::vtkPVFoam::Update
{
if (debug)
{
Info<< "<beg> updateFoamMesh" << endl;
Info<< "<beg> updateFoamMesh" << nl;
printMemory();
}
if (!caching)
{
delete meshPtr_;
meshPtr_ = nullptr;
delete volMeshPtr_;
delete areaMeshPtr_;
volMeshPtr_ = nullptr;
areaMeshPtr_ = nullptr;
}
// Check to see if the OpenFOAM mesh has been created
if (!meshPtr_)
if (!volMeshPtr_)
{
if (debug)
{
Info<< "Creating OpenFOAM mesh for region " << meshRegion_
<< " at time=" << dbPtr_().timeName() << endl;
<< " at time=" << dbPtr_().timeName() << nl;
}
meshPtr_ = new fvMesh
volMeshPtr_ = new fvMesh
(
IOobject
(
@ -567,13 +585,27 @@ void Foam::vtkPVFoam::Update
{
if (debug)
{
Info<< "Using existing OpenFOAM mesh" << endl;
Info<< "Using existing OpenFOAM mesh" << nl;
}
}
if (rangeArea_.intersects(selectedPartIds_))
{
if (!areaMeshPtr_)
{
areaMeshPtr_ = new faMesh(*volMeshPtr_);
}
}
else
{
delete areaMeshPtr_;
areaMeshPtr_ = nullptr;
}
if (debug)
{
Info<< "<end> updateFoamMesh" << endl;
Info<< "<end> updateFoamMesh" << nl;
printMemory();
}
}
@ -600,6 +632,8 @@ void Foam::vtkPVFoam::Update
reader_->UpdateProgress(0.7);
}
convertMeshArea();
convertMeshLagrangian();
reader_->UpdateProgress(0.8);
@ -607,8 +641,9 @@ void Foam::vtkPVFoam::Update
// Update fields
convertVolFields();
convertPointFields();
convertLagrangianFields();
convertAreaFields();
convertLagrangianFields();
// Assemble multiblock output
addOutputBlock(output, cachedVtu_, rangeVolume_, true); // One dataset
@ -619,16 +654,17 @@ void Foam::vtkPVFoam::Update
addOutputBlock(output, cachedVtu_, rangeCellSets_);
addOutputBlock(output, cachedVtp_, rangeFaceSets_);
addOutputBlock(output, cachedVtp_, rangePointSets_);
addOutputBlock(output, cachedVtp_, rangeArea_);
addOutputBlock
(
(outputLagrangian ? outputLagrangian : output),
cachedVtp_,
rangeLagrangian_
rangeClouds_
);
if (debug)
{
Info<< "done reader part" << nl << endl;
Info<< "done reader part" << nl << nl;
}
reader_->UpdateProgress(0.95);
@ -655,8 +691,11 @@ void Foam::vtkPVFoam::UpdateFinalize()
{
if (!reader_->GetMeshCaching())
{
delete meshPtr_;
meshPtr_ = nullptr;
delete volMeshPtr_;
delete areaMeshPtr_;
volMeshPtr_ = nullptr;
areaMeshPtr_ = nullptr;
}
reader_->UpdateProgress(1.0);
@ -674,20 +713,20 @@ std::vector<double> Foam::vtkPVFoam::findTimes(const bool skipZero) const
// find the first time for which this mesh appears to exist
label begIndex = timeLst.size();
forAll(timeLst, timeI)
forAll(timeLst, timei)
{
if
(
IOobject
(
"points",
timeLst[timeI].name(),
timeLst[timei].name(),
meshDir_,
runTime
).typeHeaderOk<pointIOField>(false, false)
)
{
begIndex = timeI;
begIndex = timei;
break;
}
}
@ -735,15 +774,15 @@ void Foam::vtkPVFoam::renderPatchNames
const bool show
)
{
// always remove old actors first
// Always remove old actors first
forAll(patchTextActors_, patchi)
for (auto& actor : patchTextActors_)
{
renderer->RemoveViewProp(patchTextActors_[patchi]);
renderer->RemoveViewProp(actor);
}
patchTextActors_.clear();
if (show && meshPtr_)
if (show && volMeshPtr_)
{
// get the display patches, strip off any prefix/suffix
hashedWordList selectedPatches = getSelected
@ -757,7 +796,7 @@ void Foam::vtkPVFoam::renderPatchNames
return;
}
const polyBoundaryMesh& pbMesh = meshPtr_->boundaryMesh();
const polyBoundaryMesh& pbMesh = volMeshPtr_->boundaryMesh();
// Find the total number of zones
// Each zone will take the patch name
@ -784,19 +823,19 @@ void Foam::vtkPVFoam::renderPatchNames
boolList featEdge(pp.nEdges(), false);
forAll(edgeFaces, edgeI)
forAll(edgeFaces, edgei)
{
const labelList& eFaces = edgeFaces[edgeI];
const labelList& eFaces = edgeFaces[edgei];
if (eFaces.size() == 1)
{
// Note: could also do ones with > 2 faces but this gives
// too many zones for baffles
featEdge[edgeI] = true;
featEdge[edgei] = true;
}
else if (mag(n[eFaces[0]] & n[eFaces[1]]) < 0.5)
{
featEdge[edgeI] = true;
featEdge[edgei] = true;
}
}
@ -808,7 +847,7 @@ void Foam::vtkPVFoam::renderPatchNames
labelList zoneNFaces(pZones.nZones(), 0);
// Create storage for additional zone centres
forAll(zoneNFaces, zoneI)
forAll(zoneNFaces, zonei)
{
zoneCentre[patchi].append(Zero);
}
@ -816,14 +855,14 @@ void Foam::vtkPVFoam::renderPatchNames
// Do averaging per individual zone
forAll(pp, facei)
{
label zoneI = pZones[facei];
zoneCentre[patchi][zoneI] += pp[facei].centre(pp.points());
zoneNFaces[zoneI]++;
const label zonei = pZones[facei];
zoneCentre[patchi][zonei] += pp[facei].centre(pp.points());
zoneNFaces[zonei]++;
}
forAll(zoneCentre[patchi], zoneI)
forAll(zoneCentre[patchi], zonei)
{
zoneCentre[patchi][zoneI] /= zoneNFaces[zoneI];
zoneCentre[patchi][zonei] /= zoneNFaces[zonei];
}
}
@ -842,7 +881,7 @@ void Foam::vtkPVFoam::renderPatchNames
if (debug)
{
Info<< "displayed zone centres = " << displayZoneI << nl
<< "zones per patch = " << nZones << endl;
<< "zones per patch = " << nZones << nl;
}
// Set the size of the patch labels to max number of zones
@ -850,7 +889,7 @@ void Foam::vtkPVFoam::renderPatchNames
if (debug)
{
Info<< "constructing patch labels" << endl;
Info<< "constructing patch labels" << nl;
}
// Actor index
@ -875,7 +914,7 @@ void Foam::vtkPVFoam::renderPatchNames
{
Info<< "patch name = " << pp.name() << nl
<< "anchor = " << zoneCentre[patchi][globalZoneI] << nl
<< "globalZoneI = " << globalZoneI << endl;
<< "globalZoneI = " << globalZoneI << nl;
}
// Into a list for later removal
@ -892,9 +931,9 @@ void Foam::vtkPVFoam::renderPatchNames
}
// Add text to each renderer
forAll(patchTextActors_, actori)
for (auto& actor : patchTextActors_)
{
renderer->AddViewProp(patchTextActors_[actori]);
renderer->AddViewProp(actor);
}
}
@ -902,10 +941,10 @@ void Foam::vtkPVFoam::renderPatchNames
void Foam::vtkPVFoam::PrintSelf(ostream& os, vtkIndent indent) const
{
os << indent << "Number of nodes: "
<< (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n";
<< (volMeshPtr_ ? volMeshPtr_->nPoints() : 0) << "\n";
os << indent << "Number of cells: "
<< (meshPtr_ ? meshPtr_->nCells() : 0) << "\n";
<< (volMeshPtr_ ? volMeshPtr_->nCells() : 0) << "\n";
os << indent << "Number of available time steps: "
<< (dbPtr_.valid() ? dbPtr_().times().size() : 0) << "\n";
@ -918,8 +957,8 @@ void Foam::vtkPVFoam::printInfo() const
{
std::cout
<< "Region: " << meshRegion_ << "\n"
<< "nPoints: " << (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n"
<< "nCells: " << (meshPtr_ ? meshPtr_->nCells() : 0) << "\n"
<< "nPoints: " << (volMeshPtr_ ? volMeshPtr_->nPoints() : 0) << "\n"
<< "nCells: " << (volMeshPtr_ ? volMeshPtr_->nCells() : 0) << "\n"
<< "nTimes: "
<< (dbPtr_.valid() ? dbPtr_().times().size() : 0) << "\n";

View File

@ -99,6 +99,7 @@ namespace Foam
// OpenFOAM class forward declarations
class argList;
class Time;
class faMesh;
class fvMesh;
class IOobjectList;
class polyPatch;
@ -127,9 +128,8 @@ class vtkPVFoam
// with the output fields.
// The original copy is reused for different timestep
template<class DataType>
class foamVtkCaching
struct foamVtkCaching
{
public:
typedef DataType dataType;
//- The geometry, without any cell/point data
@ -208,7 +208,7 @@ class vtkPVFoam
//- Bookkeeping for vtkPolyData
class foamVtpData
struct foamVtpData
:
public foamVtkCaching<vtkPolyData>,
public foamVtkMeshMaps
@ -216,7 +216,7 @@ class vtkPVFoam
//- Bookkeeping for vtkUnstructuredGrid
class foamVtuData
struct foamVtuData
:
public foamVtkCaching<vtkUnstructuredGrid>,
public foamVtkMeshMaps
@ -231,8 +231,11 @@ class vtkPVFoam
//- OpenFOAM time control
autoPtr<Time> dbPtr_;
//- OpenFOAM mesh
fvMesh* meshPtr_;
//- OpenFOAM finite volume mesh
fvMesh* volMeshPtr_;
//- OpenFOAM finite area mesh
faMesh* areaMeshPtr_;
//- The mesh region
word meshRegion_;
@ -262,8 +265,9 @@ class vtkPVFoam
// used to index into selectedPartIds and thus indirectly into
// cachedVtp, cachedVtu
arrayRange rangeVolume_;
arrayRange rangeArea_;
arrayRange rangePatches_;
arrayRange rangeLagrangian_;
arrayRange rangeClouds_;
arrayRange rangeCellZones_;
arrayRange rangeFaceZones_;
arrayRange rangePointZones_;
@ -295,6 +299,9 @@ class vtkPVFoam
//- Internal mesh info
void updateInfoInternalMesh(vtkDataArraySelection* select);
//- Finite area mesh info
void updateInfoAreaMesh(vtkDataArraySelection* select);
//- Lagrangian info
void updateInfoLagrangian(vtkDataArraySelection* select);
@ -326,18 +333,28 @@ class vtkPVFoam
template<template<class> class patchType, class meshType>
void updateInfoFields
(
vtkDataArraySelection* select
vtkDataArraySelection* select,
const IOobjectList& objects
);
//- Volume/Area field info
void updateInfoContinuumFields(vtkDataArraySelection* select);
//- Point field info
void updateInfoPointFields(vtkDataArraySelection* select);
//- Lagrangian field info
void updateInfoLagrangianFields(vtkDataArraySelection* select);
// Mesh conversion functions
//- Convert InternalMesh
//- Convert internalMesh
void convertMeshVolume();
//- Convert areaMesh
void convertMeshArea();
//- Convert Lagrangian points
void convertMeshLagrangian();
@ -490,9 +507,12 @@ class vtkPVFoam
) const;
//- Convert volume fields
//- Convert finite volume fields
void convertVolFields();
//- Convert finite area fields
void convertAreaFields();
//- Convert point fields
void convertPointFields();
@ -528,6 +548,14 @@ class vtkPVFoam
const IOobjectList& objects
);
//- Area fields - all types
template<class Type>
void convertAreaFields
(
const faMesh& mesh,
const IOobjectList& objects
);
//- Volume field - all selected parts
template<class Type>
void convertVolFieldBlock
@ -631,7 +659,7 @@ public:
//- Set the runTime to the first plausible request time,
// returns the timeIndex
// sets to "constant" on error
int setTime(int count, const double requestTimes[]);
int setTime(const std::vector<double>& requestTimes);
//- The current time index

View File

@ -38,6 +38,8 @@ InClass
#include "zeroGradientFvPatchField.H"
#include "interpolatePointToCell.H"
#include "foamPvFields.H"
#include "areaFaMesh.H"
#include "areaFields.H"
// vtk includes
#include "vtkFloatArray.h"
@ -69,7 +71,7 @@ void Foam::vtkPVFoam::convertVolField
{
if (debug)
{
Info<< "convertVolField interpolating:" << fld.name() << endl;
Info<< "convertVolField interpolating:" << fld.name() << nl;
}
ptfPtr.reset
@ -83,12 +85,12 @@ void Foam::vtkPVFoam::convertVolField
convertVolFieldBlock(fld, ptfPtr, rangeCellSets_); // cellSets
// Patches - currently skip field conversion for groups
for (auto partId : rangePatches_)
for
(
const auto partId
: rangePatches_.intersection(selectedPartIds_)
)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
auto iter = cachedVtp_.find(longName);
@ -97,10 +99,12 @@ void Foam::vtkPVFoam::convertVolField
// Should not happen, but for safety require a vtk geometry
continue;
}
foamVtpData& vtpData = iter.object();
auto dataset = vtpData.dataset;
const labelList& patchIds = vtpData.additionalIds();
if (patchIds.empty())
{
continue;
@ -184,12 +188,12 @@ void Foam::vtkPVFoam::convertVolField
// Face Zones
for (auto partId : rangeFaceZones_)
for
(
const auto partId
: rangeFaceZones_.intersection(selectedPartIds_)
)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word zoneName = getFoamName(longName);
@ -199,6 +203,7 @@ void Foam::vtkPVFoam::convertVolField
// Should not happen, but for safety require a vtk geometry
continue;
}
foamVtpData& vtpData = iter.object();
auto dataset = vtpData.dataset;
@ -224,12 +229,12 @@ void Foam::vtkPVFoam::convertVolField
// Face Sets
for (auto partId : rangeFaceSets_)
for
(
const auto partId
: rangeFaceSets_.intersection(selectedPartIds_)
)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word selectName = getFoamName(longName);
@ -349,12 +354,12 @@ void Foam::vtkPVFoam::convertVolFieldBlock
const arrayRange& range
)
{
for (auto partId : range)
for
(
const auto partId
: range.intersection(selectedPartIds_)
)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
auto iter = cachedVtu_.find(longName);
@ -363,6 +368,7 @@ void Foam::vtkPVFoam::convertVolFieldBlock
// Should not happen, but for safety require a vtk geometry
continue;
}
foamVtuData& vtuData = iter.object();
auto dataset = vtuData.dataset;
@ -387,6 +393,65 @@ void Foam::vtkPVFoam::convertVolFieldBlock
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//
// area-fields
//
template<class Type>
void Foam::vtkPVFoam::convertAreaFields
(
const faMesh& mesh,
const IOobjectList& objects
)
{
typedef GeometricField<Type, faPatchField, areaMesh> FieldType;
const List<label> partIds =
rangeArea_.intersection(selectedPartIds_);
if (partIds.empty())
{
return;
}
forAllConstIters(objects, iter)
{
// Restrict to GeometricField<Type, ...>
const auto& ioobj = *(iter.object());
if (ioobj.headerClassName() == FieldType::typeName)
{
// Load field
FieldType fld(ioobj, mesh);
// Convert
for (const auto partId : partIds)
{
const auto& longName = selectedPartIds_[partId];
auto iter = cachedVtp_.find(longName);
if (!iter.found() || !iter.object().dataset)
{
// Should not happen, but for safety require a vtk geometry
continue;
}
foamVtpData& vtpData = iter.object();
auto dataset = vtpData.dataset;
vtkSmartPointer<vtkFloatArray> cdata = convertFieldToVTK
(
fld.name(),
fld
);
dataset->GetCellData()->AddArray(cdata);
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//
@ -416,7 +481,7 @@ void Foam::vtkPVFoam::convertPointFields
if (debug)
{
Info<< "convertPointFields : " << fieldName << endl;
Info<< "convertPointFields : " << fieldName << nl;
}
FieldType pfld(ioobj, pMesh);
@ -426,12 +491,12 @@ void Foam::vtkPVFoam::convertPointFields
convertPointFieldBlock(pfld, rangeCellSets_); // cellSets
// Patches - currently skip field conversion for groups
for (auto partId : rangePatches_)
for
(
const auto partId
: rangePatches_.intersection(selectedPartIds_)
)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
auto iter = cachedVtp_.find(longName);
@ -440,6 +505,7 @@ void Foam::vtkPVFoam::convertPointFields
// Should not happen, but for safety require a vtk geometry
continue;
}
foamVtpData& vtpData = iter.object();
auto dataset = vtpData.dataset;
@ -461,12 +527,12 @@ void Foam::vtkPVFoam::convertPointFields
}
// Face Zones
for (auto partId : rangeFaceZones_)
for
(
const auto partId
: rangeFaceZones_.intersection(selectedPartIds_)
)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word zoneName = getFoamName(longName);
@ -476,6 +542,7 @@ void Foam::vtkPVFoam::convertPointFields
// Should not happen, but for safety require a vtk geometry
continue;
}
foamVtpData& vtpData = iter.object();
auto dataset = vtpData.dataset;
@ -513,12 +580,12 @@ void Foam::vtkPVFoam::convertPointFieldBlock
const arrayRange& range
)
{
for (auto partId : range)
for
(
const auto partId
: range.intersection(selectedPartIds_)
)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
auto iter = cachedVtu_.find(longName);
@ -527,6 +594,7 @@ void Foam::vtkPVFoam::convertPointFieldBlock
// Should not happen, but for safety require a vtk geometry
continue;
}
foamVtuData& vtuData = iter.object();
auto dataset = vtuData.dataset;
@ -579,7 +647,7 @@ vtkSmartPointer<vtkFloatArray> Foam::vtkPVFoam::convertPointField
<< pfld.name()
<< " size=" << (nPoints + addPointCellLabels.size())
<< " (" << nPoints << " + " << addPointCellLabels.size()
<< ") nComp=" << nComp << endl;
<< ") nComp=" << nComp << nl;
}
float vec[nComp];
@ -728,7 +796,7 @@ Foam::label Foam::vtkPVFoam::transcribeFloatData
<< pTraits<Type>::typeName
<< "' : target array has " << array->GetNumberOfComponents()
<< " components instead of " << nComp
<< endl;
<< nl;
}
const vtkIdType maxSize = array->GetNumberOfTuples();
@ -740,7 +808,7 @@ Foam::label Foam::vtkPVFoam::transcribeFloatData
<< "vtk array '" << array->GetName()
<< "' copy with out-of-range (0-" << long(maxSize-1) << ")"
<< " starting location"
<< endl;
<< nl;
return 0;
}
@ -751,7 +819,7 @@ Foam::label Foam::vtkPVFoam::transcribeFloatData
<< "' copy ends out-of-range (" << long(maxSize) << ")"
<< " using sizing (start,size) = ("
<< start << "," << input.size() << ")"
<< endl;
<< nl;
return 0;
}
@ -788,7 +856,7 @@ Foam::vtkPVFoam::convertFieldToVTK
Info<< "convert UList<" << pTraits<Type>::typeName << "> "
<< name
<< " size=" << fld.size()
<< " nComp=" << nComp << endl;
<< " nComp=" << nComp << nl;
}
auto data = vtkSmartPointer<vtkFloatArray>::New();
@ -816,7 +884,7 @@ Foam::vtkPVFoam::convertFaceFieldToVTK
Info<< "convert face field: "
<< fld.name()
<< " size=" << faceLabels.size()
<< " nComp=" << int(pTraits<Type>::nComponents) << endl;
<< " nComp=" << int(pTraits<Type>::nComponents) << nl;
}
const fvMesh& mesh = fld.mesh();
@ -887,7 +955,7 @@ Foam::vtkPVFoam::convertVolFieldToVTK
<< " size=" << cellMap.size()
<< " (" << fld.size() << " + "
<< (cellMap.size() - fld.size())
<< ") nComp=" << nComp << endl;
<< ") nComp=" << nComp << nl;
}
float scratch[nComp];
@ -906,6 +974,7 @@ Foam::vtkPVFoam::convertVolFieldToVTK
return data;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -26,6 +26,7 @@ License
#include "vtkPVFoam.H"
// OpenFOAM includes
#include "areaFaMesh.H"
#include "Cloud.H"
#include "IOobjectList.H"
#include "vtkPVFoamReader.h"
@ -42,7 +43,7 @@ License
void Foam::vtkPVFoam::convertVolFields()
{
const fvMesh& mesh = *meshPtr_;
const fvMesh& mesh = *volMeshPtr_;
const bool interpFields = reader_->GetInterpolateVolFields();
hashedWordList selectedFields = getSelected
@ -67,11 +68,11 @@ void Foam::vtkPVFoam::convertVolFields()
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
forAllConstIters(objects, iter)
{
Info<< " " << iter()->name()
<< " == " << iter()->objectPath() << endl;
<< " == " << iter()->objectPath() << nl;
}
printMemory();
}
@ -110,7 +111,7 @@ void Foam::vtkPVFoam::convertVolFields()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -118,7 +119,7 @@ void Foam::vtkPVFoam::convertVolFields()
void Foam::vtkPVFoam::convertPointFields()
{
const fvMesh& mesh = *meshPtr_;
const fvMesh& mesh = *volMeshPtr_;
hashedWordList selectedFields = getSelected
(
@ -129,7 +130,7 @@ void Foam::vtkPVFoam::convertPointFields()
{
if (debug)
{
Info<< "no point fields selected" << endl;
Info<< "no point fields selected" << nl;
}
return;
}
@ -146,11 +147,11 @@ void Foam::vtkPVFoam::convertPointFields()
if (debug)
{
Info<< "<beg> convert volume -> point fields" << endl;
Info<< "<beg> convert volume -> point fields" << nl;
forAllConstIters(objects, iter)
{
Info<< " " << iter()->name()
<< " == " << iter()->objectPath() << endl;
<< " == " << iter()->objectPath() << nl;
}
printMemory();
}
@ -166,7 +167,61 @@ void Foam::vtkPVFoam::convertPointFields()
if (debug)
{
Info<< "<end> convert volume -> point fields" << endl;
Info<< "<end> convert volume -> point fields" << nl;
printMemory();
}
}
void Foam::vtkPVFoam::convertAreaFields()
{
if (!areaMeshPtr_)
{
return;
}
const faMesh& mesh = *areaMeshPtr_;
vtkDataArraySelection* select = reader_->GetVolFieldSelection();
hashedWordList selectedFields = getSelected(select);
if (selectedFields.empty())
{
return;
}
// Get objects (fields) for this time - only keep selected fields
// the region name is already in the mesh db
IOobjectList objects(mesh.mesh(), dbPtr_().timeName());
objects.filterKeys(selectedFields);
if (objects.empty())
{
return;
}
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << nl;
forAllConstIters(objects, iter)
{
Info<< " " << iter()->name()
<< " == " << iter()->objectPath() << nl;
}
printMemory();
}
convertAreaFields<scalar>(mesh, objects);
convertAreaFields<vector>(mesh, objects);
convertAreaFields<sphericalTensor>(mesh, objects);
convertAreaFields<symmTensor>(mesh, objects);
convertAreaFields<tensor>(mesh, objects);
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -174,8 +229,10 @@ void Foam::vtkPVFoam::convertPointFields()
void Foam::vtkPVFoam::convertLagrangianFields()
{
const arrayRange& range = rangeLagrangian_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangeClouds_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
hashedWordList selectedFields = getSelected
(
@ -189,17 +246,12 @@ void Foam::vtkPVFoam::convertLagrangianFields()
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
for (auto partId : range)
for (const auto partId : partIds)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word cloudName = getFoamName(longName);
@ -229,11 +281,11 @@ void Foam::vtkPVFoam::convertLagrangianFields()
if (debug)
{
Info<< "converting OpenFOAM lagrangian fields" << endl;
Info<< "converting OpenFOAM lagrangian fields" << nl;
forAllConstIters(objects, iter)
{
Info<< " " << iter()->name()
<< " == " << iter()->objectPath() << endl;
<< " == " << iter()->objectPath() << nl;
}
}
@ -247,7 +299,7 @@ void Foam::vtkPVFoam::convertLagrangianFields()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}

View File

@ -29,6 +29,7 @@ License
#include "cellSet.H"
#include "faceSet.H"
#include "pointSet.H"
#include "faMesh.H"
#include "fvMeshSubset.H"
#include "vtkPVFoamReader.h"
#include "uindirectPrimitivePatch.H"
@ -44,60 +45,58 @@ License
void Foam::vtkPVFoam::convertMeshVolume()
{
const arrayRange& range = rangeVolume_;
const fvMesh& mesh = *meshPtr_;
// Convert internalMesh - actually only one part
const List<label> partIds =
rangeVolume_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
// Convert the internalMesh
// this looks like more than one part, but it isn't
for (auto partId : range)
for (const auto partId : partIds)
{
if (selectedPartIds_.found(partId))
const auto& longName = selectedPartIds_[partId];
foamVtuData& vtuData = cachedVtu_(longName);
vtkSmartPointer<vtkUnstructuredGrid> vtkgeom;
if (vtuData.nPoints())
{
const auto& longName = selectedPartIds_[partId];
foamVtuData& vtuData = cachedVtu_(longName);
vtkSmartPointer<vtkUnstructuredGrid> vtkgeom;
if (vtuData.nPoints())
if (meshState_ == polyMesh::UNCHANGED)
{
if (meshState_ == polyMesh::UNCHANGED)
if (debug)
{
if (debug)
{
Info<< "reuse " << longName << nl;
}
vtuData.reuse(); // reuse
continue;
}
else if (meshState_ == polyMesh::POINTS_MOVED)
{
if (debug)
{
Info<< "move points " << longName << nl;
}
vtkgeom = vtuData.getCopy();
vtkgeom->SetPoints(movePoints(mesh, vtuData));
Info<< "reuse " << longName << nl;
}
vtuData.reuse(); // reuse
continue;
}
if (!vtkgeom)
else if (meshState_ == polyMesh::POINTS_MOVED)
{
// Nothing usable from cache - create new geometry
vtkgeom = volumeVTKMesh(mesh, vtuData);
if (debug)
{
Info<< "move points " << longName << nl;
}
vtkgeom = vtuData.getCopy();
vtkgeom->SetPoints(movePoints(mesh, vtuData));
}
vtuData.set(vtkgeom);
}
if (!vtkgeom)
{
// Nothing usable from cache - create new geometry
vtkgeom = volumeVTKMesh(mesh, vtuData);
}
vtuData.set(vtkgeom);
}
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -105,33 +104,32 @@ void Foam::vtkPVFoam::convertMeshVolume()
void Foam::vtkPVFoam::convertMeshLagrangian()
{
const arrayRange& range = rangeLagrangian_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangeClouds_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
for (auto partId : range)
for (const auto partId : partIds)
{
if (selectedPartIds_.found(partId))
{
const auto& longName = selectedPartIds_[partId];
const word cloudName = getFoamName(longName);
const auto& longName = selectedPartIds_[partId];
const word cloudName = getFoamName(longName);
// Direct conversion, no caching for Lagrangian
cachedVtp_(longName).set
(
lagrangianVTKMesh(mesh, cloudName)
);
}
// Direct conversion, no caching for Lagrangian
cachedVtp_(longName).set
(
lagrangianVTKMesh(mesh, cloudName)
);
}
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -139,22 +137,20 @@ void Foam::vtkPVFoam::convertMeshLagrangian()
void Foam::vtkPVFoam::convertMeshPatches()
{
const arrayRange& range = rangePatches_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangePatches_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
for (auto partId : range)
for (const auto partId : partIds)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word partName = getFoamName(longName);
foamVtpData& vtpData = cachedVtp_(longName);
@ -198,14 +194,14 @@ void Foam::vtkPVFoam::convertMeshPatches()
if (debug)
{
Info<< "Creating VTK mesh for patches [" << patchIds <<"] "
<< longName << endl;
<< longName << nl;
}
// Store good patch ids as additionalIds
vtpData.additionalIds().reserve(patchIds.size());
label sz = 0;
for (auto id : patchIds)
for (const auto id : patchIds)
{
const label n = patches[id].size();
@ -221,7 +217,7 @@ void Foam::vtkPVFoam::convertMeshPatches()
DynamicList<label>& faceLabels = vtpData.cellMap();
faceLabels.reserve(sz);
for (auto id : vtpData.additionalIds())
for (const auto id : vtpData.additionalIds())
{
const auto& pp = patches[id];
forAll(pp, i)
@ -252,7 +248,7 @@ void Foam::vtkPVFoam::convertMeshPatches()
if (debug)
{
Info<< "Creating VTK mesh for patch [" << patchId <<"] "
<< partName << endl;
<< partName << nl;
}
if (patchId >= 0)
@ -276,7 +272,86 @@ void Foam::vtkPVFoam::convertMeshPatches()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
void Foam::vtkPVFoam::convertMeshArea()
{
// Convert areaMesh - actually only one part
const List<label> partIds =
rangeArea_.intersection(selectedPartIds_);
if (partIds.empty())
{
return;
}
else if (!areaMeshPtr_ && volMeshPtr_)
{
areaMeshPtr_ = new faMesh(*volMeshPtr_);
}
if (!areaMeshPtr_)
{
return;
}
const faMesh& mesh = *areaMeshPtr_;
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
for (const auto partId : partIds)
{
const auto& longName = selectedPartIds_[partId];
foamVtpData& vtpData = cachedVtp_(longName);
vtkSmartPointer<vtkPolyData> vtkgeom;
// This needs checking
// #if 0
// if (vtpData.nPoints())
// {
// if (meshState_ == polyMesh::UNCHANGED)
// {
// if (debug)
// {
// Info<< "reuse " << longName << nl;
// }
// vtpData.reuse(); // reuse
// continue;
// }
// else if (meshState_ == polyMesh::POINTS_MOVED)
// {
// if (debug)
// {
// Info<< "move points " << longName << nl;
// }
// vtkgeom = vtpData.getCopy();
// vtkgeom->SetPoints(movePoints(mesh, vtpData));
// }
// }
// #endif
if (!vtkgeom)
{
vtpData.clear(); // Remove any old mappings
// Nothing usable from cache - create new geometry
vtkgeom = patchVTKMesh(mesh.patch());
}
vtpData.set(vtkgeom);
}
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -284,28 +359,25 @@ void Foam::vtkPVFoam::convertMeshPatches()
void Foam::vtkPVFoam::convertMeshCellZones()
{
const arrayRange& range = rangeCellZones_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangeCellZones_.intersection(selectedPartIds_);
if (range.empty())
const fvMesh& mesh = *volMeshPtr_;
if (partIds.empty())
{
return;
}
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
const cellZoneMesh& zMesh = mesh.cellZones();
for (auto partId : range)
for (const auto partId : partIds)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word zoneName = getFoamName(longName);
const label zoneId = zMesh.findZoneID(zoneName);
@ -318,7 +390,7 @@ void Foam::vtkPVFoam::convertMeshCellZones()
if (debug)
{
Info<< "Creating VTK mesh for cellZone[" << zoneId << "] "
<< zoneName << endl;
<< zoneName << nl;
}
foamVtuData& vtuData = cachedVtu_(longName);
@ -362,7 +434,7 @@ void Foam::vtkPVFoam::convertMeshCellZones()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -370,28 +442,25 @@ void Foam::vtkPVFoam::convertMeshCellZones()
void Foam::vtkPVFoam::convertMeshCellSets()
{
const arrayRange& range = rangeCellSets_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangeCellSets_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
for (auto partId : range)
for (const auto partId : partIds)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word partName = getFoamName(longName);
if (debug)
{
Info<< "Creating VTK mesh for cellSet=" << partName << endl;
Info<< "Creating VTK mesh for cellSet=" << partName << nl;
}
foamVtuData& vtuData = cachedVtu_(longName);
@ -435,7 +504,7 @@ void Foam::vtkPVFoam::convertMeshCellSets()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -443,28 +512,25 @@ void Foam::vtkPVFoam::convertMeshCellSets()
void Foam::vtkPVFoam::convertMeshFaceZones()
{
const arrayRange& range = rangeFaceZones_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangeFaceZones_.intersection(selectedPartIds_);
if (range.empty())
const fvMesh& mesh = *volMeshPtr_;
if (partIds.empty())
{
return;
}
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
const faceZoneMesh& zMesh = mesh.faceZones();
for (auto partId : range)
for (const auto partId : partIds)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word zoneName = getFoamName(longName);
const label zoneId = zMesh.findZoneID(zoneName);
@ -476,7 +542,7 @@ void Foam::vtkPVFoam::convertMeshFaceZones()
if (debug)
{
Info<< "Creating VTKmesh for faceZone[" << zoneId << "] "
<< zoneName << endl;
<< zoneName << nl;
}
foamVtpData& vtpData = cachedVtp_(longName);
@ -513,7 +579,7 @@ void Foam::vtkPVFoam::convertMeshFaceZones()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -521,28 +587,25 @@ void Foam::vtkPVFoam::convertMeshFaceZones()
void Foam::vtkPVFoam::convertMeshFaceSets()
{
const arrayRange& range = rangeFaceSets_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangeFaceSets_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
for (auto partId : range)
for (const auto partId : partIds)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word partName = getFoamName(longName);
if (debug)
{
Info<< "Creating VTK mesh for faceSet=" << partName << endl;
Info<< "Creating VTK mesh for faceSet=" << partName << nl;
}
foamVtpData& vtpData = cachedVtp_(longName);
@ -597,7 +660,7 @@ void Foam::vtkPVFoam::convertMeshFaceSets()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -605,84 +668,83 @@ void Foam::vtkPVFoam::convertMeshFaceSets()
void Foam::vtkPVFoam::convertMeshPointZones()
{
const arrayRange& range = rangePointZones_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangePointZones_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
if (partIds.empty())
{
return;
}
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
if (range.size())
const pointZoneMesh& zMesh = mesh.pointZones();
for (const auto partId : partIds)
{
const pointZoneMesh& zMesh = mesh.pointZones();
for (auto partId : range)
const auto& longName = selectedPartIds_[partId];
const word zoneName = getFoamName(longName);
const label zoneId = zMesh.findZoneID(zoneName);
if (zoneId < 0)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word zoneName = getFoamName(longName);
const label zoneId = zMesh.findZoneID(zoneName);
if (zoneId < 0)
{
continue;
}
foamVtpData& vtpData = cachedVtp_(longName);
vtkSmartPointer<vtkPolyData> vtkgeom;
if (vtpData.nPoints() && vtpData.pointMap().size())
{
if (meshState_ == polyMesh::UNCHANGED)
{
if (debug)
{
Info<< "reusing " << longName << nl;
}
vtpData.reuse();
continue;
}
else if (meshState_ == polyMesh::POINTS_MOVED)
{
if (debug)
{
Info<< "move points " << longName << nl;
}
vtkgeom = vtpData.getCopy();
}
}
if (!vtkgeom)
{
// First time, or topo change
vtkgeom = vtkSmartPointer<vtkPolyData>::New();
vtpData.pointMap() = zMesh[zoneId];
}
const pointField& points = mesh.points();
const labelUList& pointMap = vtpData.pointMap();
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
vtkpoints->SetNumberOfPoints(pointMap.size());
forAll(pointMap, pointi)
{
vtkpoints->SetPoint(pointi, points[pointMap[pointi]].v_);
}
vtkgeom->SetPoints(vtkpoints);
vtpData.set(vtkgeom);
continue;
}
foamVtpData& vtpData = cachedVtp_(longName);
vtkSmartPointer<vtkPolyData> vtkgeom;
if (vtpData.nPoints() && vtpData.pointMap().size())
{
if (meshState_ == polyMesh::UNCHANGED)
{
if (debug)
{
Info<< "reusing " << longName << nl;
}
vtpData.reuse();
continue;
}
else if (meshState_ == polyMesh::POINTS_MOVED)
{
if (debug)
{
Info<< "move points " << longName << nl;
}
vtkgeom = vtpData.getCopy();
}
}
if (!vtkgeom)
{
// First time, or topo change
vtkgeom = vtkSmartPointer<vtkPolyData>::New();
vtpData.pointMap() = zMesh[zoneId];
}
const pointField& points = mesh.points();
const labelUList& pointMap = vtpData.pointMap();
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
vtkpoints->SetNumberOfPoints(pointMap.size());
forAll(pointMap, pointi)
{
vtkpoints->SetPoint(pointi, points[pointMap[pointi]].v_);
}
vtkgeom->SetPoints(vtkpoints);
vtpData.set(vtkgeom);
}
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}
@ -690,22 +752,19 @@ void Foam::vtkPVFoam::convertMeshPointZones()
void Foam::vtkPVFoam::convertMeshPointSets()
{
const arrayRange& range = rangePointSets_;
const fvMesh& mesh = *meshPtr_;
const List<label> partIds =
rangePointSets_.intersection(selectedPartIds_);
const fvMesh& mesh = *volMeshPtr_;
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
for (auto partId : range)
for (const auto partId : partIds)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const word partName = getFoamName(longName);
@ -757,7 +816,7 @@ void Foam::vtkPVFoam::convertMeshPointSets()
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}
}

View File

@ -50,7 +50,7 @@ vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::lagrangianVTKMesh
if (debug)
{
Info<< "<beg> lagrangianVTKMesh - timePath "
<< mesh.time().timePath()/cloud::prefix/cloudName << endl;
<< mesh.time().timePath()/cloud::prefix/cloudName << nl;
printMemory();
}
@ -71,7 +71,7 @@ vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::lagrangianVTKMesh
if (debug)
{
Info<< "cloud with " << parcels.size() << " parcels" << endl;
Info<< "cloud with " << parcels.size() << " parcels" << nl;
}
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
@ -91,7 +91,7 @@ vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::lagrangianVTKMesh
if (debug)
{
Info<< "<end> lagrangianVTKMesh" << endl;
Info<< "<end> lagrangianVTKMesh" << nl;
printMemory();
}

View File

@ -115,7 +115,7 @@ vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
{
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
printMemory();
}
@ -209,7 +209,7 @@ vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
printMemory();
}

View File

@ -69,9 +69,9 @@ vtkSmartPointer<vtkCellArray> Foam::vtkPVFoam::patchFacesVTKCells
const faceList& faces = p.localFaces();
label nAlloc = faces.size();
forAll(faces, facei)
for (const face& f : faces)
{
nAlloc += faces[facei].size();
nAlloc += f.size();
}
auto cells = vtkSmartPointer<vtkCellArray>::New();
@ -87,15 +87,13 @@ vtkSmartPointer<vtkCellArray> Foam::vtkPVFoam::patchFacesVTKCells
// Cell connectivity for polygons
// [size, verts..., size, verts... ]
label idx = 0;
forAll(faces, facei)
for (const face& f : faces)
{
const face& f = faces[facei];
cellsUL[idx++] = f.size();
forAll(f, fp)
for (const label verti : f)
{
cellsUL[idx++] = f[fp];
cellsUL[idx++] = verti;
}
}

View File

@ -34,11 +34,17 @@ License
#include "polyBoundaryMeshEntries.H"
#include "entry.H"
#include "Cloud.H"
#include "vtkPVFoamReader.h"
#include "areaFaMesh.H"
// VTK includes
#include "vtkDataArraySelection.h"
// OpenFOAM/VTK interface
#include "vtkPVFoamReader.h"
// Templates (only needed here)
#include "vtkPVFoamUpdateTemplates.C"
// * * * * * * * * * * * * * * * Private Classes * * * * * * * * * * * * * * //
namespace Foam
@ -142,17 +148,57 @@ void Foam::vtkPVFoam::updateInfoInternalMesh
{
if (debug)
{
Info<< "<beg> updateInfoInternalMesh" << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
}
// Determine mesh parts (internalMesh, patches...)
//- Add internal mesh as first entry
// Add internal mesh as first entry
rangeVolume_.reset(select->GetNumberOfArrays(), 1);
select->AddArray("internalMesh");
if (debug)
{
Info<< "<end> updateInfoInternalMesh" << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
void Foam::vtkPVFoam::updateInfoAreaMesh
(
vtkDataArraySelection* select
)
{
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << nl;
}
rangeArea_.reset(select->GetNumberOfArrays(), 0);
// Use the db directly since this might be called without a mesh,
// but the region must get added back in
fileName faMeshPrefix(faMesh::meshSubDir);
if (meshRegion_ != polyMesh::defaultRegion)
{
faMeshPrefix = meshRegion_/faMeshPrefix;
}
// Check for finiteArea mesh
if
(
isFile
(
dbPtr_->constantPath()/faMeshPrefix/"faceLabels"
)
)
{
rangeArea_ += 1;
select->AddArray("areaMesh");
}
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
@ -165,7 +211,7 @@ void Foam::vtkPVFoam::updateInfoLagrangian
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << nl
<< " " << dbPtr_->timePath()/cloud::prefix << endl;
<< " " << dbPtr_->timePath()/cloud::prefix << nl;
}
// Use the db directly since this might be called without a mesh,
@ -191,12 +237,12 @@ void Foam::vtkPVFoam::updateInfoLagrangian
);
}
rangeLagrangian_.reset(select->GetNumberOfArrays());
rangeLagrangian_ += addToArray(select, "lagrangian/", names.sortedToc());
rangeClouds_.reset(select->GetNumberOfArrays());
rangeClouds_ += addToArray(select, "lagrangian/", names.sortedToc());
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
@ -210,14 +256,14 @@ void Foam::vtkPVFoam::updateInfoPatches
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME
<< " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl;
<< " [volMeshPtr=" << (volMeshPtr_ ? "set" : "null") << "]" << nl;
}
rangePatches_.reset(select->GetNumberOfArrays());
if (meshPtr_)
if (volMeshPtr_)
{
const polyBoundaryMesh& patches = meshPtr_->boundaryMesh();
const polyBoundaryMesh& patches = volMeshPtr_->boundaryMesh();
const HashTable<labelList>& groups = patches.groupPatchIDs();
DynamicList<string> displayNames(groups.size());
@ -387,7 +433,7 @@ void Foam::vtkPVFoam::updateInfoPatches
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
@ -404,17 +450,16 @@ void Foam::vtkPVFoam::updateInfoZones
if (debug)
{
Info<< "<beg> updateInfoZones"
<< " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl;
Info<< "<beg> " << FUNCTION_NAME
<< " [volMeshPtr=" << (volMeshPtr_ ? "set" : "null") << "]" << nl;
}
// cellZones
{
const wordList names =
(
meshPtr_
? getZoneNames(meshPtr_->cellZones())
volMeshPtr_
? getZoneNames(volMeshPtr_->cellZones())
: getZoneNames("cellZones")
);
@ -426,8 +471,8 @@ void Foam::vtkPVFoam::updateInfoZones
{
const wordList names =
(
meshPtr_
? getZoneNames(meshPtr_->faceZones())
volMeshPtr_
? getZoneNames(volMeshPtr_->faceZones())
: getZoneNames("faceZones")
);
@ -439,8 +484,8 @@ void Foam::vtkPVFoam::updateInfoZones
{
const wordList names =
(
meshPtr_
? getZoneNames(meshPtr_->pointZones())
volMeshPtr_
? getZoneNames(volMeshPtr_->pointZones())
: getZoneNames("pointZones")
);
@ -450,7 +495,7 @@ void Foam::vtkPVFoam::updateInfoZones
if (debug)
{
Info<< "<end> updateInfoZones" << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
@ -467,7 +512,7 @@ void Foam::vtkPVFoam::updateInfoSets
if (debug)
{
Info<< "<beg> updateInfoSets" << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
}
// Add names of sets. Search for last time directory with a sets
@ -493,7 +538,7 @@ void Foam::vtkPVFoam::updateInfoSets
if (debug)
{
Info<< " updateInfoSets read "
<< objects.names() << " from " << setsInstance << endl;
<< objects.names() << " from " << setsInstance << nl;
}
@ -523,7 +568,91 @@ void Foam::vtkPVFoam::updateInfoSets
if (debug)
{
Info<< "<end> updateInfoSets" << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
void Foam::vtkPVFoam::updateInfoContinuumFields
(
vtkDataArraySelection* select
)
{
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << nl;
}
// Preserve the enabled selections
HashSet<string> enabled;
if (!select->GetNumberOfArrays() && !volMeshPtr_)
{
// First call: automatically enable 'p' and 'U'
enabled = { "p", "U" };
}
else
{
enabled = getSelectedArraySet(select);
}
select->RemoveAllArrays(); // Clear existing list
// Use the db directly since this might be called without a mesh,
// but the region name is still required
word regionPrefix;
if (meshRegion_ != polyMesh::defaultRegion)
{
regionPrefix = meshRegion_;
}
// Objects for this time and mesh region
IOobjectList objects(dbPtr_(), dbPtr_().timeName(), regionPrefix);
updateInfoFields<fvPatchField, volMesh>(select, objects);
updateInfoFields<faPatchField, areaMesh>(select, objects);
setSelectedArrayEntries(select, enabled); // Adjust/restore selected
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
void Foam::vtkPVFoam::updateInfoPointFields
(
vtkDataArraySelection* select
)
{
if (debug)
{
Info<< "<beg> " << FUNCTION_NAME << nl;
}
// Preserve the enabled selections
HashSet<string> enabled = getSelectedArraySet(select);
select->RemoveAllArrays(); // Clear existing list
// Use the db directly since this might be called without a mesh,
// but the region name is still required
word regionPrefix;
if (meshRegion_ != polyMesh::defaultRegion)
{
regionPrefix = meshRegion_;
}
// Objects for this time and mesh region
IOobjectList objects(dbPtr_(), dbPtr_().timeName(), regionPrefix);
updateInfoFields<pointPatchField, pointMesh>(select, objects);
setSelectedArrayEntries(select, enabled); // Adjust/restore selected
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << nl;
}
}
@ -535,14 +664,14 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields
{
if (debug)
{
Info<< "<beg> updateInfoLagrangianFields" << endl;
Info<< "<beg> " << FUNCTION_NAME << nl;
}
// Preserve the enabled selections
HashSet<string> enabled = getSelectedArraySet(select);
select->RemoveAllArrays();
const arrayRange& range = rangeLagrangian_;
const arrayRange& range = rangeClouds_;
if (range.empty())
{
return;
@ -600,7 +729,7 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields
if (debug)
{
Info<< "<end> " << FUNCTION_NAME << endl;
Info<< "<end> " << FUNCTION_NAME << nl;
}
}

View File

@ -34,43 +34,19 @@ InClass
template<template<class> class patchType, class meshType>
void Foam::vtkPVFoam::updateInfoFields
(
vtkDataArraySelection* select
vtkDataArraySelection* select,
const IOobjectList& objects
)
{
if (debug)
{
Info<< "<beg> updateInfoFields <"
<< meshType::Mesh::typeName
<< "> [meshPtr=" << (meshPtr_ ? "set" : "null") << "]"
<< endl;
<< "> [volMeshPtr=" << (volMeshPtr_ ? "set" : "null") << "]"
<< nl;
}
HashSet<string> enabled;
if (!select->GetNumberOfArrays() && !meshPtr_)
{
// Enable 'p' and 'U' only on the first call
enabled = { "p", "U" };
}
else
{
// Preserve the enabled selections
enabled = getSelectedArraySet(select);
}
select->RemoveAllArrays();
// use the db directly since this might be called without a mesh,
// but the region must get added back in
word regionPrefix;
if (meshRegion_ != polyMesh::defaultRegion)
{
regionPrefix = meshRegion_;
}
// Search for list of objects for this time and mesh region
IOobjectList objects(dbPtr_(), dbPtr_().timeName(), regionPrefix);
// Add volume fields to GUI
// Add geometric fields (volume/area) to GUI
addToSelection<GeometricField<scalar, patchType, meshType>>
(
select,
@ -91,14 +67,13 @@ void Foam::vtkPVFoam::updateInfoFields
select,
objects
);
addToSelection<GeometricField<tensor, patchType, meshType>>
(
select,
objects
);
// Add dimensioned fields to GUI
// Add dimensioned fields (volume/area) to GUI
addToSelection<DimensionedField<scalar, meshType>>
(
select,
@ -125,16 +100,13 @@ void Foam::vtkPVFoam::updateInfoFields
objects
);
// Restore the enabled selections
setSelectedArrayEntries(select, enabled);
if (debug)
{
Info<< "<end> updateInfoFields" << endl;
Info<< "<end> updateInfoFields" << nl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -3,7 +3,7 @@
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
# \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
# \\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
@ -41,7 +41,8 @@ cleanTimeDirectories()
done
rm -rf \
./[1-9]* ./-[1-9]* ./log ./log.* ./log-* ./logSummary.* \
./.fxLock ./*.xml ./ParaView* ./paraFoam* ./*.OpenFOAM ./*.blockMesh \
./.fxLock ./*.xml ./ParaView* ./paraFoam* \
./*.blockMesh ./*.foam ./*.OpenFOAM \
./.setSet > /dev/null 2>&1
}
@ -147,6 +148,16 @@ cleanUcomponents()
}
cleanFaMesh ()
{
(
cd constant/faMesh 2>/dev/null && \
rm -rf \
faceLabels* faBoundary* \
> /dev/null 2>&1 \
)
}
cleanApplication()
{
echo "Cleaning application $PWD"

View File

@ -42,6 +42,8 @@ wmake $targetType lagrangian/basic
wmake $targetType lagrangian/distributionModels
wmake $targetType genericPatchFields
wmake $targetType finiteArea
conversion/Allwmake $targetType $*
wmake $targetType mesh/extrudeModel
wmake $targetType dynamicMesh

View File

@ -1,8 +1,10 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
LIB_LIBS = \
-lfiniteVolume \
-lfiniteArea \
-lmeshTools

View File

@ -40,6 +40,7 @@ SourceFiles
#include "OFstream.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "areaFields.H"
#include "indirectPrimitivePatch.H"
#include "foamVtkOutputOptions.H"
@ -152,6 +153,13 @@ public:
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
);
//- Write surface field
template<class Type>
void write
(
const GeometricField<Type, faPatchField, areaMesh>& field
);
// Write fields (collectively)
@ -164,6 +172,16 @@ public:
const GeometricField<Type, fvsPatchField, surfaceMesh>
>& sflds
);
//- Write surface fields
template<class Type>
void write
(
const UPtrList
<
const GeometricField<Type, faPatchField, areaMesh>
>& sflds
);
};

View File

@ -74,8 +74,7 @@ void Foam::vtk::surfaceMeshWriter::write
}
else
{
format().openDataArray<float, nCmpt>(field.name())
.closeTag();
format().openDataArray<float, nCmpt>(field.name()).closeTag();
}
format().writeSize(payLoad);
@ -90,6 +89,36 @@ void Foam::vtk::surfaceMeshWriter::write
}
template<class Type>
void Foam::vtk::surfaceMeshWriter::write
(
const GeometricField<Type, faPatchField, areaMesh>& field
)
{
const int nCmpt(pTraits<Type>::nComponents);
const uint64_t payLoad(pp_.size() * nCmpt * sizeof(float));
if (legacy_)
{
legacy::floatField(os(), field.name(), nCmpt, pp_.size());
}
else
{
format().openDataArray<float, nCmpt>(field.name()).closeTag();
}
format().writeSize(payLoad);
vtk::writeList(format(), field.primitiveField());
format().flush();
if (!legacy_)
{
format().endDataArray();
}
}
template<class Type>
void Foam::vtk::surfaceMeshWriter::write
(
@ -106,4 +135,20 @@ void Foam::vtk::surfaceMeshWriter::write
}
template<class Type>
void Foam::vtk::surfaceMeshWriter::write
(
const UPtrList
<
const GeometricField<Type, faPatchField, areaMesh>
>& sflds
)
{
for (const auto& field : sflds)
{
write(field);
}
}
// ************************************************************************* //

124
src/finiteArea/Make/files Normal file
View File

@ -0,0 +1,124 @@
faMesh/faGlobalMeshData/faGlobalMeshData.C
faMesh/faMesh.C
faMesh/faMeshDemandDrivenData.C
faMesh/faMeshUpdate.C
faMesh/faBoundaryMesh/faBoundaryMesh.C
faPatches = faMesh/faPatches
$(faPatches)/faPatch/faPatch.C
$(faPatches)/faPatch/faPatchNew.C
$(faPatches)/basic/coupled/coupledFaPatch.C
$(faPatches)/constraint/empty/emptyFaPatch.C
$(faPatches)/constraint/processor/processorFaPatch.C
$(faPatches)/constraint/wedge/wedgeFaPatch.C
$(faPatches)/constraint/cyclic/cyclicFaPatch.C
$(faPatches)/constraint/symmetry/symmetryFaPatch.C
faMeshMapper = faMesh/faMeshMapper
$(faMeshMapper)/faMeshMapper.C
$(faMeshMapper)/faAreaMapper.C
$(faMeshMapper)/faEdgeMapper.C
$(faMeshMapper)/faPatchMapper.C
faPatchFields = fields/faPatchFields
$(faPatchFields)/faPatchField/faPatchFields.C
basicFaPatchFields = $(faPatchFields)/basic
$(basicFaPatchFields)/basicSymmetry/basicSymmetryFaPatchScalarField.C
$(basicFaPatchFields)/calculated/calculatedFaPatchFields.C
$(basicFaPatchFields)/coupled/coupledFaPatchFields.C
$(basicFaPatchFields)/zeroGradient/zeroGradientFaPatchFields.C
$(basicFaPatchFields)/fixedValue/fixedValueFaPatchFields.C
$(basicFaPatchFields)/fixedGradient/fixedGradientFaPatchFields.C
$(basicFaPatchFields)/mixed/mixedFaPatchFields.C
$(basicFaPatchFields)/transform/transformFaPatchFields.C
$(basicFaPatchFields)/transform/transformFaPatchScalarField.C
constraintFaPatchFields = $(faPatchFields)/constraint
$(constraintFaPatchFields)/empty/emptyFaPatchFields.C
$(constraintFaPatchFields)/processor/processorFaPatchFields.C
$(constraintFaPatchFields)/processor/processorFaPatchScalarField.C
$(constraintFaPatchFields)/wedge/wedgeFaPatchFields.C
$(constraintFaPatchFields)/wedge/wedgeFaPatchScalarField.C
$(constraintFaPatchFields)/cyclic/cyclicFaPatchFields.C
$(constraintFaPatchFields)/symmetry/symmetryFaPatchFields.C
derivedFaPatchFields = $(faPatchFields)/derived
$(derivedFaPatchFields)/fixedValueOutflow/fixedValueOutflowFaPatchFields.C
$(derivedFaPatchFields)/inletOutlet/inletOutletFaPatchFields.C
$(derivedFaPatchFields)/slip/slipFaPatchFields.C
$(derivedFaPatchFields)/edgeNormalFixedValue/edgeNormalFixedValueFaPatchVectorField.C
$(derivedFaPatchFields)/timeVaryingUniformFixedValue/timeVaryingUniformFixedValueFaPatchFields.C
faePatchFields = fields/faePatchFields
$(faePatchFields)/faePatchField/faePatchFields.C
basicFaePatchFields = $(faePatchFields)/basic
$(basicFaePatchFields)/calculated/calculatedFaePatchFields.C
$(basicFaePatchFields)/coupled/coupledFaePatchFields.C
$(basicFaePatchFields)/fixedValue/fixedValueFaePatchFields.C
constraintFaePatchFields = $(faePatchFields)/constraint
$(constraintFaePatchFields)/empty/emptyFaePatchFields.C
$(constraintFaePatchFields)/processor/processorFaePatchFields.C
$(constraintFaePatchFields)/wedge/wedgeFaePatchFields.C
$(constraintFaePatchFields)/cyclic/cyclicFaePatchFields.C
$(constraintFaePatchFields)/symmetry/symmetryFaePatchFields.C
fields/areaFields/areaFields.C
fields/edgeFields/edgeFields.C
faMatrices/faMatrices.C
faMatrices/faScalarMatrix/faScalarMatrix.C
edgeInterpolation = interpolation/edgeInterpolation
$(edgeInterpolation)/edgeInterpolation.C
$(edgeInterpolation)/edgeInterpolationScheme/edgeInterpolationSchemes.C
schemes = $(edgeInterpolation)/schemes
$(schemes)/linear/linearEdgeInterpolationMake.C
$(schemes)/upwind/upwindEdgeInterpolationMake.C
$(schemes)/linearUpwind/linearUpwindEdgeInterpolationMake.C
$(schemes)/Gamma/GammaEdgeInterpolationMake.C
$(schemes)/blended/blendedEdgeInterpolationMake.C
finiteArea/fa/fa.C
finiteArea/faSchemes/faSchemes.C
ddtSchemes = finiteArea/ddtSchemes
$(ddtSchemes)/faDdtScheme/faDdtSchemes.C
$(ddtSchemes)/steadyStateFaDdtScheme/steadyStateFaDdtSchemes.C
$(ddtSchemes)/EulerFaDdtScheme/EulerFaDdtSchemes.C
$(ddtSchemes)/backwardFaDdtScheme/backwardFaDdtSchemes.C
$(ddtSchemes)/boundedBackwardFaDdtScheme/boundedBackwardFaDdtScheme.C
divSchemes = finiteArea/divSchemes
finiteArea/fam/vectorFamDiv.C
$(divSchemes)/faDivScheme/faDivSchemes.C
$(divSchemes)/gaussFaDivScheme/gaussFaDivSchemes.C
gradSchemes = finiteArea/gradSchemes
$(gradSchemes)/faGradScheme/faGradSchemes.C
$(gradSchemes)/gaussFaGrad/gaussFaGrads.C
$(gradSchemes)/leastSquaresFaGrad/leastSquaresFaVectors.C
$(gradSchemes)/leastSquaresFaGrad/leastSquaresFaGrads.C
limitedGradSchemes = $(gradSchemes)/limitedGradSchemes
$(limitedGradSchemes)/faceLimitedFaGrad/faceLimitedFaGrads.C
$(limitedGradSchemes)/edgeLimitedFaGrad/edgeLimitedFaGrads.C
lnGradSchemes = finiteArea/lnGradSchemes
$(lnGradSchemes)/lnGradScheme/lnGradSchemes.C
$(lnGradSchemes)/correctedLnGrad/correctedLnGrads.C
$(lnGradSchemes)/limitedLnGrad/limitedLnGrads.C
$(lnGradSchemes)/fourthLnGrad/fourthLnGrads.C
laplacianSchemes = finiteArea/laplacianSchemes
$(laplacianSchemes)/faLaplacianScheme/faLaplacianSchemes.C
$(laplacianSchemes)/gaussFaLaplacianScheme/gaussFaLaplacianSchemes.C
convectionSchemes = finiteArea/convectionSchemes
$(convectionSchemes)/faConvectionScheme/faConvectionSchemes.C
$(convectionSchemes)/gaussFaConvectionScheme/gaussFaConvectionSchemes.C
LIB = $(FOAM_LIBBIN)/libfiniteArea

View File

@ -0,0 +1,5 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude
LIB_LIBS = \
-lmeshTools

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::areaMesh
Description
Mesh data needed to do the Finite Area discretisation.
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef areaFaMesh_H
#define areaFaMesh_H
#include "GeoMesh.H"
#include "faMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class areaMesh Declaration
\*---------------------------------------------------------------------------*/
class areaMesh
:
public GeoMesh<faMesh>
{
public:
explicit areaMesh(const faMesh& mesh)
:
GeoMesh<faMesh>(mesh)
{}
label size() const
{
return size(mesh_);
}
static label size(const Mesh& mesh)
{
return mesh.nFaces();
}
const areaVectorField& C()
{
return mesh_.areaCentres();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::edgeMesh
Description
Mesh data needed to do the Finite Area discretisation.
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef edgeFaMesh_H
#define edgeFaMesh_H
#include "GeoMesh.H"
#include "faMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class edgeMesh Declaration
\*---------------------------------------------------------------------------*/
class edgeMesh
:
public GeoMesh<faMesh>
{
public:
explicit edgeMesh(const faMesh& mesh)
:
GeoMesh<faMesh>(mesh)
{}
label size() const
{
return size(mesh_);
}
static label size(const Mesh& mesh)
{
return mesh.nInternalEdges();
}
const edgeVectorField& C()
{
return mesh_.edgeCentres();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Description
Finite-Volume matrix member static data members
\*---------------------------------------------------------------------------*/
#include "faMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTemplateTypeNameAndDebug(faScalarMatrix, 0);
defineTemplateTypeNameAndDebug(faVectorMatrix, 0);
defineTemplateTypeNameAndDebug(faTensorMatrix, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faMatrix
Description
A special matrix type and solver, designed for finite area
solutions of scalar equations.
Face addressing is used to make all matrix assembly
and solution loops vectorise.
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faMatrices_H
#define faMatrices_H
#include "faScalarMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef faMatrix<scalar> faScalarMatrix;
typedef faMatrix<vector> faVectorMatrix;
typedef faMatrix<tensor> faTensorMatrix;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,786 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faMatrix
Description
Finite-Area matrix.
SourceFiles
faMatrix.C
faMatrixSolve.C
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faMatrix_H
#define faMatrix_H
#include "areaFields.H"
#include "edgeFields.H"
#include "lduMatrix.H"
#include "tmp.H"
#include "autoPtr.H"
#include "dimensionedTypes.H"
#include "className.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * Forward declaration of template friend fuctions * * * * * * * //
template<class Type>
class faMatrix;
template<class Type>
Ostream& operator<<(Ostream&, const faMatrix<Type>&);
/*---------------------------------------------------------------------------*\
Class faMatrix Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class faMatrix
:
public tmp<faMatrix<Type>>::refCount,
public lduMatrix
{
// Private data
// Reference to GeometricField<Type, faPatchField, areaMesh>
const GeometricField<Type, faPatchField, areaMesh>& psi_;
//- Dimension set
dimensionSet dimensions_;
//- Source term
Field<Type> source_;
//- Boundary scalar field containing pseudo-matrix coeffs
// for internal faces
FieldField<Field, Type> internalCoeffs_;
//- Boundary scalar field containing pseudo-matrix coeffs
// for boundary faces
FieldField<Field, Type> boundaryCoeffs_;
//- Face flux field for non-orthogonal correction
mutable GeometricField<Type, faePatchField, edgeMesh>
*faceFluxCorrectionPtr_;
// Private member functions
//- Add patch contribution to internal field
template<class Type2>
void addToInternalField
(
const labelUList& addr,
const Field<Type2>& pf,
Field<Type2>& intf
) const;
template<class Type2>
void addToInternalField
(
const labelUList& addr,
const tmp<Field<Type2>>& tpf,
Field<Type2>& intf
) const;
//- Subtract patch contribution from internal field
template<class Type2>
void subtractFromInternalField
(
const labelUList& addr,
const Field<Type2>& pf,
Field<Type2>& intf
) const;
template<class Type2>
void subtractFromInternalField
(
const labelUList& addr,
const tmp<Field<Type2>>& tpf,
Field<Type2>& intf
) const;
// Matrix completion functionality
void addBoundaryDiag
(
scalarField& diag,
const direction cmpt
) const;
void addCmptAvBoundaryDiag(scalarField& diag) const;
void addBoundarySource
(
Field<Type>& source,
const bool couples = true
) const;
public:
//- Solver class returned by the solver function
class faSolver
{
faMatrix<Type>& faMat_;
autoPtr<lduMatrix::solver> solver_;
public:
// Constructors
faSolver(faMatrix<Type>& faMat, autoPtr<lduMatrix::solver> sol)
:
faMat_(faMat),
solver_(sol)
{}
// Member functions
//- Solve returning the solution statistics.
// Solver controls read from dictionary
SolverPerformance<Type> solve(const dictionary&);
//- Solve returning the solution statistics.
// Solver controls read from faSolution
SolverPerformance<Type> solve();
};
ClassName("faMatrix");
// Constructors
//- Construct given a field to solve for
faMatrix
(
const GeometricField<Type, faPatchField, areaMesh>&,
const dimensionSet&
);
//- Construct as copy
faMatrix(const faMatrix<Type>&);
//- Construct from Istream given field to solve for
faMatrix
(
const GeometricField<Type, faPatchField, areaMesh>&,
Istream&
);
//- Clone
tmp<faMatrix<Type>> clone() const;
//- Destructor
virtual ~faMatrix();
// Member functions
// Access
const GeometricField<Type, faPatchField, areaMesh>& psi() const
{
return psi_;
}
const dimensionSet& dimensions() const
{
return dimensions_;
}
Field<Type>& source()
{
return source_;
}
const Field<Type>& source() const
{
return source_;
}
//- faBoundary scalar field containing pseudo-matrix coeffs
// for internal cells
FieldField<Field, Type>& internalCoeffs()
{
return internalCoeffs_;
}
//- faBoundary scalar field containing pseudo-matrix coeffs
// for boundary cells
FieldField<Field, Type>& boundaryCoeffs()
{
return boundaryCoeffs_;
}
//- Declare return type of the faceFluxCorrectionPtr() function
typedef GeometricField<Type, faePatchField, edgeMesh>
*edgeTypeFieldPtr;
//- Return pointer to face-flux non-orthogonal correction field
edgeTypeFieldPtr& faceFluxCorrectionPtr()
{
return faceFluxCorrectionPtr_;
}
// Operations
//- Set solution in given cells and eliminate corresponding
// equations from the matrix
void setValues
(
const labelUList& faces,
const UList<Type>& values
);
//- Set reference level for solution
void setReference
(
const label facei,
const Type& value
);
//- Set reference level for a component of the solution
// on a given patch face
void setComponentReference
(
const label patchi,
const label facei,
const direction cmpt,
const scalar value
);
//- Relax matrix (for steady-state solution).
// alpha = 1 : diagonally equal
// alpha < 1 : ,, dominant
// alpha = 0 : do nothing
void relax(const scalar alpha);
//- Relax matrix (for steadty-state solution).
// alpha is read from controlDict
void relax();
//- Solve returning the solution statistics.
// Solver controls read Istream
SolverPerformance<Type> solve(const dictionary&);
//- Solve returning the solution statistics.
// Solver controls read from faSolution
SolverPerformance<Type> solve();
//- Return the matrix residual
tmp<Field<Type>> residual() const;
//- Return the matrix diagonal
tmp<scalarField> D() const;
//- Return the central coefficient
tmp<areaScalarField> A() const;
//- Return the H operation source
tmp<GeometricField<Type, faPatchField, areaMesh>> H() const;
//- Return the face-flux field from the matrix
tmp<GeometricField<Type, faePatchField, edgeMesh>> flux() const;
// Member operators
void operator=(const faMatrix<Type>&);
void operator=(const tmp<faMatrix<Type>>&);
void negate();
void operator+=(const faMatrix<Type>&);
void operator+=(const tmp<faMatrix<Type>>&);
void operator-=(const faMatrix<Type>&);
void operator-=(const tmp<faMatrix<Type>>&);
void operator+=(const GeometricField<Type,faPatchField,areaMesh>&);
void operator+=(const tmp<GeometricField<Type,faPatchField,areaMesh>>&);
void operator-=(const GeometricField<Type,faPatchField,areaMesh>&);
void operator-=(const tmp<GeometricField<Type,faPatchField,areaMesh>>&);
void operator+=(const dimensioned<Type>&);
void operator-=(const dimensioned<Type>&);
void operator*=(const areaScalarField&);
void operator*=(const tmp<areaScalarField>&);
void operator*=(const dimensioned<scalar>&);
// Ostream operator
friend Ostream& operator<< <Type>
(
Ostream&,
const faMatrix<Type>&
);
};
// * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * //
template<class Type>
void checkMethod
(
const faMatrix<Type>&,
const faMatrix<Type>&,
const char*
);
template<class Type>
void checkMethod
(
const faMatrix<Type>&,
const GeometricField<Type, faPatchField, areaMesh>&,
const char*
);
template<class Type>
void checkMethod
(
const faMatrix<Type>&,
const dimensioned<Type>&,
const char*
);
//- Solve returning the solution statistics given convergence tolerance
// Solver controls read Istream
template<class Type>
SolverPerformance<Type> solve(faMatrix<Type>&, Istream&);
//- Solve returning the solution statistics given convergence tolerance,
// deleting temporary matrix after solution.
// Solver controls read Istream
template<class Type>
SolverPerformance<Type> solve(const tmp<faMatrix<Type>>&, Istream&);
//- Solve returning the solution statistics given convergence tolerance
// Solver controls read faSolution
template<class Type>
SolverPerformance<Type> solve(faMatrix<Type>&);
//- Solve returning the solution statistics given convergence tolerance,
// deleting temporary matrix after solution.
// Solver controls read faSolution
template<class Type>
SolverPerformance<Type> solve(const tmp<faMatrix<Type>>&);
// * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * //
template<class Type>
tmp<faMatrix<Type>> operator-
(
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const faMatrix<Type>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const tmp<faMatrix<Type>>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const faMatrix<Type>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const tmp<faMatrix<Type>>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const faMatrix<Type>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<faMatrix<Type>>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const faMatrix<Type>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<faMatrix<Type>>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const faMatrix<Type>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const tmp<faMatrix<Type>>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const faMatrix<Type>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const tmp<faMatrix<Type>>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const faMatrix<Type>&,
const GeometricField<Type, faPatchField, areaMesh>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const tmp<faMatrix<Type>>&,
const GeometricField<Type, faPatchField, areaMesh>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const faMatrix<Type>&,
const tmp<GeometricField<Type, faPatchField, areaMesh>>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const tmp<faMatrix<Type>>&,
const tmp<GeometricField<Type, faPatchField, areaMesh>>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const GeometricField<Type, faPatchField, areaMesh>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const GeometricField<Type, faPatchField, areaMesh>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const tmp<GeometricField<Type, faPatchField, areaMesh>>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const tmp<GeometricField<Type, faPatchField, areaMesh>>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const faMatrix<Type>&,
const GeometricField<Type, faPatchField, areaMesh>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<faMatrix<Type>>&,
const GeometricField<Type, faPatchField, areaMesh>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const faMatrix<Type>&,
const tmp<GeometricField<Type, faPatchField, areaMesh>>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<faMatrix<Type>>&,
const tmp<GeometricField<Type, faPatchField, areaMesh>>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const GeometricField<Type, faPatchField, areaMesh>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const GeometricField<Type, faPatchField, areaMesh>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<GeometricField<Type, faPatchField, areaMesh>>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<GeometricField<Type, faPatchField, areaMesh>>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const faMatrix<Type>&,
const dimensioned<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const tmp<faMatrix<Type>>&,
const dimensioned<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const dimensioned<Type>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator+
(
const dimensioned<Type>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const faMatrix<Type>&,
const dimensioned<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const tmp<faMatrix<Type>>&,
const dimensioned<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const dimensioned<Type>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator-
(
const dimensioned<Type>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const faMatrix<Type>&,
const GeometricField<Type, faPatchField, areaMesh>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const tmp<faMatrix<Type>>&,
const GeometricField<Type, faPatchField, areaMesh>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const faMatrix<Type>&,
const tmp<GeometricField<Type, faPatchField, areaMesh>>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const tmp<faMatrix<Type>>&,
const tmp<GeometricField<Type, faPatchField, areaMesh>>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const faMatrix<Type>&,
const dimensioned<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator==
(
const tmp<faMatrix<Type>>&,
const dimensioned<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator*
(
const areaScalarField&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator*
(
const areaScalarField&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator*
(
const tmp<areaScalarField>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator*
(
const tmp<areaScalarField>&,
const tmp<faMatrix<Type>>&
);
template<class Type>
tmp<faMatrix<Type>> operator*
(
const dimensioned<scalar>&,
const faMatrix<Type>&
);
template<class Type>
tmp<faMatrix<Type>> operator*
(
const dimensioned<scalar>&,
const tmp<faMatrix<Type>>&
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "faMatrix.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Description
Finite-Area matrix basic solvers.
\*---------------------------------------------------------------------------*/
template<class Type>
void Foam::faMatrix<Type>::setComponentReference
(
const label patchi,
const label facei,
const direction cmpt,
const scalar value
)
{
internalCoeffs_[patchi][facei].component(cmpt) +=
diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]];
boundaryCoeffs_[patchi][facei].component(cmpt) +=
diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]]*value;
}
template<class Type>
Foam::SolverPerformance<Type> Foam::faMatrix<Type>::solve
(
const dictionary& solverControls
)
{
DebugInFunction
<< "solving faMatrix<Type>"
<< endl;
SolverPerformance<Type> solverPerfVec
(
"faMatrix<Type>::solve",
psi_.name()
);
scalarField saveDiag(diag());
Field<Type> source(source_);
addBoundarySource(source);
// Note: make a copy of interfaces: no longer a reference
lduInterfaceFieldPtrsList interfaces =
psi_.boundaryField().scalarInterfaces();
// Cast into a non-const to solve
GeometricField<Type, faPatchField, areaMesh>& psi =
const_cast<GeometricField<Type, faPatchField, areaMesh>&>(psi_);
for (direction cmpt = 0; cmpt < Type::nComponents; ++cmpt)
{
// copy field and source
scalarField psiCmpt(psi_.primitiveField().component(cmpt));
addBoundaryDiag(diag(), cmpt);
scalarField sourceCmpt(source.component(cmpt));
FieldField<Field, scalar> bouCoeffsCmpt
(
boundaryCoeffs_.component(cmpt)
);
FieldField<Field, scalar> intCoeffsCmpt
(
internalCoeffs_.component(cmpt)
);
// Use the initMatrixInterfaces and updateMatrixInterfaces to correct
// bouCoeffsCmpt for the explicit part of the coupled boundary
// conditions
initMatrixInterfaces
(
true,
bouCoeffsCmpt,
interfaces,
psiCmpt,
sourceCmpt,
cmpt
);
updateMatrixInterfaces
(
true,
bouCoeffsCmpt,
interfaces,
psiCmpt,
sourceCmpt,
cmpt
);
solverPerformance solverPerf;
// Solver call
solverPerf = lduMatrix::solver::New
(
psi_.name() + pTraits<Type>::componentNames[cmpt],
*this,
bouCoeffsCmpt,
intCoeffsCmpt,
interfaces,
solverControls
)->solve(psiCmpt, sourceCmpt, cmpt);
if (SolverPerformance<Type>::debug)
{
solverPerf.print(Info);
}
solverPerfVec.replace(cmpt, solverPerf);
solverPerfVec.solverName() = solverPerf.solverName();
psi.primitiveFieldRef().replace(cmpt, psiCmpt);
diag() = saveDiag;
}
psi.correctBoundaryConditions();
psi.mesh().setSolverPerformance(psi.name(), solverPerfVec);
return solverPerfVec;
}
template<class Type>
Foam::SolverPerformance<Type> Foam::faMatrix<Type>::faSolver::solve()
{
return solve(faMat_.psi().mesh().solverDict(faMat_.psi().name()));
}
template<class Type>
Foam::SolverPerformance<Type> Foam::faMatrix<Type>::solve()
{
return solve(this->psi().mesh().solverDict(this->psi().name()));
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::faMatrix<Type>::residual() const
{
tmp<Field<Type>> tres(source_);
Field<Type>& res = tres().ref();
addBoundarySource(res);
lduInterfaceFieldPtrsList interfaces =
psi_.boundaryField().scalarInterfaces();
// Loop over field components
for (direction cmpt = 0; cmpt < Type::nComponents; ++cmpt)
{
scalarField psiCmpt(psi_.internalField().component(cmpt));
scalarField boundaryDiagCmpt(psi_.size(), 0.0);
addBoundaryDiag(boundaryDiagCmpt, cmpt);
FieldField<Field, scalar> bouCoeffsCmpt
(
boundaryCoeffs_.component(cmpt)
);
res.replace
(
cmpt,
lduMatrix::residual
(
psiCmpt,
res.component(cmpt) - boundaryDiagCmpt*psiCmpt,
bouCoeffsCmpt,
interfaces,
cmpt
)
);
}
return tres;
}
// ************************************************************************* //

View File

@ -0,0 +1,154 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Description
Finite-Area scalar matrix member functions and operators
\*---------------------------------------------------------------------------*/
#include "faScalarMatrix.H"
#include "zeroGradientFaPatchFields.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<>
void Foam::faMatrix<Foam::scalar>::setComponentReference
(
const label patchI,
const label edgeI,
const direction,
const scalar value
)
{
const labelUList& faceLabels = psi_.mesh().boundary()[patchI].edgeFaces();
internalCoeffs_[patchI][edgeI] += diag()[faceLabels[edgeI]];
boundaryCoeffs_[patchI][edgeI] = value;
}
template<>
Foam::solverPerformance Foam::faMatrix<Foam::scalar>::solve
(
const dictionary& solverControls
)
{
DebugInFunction
<< "solving faMatrix<scalar>"
<< endl;
GeometricField<scalar, faPatchField, areaMesh>& psi =
const_cast<GeometricField<scalar, faPatchField, areaMesh>&>(psi_);
scalarField saveDiag(diag());
addBoundaryDiag(diag(), 0);
scalarField totalSource(source_);
addBoundarySource(totalSource, 0);
// Solver call
solverPerformance solverPerf = lduMatrix::solver::New
(
psi_.name(),
*this,
boundaryCoeffs_,
internalCoeffs_,
psi_.boundaryField().scalarInterfaces(),
solverControls
)->solve(psi.ref(), totalSource);
if (solverPerformance::debug)
{
solverPerf.print(Info);
}
diag() = saveDiag;
psi.correctBoundaryConditions();
psi.mesh().setSolverPerformance(psi.name(), solverPerf);
return solverPerf;
}
template<>
Foam::tmp<Foam::scalarField> Foam::faMatrix<Foam::scalar>::residual() const
{
scalarField boundaryDiag(psi_.size(), 0.0);
addBoundaryDiag(boundaryDiag, 0);
tmp<scalarField> tres
(
lduMatrix::residual
(
psi_.internalField(),
source_ - boundaryDiag*psi_.internalField(),
boundaryCoeffs_,
psi_.boundaryField().scalarInterfaces(),
0
)
);
addBoundarySource(tres.ref());
return tres;
}
template<>
Foam::tmp<Foam::areaScalarField> Foam::faMatrix<Foam::scalar>::H() const
{
tmp<areaScalarField> tHphi
(
new areaScalarField
(
IOobject
(
"H("+psi_.name()+')',
psi_.instance(),
psi_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
psi_.mesh(),
dimensions_/dimArea,
zeroGradientFaPatchScalarField::typeName
)
);
areaScalarField& Hphi = tHphi.ref();
Hphi.primitiveFieldRef() = (lduMatrix::H(psi_.primitiveField()) + source_);
addBoundarySource(Hphi.primitiveFieldRef());
Hphi.ref() /= psi_.mesh().S();
Hphi.correctBoundaryConditions();
return tHphi;
}
// ************************************************************************* //

View File

@ -0,0 +1,84 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faScalarMatrix
Description
Template specialisation for scalar faMatrix
SourceFiles
faScalarMatrix.C
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faScalarMatrix_H
#define faScalarMatrix_H
#include "faMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Set reference level for a component of the solution
// on a given patch face
template<>
void faMatrix<scalar>::setComponentReference
(
const label patchi,
const label facei,
const direction,
const scalar value
);
template<>
SolverPerformance<scalar> faMatrix<scalar>::solve(const dictionary&);
// Return the matrix residual
template<>
tmp<scalarField> faMatrix<scalar>::residual() const;
// H operator
template<>
tmp<areaScalarField> faMatrix<scalar>::H() const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,369 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Description
\*---------------------------------------------------------------------------*/
#include "faBoundaryMesh.H"
#include "faMesh.H"
#include "primitiveMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(faBoundaryMesh, 0);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faBoundaryMesh::faBoundaryMesh
(
const IOobject& io,
const faMesh& mesh
)
:
faPatchList(),
regIOobject(io),
mesh_(mesh)
{
if (readOpt() == IOobject::MUST_READ)
{
faPatchList& patches = *this;
// Read polyPatchList
Istream& is = readStream(typeName);
PtrList<entry> patchEntries(is);
patches.setSize(patchEntries.size());
forAll(patches, patchI)
{
patches.set
(
patchI,
faPatch::New
(
patchEntries[patchI].keyword(),
patchEntries[patchI].dict(),
patchI,
*this
)
);
}
// Check state of IOstream
is.check(FUNCTION_NAME);
close();
}
}
Foam::faBoundaryMesh::faBoundaryMesh
(
const IOobject& io,
const faMesh& pm,
const label size
)
:
faPatchList(size),
regIOobject(io),
mesh_(pm)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faBoundaryMesh::calcGeometry()
{
forAll(*this, patchi)
{
operator[](patchi).initGeometry();
}
forAll(*this, patchi)
{
operator[](patchi).calcGeometry();
}
}
const Foam::faMesh& Foam::faBoundaryMesh::mesh() const
{
return mesh_;
}
Foam::lduInterfacePtrsList Foam::faBoundaryMesh::interfaces() const
{
lduInterfacePtrsList interfaces(size());
forAll(interfaces, patchi)
{
if (isA<lduInterface>(this->operator[](patchi)))
{
interfaces.set
(
patchi,
&refCast<const lduInterface>(this->operator[](patchi))
);
}
}
return interfaces;
}
Foam::wordList Foam::faBoundaryMesh::types() const
{
const faPatchList& patches = *this;
wordList t(patches.size());
forAll(patches, patchI)
{
t[patchI] = patches[patchI].type();
}
return t;
}
Foam::wordList Foam::faBoundaryMesh::names() const
{
const faPatchList& patches = *this;
wordList t(patches.size());
forAll(patches, patchI)
{
t[patchI] = patches[patchI].name();
}
return t;
}
Foam::label Foam::faBoundaryMesh::findPatchID(const word& patchName) const
{
const faPatchList& patches = *this;
forAll(patches, patchI)
{
if (patches[patchI].name() == patchName)
{
return patchI;
}
}
// Patch not found
return -1;
}
Foam::labelList Foam::faBoundaryMesh::findIndices
(
const keyType& key,
const bool usePatchGroups
) const
{
DynamicList<label> indices;
if (!key.empty())
{
if (key.isPattern())
{
indices = findStrings(key, this->names());
}
else
{
// Literal string. Special version of above to avoid
// unnecessary memory allocations
indices.setCapacity(1);
forAll(*this, i)
{
if (key == operator[](i).name())
{
indices.append(i);
break;
}
}
}
}
return indices;
}
Foam::label Foam::faBoundaryMesh::whichPatch(const label edgeIndex) const
{
// Find out which patch the current face belongs to by comparing label
// with patch start labels.
// If the face is internal, return -1;
// if it is off the end of the list, abort
if (edgeIndex >= mesh().nEdges())
{
FatalErrorInFunction
<< "given label greater than the number of edges"
<< abort(FatalError);
}
if (edgeIndex < mesh().nInternalEdges())
{
return -1;
}
forAll(*this, patchI)
{
label start = mesh_.patchStarts()[patchI];
label size = operator[](patchI).faPatch::size();
if
(
edgeIndex >= start
&& edgeIndex < start + size
)
{
return patchI;
}
}
// If not in any of above, it's trouble!
FatalErrorInFunction
<< "error in patch search algorithm"
<< abort(FatalError);
return -1;
}
bool Foam::faBoundaryMesh::checkDefinition(const bool report) const
{
label nextPatchStart = mesh().nInternalEdges();
const faBoundaryMesh& bm = *this;
bool boundaryError = false;
forAll(bm, patchI)
{
if (bm[patchI].start() != nextPatchStart)
{
boundaryError = true;
InfoInFunction
<< "Problem with boundary patch " << patchI
<< ".\nThe patch should start on face no " << nextPatchStart
<< " and the boundary file specifies " << bm[patchI].start()
<< "." << nl << endl;
}
nextPatchStart += bm[patchI].faPatch::size();
}
if (boundaryError)
{
SeriousErrorInFunction
<< "This mesh is not valid: boundary definition is in error."
<< endl;
}
else
{
if (debug || report)
{
Info << "Boundary definition OK." << endl;
}
}
return boundaryError;
}
void Foam::faBoundaryMesh::movePoints(const pointField& p)
{
faPatchList& patches = *this;
forAll(patches, patchI)
{
patches[patchI].initMovePoints(p);
}
forAll(patches, patchI)
{
patches[patchI].movePoints(p);
}
}
void Foam::faBoundaryMesh::updateMesh()
{
faPatchList& patches = *this;
forAll(patches, patchi)
{
patches[patchi].initUpdateMesh();
}
forAll(patches, patchi)
{
patches[patchi].updateMesh();
}
}
bool Foam::faBoundaryMesh::writeData(Ostream& os) const
{
const faPatchList& patches = *this;
os << patches.size() << nl << token::BEGIN_LIST << incrIndent << nl;
forAll(patches, patchi)
{
os << indent << patches[patchi].name() << nl
<< indent << token::BEGIN_BLOCK << nl
<< incrIndent << patches[patchi] << decrIndent
<< indent << token::END_BLOCK << endl;
}
os << decrIndent << token::END_LIST;
// Check state of IOstream
os.check(FUNCTION_NAME);
return os.good();
}
Foam::Ostream& Foam::operator<<(Ostream& os, const faBoundaryMesh& bm)
{
bm.writeData(os);
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faBoundaryMesh
Description
Finite area boundary mesh
SourceFiles
faBoundaryMesh.C
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faBoundaryMesh_H
#define faBoundaryMesh_H
#include "faPatchList.H"
#include "lduInterfacePtrsList.H"
#include "wordList.H"
#include "pointField.H"
#include "regIOobject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
class faMesh;
/*---------------------------------------------------------------------------*\
Class faBoundaryMesh Declaration
\*---------------------------------------------------------------------------*/
class faBoundaryMesh
:
public faPatchList,
public regIOobject
{
// private data
//- Reference to mesh
const faMesh& mesh_;
//- Disallow construct as copy
faBoundaryMesh(const faBoundaryMesh&);
//- Disallow assignment
void operator=(const faBoundaryMesh&);
public:
//- Runtime type information
TypeName("faBoundaryMesh");
// Constructors
//- Construct from dictionary
faBoundaryMesh
(
const IOobject& io,
const faMesh& fam
);
//- Construct given size
faBoundaryMesh
(
const IOobject& io,
const faMesh& fam,
const label size
);
// Destructor - default
// Member functions
// Access
//- Calculate the geometry for the patches
// (transformation tensors etc.)
void calcGeometry();
//- Return the mesh reference
const faMesh& mesh() const;
//- Return a list of pointers for each patch
// with only those pointing to interfaces being set
lduInterfacePtrsList interfaces() const;
//- Return a list of patch types
wordList types() const;
//- Return a list of patch names
wordList names() const;
//- Find patch index given a name
label findPatchID(const word& patchName) const;
//- Find patch indices given a name
// Compatibility change HJ, 12/Aug/2017
labelList findIndices
(
const keyType&,
const bool useGroups = false
) const;
//- Return patch index for a given edge label
label whichPatch(const label edgeIndex) const;
//- Check boundary definition
bool checkDefinition(const bool report = false) const;
// Edit
//- Correct faBoundaryMesh after moving points
void movePoints(const pointField&);
//- Correct faBoundaryMesh after topology update
void updateMesh();
//- writeData member function required by regIOobject
bool writeData(Ostream&) const;
// Ostream operator
friend Ostream& operator<<(Ostream&, const faBoundaryMesh&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Description
Author
Hrvoje Jasak
\*----------------------------------------------------------------------------*/
#include "faGlobalMeshData.H"
#include "faMesh.H"
#include "globalMeshData.H"
#include "PstreamCombineReduceOps.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faGlobalMeshData::faGlobalMeshData(const faMesh& mesh)
:
faProcessorTopology(mesh.boundary(), UPstream::worldComm),
mesh_(mesh),
nGlobalPoints_(-1),
sharedPointLabels_(0),
sharedPointAddr_(0)
{
updateMesh();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::faGlobalMeshData::~faGlobalMeshData()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::faMesh& Foam::faGlobalMeshData::mesh() const
{
return mesh_;
}
void Foam::faGlobalMeshData::updateMesh()
{
label polyMeshNGlobalPoints = mesh_().globalData().nGlobalPoints();
const labelList& polyMeshSharedPointLabels =
mesh_().globalData().sharedPointLabels();
const labelList& polyMeshSharedPointAddr =
mesh_().globalData().sharedPointAddr();
labelHashSet sharedPointLabels;
labelField globalList(polyMeshNGlobalPoints, 0);
forAll(mesh_.boundary(), patchI)
{
const faPatch& fap = mesh_.boundary()[patchI];
if (isA<processorFaPatch>(fap))
{
const labelList& localPointLabels = fap.pointLabels();
forAll(localPointLabels, pointI)
{
label polyMeshPoint =
mesh_.patch().meshPoints()[localPointLabels[pointI]];
label sharedPolyMeshPoint =
findIndex(polyMeshSharedPointLabels, polyMeshPoint);
if
(
sharedPolyMeshPoint != -1
&& !sharedPointLabels.found(localPointLabels[pointI])
)
{
globalList[polyMeshSharedPointAddr[sharedPolyMeshPoint]]
+= 1;
sharedPointLabels.insert(localPointLabels[pointI]);
}
}
}
}
sharedPointLabels_ = sharedPointLabels.toc();
combineReduce(globalList, plusEqOp<labelField>());
nGlobalPoints_ = 0;
for (label i=0; i<globalList.size(); ++i)
{
if (globalList[i] > 0)
{
globalList[i] = ++nGlobalPoints_;
}
}
sharedPointAddr_.setSize(sharedPointLabels_.size());
forAll(sharedPointAddr_, pointI)
{
label polyMeshSharedPointIndex = findIndex
(
polyMeshSharedPointLabels,
mesh_.patch().meshPoints()[sharedPointLabels_[pointI]]
);
sharedPointAddr_[pointI] =
globalList[polyMeshSharedPointAddr[polyMeshSharedPointIndex]]
- 1;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,138 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faGlobalMeshData
Description
Various mesh related information for a parallel run
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faGlobalMeshData_H
#define faGlobalMeshData_H
#include "faProcessorTopology.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
class faMesh;
/*---------------------------------------------------------------------------*\
Class faGlobalMeshData Declaration
\*---------------------------------------------------------------------------*/
class faGlobalMeshData
:
public faProcessorTopology
{
// Private data
//- Reference to mesh
const faMesh& mesh_;
// Globally shared point addressing
//- Total number of global points
label nGlobalPoints_;
//- Indices of local points that are globally shared
labelList sharedPointLabels_;
//- Indices of globally shared points in the master list
// This list contains all the shared points in the mesh
labelList sharedPointAddr_;
// Private Member Functions
//- Disallow default bitwise copy construct
faGlobalMeshData(const faGlobalMeshData&);
//- Disallow default bitwise assignment
void operator=(const faGlobalMeshData&);
public:
//- Runtime type information
ClassName("faGlobalMeshData");
//- Construct from mesh
faGlobalMeshData(const faMesh& mesh);
//- Destructor
~faGlobalMeshData();
// Member Functions
// Access
//- Return mesh reference
const faMesh& mesh() const;
// Globally shared point addressing
//- Return number of globally shared points
label nGlobalPoints() const
{
return nGlobalPoints_;
}
//- Return indices of local points that are globally shared
const labelList& sharedPointLabels() const
{
return sharedPointLabels_;
}
//- Return addressing into the complete globally shared points
// list
const labelList& sharedPointAddr() const
{
return sharedPointAddr_;
}
//- Change global mesh data given a topological change.
void updateMesh();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Typedef
Foam::faProcessorTopology
Description
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faProcessorTopology_H
#define faProcessorTopology_H
#include "ProcessorTopology.H"
#include "faPatchList.H"
#include "processorFaPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef ProcessorTopology<faPatchList, processorFaPatch> faProcessorTopology;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,572 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faMesh
Description
Finite area mesh. Used for 2-D non-Euclidian finite area method.
SourceFiles
faMesh.C
faMeshDemandDrivenData.C
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faMesh_H
#define faMesh_H
#include "GeoMesh.H"
#include "MeshObject.H"
#include "polyMesh.H"
#include "lduMesh.H"
#include "faBoundaryMesh.H"
#include "edgeList.H"
#include "faceList.H"
#include "primitiveFieldsFwd.H"
#include "DimensionedField.H"
#include "areaFieldsFwd.H"
#include "edgeFieldsFwd.H"
#include "indirectPrimitivePatch.H"
#include "edgeInterpolation.H"
#include "labelIOList.H"
#include "FieldFields.H"
#include "faGlobalMeshData.H"
#include "faSchemes.H"
#include "faSolution.H"
#include "data.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Class forward declarations
class faMeshLduAddressing;
class faMeshMapper;
/*---------------------------------------------------------------------------*\
Class faMesh Declaration
\*---------------------------------------------------------------------------*/
class faMesh
:
public GeoMesh<polyMesh>,
public MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>,
public lduMesh,
public edgeInterpolation,
public faSchemes,
public faSolution,
public data
{
// Private data
//- Face labels
labelIOList faceLabels_;
//- Boundary mesh
faBoundaryMesh boundary_;
// Primitive mesh data
//- Edges, addressing into local point list
edgeList edges_;
//- Edge owner
labelList edgeOwner_;
//- Edge neighbour
labelList edgeNeighbour_;
// Primitive size data
//- Number of points
mutable label nPoints_;
//- Number of edges
mutable label nEdges_;
//- Number of internal edges
mutable label nInternalEdges_;
//- Number of faces
mutable label nFaces_;
// Communication support
//- Communicator used for parallel communication
label comm_;
// Demand-driven data
//- Primitive patch
mutable indirectPrimitivePatch* patchPtr_;
//- Ldu addressing data
mutable faMeshLduAddressing* lduPtr_;
//- Current time index for motion
// Note. The whole mechanism will be replaced once the
// dimensionedField is created and the dimensionedField
// will take care of the old-time levels.
mutable label curTimeIndex_;
//- Face areas
mutable DimensionedField<scalar, areaMesh>* SPtr_;
//- Face areas old time level
mutable DimensionedField<scalar, areaMesh>* S0Ptr_;
//- Face areas old-old time level
mutable DimensionedField<scalar, areaMesh>* S00Ptr_;
//- Patch starts in the edge list
mutable labelList* patchStartsPtr_;
//- Edge length vectors
mutable edgeVectorField* LePtr_;
//- Mag edge length vectors
mutable edgeScalarField* magLePtr_;
//- Face centres
mutable areaVectorField* centresPtr_;
//- Edge centres
mutable edgeVectorField* edgeCentresPtr_;
//- Face area normals
mutable areaVectorField* faceAreaNormalsPtr_;
//- Edge area normals
mutable edgeVectorField* edgeAreaNormalsPtr_;
//- Edge area normals
mutable vectorField* pointAreaNormalsPtr_;
//- Face curvatures
mutable areaScalarField* faceCurvaturesPtr_;
//- Edge transformation tensors
mutable FieldField<Field, tensor>* edgeTransformTensorsPtr_;
//- Whether point normals must be corrected for a patch
mutable boolList* correctPatchPointNormalsPtr_;
// Other mesh-related data
//- Parallel info
mutable faGlobalMeshData* globalMeshDataPtr_;
// Static Private Data
//- Use quadrics fit
static const int quadricsFit_;
// Private Member Functions
//- Disallow default bitwise copy construct
faMesh(const faMesh&);
//- Disallow default bitwise assignment
void operator=(const faMesh&);
//- Set primitive mesh data
void setPrimitiveMeshData();
// Private member functions to calculate demand driven data
//- Calculate ldu addressing
void calcLduAddressing() const;
//- Calculate patch starts in the edge list
void calcPatchStarts() const;
//- Calculate edge lengths
void calcLe() const;
//- Calculate mag edge lengths
void calcMagLe() const;
//- Calculate face centres
void calcAreaCentres() const;
//- Calculate edge centres
void calcEdgeCentres() const;
//- Calculate face areas
void calcS() const;
//- Calculate face area normals
void calcFaceAreaNormals() const;
//- Calculate edge area normals
void calcEdgeAreaNormals() const;
//- Calculate point area normals
void calcPointAreaNormals() const;
//- Calculate point area normals by quadrics fit
void calcPointAreaNormalsByQuadricsFit() const;
//- Calculate face curvatures
void calcFaceCurvatures() const;
//- Calculate edge transformation tensors
void calcEdgeTransformTensors() const;
//- Clear geometry but not the face areas
void clearGeomNotAreas() const;
//- Clear geometry
void clearGeom() const;
//- Clear addressing
void clearAddressing() const;
//- Clear demand-driven data
void clearOut() const;
public:
// Public typedefs
typedef faMesh Mesh;
typedef faBoundaryMesh BoundaryMesh;
//- Runtime type information
TypeName("faMesh");
//- Return the mesh sub-directory name (usually "faMesh")
static word meshSubDir;
// Constructors
//- Construct from polyMesh
explicit faMesh(const polyMesh& m);
//- Construct from components without boundary.
// Boundary is added using addFaPatches() member function
faMesh
(
const polyMesh& m,
const labelList& faceLabels
);
//- Construct from finite area mesh definition file
faMesh
(
const polyMesh& m,
const fileName& defFile
);
//- Construct from polyPatch
faMesh
(
const polyMesh& m,
const label polyPatchID
);
//- Destructor
virtual ~faMesh();
// Member Functions
// Helpers
//- Add boundary patches. Constructor helper
void addFaPatches(const List<faPatch*> &);
// Database
//- Return access to polyMesh
const polyMesh& mesh() const
{
return
MeshObject
<
polyMesh,
Foam::UpdateableMeshObject,
faMesh
>::mesh();
}
//- Return the local mesh directory (dbDir()/meshSubDir)
fileName meshDir() const;
//- Return reference to time
const Time& time() const;
//- Return the current instance directory for points
// Used in the consruction of gemometric mesh data dependent
// on points
const fileName& pointsInstance() const;
//- Return the current instance directory for faces
const fileName& facesInstance() const;
// Mesh size parameters
inline label nPoints() const
{
return nPoints_;
}
inline label nEdges() const
{
return nEdges_;
}
inline label nInternalEdges() const
{
return nInternalEdges_;
}
inline label nFaces() const
{
return nFaces_;
}
// Primitive mesh data
//- Return mesh points
const pointField& points() const;
//- Return edges
const edgeList& edges() const;
//- Return faces
const faceList& faces() const;
//- Edge owner addresing
inline const labelList& edgeOwner() const
{
return edgeOwner_;
}
//- Edge neighbour addressing
inline const labelList& edgeNeighbour() const
{
return edgeNeighbour_;
}
// Communication support
//- Return communicator used for parallel communication
label comm() const;
//- Return communicator used for parallel communication
label& comm();
// Access
//- Return reference to the mesh database
virtual const objectRegistry& thisDb() const;
//- Name function is needed to disambiguate those inherited
// from base classes
const word& name() const
{
return thisDb().name();
}
//- Return constant reference to boundary mesh
const faBoundaryMesh& boundary() const;
//- Return faMesh face labels
const labelList& faceLabels() const
{
return faceLabels_;
}
//- Return parallel info
const faGlobalMeshData& globalData() const;
//- Return ldu addressing
virtual const lduAddressing& lduAddr() const;
//- Return a list of pointers for each patch
// with only those pointing to interfaces being set
virtual lduInterfacePtrsList interfaces() const
{
return boundary().interfaces();
}
//- Internal face owner
const labelUList& owner() const
{
return lduAddr().lowerAddr();
}
//- Internal face neighbour
const labelUList& neighbour() const
{
return lduAddr().upperAddr();
}
//- Return true if given edge label is internal to the mesh
inline bool isInternalEdge(const label edgeIndex) const
{
return edgeIndex < nInternalEdges();
}
// Mesh motion and mophing
//- Is mesh moving
bool moving() const
{
return mesh().moving();
}
//- Update after mesh motion
virtual bool movePoints();
//- Update after topo change
virtual void updateMesh(const mapPolyMesh&);
// Mapping
//- Map all fields in time using given map.
virtual void mapFields(const faMeshMapper& mapper) const;
//- Map face areas in time using given map.
virtual void mapOldAreas(const faMeshMapper& mapper) const;
// Demand-driven data
//- Return constant reference to primitive patch
const indirectPrimitivePatch& patch() const;
//- Return reference to primitive patch
indirectPrimitivePatch& patch();
//- Return patch starts
const labelList& patchStarts() const;
//- Return edge length vectors
const edgeVectorField& Le() const;
//- Return edge length magnitudes
const edgeScalarField& magLe() const;
//- Return face centres as areaVectorField
const areaVectorField& areaCentres() const;
//- Return edge centres as edgeVectorField
const edgeVectorField& edgeCentres() const;
//- Return face areas
const DimensionedField<scalar, areaMesh>& S() const;
//- Return old-time face areas
const DimensionedField<scalar, areaMesh>& S0() const;
//- Return old-old-time face areas
const DimensionedField<scalar, areaMesh>& S00() const;
//- Return face area normals
const areaVectorField& faceAreaNormals() const;
//- Return edge area normals
const edgeVectorField& edgeAreaNormals() const;
//- Return point area normals
const vectorField& pointAreaNormals() const;
//- Return face curvatures
const areaScalarField& faceCurvatures() const;
//- Return edge transformation tensors
const FieldField<Field, tensor>& edgeTransformTensors() const;
//- Return internal point labels
labelList internalPoints() const;
//- Return boundary point labels
labelList boundaryPoints() const;
//- Return edge length correction
tmp<edgeScalarField> edgeLengthCorrection() const;
//- Whether point normals should be corrected for a patch
bool correctPatchPointNormals(const label patchID) const;
//- Set whether point normals should be corrected for a patch
boolList& correctPatchPointNormals() const;
//- Write mesh
virtual bool write(const bool valid = true) const;
// Member Operators
bool operator!=(const faMesh& m) const;
bool operator==(const faMesh& m) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "faPatchFaMeshTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faMeshLduAddressing
Description
lduAddressing wrapper for faMesh
SourceFiles
faMeshLduAddressing.C
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
\*---------------------------------------------------------------------------*/
#ifndef faMeshLduAddressing_H
#define faMeshLduAddressing_H
#include "lduAddressing.H"
#include "faMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faMeshLduAddressing Declaration
\*---------------------------------------------------------------------------*/
class faMeshLduAddressing
:
public lduAddressing
{
// Private data
//- Lower as a subList of allOwner
labelList::subList lowerAddr_;
//- Upper as a reference to neighbour
const labelList& upperAddr_;
//- Patch addressing as a list of sublists
List<const labelUList*> patchAddr_;
//- Patch field evaluation schedule
const lduSchedule& patchSchedule_;
// Private Member Functions
//- Disallow default bitwise copy construct
faMeshLduAddressing(const faMeshLduAddressing&);
//- Disallow default bitwise assignment
void operator=(const faMeshLduAddressing&);
public:
// Constructors
//- Construct from components
faMeshLduAddressing(const faMesh& mesh)
:
lduAddressing(mesh.nFaces()),
lowerAddr_
(
labelList::subList
(
mesh.edgeOwner(),
mesh.nInternalEdges()
)
),
upperAddr_(mesh.edgeNeighbour()),
patchAddr_(mesh.boundary().size()),
patchSchedule_(mesh.globalData().patchSchedule())
{
forAll(mesh.boundary(), patchI)
{
patchAddr_[patchI] = &mesh.boundary()[patchI].edgeFaces();
}
}
//-Destructor
virtual ~faMeshLduAddressing()
{}
// Member Functions
//- Return number of interfaces
virtual label nPatches() const
{
return patchAddr_.size();
}
//- Return lower addressing (i.e. lower label = upper triangle)
virtual const labelUList& lowerAddr() const
{
return lowerAddr_;
}
//- Return upper addressing (i.e. upper label)
virtual const labelUList& upperAddr() const
{
return upperAddr_;
}
//- Return patch addressing
virtual const labelUList& patchAddr(const label i) const
{
return *patchAddr_[i];
}
// Return patch field evaluation schedule
virtual const lduSchedule& patchSchedule() const
{
return patchSchedule_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,424 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Description
FV surface mapper.
\*---------------------------------------------------------------------------*/
#include "faAreaMapper.H"
#include "mapPolyMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::faAreaMapper::calcAddressing() const
{
if
(
newFaceLabelsPtr_
|| newFaceLabelsMapPtr_
|| directAddrPtr_
|| interpolationAddrPtr_
|| weightsPtr_
|| insertedObjectLabelsPtr_
)
{
FatalErrorInFunction
<< "Addressing already calculated"
<< abort(FatalError);
}
// Mapping
const label oldNInternal = mpm_.nOldInternalFaces();
hasUnmapped_ = false;
// Calculate new face labels
// Copy old face labels
const labelList& oldFaces = mesh_.faceLabels();
// Prepare a list of new face labels and (preliminary) addressing
// Note: dimensioned to number of boundary faces of polyMesh
newFaceLabelsPtr_ = new labelList
(
mesh_().nFaces() - mesh_().nInternalFaces(),
-1
);
labelList& newFaceLabels = *newFaceLabelsPtr_;
newFaceLabelsMapPtr_ = new labelList
(
mesh_().nFaces() - mesh_().nInternalFaces(),
-1
);
labelList& newFaceLabelsMap = *newFaceLabelsMapPtr_;
label nNewFaces = 0;
Info<< "Old face list size: " << oldFaces.size()
<< " estimated new size " << newFaceLabels.size() << endl;
// Get reverse face map
const labelList& reverseFaceMap = mpm_.reverseFaceMap();
// Pick up live old faces
forAll(oldFaces, faceI)
{
if (reverseFaceMap[oldFaces[faceI]] > -1)
{
// Face is live, add it and record addressing
newFaceLabels[nNewFaces] = reverseFaceMap[oldFaces[faceI]];
newFaceLabelsMap[nNewFaces] = faceI;
nNewFaces++;
}
}
// Assemble the maps
if (direct())
{
Info<< "Direct"<< endl;
// Direct mapping: no further faces to add. Resize list
newFaceLabels.setSize(nNewFaces);
directAddrPtr_ = new labelList(newFaceLabels.size());
labelList& addr = *directAddrPtr_;
// Adjust for creation of a boundary face from an internal face
forAll(addr, faceI)
{
if (newFaceLabelsMap[faceI] < oldNInternal)
{
addr[faceI] = 0;
}
else
{
addr[faceI] = newFaceLabelsMap[faceI];
}
}
}
else
{
// There are further faces to add. Prepare interpolation addressing
// and weights to full size
interpolationAddrPtr_ = new labelListList(newFaceLabels.size());
labelListList& addr = *interpolationAddrPtr_;
weightsPtr_ = new scalarListList(newFaceLabels.size());
scalarListList& w = *weightsPtr_;
// Insert single addressing and weights
for (label addrI = 0; addrI < nNewFaces; ++addrI)
{
addr[addrI] = labelList(1, newFaceLabelsMap[addrI]);
w[addrI] = scalarList(1, scalar(1));
}
// Pick up faces from points, edges and faces where the origin
// Only map from faces which were previously in the faMesh, using
// fast lookup
// Set of faces previously in the mesh
labelHashSet oldFaceLookup(oldFaces);
// Go through faces-from lists and add the ones where all
// old face labels belonged to the faMesh
const List<objectMap>& ffp = mpm_.facesFromPointsMap();
forAll(ffp, ffpI)
{
// Get addressing
const labelList& mo = ffp[ffpI].masterObjects();
// Check if master objects are in faMesh
labelList validMo(mo.size());
label nValidMo = 0;
forAll(mo, moI)
{
if (oldFaceLookup.found(mo[moI]))
{
validMo[nValidMo] = oldFaceLookup[mo[moI]];
nValidMo++;
}
}
if (nValidMo > 0)
{
// Some objects found: add face and interpolation to list
newFaceLabels[nNewFaces] = ffp[ffpI].index();
// No old face available
newFaceLabelsMap[nNewFaces] = -1;
// Map from masters, uniform weights
addr[nNewFaces] = validMo;
w[nNewFaces] = scalarList(validMo.size(), 1.0/validMo.size());
nNewFaces++;
}
}
const List<objectMap>& ffe = mpm_.facesFromEdgesMap();
forAll(ffe, ffeI)
{
// Get addressing
const labelList& mo = ffe[ffeI].masterObjects();
// Check if master objects are in faMesh
labelList validMo(mo.size());
label nValidMo = 0;
forAll(mo, moI)
{
if (oldFaceLookup.found(mo[moI]))
{
validMo[nValidMo] = oldFaceLookup[mo[moI]];
nValidMo++;
}
}
if (nValidMo > 0)
{
// Some objects found: add face and interpolation to list
newFaceLabels[nNewFaces] = ffe[ffeI].index();
// No old face available
newFaceLabelsMap[nNewFaces] = -1;
// Map from masters, uniform weights
addr[nNewFaces] = validMo;
w[nNewFaces] = scalarList(validMo.size(), 1.0/validMo.size());
nNewFaces++;
}
}
const List<objectMap>& fff = mpm_.facesFromFacesMap();
forAll(fff, fffI)
{
// Get addressing
const labelList& mo = fff[fffI].masterObjects();
// Check if master objects are in faMesh
labelList validMo(mo.size());
label nValidMo = 0;
forAll(mo, moI)
{
if (oldFaceLookup.found(mo[moI]))
{
validMo[nValidMo] = oldFaceLookup[mo[moI]];
nValidMo++;
}
}
if (nValidMo > 0)
{
// Some objects found: add face and interpolation to list
newFaceLabels[nNewFaces] = fff[fffI].index();
// No old face available
newFaceLabelsMap[nNewFaces] = -1;
// Map from masters, uniform weights
addr[nNewFaces] = validMo;
w[nNewFaces] = scalarList(validMo.size(), 1.0/validMo.size());
nNewFaces++;
}
}
// All faces collected. Reset sizes of lists
newFaceLabels.setSize(nNewFaces);
newFaceLabelsMap.setSize(nNewFaces);
addr.setSize(nNewFaces);
w.setSize(nNewFaces);
Info<< "addr: " << addr << nl
<< "w: " << w << endl;
}
// Inserted objects cannot appear in the new faMesh as they have no master
// HJ, 10/Aug/2011
insertedObjectLabelsPtr_ = new labelList(0);
}
void Foam::faAreaMapper::clearOut()
{
deleteDemandDrivenData(newFaceLabelsPtr_);
deleteDemandDrivenData(newFaceLabelsMapPtr_);
deleteDemandDrivenData(directAddrPtr_);
deleteDemandDrivenData(interpolationAddrPtr_);
deleteDemandDrivenData(weightsPtr_);
deleteDemandDrivenData(insertedObjectLabelsPtr_);
hasUnmapped_ = false;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faAreaMapper::faAreaMapper
(
const faMesh& mesh,
const mapPolyMesh& mpm
)
:
mesh_(mesh),
mpm_(mpm),
insertedFaces_(false),
direct_(false),
hasUnmapped_(false),
sizeBeforeMapping_(mesh.nFaces()),
newFaceLabelsPtr_(nullptr),
newFaceLabelsMapPtr_(nullptr),
directAddrPtr_(nullptr),
interpolationAddrPtr_(nullptr),
weightsPtr_(nullptr),
insertedObjectLabelsPtr_(nullptr)
{
// Check for possibility of direct mapping
if
(
mpm_.facesFromPointsMap().empty()
&& mpm_.facesFromEdgesMap().empty()
&& mpm_.facesFromFacesMap().empty()
)
{
direct_ = true;
}
else
{
direct_ = false;
}
// Inserted objects not suported: no master
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::faAreaMapper::~faAreaMapper()
{
clearOut();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::labelList& Foam::faAreaMapper::newFaceLabels() const
{
if (!newFaceLabelsPtr_)
{
calcAddressing();
}
return *newFaceLabelsPtr_;
}
const Foam::labelList& Foam::faAreaMapper::newFaceLabelsMap() const
{
if (!newFaceLabelsMapPtr_)
{
calcAddressing();
}
return *newFaceLabelsMapPtr_;
}
const Foam::labelUList& Foam::faAreaMapper::directAddressing() const
{
if (!direct())
{
FatalErrorInFunction
<< "Requested direct addressing for an interpolative mapper."
<< abort(FatalError);
}
if (!directAddrPtr_)
{
calcAddressing();
}
return *directAddrPtr_;
}
const Foam::labelListList& Foam::faAreaMapper::addressing() const
{
if (direct())
{
FatalErrorInFunction
<< "Requested interpolative addressing for a direct mapper."
<< abort(FatalError);
}
if (!interpolationAddrPtr_)
{
calcAddressing();
}
return *interpolationAddrPtr_;
}
const Foam::scalarListList& Foam::faAreaMapper::weights() const
{
if (direct())
{
FatalErrorInFunction
<< "Requested interpolative weights for a direct mapper."
<< abort(FatalError);
}
if (!weightsPtr_)
{
calcAddressing();
}
return *weightsPtr_;
}
const Foam::labelList& Foam::faAreaMapper::insertedObjectLabels() const
{
if (!insertedObjectLabelsPtr_)
{
calcAddressing();
}
return *insertedObjectLabelsPtr_;
}
// ************************************************************************* //

View File

@ -0,0 +1,195 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faAreaMapper
Description
FA area mapper.
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
SourceFiles
faAreaMapper.C
\*---------------------------------------------------------------------------*/
#ifndef faAreaMapper_H
#define faAreaMapper_H
#include "morphFieldMapper.H"
#include "faMesh.H"
#include "faceMapper.H"
#include "HashSet.H"
#include "mapPolyMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faAreaMapper Declaration
\*---------------------------------------------------------------------------*/
class faAreaMapper
:
public morphFieldMapper
{
// Private data
//- Reference to mesh mapper
const faMesh& mesh_;
//- Reference to mapPolyMesh
const mapPolyMesh& mpm_;
//- Are there any inserted (unmapped) faces
bool insertedFaces_;
//- Is the mapping direct
bool direct_;
// Demand-driven private data
mutable bool hasUnmapped_;
//- Old mesh size
label sizeBeforeMapping_;
//- New face labels after mapping
mutable labelList* newFaceLabelsPtr_;
//- New face labels after mapping
mutable labelList* newFaceLabelsMapPtr_;
//- Direct addressing (only one form of addressing is used)
mutable labelList* directAddrPtr_;
//- Interpolated addressing (only one form of addressing is used)
mutable labelListList* interpolationAddrPtr_;
//- Interpolation weights
mutable scalarListList* weightsPtr_;
//- Inserted faces
mutable labelList* insertedObjectLabelsPtr_;
// Private Member Functions
//- Disallow default bitwise copy construct
faAreaMapper(const faAreaMapper&);
//- Disallow default bitwise assignment
void operator=(const faAreaMapper&);
//- Calculate addressing
void calcAddressing() const;
//- Clear out local storage
void clearOut();
public:
//- Construct from components
faAreaMapper
(
const faMesh& mesh,
const mapPolyMesh& mpm
);
//- Destructor
virtual ~faAreaMapper();
// Member Functions
//- Return new face labels
const labelList& newFaceLabels() const;
//- Return new face labels map
// For new faces return old face index if it exists
// If the face has been added, index will be -1
const labelList& newFaceLabelsMap() const;
//- Return size
virtual label size() const
{
return newFaceLabels().size();
}
//- Return size of field before mapping
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
//- Is the mapping direct
virtual bool direct() const
{
return direct_;
}
virtual bool hasUnmapped() const
{
return hasUnmapped_;
}
//- Return direct addressing
virtual const labelUList& directAddressing() const;
//- Return interpolated addressing
virtual const labelListList& addressing() const;
//- Return interpolaion weights
virtual const scalarListList& weights() const;
//- Are there any inserted faces
virtual bool insertedObjects() const
{
return !insertedObjectLabels().empty();
}
//- Return list of inserted faces
virtual const labelList& insertedObjectLabels() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faBoundaryMeshMapper
Description
Foam::faBoundaryMeshMapper
\*---------------------------------------------------------------------------*/
#ifndef faBoundaryMeshMapper_H
#define faBoundaryMeshMapper_H
#include "PtrList.H"
#include "faPatchMapper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faBoundaryMeshMapper Declaration
\*---------------------------------------------------------------------------*/
class faBoundaryMeshMapper
:
public PtrList<faPatchMapper>
{
// Private Member Functions
//- Disallow default bitwise copy construct
faBoundaryMeshMapper(const faBoundaryMeshMapper&);
//- Disallow default bitwise assignment
void operator=(const faBoundaryMeshMapper&);
public:
// Constructors
//- Construct from components
faBoundaryMeshMapper
(
const faMesh& mesh,
const mapPolyMesh& mpm
)
:
PtrList<faPatchMapper>(mesh.boundary().size())
{
const faBoundaryMesh& patches = mesh.boundary();
forAll(patches, patchI)
{
set
(
patchI,
new faPatchMapper
(
patches[patchI],
mpm
)
);
}
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Description
FA edge mapper.
\*---------------------------------------------------------------------------*/
#include "faEdgeMapper.H"
#include "mapPolyMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::faEdgeMapper::calcAddressing() const
{
if (directAddrPtr_)
{
FatalErrorInFunction
<< "Addressing already calculated"
<< abort(FatalError);
}
hasUnmapped_ = false;
// Dummy mapping: take value from edge 0
directAddrPtr_ = new labelList(size(), 0);
}
void Foam::faEdgeMapper::clearOut()
{
deleteDemandDrivenData(directAddrPtr_);
hasUnmapped_ = false;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faEdgeMapper::faEdgeMapper
(
const faMesh& mesh,
const mapPolyMesh& mpm
)
:
mesh_(mesh),
mpm_(mpm),
sizeBeforeMapping_(mesh.nInternalEdges()),
hasUnmapped_(false),
directAddrPtr_(nullptr)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::faEdgeMapper::~faEdgeMapper()
{
clearOut();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::labelUList& Foam::faEdgeMapper::directAddressing() const
{
if (!directAddrPtr_)
{
calcAddressing();
}
return *directAddrPtr_;
}
const Foam::labelListList& Foam::faEdgeMapper::addressing() const
{
FatalErrorInFunction
<< "Requested interpolative addressing for a direct mapper."
<< abort(FatalError);
return labelListList::null();
}
const Foam::scalarListList& Foam::faEdgeMapper::weights() const
{
FatalErrorInFunction
<< "Requested interpolative weights for a direct mapper."
<< abort(FatalError);
return scalarListList::null();
}
// ************************************************************************* //

View File

@ -0,0 +1,169 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faEdgeMapper
Description
FA edge mapper. Currently, edge-based finite area data is not mapped,
but only resized, since edge-based mapping data is not available
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
SourceFiles
faEdgeMapper.C
\*---------------------------------------------------------------------------*/
#ifndef faEdgeMapper_H
#define faEdgeMapper_H
#include "morphFieldMapper.H"
#include "faMesh.H"
#include "faceMapper.H"
#include "HashSet.H"
#include "mapPolyMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faEdgeMapper Declaration
\*---------------------------------------------------------------------------*/
class faEdgeMapper
:
public morphFieldMapper
{
// Private data
//- Reference to mesh
const faMesh& mesh_;
//- Reference to mapPolyMesh
const mapPolyMesh& mpm_;
//- Old mesh size
label sizeBeforeMapping_;
// Demand-driven private data
mutable bool hasUnmapped_;
//- Direct addressing
mutable labelList* directAddrPtr_;
// Private Member Functions
//- Disallow default bitwise copy construct
faEdgeMapper(const faEdgeMapper&);
//- Disallow default bitwise assignment
void operator=(const faEdgeMapper&);
//- Calculate addressing
void calcAddressing() const;
//- Clear out local storage
void clearOut();
public:
//- Construct from components
faEdgeMapper
(
const faMesh& mesh,
const mapPolyMesh& mpm
);
//- Destructor
virtual ~faEdgeMapper();
// Member Functions
//- Return size
virtual label size() const
{
return mesh_.nInternalEdges();
}
//- Return size of field before mapping
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
//- Is the mapping direct
virtual bool direct() const
{
return true;
}
virtual bool hasUnmapped() const
{
return hasUnmapped_;
}
//- Return direct addressing
virtual const labelUList& directAddressing() const;
//- Return interpolated addressing
virtual const labelListList& addressing() const;
//- Return interpolaion weights
virtual const scalarListList& weights() const;
//- Are there any inserted faces
virtual bool insertedObjects() const
{
return false;
}
//- Return list of inserted faces
virtual const labelList& insertedObjectLabels() const
{
return labelList::null();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "faMeshMapper.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faMeshMapper::faMeshMapper
(
const faMesh& mesh,
const mapPolyMesh& mpm
)
:
mesh_(mesh),
nOldPoints_(mesh.nPoints()),
nOldEdges_(mesh.nEdges()),
nOldInternalEdges_(mesh.nInternalEdges()),
nOldFaces_(mesh.nFaces()),
oldPatchSizes_(mesh.boundary().size(), 0),
oldPatchStarts_(mesh.boundary().size(), -1),
oldPatchEdgeFaces_(mesh.boundary().size()),
areaMap_(mesh, mpm),
edgeMap_(mesh, mpm),
boundaryMap_(mesh, mpm)
{
// Capture old patch information
const faBoundaryMesh& patches = mesh.boundary();
forAll(patches, patchI)
{
oldPatchSizes_[patchI] = patches[patchI].size();
oldPatchStarts_[patchI] = patches[patchI].start();
oldPatchEdgeFaces_[patchI] = patches[patchI].edgeFaces();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,221 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2016-2017 Wikki Ltd
-------------------------------------------------------------------------------
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/>.
Class
Foam::faMeshMapper
Description
Class holds all the necessary information for mapping fields associated
with faMesh
Note
In order to capture all necessary mesh sizes and mapping data, mapper
is created with the OLD mesh, and provides new mesh data.
In the process, field mapping information is assembled from the old faMesh
and the mapping data
Author
Zeljko Tukovic, FMENA
Hrvoje Jasak, Wikki Ltd.
SourceFiles
faMeshMapper.C
\*---------------------------------------------------------------------------*/
#ifndef faMeshMapper_H
#define faMeshMapper_H
#include "faceMapper.H"
#include "faAreaMapper.H"
#include "faEdgeMapper.H"
#include "faBoundaryMeshMapper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class faMesh;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class faMeshMapper Declaration
\*---------------------------------------------------------------------------*/
class faMeshMapper
{
// Private data
//- Reference to mesh
const faMesh& mesh_;
// Old mesh data
//- Number of old points
label nOldPoints_;
//- Number of old edges
label nOldEdges_;
//- Number of old internal edges
label nOldInternalEdges_;
//- Number of old faces
label nOldFaces_;
//- Old patch sizes
labelList oldPatchSizes_;
//- Old patch starts
labelList oldPatchStarts_;
//- Old patch edgeFaces
labelListList oldPatchEdgeFaces_;
// Mappers
//- Area mapper
faAreaMapper areaMap_;
//- Edge mapper
faEdgeMapper edgeMap_;
//- Boundary mapper
faBoundaryMeshMapper boundaryMap_;
// Private Member Functions
//- Disallow default bitwise copy construct
faMeshMapper(const faMeshMapper&);
//- Disallow default bitwise assignment
void operator=(const faMeshMapper&);
public:
// Constructors
//- Construct from components
faMeshMapper(const faMesh& mesh, const mapPolyMesh& mpm);
// Member Functions
//- Return reference to mesh
const faMesh& mesh() const
{
return mesh_;
}
//- Return reference to objectRegistry storing fields. Can be
// removed once fields stored on pointMesh.
const objectRegistry& thisDb() const
{
return mesh_.thisDb();
}
// Basic sizing information
//- Return number of old points
label nOldPoints() const
{
return nOldPoints_;
}
//- Return number of old edges
label nOldEdges() const
{
return nOldEdges_;
};
//- Return number of old internal edges
label nOldInternalEdges() const
{
return nOldInternalEdges_;
};
//- Return number of old faces
label nOldFaces() const
{
return nOldFaces_;
};
//- Return old patch sizes
const labelList& oldPatchSizes() const
{
return oldPatchSizes_;
};
//- Return old patch starts
const labelList& oldPatchStarts() const
{
return oldPatchStarts_;
};
//- Return old patch edgeFaces
const labelListList& oldPatchEdgeFaces() const
{
return oldPatchEdgeFaces_;
};
// Mappers
//- Return surface mapper
const faAreaMapper& areaMap() const
{
return areaMap_;
}
//- Return edge mapper
const faEdgeMapper& edgeMap() const
{
return edgeMap_;
}
//- Return boundary mapper
const faBoundaryMeshMapper& boundaryMap() const
{
return boundaryMap_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show More