multiValveEngine: New fvMeshMover for multi-valve IC engine mesh motion

This mesh mover facilitates explicit node translation based on scaled distance
functions for the providing smooth deformation of the mesh to accommodate the
motion piston and multiple valves present in IC engines.   and run-time mesh-to-mesh mapping used to avoid
extreme mesh distortion and support the necessary topology changes that occur at
valve closure.

Highlighted features include:

* Piston motion based on user-defined functions, with options for standard crank
  and connecting rod motion.
* Valve motion based on user-provided lift data or table.
* Support for linerPatches, slidingPatches, and frozenZones.
* Non-conformal coupled (NCC) interfaces can be used to provide better control
  of the mesh-motion around valves
* Run-time mesh-to-mesh mapping used to avoid extreme mesh distortion and
  support the necessary topology changes that occur at valve closure
* Control over mesh motion per moving object including motion parameters and layer
  thickness.

Description from the multiValveEngine.H file:

    A mesh mover using explicit node translation based on scaled distance
    functions per moving object. The mover supports any number of valves
    together with piston motion and following features:

    - Piston motion: Function1 of user-time, may be set to
      crankConnectingRodMotion for standard crank and connecting rod motion.

    - Valve motion: Function1, may be set to table if the valve lift date is
      provided in the form of a table.

    - Smooth mesh motion between a moving object and other patches.

    - linerPatches: the set of patches corresponding to the cylinder liner
      Used by createEngineZones

    - slidingPatches: a set of patches along which mesh is allowed
      to deform. For example, on the cylinder liner, it is desired to
      slide mesh nodes while piston is moving.

    - frozenZones: list of pointZones the points of which are frozen,
      i.e. do not move.

    - Run-time clearance estimation based on patch-to-patch distances printed.

    - Supports cellSet and cellZone definitions to restrict mesh motion.

    - Supports domains with nonConformalCoupling (NCC) interfaces,
      enabling e.g. nodes to slide along with the interface.

    - Closing the valve can be achieved by meshToMesh mapping onto a new
      grid with closed valve geometry at user given time.

    - Mesh motion can be controlled per moving object by setting:

        - patches: list of patches defining the object.

        - motion: a Function1 which returns the object position
          as a function of time.

        - movingZones: list of pointZones the points of which move with the
          object.

        - maxMotionDistance: a distance away from the moving object
          after nodes are not allowed to move. (Default inf.)

        - movingFrozenLayerThickness: thickness of layer in which points move
          with the moving object. (Default 0)

        - staticFrozenLayerThickness: thickness of layer in which points
          are fixed with respect to static patches (e.g. walls). (Default 0)

        - cosineScaling: a switch whether nodal translation is weighted by
          its distance from the moving object. The objective is to yield less
          deformation near the moving object and sustain e.g. boundary layer.
          (Default no, i.e. linear weighting)

        - fractionalTravelInterval: fraction of the stroke travelled after
          which the cached motion scaling weights are recalculated

        For valve object only:

            - minLift: a minimum valve lift value after considered closed.

    Some of the above parameters are highlighted in a given schematic
    piston-valve configuration w.r.t entries used to control piston motion.
    Furthermore, an example dictionary entries are provided below.

                      |             |         |             |
                      |             |         |             |
                      |             |    S    |             |
                      |             |    T    |             |
                      |             |    E    |             |
                      |             |    M    |             |
                     /              |         |              \
                    /               |         |               \
                   /                |         |                \
     _____________/                 |         |                 \_____________
    |        :                      |         |                      :        |
    |        :      /```````````````           ```````````````\      :        |
    |        :     /                VALVE HEAD                 \     :        |
    | L      :    /_____________________________________________\    :        |
    | I      :                         /\                            :        |
    | N      :                         || staticFrozenLayerThickness :        |
    | E      : NCC (optional)          \/ (w.r.t. piston motion)     :        |
    | R      :                      ``````````                       :        |
    |        :                                                       :        |
    |        :                                                       :        |
    |........:.......................................................:........|
    |        :                         /\                            :        |
    |        :                         || movingFrozenLayerThickness :        |
    |________:_________________________\/____________________________:________|
                                       PISTON

    \verbatim
    mover
    {
        type                multiValveEngine;
        libs                ("libfvMeshMoversMultiValveEngine.so");

        frozenZones         (frozenZone1 frozenZone2);

        slidingPatches
        (
            liner
            valveStem
            "nonCouple.*"
        );

        linerPatches        (liner);

        piston
        {
            patches             (piston);
            axis                (0 0 1);

            motion
            {
                type                crankConnectingRodMotion;

                conRodLength        1e3;
                stroke              1.0;
            }

            // Move the points in the piston bowl with the piston
            movingZones         (pistonBowl);

            // Optional
            maxMotionDistance    1e30;
            movingFrozenLayerThickness  0;
            staticFrozenLayerThickness  0;

            fractionalTravelInterval    0.1;

            cosineScaling       yes;
        }

        valves
        {
            iv
            {
                patches     (valveHead);
                axis        (0 0 1);

                // Optional
                maxMotionDistance   1e30;
                movingFrozenLayerThickness  0;
                staticFrozenLayerThickness  0;

                fractionalTravelInterval    0.1;

                cosineScaling       yes;

                minLift     0.001;

                motion
                {
                    type    table;
                    values
                    (
                        (0      0)
                        (480    0.1)
                        (720    0)
                    );
                    // For multi-cycle simulations, use repeat
                    outOfBounds     repeat;
                    interpolationScheme linear;
                }
            }
        }
    }
    \endverbatim

    Note:
      The implementation utilises pointDist objects for distance computation,
      resulting distance fields do not propagate through NCC interfaces.  Hence,
      there should be no horizontal NCC interface separating piston from
      cylinder head as it would result in potentially ill defined mesh
      deformation. Due to same feature, in a schematic case setup above, valve
      motion affects only cells between NCC patches even though no cellSet is
      explicitly defined.

SourceFiles
    multiValveEngine.C

Patch contributed by:
* Heikki Kahila, Wärtsilä Finland: Original implementation
* Bulut Tekgül, Wärtsilä Finland: Testing, cleanup, help with refactoring
* Henry Weller, CFD Direct: Refactoring, generalisation, optimisation and
  merging into OpenFOAM
This commit is contained in:
Henry Weller
2024-02-13 21:30:49 +00:00
parent c84e216282
commit 7d65e66b86
44 changed files with 4307 additions and 152 deletions

View File

@ -1,59 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2021 OpenFOAM Foundation
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# XiEngineFoam
#
# Description
# Script to inform the user that XiEngineFoam has been replaced by the more
# general XiFoam solver.
#
#------------------------------------------------------------------------------
cat << EOF
The XiEngineFoam solver has solver has been replaced by the more general XiFoam
solver, which supports engine mesh motion using an appropriate
fvMeshMover. e.g. layeredEngine
To run a XiEngineFoam case in XiFoam add a mover entry in
constant/dynamicMeshDict
e.g. from the tutorials/combustion/XiFoam/RAS/kivaTest case:
mover
{
type layeredEngine;
libs ("libfvMeshMovers.so");
conRodLength 0.147;
bore 0.092;
stroke 0.08423;
clearance 0.00115;
pistonLayers 0;
}
EOF
#------------------------------------------------------------------------------

View File

@ -1,62 +0,0 @@
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2021-2023 OpenFOAM Foundation
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# coldEngineFoam
#
# Description
# Script to inform the user that coldEngineFoam has been replaced by the
# more general fluid solver module.
#
#------------------------------------------------------------------------------
cat << EOF
The coldEngineFoam solver has solver has been replaced by the more general
fluid solver module, which supports engine mesh motion using an appropriate
fvMeshMover. e.g. layeredEngine
To run a coldEngineFoam case with
foamRun -solver fluid
add a mover entry in constant/dynamicMeshDict
e.g. from the tutorials/fluid/RAS/kivaTest case:
mover
{
type layeredEngine;
libs ("libfvMeshMovers.so");
conRodLength 0.147;
bore 0.092;
stroke 0.08423;
clearance 0.00115;
pistonLayers 0;
}
EOF
#------------------------------------------------------------------------------

View File

@ -0,0 +1,9 @@
multiValveEngine.C
movingObject.C
piston.C
valve.C
valveList.C
crankConnectingRodMotion/crankConnectingRodMotion.C
pistonPointEdgeData/pistonPointEdgeData.C
LIB = $(FOAM_LIBBIN)/libfvMeshMoversMultiValveEngine

View File

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

View File

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "crankConnectingRodMotion.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace Function1s
{
addScalarFunction1(crankConnectingRodMotion);
}
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void Foam::Function1s::crankConnectingRodMotion::read(const dictionary& dict)
{
conRodLength_ = dict.lookup<scalar>("conRodLength");
stroke_ = dict.lookup<scalar>("stroke");
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::Function1s::crankConnectingRodMotion::crankConnectingRodMotion
(
const word& name,
const dictionary& dict
)
:
Function1<scalar>(name)
{
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::Function1s::crankConnectingRodMotion::~crankConnectingRodMotion()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::Function1s::crankConnectingRodMotion::write(Ostream& os) const
{
writeEntry(os, "conRodLength", conRodLength_);
writeEntry(os, "stroke", stroke_);
}
// ************************************************************************* //

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::Function1s::crankConnectingRodMotion
Description
Crank and connecting-rod motion function for piston engines etc.
\c value returns the current piston position as a function of
the crank-angle in degrees.
Usage:
\verbatim
<name>
{
type crankConnectingRodMotion;
conRodLength 0.2;
stroke 0.12;
}
\endverbatim
See also
Foam::Function1
SourceFiles
crankConnectingRodMotionI.H
crankConnectingRodMotion.C
\*---------------------------------------------------------------------------*/
#ifndef crankConnectingRodMotion_H
#define crankConnectingRodMotion_H
#include "Function1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace Function1s
{
/*---------------------------------------------------------------------------*\
Class crankConnectingRodMotion Declaration
\*---------------------------------------------------------------------------*/
class crankConnectingRodMotion
:
public Function1<scalar>
{
// Private data
//- Connecting-rod length
scalar conRodLength_;
//- Stroke
scalar stroke_;
// Private Member Functions
//- Read the coefficients from the given dictionary
void read(const dictionary& dict);
public:
// Runtime type information
TypeName("crankConnectingRodMotion");
// Constructors
//- Construct from name and dictionary
crankConnectingRodMotion
(
const word& name,
const dictionary& dict
);
//- Construct and return a clone
virtual tmp<Function1<scalar>> clone() const
{
return tmp<Function1<scalar>>
(
new crankConnectingRodMotion(*this)
);
}
//- Destructor
virtual ~crankConnectingRodMotion();
// Member Functions
//- Return position for crank-angle theta in deg
virtual inline scalar value(const scalar theta) const;
//- Not implemented
virtual inline tmp<Field<scalar>> value(const scalarField&) const;
//- Not implemented
virtual inline scalar integral
(
const scalar,
const scalar
) const;
//- Not implemented
virtual inline tmp<Field<scalar>> integral
(
const scalarField&,
const scalarField&
) const;
//- Write data to dictionary stream
virtual void write(Ostream& os) const;
// Member Operators
//- Disallow default bitwise assignment
void operator=(const crankConnectingRodMotion&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Function1s
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "crankConnectingRodMotionI.H"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "crankConnectingRodMotion.H"
#include "unitConversion.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::scalar Foam::Function1s::crankConnectingRodMotion::value
(
const scalar theta
) const
{
return
(
conRodLength_ + stroke_/2
)
- (
stroke_*cos(degToRad(theta))/2
+ sqrt(sqr(conRodLength_) - sqr(stroke_*sin(degToRad(theta))/2))
);
}
inline Foam::tmp<Foam::Field<Foam::scalar>>
Foam::Function1s::crankConnectingRodMotion::value
(
const scalarField&
) const
{
NotImplemented;
return tmp<Field<scalar>>(nullptr);
}
inline Foam::scalar Foam::Function1s::crankConnectingRodMotion::integral
(
const scalar,
const scalar
) const
{
NotImplemented;
return NaN;
}
inline Foam::tmp<Foam::Field<Foam::scalar>>
Foam::Function1s::crankConnectingRodMotion::integral
(
const scalarField&,
const scalarField&
) const
{
NotImplemented;
return tmp<Field<scalar>>(nullptr);
}
// ************************************************************************* //

View File

@ -0,0 +1,328 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "multiValveEngine.H"
#include "pointConstraints.H"
#include "polyCellSet.H"
#include "syncTools.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void Foam::fvMeshMovers::multiValveEngine::movingObject::calcScale
(
const pointMesh& pMesh,
const scalarField& pDistMoving,
const scalarField& pDistStatic,
scalar dMoving,
scalar dMax,
scalar dStatic
)
{
scalarField& scale = scale_.primitiveFieldRef();
forAll(scale, pi)
{
// If original dMoving and dStatic regions overlay set to zero.
// This may happen when e.g. valve-piston distance becomes small.
if
(
((pDistMoving[pi] - dMoving) <= 0) &&
((pDistStatic[pi] - dStatic) <= 0)
)
{
dMoving = 0;
dStatic = 0;
}
// - Near static patches
if (pDistStatic[pi] - dStatic <= 0)
{
scale[pi] = 0;
}
// - Near object
else if (pDistMoving[pi] - dMoving <= 0)
{
scale[pi] = 1;
}
// - Outside outer boundary
else if (dMax - pDistMoving[pi] <= 0)
{
scale[pi] = 0;
}
// Linear scaling from the moving patch:
// patch->dMoving: 1
// dMoving->min(dMax, min(dStatic - dh, dFrozenZone)): linear 1->0
else
{
const scalar d1 = pDistMoving[pi] - dMoving;
const scalar d2 = min
(
dMax - pDistMoving[pi],
pDistStatic[pi] - dStatic
);
scale[pi] = 1 - d1/(d1 + d2 + rootVSmall);
}
}
// Convert the scale function to a cosine
if (cosine_)
{
scale =
min
(
max
(
0.5
- 0.5
*cos(scale_.primitiveField()*constant::mathematical::pi),
scalar(0)
),
scalar(1)
);
}
pointConstraints::New(pMesh).constrain(scale_);
if (debug)
{
scale_.write();
}
}
void Foam::fvMeshMovers::multiValveEngine::movingObject::transformPoints
(
pointField& newPoints,
const vector& translationVector
)
{
// Explicit filtering of displacement to avoid pointMesh looping
if (mag(translationVector) < small)
{
executionCount_++;
return;
}
forAll(newPoints, pi)
{
const point displacementVector = scale_[pi]*translationVector;
if (mag(displacementVector) > small)
{
newPoints[pi] += displacementVector;
}
}
executionCount_++;
}
void Foam::fvMeshMovers::multiValveEngine::movingObject::createStaticPatchSet()
{
staticPatchSet_.clear();
forAll(meshMover_.mesh().boundaryMesh(), patchI)
{
const polyPatch& pp = meshMover_.mesh().boundaryMesh()[patchI];
// Exclude non-static patches
if
(
!polyPatch::constraintType(pp.type())
&& !meshMover_.slidingPatchSet_.found(pp.index())
&& !patchSet.found(pp.index())
)
{
staticPatchSet_.insert(pp.index());
}
}
}
void Foam::fvMeshMovers::multiValveEngine::movingObject::initPatchSets()
{
// Set patch-sets
patchSet_ = meshMover_.mesh().boundaryMesh().patchSet
(
wordReList(dict_.lookup("patches"))
);
if (patchSet_.empty())
{
FatalErrorInFunction
<< "Empty patchSet in " << dict_.name()
<< exit(FatalError);
}
createStaticPatchSet();
}
Foam::labelHashSet
Foam::fvMeshMovers::multiValveEngine::movingObject::movingPointZones() const
{
labelHashSet movingPointZones;
if (movingPointZones_.size())
{
forAll(movingPointZones_, i)
{
const labelList indices
(
meshMover_.mesh().pointZones().findIndices(movingPointZones_[i])
);
if (indices.size())
{
movingPointZones.insert(indices);
Info<< " pointZone " << movingPointZones_[i]
<< " will move with the object " << name << endl;
}
else
{
Info<< " movingZone " << movingPointZones_[i]
<< " not found in pointZones" << endl;
}
}
}
return movingPointZones;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvMeshMovers::multiValveEngine::movingObject::movingObject
(
const word& objectName,
const multiValveEngine& engine,
const dictionary& dict
)
:
dict_(dict),
meshMover_(engine),
name(objectName),
axis(dict.lookup("axis")),
motion_(Function1<scalar>::New("motion", dict)),
maxMotionDistance_
(
dict.lookupOrDefault<scalar>("maxMotionDistance", great)
),
movingFrozenLayerThickness_
(
dict.lookupOrDefault<scalar>("movingFrozenLayerThickness", 0)
),
staticFrozenLayerThickness_
(
dict.lookupOrDefault<scalar>("staticFrozenLayerThickness", 0)
),
movingPointZones_
(
dict.lookupOrDefault("movingZones", wordReList::null())
),
scale_
(
IOobject
(
"motionScale_" + name,
meshMover_.mesh().time().timeName(),
meshMover_.mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
pointMesh::New(meshMover_.mesh()),
dimensionedScalar(dimless, 0)
),
cosine_(dict.lookupOrDefault("cosineScaling", false)),
fractionalTravelInterval_
(
dict.lookupOrDefault<scalar>("fractionalTravelInterval", 1)
),
executionCount_(0),
position0_(-great),
patchSet(patchSet_)
{
Info << indent << "Setting motion for " << name << endl;
scalar maxTravel = -great;
scalar minTravel = great;
const scalar userBeginTime
(
meshMover_.mesh().time().timeToUserTime
(
meshMover_.mesh().time().beginTime().value()
)
);
const scalar userEndTime
(
meshMover_.mesh().time().timeToUserTime
(
meshMover_.mesh().time().endTime().value()
)
);
const scalar userDeltaT = meshMover_.userDeltaT();
scalar userTime = userBeginTime;
while (userTime <= userEndTime)
{
const scalar position = motion_->value(userTime);
maxTravel = max(maxTravel, position);
minTravel = min(minTravel, position);
userTime += userDeltaT;
}
travel_ = maxTravel - minTravel;
initPatchSets();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fvMeshMovers::multiValveEngine::movingObject::mapMesh
(
const polyMeshMap&
)
{
// Reset patch sets.
initPatchSets();
// scale_ is resized by the meshToMesh mapper
scale_ = Zero;
// Reset count of the scale_ field updates
executionCount_ = 0;
// Reset position at last scale update
position0_ = -great;
}
// ************************************************************************* //

View File

@ -0,0 +1,237 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "multiValveEngine.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace fvMeshMovers
{
defineTypeNameAndDebug(multiValveEngine, 0);
addToRunTimeSelectionTable(fvMeshMover, multiValveEngine, fvMesh);
}
}
Foam::word Foam::fvMeshMovers::multiValveEngine::cylinderHeadName
(
"cylinderHead"
);
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::labelHashSet
Foam::fvMeshMovers::multiValveEngine::findLinerPatchSet() const
{
return mesh().boundaryMesh().patchSet
(
wordReList(dict().lookup("linerPatches"))
);
}
Foam::labelHashSet Foam::fvMeshMovers::multiValveEngine::findSlidingPatchSet()
{
return mesh().boundaryMesh().patchSet
(
wordReList(dict().lookup("slidingPatches"))
);
}
Foam::labelHashSet Foam::fvMeshMovers::multiValveEngine::findStaticPatchSet()
{
labelHashSet movingPatchSet(piston_.patchSet_);
forAll(valves_, valvei)
{
movingPatchSet += valves_[valvei].patchSet_;
}
labelHashSet staticPatchSet;
forAll(mesh().boundaryMesh(), patchi)
{
const polyPatch& pp = mesh().boundaryMesh()[patchi];
// Exclude non-static patches
if
(
!polyPatch::constraintType(pp.type())
&& !slidingPatchSet_.found(pp.index())
&& !movingPatchSet.found(pp.index())
)
{
staticPatchSet.insert(pp.index());
}
}
return staticPatchSet;
}
Foam::labelHashSet
Foam::fvMeshMovers::multiValveEngine::staticPointZones() const
{
labelHashSet staticPointZones;
if (frozenPointZones_.size())
{
forAll(frozenPointZones_, i)
{
const labelList indices
(
mesh().pointZones().findIndices(frozenPointZones_[i])
);
if (indices.size())
{
staticPointZones.insert(indices);
Info<< " pointZone " << frozenPointZones_[i]
<< " is frozen (stationary)" << endl;
}
else
{
Info<< " frozenZone " << frozenPointZones_[i]
<< " not found in pointZones" << endl;
}
}
}
return staticPointZones;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvMeshMovers::multiValveEngine::multiValveEngine(fvMesh& mesh)
:
fvMeshMover(mesh),
linerPatchSet_(findLinerPatchSet()),
slidingPatchSet_(findSlidingPatchSet()),
piston_("piston", *this, dict().subDict("piston")),
valves_(*this, dict().subOrEmptyDict("valves")),
staticPatchSet_(findStaticPatchSet()),
frozenPointZones_
(
dict().lookupOrDefault("frozenZones", wordReList::null())
),
linerPatchSet(linerPatchSet_),
slidingPatchSet(slidingPatchSet_),
piston(piston_),
valves(valves_),
staticPatchSet(staticPatchSet_)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fvMeshMovers::multiValveEngine::~multiValveEngine()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::fvMeshMovers::multiValveEngine::userTime() const
{
return mesh().time().userTimeValue();
}
Foam::scalar Foam::fvMeshMovers::multiValveEngine::userDeltaT() const
{
return mesh().time().timeToUserTime(mesh().time().deltaTValue());
}
bool Foam::fvMeshMovers::multiValveEngine::update()
{
// Accumulate point motion from each moving object into newPoints field.
pointField newPoints(mesh().points());
Info<< "Piston: " << nl;
piston_.updatePoints(newPoints);
Info<< " position from TDC: " << piston_.position() << " m" << nl
<< " displacement: " << piston_.displacement() << " m" << nl
<< " speed = " << piston_.speed() << " m/s" << nl
<< " clearance: " << piston_.clearance() << " m" << endl;
forAll(valves_, valvei)
{
valveObject& valve = valves_[valvei];
Info<< "Valve " << valve.name << nl;
valve.updatePoints(newPoints);
Info<< " lift: " << (valve.isOpen() ? valve.lift() : 0.0) << " m "
<< (valve.isOpen() ? "(open)" : "(closed)") << nl
<< " speed: " << valve.speed() << " m/s" << nl
<< " displacement: " << valve.displacement() << " m" << endl;
}
// Update the mesh according to the newPoints field.
mesh().movePoints(newPoints);
return true;
}
void Foam::fvMeshMovers::multiValveEngine::topoChange(const polyTopoChangeMap&)
{
NotImplemented;
}
void Foam::fvMeshMovers::multiValveEngine::mapMesh(const polyMeshMap& map)
{
slidingPatchSet_ = findSlidingPatchSet();
linerPatchSet_ = findLinerPatchSet();
staticPatchSet_ = findStaticPatchSet();
piston_.mapMesh(map);
forAll(valves_, valvei)
{
valves_[valvei].mapMesh(map);
}
}
void Foam::fvMeshMovers::multiValveEngine::distribute
(
const polyDistributionMap&
)
{
NotImplemented;
}
// ************************************************************************* //

View File

@ -0,0 +1,632 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::fvMeshMovers::multiValveEngine
Description
A mesh mover using explicit node translation based on scaled distance
functions per moving object. The mover supports any number of valves
together with piston motion and following features:
- Piston motion: Function1 of user-time, may be set to
crankConnectingRodMotion for standard crank and connecting rod motion.
- Valve motion: Function1, may be set to table if the valve lift date is
provided in the form of a table.
- Smooth mesh motion between a moving object and other patches.
- linerPatches: the set of patches corresponding to the cylinder liner
Used by createEngineZones
- slidingPatches: a set of patches along which mesh is allowed
to deform. For example, on the cylinder liner, it is desired to
slide mesh nodes while piston is moving.
- frozenZones: list of pointZones the points of which are frozen,
i.e. do not move.
- Run-time clearance estimation based on patch-to-patch distances printed.
- Supports cellSet and cellZone definitions to restrict mesh motion.
- Supports domains with nonConformalCoupling (NCC) interfaces,
enabling e.g. nodes to slide along with the interface.
- Closing the valve can be achieved by meshToMesh mapping onto a new
grid with closed valve geometry at user given time.
- Mesh motion can be controlled per moving object by setting:
- patches: list of patches defining the object.
- motion: a Function1 which returns the object position
as a function of time.
- movingZones: list of pointZones the points of which move with the
object.
- maxMotionDistance: a distance away from the moving object
after nodes are not allowed to move. (Default inf.)
- movingFrozenLayerThickness: thickness of layer in which points move
with the moving object. (Default 0)
- staticFrozenLayerThickness: thickness of layer in which points
are fixed with respect to static patches (e.g. walls). (Default 0)
- cosineScaling: a switch whether nodal translation is weighted by
its distance from the moving object. The objective is to yield less
deformation near the moving object and sustain e.g. boundary layer.
(Default no, i.e. linear weighting)
- fractionalTravelInterval: fraction of the stroke travelled after
which the cached motion scaling weights are recalculated
For valve object only:
- minLift: a minimum valve lift value after considered closed.
Some of the above parameters are highlighted in a given schematic
piston-valve configuration w.r.t entries used to control piston motion.
Furthermore, an example dictionary entries are provided below.
| | | |
| | | |
| | S | |
| | T | |
| | E | |
| | M | |
/ | | \
/ | | \
/ | | \
_____________/ | | \_____________
| : | | : |
| : /``````````````` ```````````````\ : |
| : / VALVE HEAD \ : |
| L : /_____________________________________________\ : |
| I : /\ : |
| N : || staticFrozenLayerThickness : |
| E : NCC (optional) \/ (w.r.t. piston motion) : |
| R : `````````` : |
| : : |
| : : |
|........:.......................................................:........|
| : /\ : |
| : || movingFrozenLayerThickness : |
|________:_________________________\/____________________________:________|
PISTON
\verbatim
mover
{
type multiValveEngine;
libs ("libfvMeshMoversMultiValveEngine.so");
frozenZones (frozenZone1 frozenZone2);
slidingPatches
(
liner
valveStem
"nonCouple.*"
);
linerPatches (liner);
piston
{
patches (piston);
axis (0 0 1);
motion
{
type crankConnectingRodMotion;
conRodLength 1e3;
stroke 1.0;
}
// Move the points in the piston bowl with the piston
movingZones (pistonBowl);
// Optional
maxMotionDistance 1e30;
movingFrozenLayerThickness 0;
staticFrozenLayerThickness 0;
fractionalTravelInterval 0.1;
cosineScaling yes;
}
valves
{
iv
{
patches (valveHead);
axis (0 0 1);
// Optional
maxMotionDistance 1e30;
movingFrozenLayerThickness 0;
staticFrozenLayerThickness 0;
fractionalTravelInterval 0.1;
cosineScaling yes;
minLift 0.001;
motion
{
type table;
values
(
(0 0)
(480 0.1)
(720 0)
);
// For multi-cycle simulations, use repeat
outOfBounds repeat;
interpolationScheme linear;
}
}
}
}
\endverbatim
Note:
The implementation utilises pointDist objects for distance computation,
resulting distance fields do not propagate through NCC interfaces. Hence,
there should be no horizontal NCC interface separating piston from
cylinder head as it would result in potentially ill defined mesh
deformation. Due to same feature, in a schematic case setup above, valve
motion affects only cells between NCC patches even though no cellSet is
explicitly defined.
SourceFiles
multiValveEngine.C
\*---------------------------------------------------------------------------*/
#ifndef multiValveEngine_H
#define multiValveEngine_H
#include "fvMeshMover.H"
#include "Function1.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class pointDist;
namespace fvMeshMovers
{
/*---------------------------------------------------------------------------*\
Class multiValveEngine Declaration
\*---------------------------------------------------------------------------*/
class multiValveEngine
:
public fvMeshMover
{
public:
class movingObject
{
friend class multiValveEngine;
protected:
// Protected member data
//- Coefficients dictionary
dictionary dict_;
// Protected Data
//- Reference to engine mesh mover
const multiValveEngine& meshMover_;
public:
//- Name of the object
const word name;
//- Axis
const vector axis;
protected:
// Protected member data
//- Piston motion function
autoPtr<Function1<scalar>> motion_;
//- Maximum travel of the object
scalar travel_;
//- Object patchSet
labelHashSet patchSet_;
//- Patches which must not deform during mesh motion
labelHashSet staticPatchSet_;
//- Distance from object beyond which the mesh does not deform
scalar maxMotionDistance_;
//- Distance from object within mesh nodes move
// along with the patch
scalar movingFrozenLayerThickness_;
//- Distance from static wall patch at domain perimeter
// within mesh nodes do not move
scalar staticFrozenLayerThickness_;
wordReList movingPointZones_;
//- Points to move when cell zone is supplied
labelList pointIDs_;
//- Interpolation scale (1 at moving patches, 0 at far-field)
pointScalarField scale_;
//- Switch to use cosine-based scaling
// for the boundary point motion
Switch cosine_;
//- Update the scale_ field when the normalised travel exceeds
// fractionalTravelInterval_
const scalar fractionalTravelInterval_;
//- Count of the scale_ field updates
mutable label executionCount_;
//- Position at last scale update
mutable scalar position0_;
// Protected Member Functions
//- Scale the mesh point deformation with distance functions
// w.r.t. moving patches, static patches and a frozen zones.
void calcScale
(
const pointMesh& pMesh,
const scalarField& pDistMoving,
const scalarField& pDistStatic,
scalar dMoving,
scalar dMax,
scalar dStatic
);
void transformPoints
(
pointField& newPoints,
const vector& translationVector
);
//- Generate staticPatchSet_ based on patch entries
void createStaticPatchSet();
//- Patch-set construction
void initPatchSets();
labelHashSet movingPointZones() const;
public:
//- Object patchSet
const labelHashSet& patchSet;
// Constructors
//- Construct from dictionary
movingObject
(
const word& name,
const multiValveEngine& engine,
const dictionary& dict
);
//- Destructor
virtual ~movingObject()
{}
// Member Functions
//- Update from another mesh using the given map
virtual void mapMesh(const polyMeshMap&);
};
class pistonObject
:
public movingObject
{
// Private member data
//- Bore
scalar bore_;
//- Clearance
scalar clearance_;
// Private member functions
//- Return the bore
// calculated from the lateral extent of the piston
scalar bore() const;
//- Calculate clearance estimate based on minimum distance
// between piston and any other patch excluding slidingPatches.
void correctClearance(pointDist&);
public:
//- Name of the piston bowl pointZone
static word pistonBowlName;
// Constructors
//- Construct from dictionary
pistonObject
(
const word& name,
const multiValveEngine& engine,
const dictionary& dict
);
// Member Functions
//- Return the piston position for the given CA theta
scalar position(const scalar theta) const;
//- Return the current piston position
scalar position() const;
//- Return piston displacement for current time-step
scalar displacement() const;
//- Return piston position for current time-step
scalar speed() const;
//- Return clearance estimate
scalar clearance() const;
//- update points due to piston motion
void updatePoints(pointField&);
//- Update from another mesh using the given map
virtual void mapMesh(const polyMeshMap&);
};
class valveObject
:
public movingObject
{
// Private member data
//- Minimum valve lift.
// On this lift the valve is considered closed
const scalar minLift_;
// Private member functions
public:
// Constructors
//- Construct from dictionary
valveObject
(
const word& name,
const multiValveEngine& engine,
const dictionary& dict
);
//- Dummy clone function for PtrList
autoPtr<valveObject> clone() const
{
NotImplemented;
return autoPtr<valveObject>(nullptr);
}
// Member Functions
// Valve position and velocity
//- Return valve position for the given time
scalar lift(const scalar theta) const;
//- Return current valve position
scalar lift() const;
//- Return current valve speed
scalar speed() const;
//- Return valve displacement for current time-step
scalar displacement() const;
//- Is the valve open?
bool isOpen() const;
//- update points due to valve motion
void updatePoints(pointField&);
};
class valveList
:
public PtrList<valveObject>
{
public:
// Constructors
//- Construct from Istream
valveList
(
const multiValveEngine& engine,
const dictionary& dict
);
};
friend class movingObject;
friend class pistonObject;
friend class valveObject;
private:
// Private member data
//- User-defined liner patches
labelHashSet linerPatchSet_;
//- User-defined patches which the mesh can slide along
labelHashSet slidingPatchSet_;
//- Piston object
pistonObject piston_;
//- Container for all valves
valveList valves_;
//- Static patch set
labelHashSet staticPatchSet_;
wordReList frozenPointZones_;
// Private member functions
//- Lookup and return the liner patch set
labelHashSet findLinerPatchSet() const;
//- Lookup and return the sliding patch set
labelHashSet findSlidingPatchSet();
//- Find and return the static patch set
labelHashSet findStaticPatchSet();
labelHashSet staticPointZones() const;
public:
//- Runtime type information
TypeName("multiValveEngine");
//- Name of the cylinder head pointZone
static word cylinderHeadName;
// Constant access to member data
//- User-defined liner patches
const labelHashSet& linerPatchSet;
//- User-defined patches which the mesh can slide along
const labelHashSet& slidingPatchSet;
//- Piston object
const pistonObject& piston;
//- Container for all valves
const valveList& valves;
//- Static patch set
const labelHashSet& staticPatchSet;
// Constructors
//- Construct from fvMesh
multiValveEngine(fvMesh& mesh);
//- Disallow default bitwise copy construction
multiValveEngine(const multiValveEngine&) = delete;
//- Destructor
~multiValveEngine();
// Member Functions
//- Return current user-time, CAD, s or ...
scalar userTime() const;
//- Return current user-time-step, CAD, s, ...
scalar userDeltaT() const;
//- Update the mesh for both mesh motion and topology change
virtual bool update();
//- Update corresponding to the given map
virtual void topoChange(const polyTopoChangeMap&);
//- Update from another mesh using the given map
virtual void mapMesh(const polyMeshMap&);
//- Update corresponding to the given distribution map
virtual void distribute(const polyDistributionMap&);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const multiValveEngine&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fvMeshMovers
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,220 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "multiValveEngine.H"
#include "pointDist.H"
/* * * * * * * * * * * * * Static Private Member Data * * * * * * * * * * * */
Foam::word Foam::fvMeshMovers::multiValveEngine::pistonObject::pistonBowlName
(
"pistonBowl"
);
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::scalar Foam::fvMeshMovers::multiValveEngine::pistonObject::bore() const
{
const polyBoundaryMesh& pbm = meshMover_.mesh().boundaryMesh();
// Find the maximum and minimum coordinates of the piston patch-set
vector pistonMax(vector::min);
vector pistonMin(vector::max);
forAllConstIter(labelHashSet, patchSet, iter)
{
const label patchi = iter.key();
if (pbm[patchi].localPoints().size())
{
pistonMax = max(pistonMax, max(pbm[patchi].localPoints()));
pistonMin = min(pistonMin, min(pbm[patchi].localPoints()));
}
}
reduce(pistonMax, maxOp<point>());
reduce(pistonMin, minOp<point>());
// Assuming the piston moves in the positive axis direction
// remove the axis_ component to find the lateral extent of the piston
return mag
(
(pistonMax - (axis& pistonMax)*pistonMax)
- (pistonMin - (axis& pistonMin)*pistonMin)
)/sqrt(2.0);
}
void Foam::fvMeshMovers::multiValveEngine::pistonObject::correctClearance
(
pointDist& pDist
)
{
clearance_ = great;
forAllConstIter(labelHashSet, staticPatchSet_, iter)
{
const polyPatch& pp = meshMover_.mesh().boundaryMesh()[iter.key()];
const labelList& meshPoints = pp.meshPoints();
forAll(meshPoints, pointi)
{
clearance_ = min(clearance_, pDist[meshPoints[pointi]]);
}
}
reduce(clearance_, minOp<scalar>());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvMeshMovers::multiValveEngine::pistonObject::pistonObject
(
const word& name,
const multiValveEngine& engine,
const dictionary& dict
)
:
movingObject(name, engine, dict),
bore_(bore()),
clearance_(great)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::fvMeshMovers::multiValveEngine::pistonObject::position
(
const scalar theta
) const
{
return motion_->value(theta);
}
Foam::scalar
Foam::fvMeshMovers::multiValveEngine::pistonObject::position() const
{
return position(meshMover_.userTime());
}
Foam::scalar
Foam::fvMeshMovers::multiValveEngine::pistonObject::displacement() const
{
return
position(meshMover_.userTime() - meshMover_.userDeltaT())
- position();
}
Foam::scalar Foam::fvMeshMovers::multiValveEngine::pistonObject::speed() const
{
return displacement()/(meshMover_.mesh().time().deltaTValue() + vSmall);
}
Foam::scalar
Foam::fvMeshMovers::multiValveEngine::pistonObject::clearance() const
{
if (mag(position() - position0_)/travel_ > fractionalTravelInterval_)
{
return clearance_;
}
else
{
// Note, valve movement is not considered as valveSet may include
// other valves than ones related to ports. Furthermore, this value
// is only an estimate and updated rather frequently anyway.
return clearance_ - displacement();
}
}
void Foam::fvMeshMovers::multiValveEngine::pistonObject::updatePoints
(
pointField& newPoints
)
{
const scalar position = this->position();
// Update a cached scale_ field if needed
if (mag(position - position0_)/travel_ > fractionalTravelInterval_)
{
Info << " Updating scale field" << endl;
const pointMesh& pMesh = pointMesh::New(meshMover_.mesh());
const pointField& points(meshMover_.mesh().points());
pointDist pDistMoving
(
pMesh,
patchSet,
movingPointZones(),
points,
maxMotionDistance_
);
pointDist pDistStatic
(
pMesh,
staticPatchSet_,
meshMover_.staticPointZones(),
points,
maxMotionDistance_
);
// Update the clearance from the distance to piston field
correctClearance(pDistMoving);
calcScale
(
pMesh,
pDistMoving,
pDistStatic,
movingFrozenLayerThickness_,
maxMotionDistance_,
staticFrozenLayerThickness_
);
position0_ = position;
}
const vector translationVector(displacement()*axis);
transformPoints(newPoints, translationVector);
}
void Foam::fvMeshMovers::multiValveEngine::pistonObject::mapMesh
(
const polyMeshMap& map
)
{
movingObject::mapMesh(map);
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "pistonPointEdgeData.H"
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
(
Foam::Ostream& os,
const Foam::pistonPointEdgeData& wDist
)
{
return os << wDist.visited_ << " " << wDist.inBowl();
}
Foam::Istream& Foam::operator>>
(
Foam::Istream& is,
Foam::pistonPointEdgeData& wDist
)
{
return is >> wDist.visited_ >> wDist.inBowl_;
}
// ************************************************************************* //

View File

@ -0,0 +1,217 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::pistonPointEdgeData
Description
Holds information regarding nearest wall point. Used in PointEdgeWave.
(so not standard FaceCellWave)
To be used in wall distance calculation.
SourceFiles
pistonPointEdgeDataI.H
pistonPointEdgeData.C
\*---------------------------------------------------------------------------*/
#ifndef pistonPointEdgeData_H
#define pistonPointEdgeData_H
#include "pointField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class polyPatch;
class polyMesh;
class transformer;
// Forward declaration of friend functions and operators
class pistonPointEdgeData;
Istream& operator>>(Istream&, pistonPointEdgeData&);
Ostream& operator<<(Ostream&, const pistonPointEdgeData&);
/*---------------------------------------------------------------------------*\
Class pistonPointEdgeData Declaration
\*---------------------------------------------------------------------------*/
class pistonPointEdgeData
{
// Private Data
//- Has this point or edge been visited
bool visited_;
//- Is this point in the bowl
bool inBowl_;
public:
//- Class used to pass data into container
class trackingData
{
public:
const pointField& points_;
const vector axis_;
const scalar maxZ_;
trackingData
(
const pointField& points,
const vector& axis,
const scalar maxZ
)
:
points_(points),
axis_(axis),
maxZ_(maxZ)
{}
};
private:
// Private Member Functions
//- Update visited and inBowl
inline bool update(const point&, trackingData& td);
public:
// Constructors
//- Construct null
inline pistonPointEdgeData();
//- Construct from inBowl
inline pistonPointEdgeData(const bool inBowl);
// Member Functions
// Access
inline bool inBowl() const;
// Needed by PointEdgeWave
//- Check whether origin has been changed at all or
// still contains original (invalid) value.
inline bool valid(trackingData& td) const;
//- Transform across an interface
inline void transform
(
const polyPatch& patch,
const label patchFacei,
const transformer& transform,
trackingData& td
);
//- Influence of edge on point
inline bool updatePoint
(
const polyMesh& mesh,
const label pointi,
const label edgei,
const pistonPointEdgeData& edgeinfo,
const scalar tol,
trackingData& td
);
//- Influence of different value on same point.
// Merge new and old info.
inline bool updatePoint
(
const polyMesh& mesh,
const label pointi,
const pistonPointEdgeData& newPointInfo,
const scalar tol,
trackingData& td
);
//- Influence of point on edge.
inline bool updateEdge
(
const polyMesh& mesh,
const label edgei,
const label pointi,
const pistonPointEdgeData& pointInfo,
const scalar tol,
trackingData& td
);
//- Equivalent to operator== with trackingData
inline bool equal
(
const pistonPointEdgeData&,
trackingData& td
) const;
// Member Operators
// Needed for List IO
inline bool operator==(const pistonPointEdgeData&) const;
inline bool operator!=(const pistonPointEdgeData&) const;
// IOstream Operators
friend Ostream& operator<<(Ostream&, const pistonPointEdgeData&);
friend Istream& operator>>(Istream&, pistonPointEdgeData&);
};
//- Data associated with pistonPointEdgeData type are contiguous
template<>
inline bool contiguous<pistonPointEdgeData>()
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "pistonPointEdgeDataI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline bool Foam::pistonPointEdgeData::update
(
const point& pt,
trackingData& td
)
{
inBowl_ = (td.axis_& pt) < td.maxZ_;
const bool propagate = !visited_ && inBowl_;
visited_ = true;
return propagate;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::pistonPointEdgeData::pistonPointEdgeData()
:
visited_(false),
inBowl_(false)
{}
inline Foam::pistonPointEdgeData::pistonPointEdgeData(const bool inBowl)
:
visited_(true),
inBowl_(inBowl)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::pistonPointEdgeData::inBowl() const
{
return inBowl_;
}
inline bool Foam::pistonPointEdgeData::valid(trackingData& td) const
{
return visited_;
}
inline void Foam::pistonPointEdgeData::transform
(
const polyPatch& patch,
const label patchFacei,
const transformer& transform,
trackingData& td
)
{}
inline bool Foam::pistonPointEdgeData::updatePoint
(
const polyMesh& mesh,
const label pointi,
const label edgei,
const pistonPointEdgeData& edgeInfo,
const scalar tol,
trackingData& td
)
{
return update(td.points_[pointi], td);
}
inline bool Foam::pistonPointEdgeData::updatePoint
(
const polyMesh& mesh,
const label pointi,
const pistonPointEdgeData& newPointInfo,
const scalar tol,
trackingData& td
)
{
return update(td.points_[pointi], td);
}
inline bool Foam::pistonPointEdgeData::updateEdge
(
const polyMesh& mesh,
const label edgei,
const label pointi,
const pistonPointEdgeData& pointInfo,
const scalar tol,
trackingData& td
)
{
visited_ = true;
return true;
}
inline bool Foam::pistonPointEdgeData::equal
(
const pistonPointEdgeData& rhs,
trackingData& td
) const
{
return operator==(rhs);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline bool Foam::pistonPointEdgeData::operator==
(
const Foam::pistonPointEdgeData& rhs
)
const
{
return visited_ == rhs.visited_ && inBowl_ == rhs.inBowl_;
}
inline bool Foam::pistonPointEdgeData::operator!=
(
const Foam::pistonPointEdgeData& rhs
)
const
{
return !(*this == rhs);
}
// ************************************************************************* //

View File

@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "multiValveEngine.H"
#include "pointDist.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvMeshMovers::multiValveEngine::valveObject::valveObject
(
const word& name,
const multiValveEngine& engine,
const dictionary& dict
)
:
movingObject(name, engine, dict),
minLift_(dict.lookup<scalar>("minLift"))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::fvMeshMovers::multiValveEngine::valveObject::lift
(
const scalar theta
) const
{
return motion_->value(theta);
}
bool Foam::fvMeshMovers::multiValveEngine::valveObject::isOpen() const
{
return lift(meshMover_.userTime()) >= minLift_;
}
Foam::scalar Foam::fvMeshMovers::multiValveEngine::valveObject::lift() const
{
return max
(
lift(meshMover_.userTime()),
minLift_
);
}
Foam::scalar Foam::fvMeshMovers::multiValveEngine::valveObject::speed() const
{
return
-(
lift()
- max
(
lift(meshMover_.userTime() - meshMover_.userDeltaT()),
minLift_
)
)/(meshMover_.mesh().time().deltaTValue() + vSmall);
}
Foam::scalar
Foam::fvMeshMovers::multiValveEngine::valveObject::displacement() const
{
return
lift(meshMover_.userTime() - meshMover_.userDeltaT())
- lift(meshMover_.userTime());
}
void Foam::fvMeshMovers::multiValveEngine::valveObject::updatePoints
(
pointField& newPoints
)
{
// Update points only if valve is moving
if (isOpen())
{
const scalar position = this->lift();
// Update a cached scale_ field if needed
if (mag(position - position0_)/travel_ > fractionalTravelInterval_)
{
const pointMesh& pMesh = pointMesh::New(meshMover_.mesh());
const pointField& points(meshMover_.mesh().points());
const pointDist pDistMoving
(
pMesh,
patchSet,
movingPointZones(),
points,
maxMotionDistance_
);
const pointDist pDistStatic
(
pMesh,
staticPatchSet_,
meshMover_.staticPointZones(),
points,
maxMotionDistance_
);
calcScale
(
pMesh,
pDistMoving,
pDistStatic,
movingFrozenLayerThickness_,
maxMotionDistance_,
staticFrozenLayerThickness_
);
position0_ = position;
}
const vector translationVector(displacement()*axis);
transformPoints(newPoints, translationVector);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "multiValveEngine.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvMeshMovers::multiValveEngine::valveList::valveList
(
const multiValveEngine& engine,
const dictionary& dict
)
{
// Count number of valves
label nValves = 0;
forAllConstIter(dictionary, dict, iter)
{
if (iter().isDict())
{
nValves++;
}
}
// Add the valves to the list
if (nValves > 0)
{
PtrList<valveObject>::setSize(nValves);
label i = 0;
forAllConstIter(dictionary, dict, iter)
{
if (iter().isDict())
{
const word& name = iter().keyword();
const dictionary& valveDict = iter().dict();
PtrList<valveObject>::set
(
i++,
new valveObject(name, engine, valveDict)
);
}
}
}
}
// ************************************************************************* //

View File

@ -9,6 +9,8 @@ application=$(getApplication)
runApplication kivaToFoam -file otape17
runApplication createEngineZones -cylinderHead -pistonBowl
runApplication $application
#------------------------------------------------------------------------------

View File

@ -16,15 +16,36 @@ FoamFile
mover
{
type layeredEngine;
libs ("libfvMeshMovers.so");
type multiValveEngine;
conRodLength 0.147;
bore 0.092;
stroke 0.08423;
clearance 0.00115;
pistonLayers 0;
libs ("libfvMeshMoversMultiValveEngine.so");
slidingPatches (liner);
linerPatches (liner);
// Freeze the points in the cylinder head
frozenZones (cylinderHead);
piston
{
patches (piston);
axis (0 0 1);
motion
{
type crankConnectingRodMotion;
conRodLength 0.147;
stroke 0.08423;
}
// Move the points in the piston bowl with the piston
movingZones (pistonBowl);
// There is no need to update the motion weights
fractionalTravelInterval 1;
}
}

View File

@ -58,4 +58,32 @@ userTime
rpm 1500;
}
functions
{
setDeltaT
{
type coded;
// Load the library containing the 'coded' functionObject
libs ("libutilityFunctionObjects.so");
codeInclude
#{
#include "volFields.H"
#};
codeExecute
#{
const Time& runTime = mesh().time();
if (runTime.userTimeValue() >= -15.0)
{
const_cast<Time&>(runTime).setDeltaT
(
runTime.userTimeToTime(0.025)
);
}
#};
}
}
// ************************************************************************* //

View File

@ -0,0 +1,86 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class volScalarField;
location "0";
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 300;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
inlet
{
type inletOutlet;
inletValue $internalField;
value $internalField;
}
outlet
{
type inletOutlet;
inletValue $internalField;
value $internalField;
}
piston
{
type zeroGradient;
}
liner
{
type zeroGradient;
}
cylinderHead
{
type zeroGradient;
}
ivHead
{
type zeroGradient;
}
ivStem
{
type zeroGradient;
}
evHead
{
type zeroGradient;
}
evStem
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
"nonCouple.*"
{
type zeroGradient;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,89 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
inlet
{
type pressureInletOutletVelocity;
value uniform (0 0 0);
}
outlet
{
type pressureInletOutletVelocity;
value uniform (0 0 0);
}
piston
{
type movingWallVelocity;
value uniform (0 0 0);
}
liner
{
type noSlip;
}
cylinderHead
{
type noSlip;
}
ivHead
{
type movingWallVelocity;
value uniform (0 0 0);
}
ivStem
{
type movingWallVelocity;
value uniform (0 0 0);
}
evHead
{
type movingWallVelocity;
value uniform (0 0 0);
}
evStem
{
type movingWallVelocity;
value uniform (0 0 0);
}
frontAndBack
{
type empty;
}
"nonCouple.*"
{
type slip;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,117 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class volScalarField;
location "0";
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 1e5;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
inlet
{
type uniformTotalPressure;
p0
{
type tableFile;
format csv;
file "constant/expData/pInlet";
nHeaderLine 2; // Number of header lines
refColumn 0; // Reference column index
separator " "; // Optional (defaults to ",")
componentColumns (1); // Component column indices
mergeSeparators yes; // Merge multiple separators
// For multi-cycle simulations, use repeat
outOfBounds repeat;
interpolationScheme linear;
}
value $internalField;
psi psi;
rho rho;
gamma 1.4;
}
outlet
{
type uniformTotalPressure;
p0 table
(
(0 1.0e5)
(100 1.0e5)
(240 1.7e5)
(380 1.0e5)
(720 1.0e5)
);
// For multi-cycle simulations, use repeat
outOfBounds repeat;
interpolationScheme linear;
value $internalField;
psi psi;
rho rho;
gamma 1.4;
}
piston
{
type zeroGradient;
}
liner
{
type zeroGradient;
}
cylinderHead
{
type zeroGradient;
}
ivHead
{
type zeroGradient;
}
evHead
{
type zeroGradient;
}
ivStem
{
type zeroGradient;
}
evStem
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
"nonCouple.*"
{
type zeroGradient;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,10 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
rm -rf constant/meshToMesh_*
#------------------------------------------------------------------------------

View File

@ -0,0 +1,300 @@
#!/bin/bash
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
createSingleValveBaseMesh()
{
valveLift=-$1
nGap=$2
pistonPos=-$3
nClearance=$4
valveRegion=$5
OPEN=$(echo "$1 > 0" | bc -l)
if [ $OPEN -eq 1 ]; then
cp system/blockMeshDict.valveOpen system/blockMeshDict
else
cp system/blockMeshDict.valveClosed system/blockMeshDict
fi
foamDictionary system/blockMeshDict -set " \
valveLift=$valveLift, \
nValve=$nGap, \
x0=-5, \
nXLeft=4, \
pistonPos=$pistonPos, \
nPiston=$nClearance"
runApplication -a blockMesh -region $valveRegion \
-dict system/blockMeshDict
runApplication -a mirrorMesh -region $valveRegion \
-dict system/mirrorMeshDict -overwrite
}
createExhaustValveMesh()
{
createSingleValveBaseMesh $1 $2 $3 $4 _tmp_exhaust
runApplication -a transformPoints -region _tmp_exhaust "translate=(-6 0 0)"
foamDictionary constant/_tmp_exhaust/polyMesh/boundary -rename " \
entry0/valveHead=evHead, \
entry0/valveStem=evStem, \
entry0/liner=nonCouple_ev_cyl, \
entry0/inlet=outlet"
}
createIntakeValveMesh()
{
createSingleValveBaseMesh $1 $2 $3 $4 _tmp_intake
runApplication -a transformPoints -region _tmp_intake "translate=(6 0 0)"
foamDictionary constant/_tmp_intake/polyMesh/boundary -rename " \
entry0/valveHead=ivHead, \
entry0/valveStem=ivStem, \
entry0/liner=nonCouple_iv_cyl"
}
createCylinderMesh()
{
pistonPos=-$1
nClearance=$2
cp system/blockMeshDict.cylinder system/blockMeshDict
foamDictionary system/blockMeshDict -set " \
pistonPos=$pistonPos,
nPiston=$nClearance"
runApplication -a blockMesh -region $region -dict system/blockMeshDict
}
pistonPositionFromTDC()
{
cad=$1
pi=$(echo "scale=10; 4*a(1)" | bc --mathlib)
theta=$(echo "$cad*($pi/180)" | bc --mathlib)
# - r: position from the crank center
TERM1="$CONROD_LENGHT * $CONROD_LENGHT"
TERM2="($STROKE * s($theta) / 2.0) * ($STROKE * s($theta) / 2.0)"
R=$(echo "$STROKE * c($theta) / 2.0 + sqrt( $TERM1 - $TERM2 )" \
| bc --mathlib)
# - pos: position from tdc
POS=$(echo "$CONROD_LENGHT + $STROKE / 2.0 - $R" | bc --mathlib)
echo $POS
}
round()
{
echo $(printf %.$2f $(echo "scale=$2;(((10^$2)*$1)+0.5)/(10^$2)" | bc))
};
setMeshResolution()
{
CYL_BASE_RES=3
VALVE_BASE_RES=3
oneOverDX=3
N_IV=$(( $VALVE_BASE_RES + $oneOverDX*$(round $LIFT_IV 0) ))
N_EV=$(( $VALVE_BASE_RES + $oneOverDX*$(round $LIFT_EV 0) ))
N_CYL=$(( $CYL_BASE_RES + $oneOverDX*$(round $POS 0) ))
# as valve lift increases, we do not need so many cells below
vp_cl=$(echo "$POS - $LIFT_IV" | bc --mathlib)
N_CYL_IV=$(( $CYL_BASE_RES + $oneOverDX*$(round $vp_cl 0) ))
vp_cl=$(echo "$POS - $LIFT_EV" | bc --mathlib)
N_CYL_EV=$(( $CYL_BASE_RES + $oneOverDX*$(round $vp_cl 0) ))
}
mergeMeshModules()
{
runApplication -a mergeMeshes -overwrite -region $region \
-addRegions '(_tmp_exhaust _tmp_intake)'
# Delete temporary valve meshes
rm -rf constant/_tmp*
# Separate ports to mimic complicated engine assembly
runApplication -a createBaffles -region $region \
-dict system/createBafflesDict -overwrite
# Use NCC to enable sliding interface near the valve
runApplication -a createNonConformalCouples -region $region \
-dict system/createNonConformalCouplesDict -overwrite
runApplication -a transformPoints -region $region \
"Rx=90, scale=($SCALE_INV $SCALE_INV $SCALE_INV)"
# Delete temporary fvMesh
rm -rf constant/fvMesh
}
createMesh()
{
region=meshToMesh_$CAD
POS0=$(pistonPositionFromTDC $CAD)
POS=$(echo "$POS0 + $TDC_CLEARANCE" | bc --mathlib)
setMeshResolution
createCylinderMesh $POS $N_CYL
createExhaustValveMesh $LIFT_EV $N_EV $POS $N_CYL_EV
createIntakeValveMesh $LIFT_IV $N_IV $POS $N_CYL_IV
mergeMeshModules
}
# Set geometrical variables according to constant/dynamicMeshDict
SCALE=10
SCALE_INV=$(echo "1.0 / $SCALE" | bc --mathlib)
dynamicMeshDict=constant/dynamicMeshDict
STROKE0=$(foamDictionary $dynamicMeshDict -writePrecision 12 \
-entry mover/piston/motion/stroke -value)
STROKE=$(echo "$SCALE * $STROKE0" | bc --mathlib)
CONROD_LENGHT0=$(foamDictionary $dynamicMeshDict -writePrecision 12 \
-entry mover/piston/motion/conRodLength -value)
CONROD_LENGHT=$(echo "$SCALE * $CONROD_LENGHT0" | bc --mathlib)
TDC_CLEARANCE=10
# Valve lift values are chosen to align with the liftProfile
# values defined in the dynamicMeshDict
CAD=0
LIFT_IV=0
LIFT_EV=0
createMesh
# EV opening
CAD=100
LIFT_IV=0
LIFT_EV=0.1
createMesh
CAD=120
LIFT_IV=0
LIFT_EV=0.5
createMesh
CAD=140
LIFT_IV=0
LIFT_EV=0.9
createMesh
CAD=180
LIFT_IV=0
LIFT_EV=1.7
createMesh
CAD=200
LIFT_IV=0
LIFT_EV=2.1
createMesh
CAD=220
LIFT_IV=0
LIFT_EV=2.5
createMesh
CAD=300
LIFT_IV=0
LIFT_EV=1.7
createMesh
# IV opening
CAD=340
LIFT_IV=0.1
LIFT_EV=0.9
createMesh
CAD=345
LIFT_IV=0.2
LIFT_EV=0.8
createMesh
CAD=350
LIFT_IV=0.3
LIFT_EV=0.7
createMesh
CAD=360
LIFT_IV=0.5
LIFT_EV=0.5
createMesh
CAD=370
LIFT_IV=0.7
LIFT_EV=0.3
createMesh
# EV closing
CAD=380
LIFT_IV=0.9
LIFT_EV=0
createMesh
CAD=390
LIFT_IV=1.1
LIFT_EV=0
createMesh
CAD=410
LIFT_IV=1.5
LIFT_EV=0
createMesh
CAD=440
LIFT_IV=2.1
LIFT_EV=0
createMesh
CAD=460
LIFT_IV=2.5
LIFT_EV=0
createMesh
CAD=520
LIFT_IV=2.1
LIFT_EV=0
createMesh
CAD=550
LIFT_IV=1.5
LIFT_EV=0
createMesh
CAD=580
LIFT_IV=0.9
LIFT_EV=0
createMesh
CAD=600
LIFT_IV=0.5
LIFT_EV=0
createMesh
CAD=610
LIFT_IV=0.3
LIFT_EV=0
createMesh
# IV closing
CAD=620
LIFT_IV=0
LIFT_EV=0
createMesh
ls -d constant/meshToMesh_* | sed 's/.*meshToMesh_//' \
| sort -n > constant/meshTimes
#------------------------------------------------------------------------------

View File

@ -0,0 +1,14 @@
#!/bin/bash
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
./Allmesh
# Copy the start time mesh
cp -r constant/meshToMesh_0/polyMesh constant/
runApplication $(getApplication)
#------------------------------------------------------------------------------

View File

@ -0,0 +1,23 @@
#!/bin/bash
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
./Allmesh
# Copy the start time mesh
cp -r constant/meshToMesh_0/polyMesh constant/
runApplication decomposePar
for meshDir in constant/meshToMesh_*; do
# Extract mapTime from the directory name
mapTime=$(basename "$meshDir")
# Run the command with the extracted mapTime
runApplication -a decomposePar -region "$mapTime"
done
runParallel $(getApplication)
#------------------------------------------------------------------------------

View File

@ -0,0 +1,129 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
mover
{
type multiValveEngine;
libs ("libfvMeshMoversMultiValveEngine.so");
slidingPatches
(
liner
evStem
ivStem
nonCouple_cyl_ev
nonCouple_ev_cyl
nonCouple_cyl_iv
nonCouple_iv_cyl
);
linerPatches (liner);
piston
{
patches (piston);
axis (0 0 1);
motion
{
type crankConnectingRodMotion;
conRodLength 1000; // To mimic pure sinusoidal motion
stroke 1;
}
movingFrozenLayerThickness 0;
fractionalTravelInterval 0.1;
cosineScaling yes;
}
valves
{
iv
{
patches (ivHead);
axis (0 0 1);
movingFrozenLayerThickness 0;
fractionalTravelInterval 0.02;
cosineScaling yes;
minLift 0.01;
motion
{
type table;
values
(
// lift: 0.002 / CAD
(0 0.0)
(340 0.01) // IVO + meshToMesh map
(480 0.29)
(620 0.01) // IVC + meshToMesh map
(720 0.0)
);
// For multi-cycle simulations, use repeat
outOfBounds repeat;
interpolationScheme linear;
}
}
ev
{
$iv;
patches (evHead);
motion
{
type table;
values
(
(0 0.0)
(100 0.01) // EVO + meshToMesh map
(240 0.29)
(380 0.01) // EVC + meshToMesh map
(720 0.0)
);
// For multi-cycle simulations, use repeat
outOfBounds repeat;
interpolationScheme linear;
}
}
};
}
topoChanger
{
type meshToMesh;
libs ("libmeshToMeshTopoChanger.so");
times
(
#include "$FOAM_CASE/constant/meshTimes"
);
repeat 720;
timeDelta 1e-6;
}
// ************************************************************************* //

View File

@ -0,0 +1,7 @@
# Intake pressure profile
#CAD Pa
0 1.0e5
340 1.5e5
480 1.6e5
620 1.5e5
720 1.0e5

View File

@ -0,0 +1,24 @@
0
100
120
140
180
200
220
300
340
345
350
360
370
380
390
410
440
460
520
550
580
600
610
620

View File

@ -0,0 +1,19 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "constant";
object momentumTransport;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,68 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "constant";
object physicalProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
thermoType
{
type hePsiThermo;
mixture pureMixture;
transport sutherland;
thermo janaf;
equationOfState perfectGas;
specie specie;
energy sensibleEnthalpy;
}
// air
mixture
{
specie
{
molWeight 28.85097;
}
thermodynamics
{
Tlow 200;
Thigh 3000;
Tcommon 1000;
highCpCoeffs
(
3.05809
0.00133634
-4.73394e-07
7.38653e-11
-3.34205e-15
-972.89
6.09034
);
lowCpCoeffs
(
3.393
0.000544363
-1.24622e-06
2.65579e-09
-1.35538e-12
-1029.28
4.43259
);
}
transport
{
As 1.6853581850699974e-06;
Ts 227.72854078370528;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,65 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
valveLift 0;
pistonPos -15.8695;
nValve 3;
nPiston 51;
nXLeft 4;
x0 -5;
x1 -4;
x2 -3;
x3 -1;
x4 0;
y0 $valveLift;
y1 $pistonPos;
y2 1;
y3 8;
y4 #calc "$valveLift+1";
z0 0;
z1 0.5;
vertices ( ( $x0 0 $z0 ) ( $x1 0 $z0 ) ( $x0 $y0 $z0 ) ( $x1 $y0 $z0 ) ( $x0 $y1 $z0 ) ( $x1 $y1 $z0 ) ( $x2 $y3 $z0 ) ( $x2 $y2 $z0 ) ( $x2 $y4 $z0 ) ( $x3 $y3 $z0 ) ( $x3 $y2 $z0 ) ( $x3 $y4 $z0 ) ( $x4 $y0 $z0 ) ( $x4 $y1 $z0 ) ( $x0 0 $z1 ) ( $x1 0 $z1 ) ( $x0 $y0 $z1 ) ( $x1 $y0 $z1 ) ( $x0 $y1 $z1 ) ( $x1 $y1 $z1 ) ( $x2 $y3 $z1 ) ( $x2 $y2 $z1 ) ( $x2 $y4 $z1 ) ( $x3 $y3 $z1 ) ( $x3 $y2 $z1 ) ( $x3 $y4 $z1 ) ( $x4 $y0 $z1 ) ( $x4 $y1 $z1 ) );
blocks ( hex ( 2 4 5 3 16 18 19 17 ) ( $nPiston $nXLeft 1 ) simpleGrading ( 1 1 1 ) hex ( 6 7 10 9 20 21 24 23 ) ( 24 8 1 ) simpleGrading ( 1 1 1 ) hex ( 3 5 13 12 17 19 27 26 ) ( $nPiston 15 1 ) simpleGrading ( 1 1 1 ) );
defaultPatch
{
name frontAndBack;
type empty;
}
boundary ( piston { type wall ; faces ( ( 4 5 18 19 ) ( 5 13 19 27 ) ) ; } liner { type wall ; faces ( ( 4 2 18 16 ) ) ; } cylinderHead { type wall ; faces ( ( 2 3 17 16 ) ( 7 6 20 21 ) ) ; } inlet { type patch ; faces ( ( 6 9 23 20 ) ) ; } valveHead { type wall ; faces ( ( 7 21 24 10 ) ( 12 3 17 26 ) ) ; } valveStem { type wall ; faces ( ( 9 10 24 23 ) ) ; } symmetry { type patch ; faces ( ( 12 13 27 26 ) ) ; } frontAndBack { type empty ; faces ( ( 4 5 3 2 ) ( 7 10 9 6 ) ( 5 13 12 3 ) ( 18 19 17 16 ) ( 21 24 23 20 ) ( 19 27 26 17 ) ) ; } );
// ************************************************************************* //

View File

@ -0,0 +1,151 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
// The cylinder blocks are designed to surround the valve
// modules generated separately.
// 0 _ _ 1 8 _ _ 9 16 _ _ 17
// | | | | | |
// | | | | | |
// 2 _ _ 3 10 _ _ 11 18 _ _ 19
pistonPos -4;
nPiston 8;
x0a -13;
x1a -11;
x0b -1;
x1b 1;
x0c 11;
x1c 13;
y0 0;
y1 $pistonPos;
z0 0.0;
z1 0.5;
vertices
(
($x0a 0.0 $z0) //0
($x1a 0.0 $z0) //1
($x0a $y1 $z0) //2
($x1a $y1 $z0) //3
// + 4
($x0a 0.0 $z1) //0
($x1a 0.0 $z1) //1
($x0a $y1 $z1) //2
($x1a $y1 $z1) //3
// + 8
($x0b 0.0 $z0) //0
($x1b 0.0 $z0) //1
($x0b $y1 $z0) //2
($x1b $y1 $z0) //3
// + 12
($x0b 0.0 $z1) //0
($x1b 0.0 $z1) //1
($x0b $y1 $z1) //2
($x1b $y1 $z1) //3
// + 16
($x0c 0.0 $z0) //0
($x1c 0.0 $z0) //1
($x0c $y1 $z0) //2
($x1c $y1 $z0) //3
// + 20
($x0c 0.0 $z1) //0
($x1c 0.0 $z1) //1
($x0c $y1 $z1) //2
($x1c $y1 $z1) //3
);
blocks
(
hex (0 2 3 1 4 6 7 5) ($nPiston 6 1) simpleGrading (1 1 1)
hex (8 10 11 9 12 14 15 13) ($nPiston 6 1) simpleGrading (1 1 1)
hex (16 18 19 17 20 22 23 21) ($nPiston 6 1) simpleGrading (1 1 1)
);
defaultPatch
{
name frontAndBack;
type empty;
}
boundary
(
piston
{
type wall;
faces
(
(3 2 6 7)
(11 10 14 15)
(19 18 22 23)
);
}
liner
{
type wall;
faces
(
(2 0 4 6)
(19 23 21 17)
);
}
cylinderHead
{
type wall;
faces
(
(0 1 5 4)
(8 9 13 12)
(16 17 21 20)
);
}
nonCouple_cyl_ev
{
type patch;
faces
(
(3 7 5 1)
(10 8 12 14)
);
}
nonCouple_cyl_iv
{
type patch;
faces
(
(18 16 20 22)
(11 15 13 9)
);
}
);
// ************************************************************************* //

View File

@ -0,0 +1,180 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
// 6.--------.9 .
// | | |
// | | |
// 7. _ _ _ _10 .
// / |
// 2 _ _ 3 /_ _ _ _ _ _12
// | | |
// 4 _ _ 5 _ _ _ _ _ _ |13
valveLift -0;
pistonPos -4;
nValve 8;
nPiston 8;
nXLeft 8;
x0 -6;
x1 -4;
x2 -3;
x3 -1;
x4 0;
y0 $valveLift;
y1 $pistonPos;
y2 1;
y3 8;
y4 #calc "$valveLift+1";
z0 0.0;
z1 0.5;
vertices
(
($x0 0.0 $z0) //0
($x1 0.0 $z0) //1
($x0 $y0 $z0) //2
($x1 $y0 $z0) //3
($x0 $y1 $z0) //4
($x1 $y1 $z0) //5
($x2 $y3 $z0) //6
($x2 $y2 $z0) //7
($x2 $y4 $z0) //8
($x3 $y3 $z0) //9
($x3 $y2 $z0) //10
($x3 $y4 $z0) //11
($x4 $y0 $z0) //12
($x4 $y1 $z0) //13
// + 14
($x0 0.0 $z1) //0
($x1 0.0 $z1) //1
($x0 $y0 $z1) //2
($x1 $y0 $z1) //3
($x0 $y1 $z1) //4
($x1 $y1 $z1) //5
($x2 $y3 $z1) //6
($x2 $y2 $z1) //7
($x2 $y4 $z1) //8
($x3 $y3 $z1) //9
($x3 $y2 $z1) //10
($x3 $y4 $z1) //11
($x4 $y0 $z1) //12
($x4 $y1 $z1) //13
);
blocks
(
hex (2 4 5 3 16 18 19 17) ($nPiston $nXLeft 1) simpleGrading (1 1 1)
hex (6 7 10 9 20 21 24 23) (24 8 1) simpleGrading (1 1 1)
hex (3 5 13 12 17 19 27 26) ($nPiston 15 1) simpleGrading (1 1 1)
);
defaultPatch
{
name frontAndBack;
type empty;
}
boundary
(
piston
{
type wall;
faces
(
(4 5 18 19)
(5 13 19 27)
);
}
liner
{
type wall;
faces
(
(4 2 18 16)
);
}
cylinderHead
{
type wall;
faces
(
(2 3 17 16)
(7 6 20 21)
);
}
inlet
{
type patch;
faces
(
(6 9 23 20)
);
}
valveHead
{
type wall;
faces
(
(7 21 24 10)
(12 3 17 26)
);
}
valveStem
{
type wall;
faces
(
(9 10 24 23)
);
}
symmetry
{
type patch;
faces
(
(12 13 27 26)
);
}
frontAndBack
{
type empty;
faces
(
(4 5 3 2)
(7 10 9 6)
(5 13 12 3)
(18 19 17 16)
(21 24 23 20)
(19 27 26 17)
);
}
);
// ************************************************************************* //

View File

@ -0,0 +1,196 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
// 6.--------.9 .
// | | |
// | | |
// 7. _ _ _ _10 .
// /| | |
// 0 _ _ 1/ | | |
// | | |8 _ _ _11 |
// | | / |
// 2 _ _ 3 /_ _ _ _ _ _12
// | | |
// 4 _ _ 5 _ _ _ _ _ _ |13
valveLift -2;
pistonPos -4;
nValve 8;
nPiston 8;
nXLeft 8;
x0 -6;
x1 -4;
x2 -3;
x3 -1;
x4 0;
y0 $valveLift;
y1 $pistonPos;
y2 1;
y3 8;
y4 #calc "$valveLift+1";
z0 0.0;
z1 0.5;
vertices
(
($x0 0.0 $z0) //0
($x1 0.0 $z0) //1
($x0 $y0 $z0) //2
($x1 $y0 $z0) //3
($x0 $y1 $z0) //4
($x1 $y1 $z0) //5
($x2 $y3 $z0) //6
($x2 $y2 $z0) //7
($x2 $y4 $z0) //8
($x3 $y3 $z0) //9
($x3 $y2 $z0) //10
($x3 $y4 $z0) //11
($x4 $y0 $z0) //12
($x4 $y1 $z0) //13
// + 14
($x0 0.0 $z1) //0
($x1 0.0 $z1) //1
($x0 $y0 $z1) //2
($x1 $y0 $z1) //3
($x0 $y1 $z1) //4
($x1 $y1 $z1) //5
($x2 $y3 $z1) //6
($x2 $y2 $z1) //7
($x2 $y4 $z1) //8
($x3 $y3 $z1) //9
($x3 $y2 $z1) //10
($x3 $y4 $z1) //11
($x4 $y0 $z1) //12
($x4 $y1 $z1) //13
);
blocks
(
hex (0 2 3 1 14 16 17 15) ($nValve $nXLeft 1) simpleGrading (1 1 1)
hex (2 4 5 3 16 18 19 17) ($nPiston $nXLeft 1) simpleGrading (1 1 1)
hex (1 3 8 7 15 17 22 21) ($nValve 4 1) simpleGrading (1 1 1)
hex (7 8 11 10 21 22 25 24) ($nValve 8 1) simpleGrading (1 1 1)
hex (6 7 10 9 20 21 24 23) (24 8 1) simpleGrading (1 1 1)
hex (3 5 13 12 17 19 27 26) ($nPiston 15 1) simpleGrading (1 1 1)
);
defaultPatch
{
name frontAndBack;
type empty;
}
boundary
(
piston
{
type wall;
faces
(
(4 5 18 19)
(5 13 19 27)
);
}
liner
{
type wall;
faces
(
(4 2 18 16)
(2 0 16 14)
);
}
cylinderHead
{
type wall;
faces
(
(0 1 15 14)
(1 7 21 15)
(7 6 20 21)
);
}
inlet
{
type patch;
faces
(
(6 9 23 20)
);
}
valveHead
{
type wall;
faces
(
(8 11 25 22)
(3 8 22 17)
(12 3 17 26)
);
}
valveStem
{
type wall;
faces
(
(9 10 24 23)
(10 11 25 24)
);
}
symmetry
{
type patch;
faces
(
(13 27 26 12)
);
}
frontAndBack
{
type empty;
faces
(
(2 3 1 0)
(4 5 3 2)
(1 3 8 7)
(8 11 10 7)
(7 10 9 6)
(5 13 12 3)
(16 17 15 14)
(18 19 17 16)
(15 17 22 21)
(22 25 24 21)
(21 24 23 20)
(19 27 26 17)
);
}
);
// ************************************************************************* //

View File

@ -0,0 +1,61 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application foamRun;
solver fluid;
startFrom latestTime;
startTime 0;
stopAt endTime;
endTime 1440;
deltaT 0.1;
writeControl adjustableRunTime;
writeInterval 5;
purgeWrite 0;
writeFormat binary;
writePrecision 10;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable true;
adjustTimeStep no;
maxCo 5;
maxDeltaT 1;
userTime
{
type engine;
rpm 60;
}
// ************************************************************************* //

View File

@ -0,0 +1,59 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object createBafflesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
internalFacesOnly true;
baffles
{
baffles_ev_port
{
type searchableSurface;
surface searchablePlate;
origin (-10 5 0);
span (12 0 1e30);
owner
{
name nonCouple_ep_ev;
type patch;
}
neighbour
{
name nonCouple_ev_ep;
type patch;
}
}
baffles_iv_port
{
type searchableSurface;
surface searchablePlate;
origin (2 5 0);
span (10 0 1e30);
owner
{
name nonCouple_ip_iv;
type patch;
}
neighbour
{
name nonCouple_iv_ip;
type patch;
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,47 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object createNonConformalCouplesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
fields no;
nonConformalCouples
{
NCC_iv
{
patches (nonCouple_iv_cyl nonCouple_cyl_iv);
transform none;
}
NCC_ev
{
patches (nonCouple_ev_cyl nonCouple_cyl_ev);
transform none;
}
NCC_iv_port
{
patches (nonCouple_ip_iv nonCouple_iv_ip);
transform none;
}
NCC_ev_port
{
patches (nonCouple_ep_ev nonCouple_ev_ep);
transform none;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 8;
method scotch;
// ************************************************************************* //

View File

@ -14,29 +14,6 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
setDeltaT
{
type coded;
// Load the library containing the 'coded' functionObject
libs ("libutilityFunctionObjects.so");
codeInclude
#{
#include "volFields.H"
#};
codeExecute
#{
const Time& runTime = mesh().time();
if (runTime.userTimeValue() >= -15.0)
{
const_cast<Time&>(runTime).setDeltaT
(
runTime.userTimeToTime(0.025)
);
}
#};
}
#includeFunc checkMesh(executeControl=adjustableRunTime, executeInterval=5)
// ************************************************************************* //

View File

@ -0,0 +1,20 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object fvConstraints;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#includeConstraint limitLowPressure(min=1e4)
#includeConstraint limitTemperature(min=200, max=1000)
// ************************************************************************* //

View File

@ -0,0 +1,63 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
div(phi,U) Gauss limitedLinearV 1;
div(phi,(p|rho)) Gauss limitedLinear 1;
div(phid,p) Gauss limitedLinear 1;
div(meshPhi,p) Gauss limitedLinear 1;
div(phi,K) Gauss limitedLinear 1;
div(phi,h) Gauss limitedLinear 1;
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
wallDist
{
method meshWave;
}
// ************************************************************************* //

View File

@ -0,0 +1,80 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
"rho.*"
{
solver diagonal;
}
p
{
solver PBiCGStab;
preconditioner DIC;
tolerance 1e-8;
relTol 0.001;
}
pFinal
{
$p;
relTol 0;
}
"pcorr.*"
{
solver PCG;
preconditioner DIC;
tolerance 1e-2;
relTol 0;
}
MeshPhi
{
solver smoothSolver;
smoother symGaussSeidel;
tolerance 1e-2;
relTol 0;
}
"(U|h|k|epsilon|omega)"
{
solver PBiCGStab;
preconditioner DILU;
tolerance 1e-8;
relTol 0.01;
}
"(U|h|k|epsilon|omega)Final"
{
$U;
relTol 0;
}
}
PIMPLE
{
momentumPredictor yes;
nOuterCorrectors 3;
nCorrectors 1;
nNonOrthogonalCorrectors 0;
correctPhi yes;
correctMeshPhi no;
checkMeshCourantNo no;
}
// ************************************************************************* //

View File

@ -0,0 +1,24 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object mirrorMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
planeType pointAndNormal;
point (0 0 0);
normal (1 0 0);
planeTolerance 1e-6;
// ************************************************************************* //