FSI solvers and tutorials, and miscellaneous fixes by Zeljko Tukovic

This commit is contained in:
Vanja Skuric 2016-06-08 13:49:54 +02:00 committed by Hrvoje Jasak
parent a7d5aa2e89
commit 373ac3a85c
670 changed files with 486222 additions and 505 deletions

4
ThirdParty/AllMake vendored
View file

@ -77,6 +77,10 @@ echo
# this stage should be called last in your compilation process
./AllMake.stage5
# Running stage eigen
./AllMake.eigen
echo ========================================
echo Done ThirdParty Allwmake
echo ========================================

80
ThirdParty/AllMake.eigen vendored Executable file
View file

@ -0,0 +1,80 @@
#!/bin/bash
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | foam-extend: Open Source CFD
# \\ / O peration |
# \\ / A nd | For copyright notice see file Copyright
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of foam-extend.
#
# foam-extend 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.
#
# foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# AllMake.stage3
#
# Description
# Build script for ThirdParty packages: eigen
#
# The ThirdParty libraries
#
# Requirements:
# 1: Your foam-extend environment must be properly initialized
# 2: AllMake.stage1 if you are overriding your system compiler
# 3: AllMake.stage2 if you are overriding your system comm. libraries
#
# Author:
# Martin Beaudoin, Hydro-Quebec, (2015)
#
#------------------------------------------------------------------------------
# run from third-party directory only
cd ${0%/*} || exit 1
wmakeCheckPwd "$WM_THIRD_PARTY_DIR" || {
echo "Error: Current directory is not \$WM_THIRD_PARTY_DIR"
echo " The environment variables are inconsistent with the installation."
echo " Check the foam-extend entries in your dot-files and source them."
exit 1
}
. tools/makeThirdPartyFunctionsForRPM
#------------------------------------------------------------------------------
echo ========================================
echo Starting ThirdParty AllMake: eigen
echo ========================================
echo
# Eigen
if [ -d $(WM_THIRD_PARTY_DIR)/packages/eigen3 ]
then
echo "eigen3 found."
else
# Download eigen using wget
echo "Downloading eigen3 to eigen3"
wget http://bitbucket.org/eigen/eigen/get/3.2.8.tar.gz
\tar xvzf 3.2.8.tar.gz
\rm -f 3.2.8.tar.gz
\mv eigen-eigen-07105f7124f9 ./packages/eigen3
fi
fi
echo ========================================
echo Done ThirdParty AllMake: Stage3
echo ========================================
echo
# ----------------------------------------------------------------- end-of-file

View file

@ -0,0 +1,18 @@
#!/bin/sh
set -x
wclean fluidSolidInteraction
wclean solvers/fsiFoam
wclean solvers/ampFsiFoam
wclean solvers/weakFsiFoam
wclean solvers/fluidFoam
wclean solvers/solidFoam
wclean solvers/thermalSolidFoam
wclean utilities/functionObjects/pointHistory
wclean utilities/functionObjects/patchAvgTractionHistory
wclean utilities/functionObjects/centrifugalBodyForce
# Wipe out all lnInclude directories and re-link
wcleanLnIncludeAll

View file

@ -0,0 +1,15 @@
#!/bin/sh
set -x
wmake libso fluidSolidInteraction
wmake solvers/fsiFoam
wmake solvers/ampFsiFoam
wmake solvers/weakFsiFoam
wmake solvers/fluidFoam
wmake solvers/solidFoam
wmake solvers/thermalSolidFoam
wmake libso utilities/functionObjects/pointHistory
wmake libso utilities/functionObjects/patchAvgTractionHistory
wmake libso utilities/functionObjects/centrifugalBodyForce

View file

@ -0,0 +1,141 @@
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFInterpolation.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFCoarsening.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFMeshMotionSolver.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/twoDPointCorrectorRBF.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFFunctions/TPSFunction.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFFunctions/WendlandC0Function.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFFunctions/WendlandC2Function.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFFunctions/WendlandC4Function.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFFunctions/WendlandC6Function.C
fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFFunctions/LinearFunction.C
contactModels = solidSolvers/solidModels/fvPatchFields/solidContact/contactModels
$(contactModels)/frictionContactModels/frictionContactModel/frictionContactModel.C
$(contactModels)/frictionContactModels/frictionContactModel/newFrictionContactModel.C
$(contactModels)/frictionContactModels/frictionless/frictionless.C
$(contactModels)/frictionContactModels/standardPenaltyFriction/standardPenaltyFriction.C
$(contactModels)/frictionContactModels/frictionLaws/frictionLaw/frictionLaw.C
$(contactModels)/frictionContactModels/frictionLaws/frictionLaw/newFrictionLaw.C
$(contactModels)/frictionContactModels/frictionLaws/coulombFriction/coulombFriction.C
$(contactModels)/frictionContactModels/frictionLaws/coulombOrowanFriction/coulombOrowanFriction.C
$(contactModels)/frictionContactModels/frictionLaws/timeVaryingCoulomb/timeVaryingCoulomb.C
$(contactModels)/normalContactModels/normalContactModel/normalContactModel.C
$(contactModels)/normalContactModels/normalContactModel/newNormalContactModel.C
$(contactModels)/normalContactModels/standardPenalty/standardPenalty.C
fluidSolvers/fluidSolver/fluidSolver.C
fluidSolvers/fluidSolver/newFluidSolver.C
fluidSolvers/icoFluid/icoFluid.C
fluidSolvers/pisoFluid/pisoFluid.C
fluidSolvers/consistentIcoFluid/consistentIcoFluid.C
fluidSolvers/fvPatchFields/freeSurfacePressure/freeSurfacePressureFvPatchScalarField.C
fluidSolvers/fvPatchFields/freeSurfaceVelocity/freeSurfaceVelocityFvPatchVectorField.C
fluidSolvers/fvPatchFields/extrapolated/extrapolatedFvPatchFields.C
fluidSolvers/fvPatchFields/extrapolatedPressure/extrapolatedPressureFvPatchScalarField.C
fluidSolvers/fvPatchFields/transitionalParabolicVelocity/transitionalParabolicVelocityFvPatchVectorField.C
fluidSolvers/fvPatchFields/movingWallVelocity/movingWallVelocityFvPatchVectorField.C
fluidSolvers/fvPatchFields/fixedVelocityPressure/fixedVelocityPressureFvPatchScalarField.C
fluidSolvers/fvPatchFields/normalInletVelocity/normalInletVelocityFvPatchVectorField.C
fluidSolvers/fvPatchFields/outflowPressure/outflowPressureFvPatchScalarField.C
fluidSolvers/fvPatchFields/movingWallPressure/movingWallPressureFvPatchScalarField.C
fluidSolvers/fvPatchFields/robin/robinFvPatchFields.C
fluidSolvers/fvPatchFields/elasticWallPressure/elasticWallPressureFvPatchScalarField.C
fluidSolvers/fvPatchFields/skewCorrectedLinearDC/skewCorrectedLinearDC.C
fluidSolvers/fvPatchFields/elasticSlipWallVelocity/elasticSlipWallVelocityFvPatchVectorField.C
fluidSolvers/fvPatchFields/elasticWallVelocity/elasticWallVelocityFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/tractionDisplacement/tractionDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/tractionDisplacementIncrement/tractionDisplacementIncrementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/symmetryDisplacement/symmetryDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/fixedDisplacement/fixedDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/fixedNormalDisplacement/fixedNormalDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/fixedNormalDisplacementIncrement/fixedNormalDisplacementIncrementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/componentMixed/componentMixedPointPatchFields.C
solidSolvers/solidModels/fvPatchFields/cohesiveZoneModeI/cohesiveZoneFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/cohesiveZoneIncrementalModeI/cohesiveZoneIncrementalFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/planeContactDisplacement/planeContactDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/directionMixedDisplacement/directionMixedDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/timeVaryingFixedNormalDisplacement/timeVaryingFixedNormalDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/timeVaryingFixedDisplacement/timeVaryingFixedDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/solidWedge/solidWedgeFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/timeVaryingPressureDisplacement/timeVaryingPressureDisplacementFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/fixedHydPressure/fixedHydPressureFvPatchScalarField.C
solidSolvers/solidModels/fvPatchFields/fixedHydPressureIncrement/fixedHydPressureIncrementFvPatchScalarField.C
solidSolvers/solidModels/fvPatchFields/convectiveFlux/convectiveFluxFvPatchScalarField.C
solidSolvers/solidModels/fvPatchFields/wedge/wedgeFvPatchFields.C
solidSolvers/solidModels/fvPatchFields/wedge/wedgeFvPatchScalarField.C
solidSolvers/solidModels/fvPatchFields/solidContact/solidContactFvPatchVectorField.C
solidSolvers/solidModels/fvPatchFields/correctedSymmetry/correctedSymmetryFvPatchFields.C
solidSolvers/solidModels/fvPatchFields/velocityTractionDisplacement/velocityTractionDisplacementFvPatchVectorField.C
solidSolvers/solidSolver/solidSolver.C
solidSolvers/solidSolver/newSolidSolver.C
solidSolvers/unsTotalLagrangianSolid/unsTotalLagrangianSolid.C
solidSolvers/unsTotalLagrangianSolid/unsTotalLagrangianSolidSolve.C
solidSolvers/unsIncrTotalLagrangianSolid/unsIncrTotalLagrangianSolid.C
solidSolvers/unsIncrTotalLagrangianSolid/unsIncrTotalLagrangianSolidSolve.C
fluidSolvers/finiteVolume/ddtSchemes/EulerDdtScheme.C
fluidSolvers/finiteVolume/ddtSchemes/backwardDdtScheme.C
solidSolvers/finiteVolume/fvc/fvcCellLimitedGrad.C
solidSolvers/solidModels/constitutiveModel/plasticityStressReturnMethods/plasticityStressReturn/plasticityStressReturn.C
solidSolvers/solidModels/constitutiveModel/plasticityStressReturnMethods/plasticityStressReturn/newPlasticityStressReturn.C
solidSolvers/solidModels/constitutiveModel/plasticityStressReturnMethods/aravasMises/aravasMises.C
solidSolvers/solidModels/constitutiveModel/plasticityStressReturnMethods/newAravasMises/newAravasMises.C
solidSolvers/solidModels/constitutiveModel/constitutiveModel.C
solidSolvers/solidModels/constitutiveModel/plasticityStressReturnMethods/kirchhoffMises/kirchhoffMises.C
rheologyLaws = solidSolvers/solidModels/constitutiveModel/rheologyLaws
$(rheologyLaws)/rheologyLaw/rheologyLaw.C
$(rheologyLaws)/rheologyLaw/newRheologyLaw.C
$(rheologyLaws)/linearElastic/linearElastic.C
$(rheologyLaws)/elasticPlastic/elasticPlastic.C
$(rheologyLaws)/linearElasticTabulatedPlastic/linearElasticTabulatedPlastic.C
$(rheologyLaws)/multiMaterial/multiMaterial.C
$(rheologyLaws)/orthotropicElasticPlastic/orthotropicElasticPlastic.C
$(rheologyLaws)/orthotropicLinearElastic/orthotropicLinearElastic.C
$(rheologyLaws)/PronyViscoelastic/PronyViscoelastic.C
$(rheologyLaws)/expElasticPlastic/expElasticPlastic.C
solidSolvers/solidModels/thermalModel/thermalModel.C
thermalLaws = solidSolvers/solidModels/thermalModel/thermalLaws
$(thermalLaws)/thermalLaw/thermalLaw.C
$(thermalLaws)/thermalLaw/newThermalLaw.C
$(thermalLaws)/constantThermal/constantThermal.C
$(thermalLaws)/multiMaterialThermal/multiMaterialThermal.C
solidSolvers/solidModels/arbitraryCrack/crackerMovingFvMesh/crackerMovingFvMesh.C
solidSolvers/solidModels/arbitraryCrack/crackerFvMesh/crackerFvMesh.C
solidSolvers/solidModels/arbitraryCrack/faceCracker/faceCracker.C
solidSolvers/solidModels/arbitraryCrack/faceCracker/detachFaceCracker.C
solidSolvers/solidModels/arbitraryCrack/cohesive/cohesivePolyPatch.C
solidSolvers/solidModels/arbitraryCrack/cohesiveLaw/cohesiveLawFvPatchVectorField.C
solidSolvers/solidModels/SolidInterfaces/solidInterfaceTL/solidInterfaceTL.C
solidSolvers/solidModels/SolidInterfaces/solidInterfaceITL/solidInterfaceITL.C
solidSolvers/solidModels/materialInterfaces/materialInterface/materialInterface.C
solidSolvers/solidModels/materialInterfaces/TLMaterialInterface/TLMaterialInterface.C
solidSolvers/solidModels/materialInterfaces/ITLMaterialInterface/ITLMaterialInterface.C
solidSolvers/solidModels/materialInterfaces/ULLSMaterialInterface/ULLSMaterialInterface.C
solidSolvers/solidModels/simpleCohesiveLaws/simpleCohesiveLaw/simpleCohesiveLaw.C
solidSolvers/solidModels/simpleCohesiveLaws/linear/linearSimpleCohesiveLaw.C
solidSolvers/solidModels/simpleCohesiveLaws/Dugdale/DugdaleSimpleCohesiveLaw.C
solidSolvers/solidModels/eig3/eig3.C
solidSolvers/solidModels/eig3/eig3Field.C
solidSolvers/solidModels/nonLinearGeometry/nonLinearGeometry.C
solidSolvers/solidModels/constitutiveModel/tractionBoundaryGradient/tractionBoundaryGradient.C
fluidSolidInterface/fluidSolidInterface.C
LIB = $(FOAM_LIBBIN)/libfluidSolidInteraction

View file

@ -0,0 +1,54 @@
c++WARN = -Wno-deprecated -Wall -Wextra -Wno-unused-parameter -Wnon-virtual-dtor -Wunused-local-typedefs -Werror -Wredundant-decls -Wcast-align -Wmissing-declarations -Wswitch-enum -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral
EXE_INC = -std=c++11 \
-I./fluidSolvers/finiteVolume/RBFMeshMotionSolver \
-I./fluidSolvers/finiteVolume/RBFMeshMotionSolver/RBFFunctions \
-I./solidSolvers/solidModels/fvPatchFields/symmetry \
-I./solidSolvers/solidModels/contactModels/frictionContactModels/frictionContactModel/frictionLaws/frictionLaw \
-I./solidSolvers/solidModels/contactModels/frictionContactModels/frictionContactModel \
-I./solidSolvers/solidModels/contactModels/normalContactModels/normalContactModel \
-I./solidSolvers/solidModels/constitutiveModel/tractionBoundaryGradient \
-I./solidSolvers/solidModels/nonLinearGeometry \
-I./solidSolvers/solidModels/constitutiveModel/rheologyLaws/PronyViscoelastic \
-I./solidSolvers/solidModels/arbitraryCrack/pointDistDiff \
-I$(WM_THIRD_PARTY_DIR)/packages/eigen3 \
-I./solidSolvers/solidModels/componentReference \
-I./solidSolvers/solidModels/constitutiveModel/lnInclude \
-I./solidSolvers/solidModels/constitutiveModel/plasticityStressReturnMethods/plasticityStressReturn \
-I./solidSolvers/solidModels/constitutiveModel/rheologyLaws/rheologyLaw \
-I./solidSolvers/solidModels/constitutiveModel \
-I./fluidSolidInterface \
-I./solidSolvers/finiteVolume/fvc \
-I./solidSolvers/solidModels/fvPatchFields/tractionDisplacement \
-I./solidSolvers/solidModels/fvPatchFields/tractionDisplacementIncrement \
-I./solidSolvers/solidModels/fvPatchFields/fixedDisplacement \
-I./solidSolvers/solidModels/fvPatchFields/symmetryDisplacement \
-I./solidSolvers/solidSolver \
-I./solidSolvers/solidModels/arbitraryCrack/crackerFvMesh \
-I./fluidSolvers/finiteVolume/ddtSchemes \
-I./fluidSolvers/fluidSolver \
-I$(LIB_SRC)/foam/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/meshMotion/fvMotionSolver/lnInclude \
-I$(LIB_SRC)/dynamicMesh/meshMotion/tetMotionSolver/lnInclude \
-I$(LIB_SRC)/dynamicMesh/topoChangerFvMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/tetFiniteElement/lnInclude \
EXE_LIBS = \
-lincompressibleTurbulenceModel \
-lincompressibleRASModels \
-lincompressibleLESModels \
-lincompressibleTransportModels \
-lfiniteVolume \
-ldynamicFvMesh \
-ldynamicMesh \
-lmeshTools

View file

@ -0,0 +1,590 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
fluidSolidInterface
Description
Fluid-structure interface class
Author
Zeljko Tukovic, FSB Zagreb. All rights reserved.
SourceFiles
fluidSolidInterface.C
\*---------------------------------------------------------------------------*/
#ifndef fluidSolidInterface_H
#define fluidSolidInterface_H
#include "fluidSolver.H"
#include "solidSolver.H"
#include "IOdictionary.H"
#include "patchToPatchInterpolation.H"
#include "dynamicFvMesh.H"
#include "ggiInterpolation.H"
#include "movingWallVelocityFvPatchVectorField.H"
#include "RBFInterpolation.H"
#include "TPSFunction.H"
using namespace rbf;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fluidSolidInterface Declaration
\*---------------------------------------------------------------------------*/
class fluidSolidInterface
:
public IOdictionary
{
// Private data
//- Fluid (flow) mesh
dynamicFvMesh& fluidMesh_;
//- Fluid model
autoPtr<fluidSolver> flow_;
//- Solid (stress) mesh
fvMesh& solidMesh_;
//- Stress model
autoPtr<solidSolver> stress_;
//- Solid patch index
label solidPatchIndex_;
//- Solid face zone index
label solidZoneIndex_;
//- Fluid patch index
label fluidPatchIndex_;
//- Fluid face zone index
label fluidZoneIndex_;
//- Solid face zone current points
mutable vectorField* currentSolidZonePointsPtr_;
//- Solid face zone primitive patch in current configuration
mutable PrimitivePatch<face, List, const pointField&>*
currentSolidZonePatchPtr_;
//- Fluid zone to solid zone interpolator
mutable std::shared_ptr<RBFInterpolation> fluidToSolidPtr_;
// //- Ggi zone-to-zone interpolation
// mutable ggiZoneInterpolation* ggiFluidToSolidPtr_;
//- Ggi zone-to-zone interpolation
mutable ggiZoneInterpolation* ggiInterpolatorPtr_;
//- Solid zone to fluid zone interpolator
mutable std::shared_ptr<RBFInterpolation> solidToFluidPtr_;
//- Coupling scheme
word couplingScheme_;
//- Relaxation factor
scalar relaxationFactor_;
//- Relaxation factor
scalar aitkenRelaxationFactor_;
//- Outer correction loop stoping tolerance
scalar outerCorrTolerance_;
//- Maximal number of outer correctors
label nOuterCorr_;
//- Fsi coupling on/off
Switch coupled_;
//- Predictor on/off
Switch predictor_;
//- Use rbf interpolation
Switch rbfInterpolation_;
//- Coupling reuse
label couplingReuse_;
//- Interface deformation limit
scalar interfaceDeformationLimit_;
//- Fluid zone point displacement
vectorField fluidZonePointsDispl_;
//- Fluid zone ref. point displacement
vectorField fluidZonePointsDisplRef_;
//- Fluid zone previous point displacement
vectorField fluidZonePointsDisplPrev_;
//- Solid zone point displacement
vectorField solidZonePointsDispl_;
//- Solid zone ref. point displacement
vectorField solidZonePointsDisplRef_;
//- Solid zone point displacement
vectorField interfacePointsDispl_;
//- Solid zone ref. point displacement
vectorField interfacePointsDisplPrev_;
//- Solid zone pressure
scalarField solidZonePressure_;
//- Solid zone traction (pressure + vicous)
vectorIOField solidZoneTraction_;
//- Solid zone traction (pressure + vicous)
vectorField solidZoneTractionPrev_;
//- Solid zone traction (pressure + vicous)
vectorIOField predictedSolidZoneTraction_;
//- Current fsi residual
vectorField residual_;
//- Previous fsi residual
vectorField residualPrev_;
//- Maximal resudual norm
scalar maxResidualNorm_;
//- Maximal interface displacement norm
scalar maxIntDisplNorm_;
//- Outer corrector
label outerCorr_;
// //- Is it fluid domain pure Dirichlet (witout outlets)?
// Switch closedFluidDomain_;
// //- Reference pressure
// scalar refPressure_;
// //- Reference pressure
// scalar refPressureIncrement_;
// //- Current time index
// label timeIndex_;
// //- Copressibility
// scalar compressibility_;
//- Interpolator update frequency
label interpolatorUpdateFrequency_;
//- IQN-ILS coupling fields
DynamicList<vectorField> fluidPatchPointsV_;
DynamicList<vectorField> fluidPatchPointsW_;
DynamicList<scalar> fluidPatchPointsT_;
//- Accumulated fluid side interface displacement
mutable vectorIOField* accumulatedFluidInterfaceDisplacementPtr_;
//- Min edge length for interface points at fluid side
mutable scalarField* minEdgeLengthPtr_;
// Private Member Functions
//- Calculate current solid zone points
void calcCurrentSolidZonePoints() const;
//- Calculate current solid zone primitive patch
void calcCurrentSolidZonePatch() const;
//- Calculate fluid to solid interpolator
void calcFluidToSolidInterpolator() const;
// //- Calculate fluid to solid ggi interpolator
// void calcGgiFluidToSolidInterpolator() const;
//- Calculate fluid to solid ggi interpolator
void calcGgiInterpolator() const;
//- Calculate fluid to solid interpolator
void calcSolidToFluidInterpolator() const;
//- Accumulated fluid interface displacement
void calcAccumulatedFluidInterfaceDisplacement() const;
//- Calculate minimal edge lengths
void calcMinEdgeLength() const;
//- Return accumulated interface displacement
vectorIOField& accumulatedFluidInterfaceDisplacement();
//- Return minimal edge length
const scalarField& minEdgeLength() const;
//- Disallow default bitwise copy construct
fluidSolidInterface(const fluidSolidInterface&);
//- Disallow default bitwise assignment
void operator=(const fluidSolidInterface&);
protected:
// Protected member functions
public:
//- Runtime type information
TypeName("fluidSolidInterface");
// Declare run-time constructor selection table
// Constructors
//- Construct from components
fluidSolidInterface
(
dynamicFvMesh& fluidMesh,
fvMesh& solidMesh
);
// Selectors
// Destructor
virtual ~fluidSolidInterface();
// Member Functions
// Access
//- Return fluid mesh
const dynamicFvMesh& fluidMesh() const
{
return fluidMesh_;
}
//- Return solid mesh
const fvMesh& solidMesh() const
{
return solidMesh_;
}
//- Return time
const Time& runTime() const
{
return fluidMesh_.time();
}
//- Return fluid solver
const fluidSolver& flow() const
{
return flow_();
}
//- Return fluid solver
fluidSolver& flow()
{
return flow_();
}
//- Return solid solver
const solidSolver& stress() const
{
return stress_();
}
//- Return solid solver
solidSolver& stress()
{
return stress_();
}
//- Return solid patch index
label solidPatchIndex() const
{
return solidPatchIndex_;
}
//- Return solid face zone index
label solidZoneIndex() const
{
return solidZoneIndex_;
}
//- Return fluid patch index
label fluidPatchIndex() const
{
return fluidPatchIndex_;
}
//- Return fluid face zone index
label fluidZoneIndex() const
{
return fluidZoneIndex_;
}
//- Return current solid zone points
const vectorField& currentSolidZonePoints() const;
//- Return current solid zone patch
const PrimitivePatch<face, List, const pointField&>&
currentSolidZonePatch() const;
//- Return fluid to solid interpolator
const std::shared_ptr<RBFInterpolation>& fluidToSolid() const;
// //- Return fluid to solid interpolator
// const ggiZoneInterpolation& ggiFluidToSolid() const;
//- Return fluid to solid interpolator
const ggiZoneInterpolation& ggiInterpolator() const;
//- Return fluid to solid interpolator
const std::shared_ptr<RBFInterpolation>& solidToFluid() const;
//- Return coupling scheme
const word& couplingScheme() const
{
return couplingScheme_;
}
//- Return relaxation factor
scalar relaxationFactor() const
{
return relaxationFactor_;
}
//- Return relaxation factor
scalar& aitkenRelaxationFactor()
{
return aitkenRelaxationFactor_;
}
//- Return outer corrector loop tolerance
scalar outerCorrTolerance() const
{
return outerCorrTolerance_;
}
//- Return max numter of outer correctors
label nOuterCorr() const
{
return nOuterCorr_;
}
//- Is it fluid and structure coupled
const Switch& coupled() const
{
return coupled_;
}
//- Is it fluid and structure coupled
const Switch& predictor() const
{
return predictor_;
}
//- Is it fluid and structure coupled
Switch& coupled()
{
return coupled_;
}
//- Is it fluid and structure coupled
label couplingReuse() const
{
return couplingReuse_;
}
//- Return relaxation factor
scalar interfaceDeformationLimit() const
{
return interfaceDeformationLimit_;
}
//- Return fluid zone point displacement
vectorField& fluidZonePointsDispl()
{
return fluidZonePointsDispl_;
}
//- Return fluid zone ref. point displacement
vectorField& fluidZonePointsDisplRef()
{
return fluidZonePointsDisplRef_;
}
//- Return fluid zone previous point displacement
vectorField& fluidZonePointsDisplPrev()
{
return fluidZonePointsDisplPrev_;
}
//- Return solid zone point displacement
vectorField& solidZonePointsDispl()
{
return solidZonePointsDispl_;
}
//- Return solid zone ref. point displacement
vectorField& solidZonePointsDisplRef()
{
return solidZonePointsDisplRef_;
}
//- Return solid zone pressure
scalarField& solidZonePressure()
{
return solidZonePressure_;
}
//- Return solid zone total traction
vectorField& solidZoneTraction()
{
return solidZoneTraction_;
}
//- Return solid zone total traction
vectorField& solidZoneTractionPrev()
{
return solidZoneTractionPrev_;
}
//- Return current fsi residual
vectorField& residual()
{
return residual_;
}
//- Return previous fsi residual
vectorField& residualPrev()
{
return residualPrev_;
}
//- Return current outer iteration
label& outerCorr()
{
return outerCorr_;
}
//- Return current outer iteration
const label& outerCorr() const
{
return outerCorr_;
}
// //- Is it fluid domain pure Dirichlet
// Switch closedFluidDomain() const
// {
// return closedFluidDomain_;
// }
// //- Ref. pressure used in case of closed fluid domain
// scalar refPressure()
// {
// return refPressure_;
// }
// //- Ref. pressure used in case of closed fluid domain
// scalar refPressureIncrement()
// {
// return refPressureIncrement_;
// }
// //- Compressibility used in case of closed fluid domain
// scalar compressibility()
// {
// return compressibility_;
// }
// Edit
//- Initialize fields
void initializeFields();
//- Initialize fields
void updateInterpolator();
//- Calculate interface displacement
void updateDisplacement();
//- Calculate interface displacement
scalar updateWeakDisplacement();
//- Calculate interface displacement
void updateDisplacementUsingIQNILS();
//- Move fluid mesh
void moveFluidMesh();
//- Update interface force
void updateForce();
//- Update interface force
void updateWeakForce();
//- Update interface force
void updateWeakTraction();
//- Update interface force
void predictAndUpdateForce();
//- Solve solid
void evolveStress();
//- Update interface force
scalar updateResidual();
// //- Evolve the fluid solver
// virtual void evolve() = 0;
// //- Read dictionary
// virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,21 @@
{
phi() =
(
fvc::interpolate(HU, "interpolate(U)")
/fvc::interpolate(AU, "interpolate(U)")
) & mesh.Sf();
forAll(phi().boundaryField(), patchI)
{
if (!phi().boundaryField()[patchI].coupled())
{
phi().boundaryField()[patchI] =
(
U().boundaryField()[patchI]
& mesh.Sf().boundaryField()[patchI]
);
}
}
phi() += fvc::ddtPhiCorr(1.0/AU, U(), phi());
}

View file

@ -0,0 +1,290 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "consistentIcoFluid.H"
#include "volFields.H"
#include "fvm.H"
#include "fvc.H"
#include "fvMatrices.H"
#include "addToRunTimeSelectionTable.H"
#include "adjustPhi.H"
#include "EulerDdtScheme.H"
#include "CrankNicolsonDdtScheme.H"
#include "backwardDdtScheme.H"
#include "elasticSlipWallVelocityFvPatchVectorField.H"
#include "elasticWallVelocityFvPatchVectorField.H"
#include "elasticWallPressureFvPatchScalarField.H"
#include "findRefCell.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fluidSolvers
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(consistentIcoFluid, 0);
addToRunTimeSelectionTable(fluidSolver, consistentIcoFluid, dictionary);
// addToRunTimeSelectionTable(icoFluid, consistentIcoFluid, dictionary);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void consistentIcoFluid::makeSf() const
{
// Find global face zones
if (SfPtr_)
{
FatalErrorIn
(
"void fluidSolver::makeSf() const"
)
<< "Face surface vectors alrady created"
<< abort(FatalError);
}
// const fvMesh& mesh = fluidSolver::mesh();
IOobject SfHeader
(
"Sf",
runTime().timeName(),
mesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
);
SfPtr_ =
new surfaceVectorField
(
SfHeader,
mesh(),
dimensionedVector("0", dimArea, vector::zero)
);
surfaceVectorField& Sf = *SfPtr_;
if(!SfHeader.headerOk())
{
const vectorField& allFaceAreas = mesh().faceAreas();
Sf.internalField() =
vectorField::subField(allFaceAreas, mesh().nInternalFaces());
const fvPatchList& patches = mesh().boundary();
forAll (patches, patchI)
{
Sf.boundaryField()[patchI] =
patches[patchI].patchSlice(allFaceAreas);
}
}
}
void consistentIcoFluid::updateSf()
{
Sf().oldTime();
const vectorField& allFaceAreas = mesh().faceAreas();
Sf().internalField() =
vectorField::subField(allFaceAreas, mesh().nInternalFaces());
const fvPatchList& patches = mesh().boundary();
forAll (patches, patchI)
{
Sf().boundaryField()[patchI] =
patches[patchI].patchSlice(allFaceAreas);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
consistentIcoFluid::consistentIcoFluid(const fvMesh& mesh)
:
icoFluid(mesh),
SfPtr_(NULL)
{
phi().oldTime();
updateSf();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void consistentIcoFluid::evolve()
{
Info << "Evolving fluid solver: " << this->type() << endl;
const fvMesh& mesh = fluidSolver::mesh();
updateSf();
int nCorr(readInt(fluidProperties().lookup("nCorrectors")));
int nNonOrthCorr =
readInt(fluidProperties().lookup("nNonOrthogonalCorrectors"));
// Prepare for the pressure solution
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p(), fluidProperties(), pRefCell, pRefValue);
if(mesh.moving())
{
// Make the fluxes relative
phi() -= fvc::meshPhi(U());
}
// CourantNo
{
scalar CoNum = 0.0;
scalar meanCoNum = 0.0;
scalar velMag = 0.0;
if (mesh.nInternalFaces())
{
surfaceScalarField SfUfbyDelta =
mesh.surfaceInterpolation::deltaCoeffs()*mag(phi());
CoNum = max(SfUfbyDelta/mesh.magSf())
.value()*runTime().deltaT().value();
meanCoNum = (sum(SfUfbyDelta)/sum(mesh.magSf()))
.value()*runTime().deltaT().value();
velMag = max(mag(phi())/mesh.magSf()).value();
}
Info<< "Courant Number mean: " << meanCoNum
<< " max: " << CoNum
<< " velocity magnitude: " << velMag << endl;
}
fvVectorMatrix UEqn
(
fvm::ddt(U())
+ fvm::div(phi(), U())
- fvm::laplacian(nu(), U())
);
solve(UEqn == -gradp());
// --- PISO loop
volScalarField AU = UEqn.A();
surfaceScalarField rAUf("rAUf", 1.0/fvc::interpolate(AU, "interpolate(U)"));
for (int corr=0; corr<nCorr; corr++)
{
volVectorField HU = UEqn.H();
U() = HU/AU;
// U() = UEqn.H()/AU;
// phi() = (fvc::interpolate(U())&mesh.Sf());
# include "calcPhi.H"
# include "updateRobinFsiInterface.H"
adjustPhi(phi(), U(), p());
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix pEqn
(
fvm::laplacian
(
rAUf, p(), "laplacian((1|A(U)),p)"
)
== fvc::div(phi())
);
pEqn.setReference(pRefCell, pRefValue);
pEqn.solve();
gradp() = fvc::grad(p());
if (nonOrth == nNonOrthCorr)
{
phi() -= pEqn.flux();
}
}
// Continuity error
{
volScalarField contErr = fvc::div(phi());
scalar sumLocalContErr = runTime().deltaT().value()*
mag(contErr)().weightedAverage(mesh.V()).value();
scalar globalContErr = runTime().deltaT().value()*
contErr.weightedAverage(mesh.V()).value();
Info<< "time step continuity errors : sum local = "
<< sumLocalContErr << ", global = " << globalContErr << endl;
}
U() -= gradp()/AU;
U().correctBoundaryConditions();
gradU() = fvc::grad(U());
}
}
const surfaceVectorField& consistentIcoFluid::Sf() const
{
if (!SfPtr_)
{
makeSf();
}
return *SfPtr_;
}
surfaceVectorField& consistentIcoFluid::Sf()
{
if (!SfPtr_)
{
makeSf();
}
return *SfPtr_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fluidSolvers
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,124 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
consistentIcoFluid
Description
icoFoam fluid solver
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
consistentIcoFluid.C
\*---------------------------------------------------------------------------*/
#ifndef consistentIcoFluid_H
#define consistentIcoFluid_H
#include "icoFluid.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fluidSolvers
{
/*---------------------------------------------------------------------------*\
Class consistentIcoFluid Declaration
\*---------------------------------------------------------------------------*/
class consistentIcoFluid
:
public icoFluid
{
// Private data
//- Face area vectors
mutable surfaceVectorField* SfPtr_;
// Private Member Functions
//- Make face area vectors
void makeSf() const;
//- Make face area vectors
void updateSf();
//- Disallow default bitwise copy construct
consistentIcoFluid(const consistentIcoFluid&);
//- Disallow default bitwise assignment
void operator=(const consistentIcoFluid&);
public:
//- Runtime type information
TypeName("consistentIcoFluid");
// Constructors
//- Construct from components
consistentIcoFluid(const fvMesh& mesh);
// Destructor
virtual ~consistentIcoFluid()
{}
// Member Functions
// Access
//- Return face area vectors
const surfaceVectorField& Sf() const;
//- Return face area vectors
surfaceVectorField& Sf();
// Edit
//- Evolve the fluid solver
virtual void evolve();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fluidSolvers
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,59 @@
forAll(p().boundaryField(), patchI)
{
if
(
(
isA<elasticWallPressureFvPatchScalarField>(p().boundaryField()[patchI])
&& isA<elasticSlipWallVelocityFvPatchVectorField>(U().boundaryField()[patchI])
)
|| (
isA<elasticWallPressureFvPatchScalarField>(p().boundaryField()[patchI])
&& isA<elasticWallVelocityFvPatchVectorField>(U().boundaryField()[patchI])
)
)
{
word ddtScheme
(
mesh.schemesDict().ddtScheme("ddt(" + U().name() +')')
);
if
(
ddtScheme
== fv::EulerDdtScheme<vector>::typeName
)
{
phi().boundaryField()[patchI] = phi().oldTime().boundaryField()[patchI];
rAUf.boundaryField()[patchI] = runTime().deltaT().value();
}
else if
(
ddtScheme
== fv::backwardDdtScheme<vector>::typeName
)
{
if(runTime().timeIndex() == 1)
{
phi().boundaryField()[patchI] = phi().oldTime().boundaryField()[patchI];
rAUf.boundaryField()[patchI] = runTime().deltaT().value();
phi().oldTime().oldTime();
}
else
{
scalar deltaT = runTime().deltaT().value();
scalar deltaT0 = runTime().deltaT0().value();
scalar Cn = 1 + deltaT/(deltaT + deltaT0);
scalar Coo = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
scalar Co = Cn + Coo;
phi().boundaryField()[patchI] =
(Co/Cn)*phi().oldTime().boundaryField()[patchI]
- (Coo/Cn)*phi().oldTime().oldTime().boundaryField()[patchI];
rAUf.boundaryField()[patchI] = runTime().deltaT().value()/Cn;
}
}
}
}

View file

@ -0,0 +1,12 @@
RBFInterpolation.C
RBFCoarsening.C
RBFMeshMotionSolver.C
twoDPointCorrectorRBF.C
RBFFunctions/TPSFunction.C
RBFFunctions/WendlandC0Function.C
RBFFunctions/WendlandC2Function.C
RBFFunctions/WendlandC4Function.C
RBFFunctions/WendlandC6Function.C
RBFFunctions/LinearFunction.C
LIB = $(FOAM_LIBBIN)/libRBFMeshMotionSolver

View file

@ -0,0 +1,14 @@
c++WARN = -Wall -Wextra -Wno-unused-parameter -Wnon-virtual-dtor -Wunused-local-typedefs -Werror -Wredundant-decls -Wcast-align -Wmissing-declarations -Wswitch-enum -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral
EXE_INC = -std=c++11 \
-isystem ../thirdParty/eigen/ \
-isystem ../fsi/lnInclude \
-isystem $(LIB_SRC)/finiteVolume/lnInclude \
-isystem $(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
-isystem $(LIB_SRC)/meshTools/lnInclude
LIB_LIBS = \
-L$(FOAM_USER_LIBBIN) \
-lfiniteVolume \
-ldynamicMesh \
-lmeshTools

View file

@ -0,0 +1,647 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "RBFCoarsening.H"
#include "WendlandC2Function.H"
namespace rbf
{
Foam::debug::debugSwitch RBFCoarsening::debug( "RBFInterpolation", 0 );
RBFCoarsening::RBFCoarsening()
:
rbf( std::shared_ptr<RBFInterpolation> ( new RBFInterpolation() ) ),
rbfCoarse( std::shared_ptr<RBFInterpolation> ( new RBFInterpolation( rbf->rbfFunction, rbf->polynomialTerm, rbf->cpu ) ) ),
enabled( false ),
livePointSelection( false ),
livePointSelectionSumValues( false ),
tol( 0 ),
tolLivePointSelection( 0 ),
coarseningMinPoints( 0 ),
coarseningMaxPoints( 0 ),
twoPointSelection( false ),
surfaceCorrection( false ),
ratioRadiusError( 10 ),
exportTxt( false ),
selectedPositions(),
nbStaticFaceCentersRemove( 0 ),
positions(),
positionsInterpolation(),
values(),
errorInterpolationCoarse(),
closestBoundaryIndexCorrection(),
valuesCorrection(),
nbMovingFaceCenters( 0 ),
fileExportIndex( 0 )
{
assert( rbf );
}
RBFCoarsening::RBFCoarsening( std::shared_ptr<RBFInterpolation> rbf )
:
rbf( rbf ),
rbfCoarse( std::shared_ptr<RBFInterpolation> ( new RBFInterpolation( rbf->rbfFunction, rbf->polynomialTerm, rbf->cpu ) ) ),
enabled( false ),
livePointSelection( false ),
livePointSelectionSumValues( false ),
tol( 0 ),
tolLivePointSelection( 0 ),
coarseningMinPoints( 0 ),
coarseningMaxPoints( 0 ),
twoPointSelection( false ),
surfaceCorrection( false ),
ratioRadiusError( 10 ),
exportTxt( false ),
selectedPositions(),
nbStaticFaceCentersRemove( 0 ),
positions(),
positionsInterpolation(),
values(),
errorInterpolationCoarse(),
closestBoundaryIndexCorrection(),
valuesCorrection(),
nbMovingFaceCenters( 0 ),
fileExportIndex( 0 )
{
assert( rbf );
}
RBFCoarsening::RBFCoarsening(
std::shared_ptr<RBFInterpolation> rbf,
bool enabled,
bool livePointSelection,
bool livePointSelectionSumValues,
scalar tol,
scalar tolLivePointSelection,
int coarseningMinPoints,
int coarseningMaxPoints,
bool exportTxt
)
:
rbf( rbf ),
rbfCoarse( std::shared_ptr<RBFInterpolation> ( new RBFInterpolation( rbf->rbfFunction, rbf->polynomialTerm, rbf->cpu ) ) ),
enabled( enabled ),
livePointSelection( livePointSelection ),
livePointSelectionSumValues( livePointSelectionSumValues ),
tol( tol ),
tolLivePointSelection( tolLivePointSelection ),
coarseningMinPoints( coarseningMinPoints ),
coarseningMaxPoints( coarseningMaxPoints ),
twoPointSelection( false ),
surfaceCorrection( false ),
ratioRadiusError( 10.0 ),
exportTxt( exportTxt ),
selectedPositions(),
nbStaticFaceCentersRemove( 0 ),
positions(),
positionsInterpolation(),
values(),
errorInterpolationCoarse(),
closestBoundaryIndexCorrection(),
valuesCorrection(),
nbMovingFaceCenters( 0 ),
fileExportIndex( 0 )
{
assert( rbf );
assert( coarseningMinPoints <= coarseningMaxPoints );
assert( coarseningMinPoints > 0 );
assert( coarseningMaxPoints > 0 );
assert( tol > 0 );
assert( tol < 1 );
assert( tolLivePointSelection > 0 );
assert( tolLivePointSelection < 1 );
// If unit displacement do not use polynomial for selection
if ( enabled && !livePointSelection && rbf->polynomialTerm )
{
WarningIn( "RBFCoarsening::RBFCoarsening" )
<< "Unit displacement is combined with polynomial addition into RBF interpolation. Could cause 'strange' results." << endl;
}
}
RBFCoarsening::RBFCoarsening(
std::shared_ptr<RBFInterpolation> rbf,
bool enabled,
bool livePointSelection,
bool livePointSelectionSumValues,
scalar tol,
scalar tolLivePointSelection,
int coarseningMinPoints,
int coarseningMaxPoints,
bool twoPointSelection,
bool exportTxt
)
:
rbf( rbf ),
rbfCoarse( std::shared_ptr<RBFInterpolation> ( new RBFInterpolation( rbf->rbfFunction, rbf->polynomialTerm, rbf->cpu ) ) ),
enabled( enabled ),
livePointSelection( livePointSelection ),
livePointSelectionSumValues( livePointSelectionSumValues ),
tol( tol ),
tolLivePointSelection( tolLivePointSelection ),
coarseningMinPoints( coarseningMinPoints ),
coarseningMaxPoints( coarseningMaxPoints ),
twoPointSelection( twoPointSelection ),
surfaceCorrection( false ),
ratioRadiusError( 10.0 ),
exportTxt( exportTxt ),
selectedPositions(),
nbStaticFaceCentersRemove( 0 ),
positions(),
positionsInterpolation(),
values(),
errorInterpolationCoarse(),
closestBoundaryIndexCorrection(),
valuesCorrection(),
nbMovingFaceCenters( 0 ),
fileExportIndex( 0 )
{
assert( rbf );
assert( coarseningMinPoints <= coarseningMaxPoints );
assert( coarseningMinPoints > 0 );
assert( coarseningMaxPoints > 0 );
assert( tol > 0 );
assert( tol < 1 );
assert( tolLivePointSelection > 0 );
assert( tolLivePointSelection < 1 );
// If unit displacement do not use polynomial for selection
if ( enabled && !livePointSelection && rbf->polynomialTerm )
{
WarningIn( "RBFCoarsening::RBFCoarsening" )
<< "Unit displacement is combined with polynomial addition into RBF interpolation. Could cause 'strange' results." << endl;
}
}
RBFCoarsening::RBFCoarsening(
std::shared_ptr<RBFInterpolation> rbf,
bool enabled,
bool livePointSelection,
bool livePointSelectionSumValues,
scalar tol,
scalar tolLivePointSelection,
int coarseningMinPoints,
int coarseningMaxPoints,
bool twoPointSelection,
bool surfaceCorrection,
scalar ratioRadiusError,
bool exportTxt
)
:
rbf( rbf ),
rbfCoarse( std::shared_ptr<RBFInterpolation> ( new RBFInterpolation( rbf->rbfFunction, rbf->polynomialTerm, rbf->cpu ) ) ),
enabled( enabled ),
livePointSelection( livePointSelection ),
livePointSelectionSumValues( livePointSelectionSumValues ),
tol( tol ),
tolLivePointSelection( tolLivePointSelection ),
coarseningMinPoints( coarseningMinPoints ),
coarseningMaxPoints( coarseningMaxPoints ),
twoPointSelection( twoPointSelection ),
surfaceCorrection( surfaceCorrection ),
ratioRadiusError( ratioRadiusError ),
exportTxt( exportTxt ),
selectedPositions(),
nbStaticFaceCentersRemove( 0 ),
positions(),
positionsInterpolation(),
values(),
errorInterpolationCoarse(),
closestBoundaryIndexCorrection(),
valuesCorrection(),
nbMovingFaceCenters( 0 ),
fileExportIndex( 0 )
{
assert( rbf );
assert( coarseningMinPoints <= coarseningMaxPoints );
assert( coarseningMinPoints > 0 );
assert( coarseningMaxPoints > 0 );
assert( tol > 0 );
assert( tol < 1 );
assert( tolLivePointSelection > 0 );
assert( tolLivePointSelection < 1 );
// If unit displacement do not use polynomial for selection
if ( enabled && !livePointSelection && rbf->polynomialTerm )
{
WarningIn( "RBFCoarsening::RBFCoarsening" )
<< "Unit displacement is combined with polynomial addition into RBF interpolation. Could cause 'strange' results." << endl;
}
}
/* Select a subset of control point with a greedy algorithm.
* The selection of the points is based on a displacement/motion of
* a unit displacement at every control point. Based on a user specified tolerance,
* the control points are selected.
*/
void RBFCoarsening::compute(
const matrix & positions,
const matrix & positionsInterpolation
)
{
this->positions = positions;
this->positionsInterpolation = positionsInterpolation;
}
void RBFCoarsening::greedySelection( const matrix & values )
{
assert( positions.cols() == positionsInterpolation.cols() );
assert( positions.cols() > 0 );
assert( positions.rows() > 0 );
assert( positionsInterpolation.rows() > 0 );
assert( positions.rows() == values.rows() );
matrix usedPositions = positions;
if ( enabled )
{
// Greedy algorithm
rbf::vector errorList( positions.rows() );
selectedPositions.resize( 2 );
for ( int i = 0; i < selectedPositions.rows(); i++ )
selectedPositions( i ) = i;
assert( positions.rows() >= selectedPositions.rows() );
rbf::matrix positionsInterpolationCoarse = positions;
int maxNbPoints = std::min( coarseningMaxPoints, static_cast<int>( positions.rows() ) );
int minPoints = std::min( coarseningMinPoints, static_cast<int>( positions.rows() ) );
scalar error = 0;
scalar errorMax = 0;
// Create RBF interpolator
// Run the greedy algorithm
scalar runTimeInterpolate = 0.0;
scalar runTimeError = 0.0;
scalar runTimeConvergence = 0.0;
bool addedSecondPoint = false;
int counter = selectedPositions.rows();
while ( true )
{
std::clock_t t = std::clock();
// Build the matrices used for the RBF interpolation
rbf::matrix positionsCoarse( counter, positions.cols() );
rbf::matrix valuesCoarse( positionsCoarse.rows(), positionsCoarse.cols() );
rbf::matrix valuesInterpolationCoarse( positionsInterpolationCoarse.rows(), positionsInterpolationCoarse.cols() );
for ( int j = 0; j < selectedPositions.rows(); j++ )
{
positionsCoarse.row( j ) = positions.row( selectedPositions( j ) );
valuesCoarse.row( j ) = values.row( selectedPositions( j ) );
}
// Perform the RBF interpolation.
rbfCoarse->interpolate( positionsCoarse, positionsInterpolationCoarse, valuesCoarse, valuesInterpolationCoarse );
if ( debug > 0 )
{
t = std::clock() - t;
runTimeInterpolate += static_cast<float>(t) / CLOCKS_PER_SEC;
t = std::clock();
}
// Evaluate the error
for ( int j = 0; j < valuesInterpolationCoarse.rows(); j++ )
errorList( j ) = ( valuesInterpolationCoarse.row( j ) - values.row( j ) ).norm();
// Select the point with the largest error which is not already selected.
int index = -1;
scalar largestError = errorList.maxCoeff( &index );
// Additional function to check whether the largestError = 0 (<SMALL) and do select next consecutive point
if ( largestError < SMALL )
{
index = selectedPositions.rows();
}
int index2 = -1;
scalar largestError2 = -1;
// selected point with largest error in opposite direction (more than 90 degrees differenc in direction)
if ( twoPointSelection )
{
vector largestErrorVector = valuesInterpolationCoarse.row( index ) - values.row( index );
for ( int j = 0; j < errorList.rows(); j++ )
{
vector errorVector = valuesInterpolationCoarse.row( j ) - values.row( j );
if ( largestErrorVector.dot( errorVector ) < -SMALL && largestError2 < errorList( j ) )
{
index2 = j;
largestError2 = errorList( j );
}
}
}
if ( debug > 0 )
{
t = std::clock() - t;
runTimeError += static_cast<float>(t) / CLOCKS_PER_SEC;
t = std::clock();
}
scalar epsilon = std::sqrt( SMALL );
error = (errorList).norm() / (values.norm() + epsilon);
errorMax = largestError / ( ( values.rowwise().norm() ).maxCoeff() + epsilon );
// bool convergence = (error < tol && counter >= minPoints) || counter >= maxNbPoints;
bool convergence = (error < tol && errorMax < tol && counter >= minPoints) || counter >= maxNbPoints;
if ( convergence )
{
if ( livePointSelection )
errorInterpolationCoarse = valuesInterpolationCoarse - values;
break;
}
// Break if maximum point are reached
if ( counter >= maxNbPoints )
{
if ( livePointSelection )
errorInterpolationCoarse = valuesInterpolationCoarse - values;
break;
}
selectedPositions.conservativeResize( selectedPositions.rows() + 1 );
selectedPositions( selectedPositions.rows() - 1 ) = index;
counter++;
// Add second point if possible
if ( twoPointSelection && index2 >= 0 && index != index2 )
{
addedSecondPoint = true;
selectedPositions.conservativeResize( selectedPositions.rows() + 1 );
selectedPositions( selectedPositions.rows() - 1 ) = index2;
counter++;
}
if ( debug > 0 )
{
t = std::clock() - t;
runTimeConvergence += static_cast<float>(t) / CLOCKS_PER_SEC;
t = std::clock();
}
}
if ( debug > 0 )
{
Info << "RBFCoarsening::debug 1. interpolate to surface = " << runTimeInterpolate << " s" << endl;
Info << "RBFCoarsening::debug 2. find largest error = " << runTimeError << " s" << ". Added second point = " << addedSecondPoint << endl;
Info << "RBFCoarsening::debug 3. convergence check = " << runTimeConvergence << " s" << endl;
}
Info << "RBF interpolation coarsening: selected " << selectedPositions.rows() << "/" << positions.rows() << " points, 2-norm(error) = "
<< error << ", max(error) = " << errorMax << ", tol = " << tol << endl;
rbf::matrix positionsCoarse( selectedPositions.rows(), positions.cols() );
for ( int i = 0; i < selectedPositions.rows(); i++ )
positionsCoarse.row( i ) = positions.row( selectedPositions( i ) );
usedPositions = positionsCoarse;
if ( exportTxt )
{
std::string fileNameTXT = "rbf-coarsening-greedy-selection-" + std::to_string( fileExportIndex ) + ".txt";
std::ofstream fileTXT( fileNameTXT );
if ( fileTXT.is_open() )
fileTXT << usedPositions;
std::string fileNameCSV = "rbf-coarsening-greedy-selection-" + std::to_string( fileExportIndex ) + ".csv";
std::ofstream fileCSV( fileNameCSV );
Eigen::IOFormat CSVFmt( Eigen::FullPrecision, Eigen::DontAlignCols, "," );
if ( fileCSV.is_open() )
fileCSV << usedPositions.format( CSVFmt );
fileExportIndex++;
}
}
rbf->compute( usedPositions, positionsInterpolation );
}
void RBFCoarsening::interpolate(
const matrix & values,
matrix & valuesInterpolation
)
{
matrix usedValues = values;
if ( enabled )
{
if ( livePointSelection )
{
// For RBF mesh interpolation, the values to be interpolated need to be
// the total displacements. As input, the incremental displacements
// are given.
if ( livePointSelectionSumValues )
{
if ( this->values.cols() != values.cols() )
this->values = values;
else
this->values.array() += values.array();
}
else
this->values = values;
// Check if re-selection is necessary
bool reselection = true;
if ( rbfCoarse->computed )
{
rbf::matrix valuesCoarse( selectedPositions.rows(), values.cols() );
rbf::matrix valuesInterpolationCoarse( positions.rows(), valuesInterpolation.cols() );
for ( int j = 0; j < selectedPositions.rows(); j++ )
valuesCoarse.row( j ) = this->values.row( selectedPositions( j ) );
rbfCoarse->interpolate2( valuesCoarse, valuesInterpolationCoarse );
scalar epsilon = std::sqrt( SMALL );
errorInterpolationCoarse = valuesInterpolationCoarse - this->values;
scalar error = (errorInterpolationCoarse).matrix().norm() / (this->values.norm() + epsilon);
scalar errorMax = ( errorInterpolationCoarse.rowwise().norm() ).maxCoeff() / ( ( this->values.rowwise().norm() ).maxCoeff() + epsilon );
// bool convergence = error < tolLivePointSelection;
bool convergence = (error < tolLivePointSelection && errorMax < tolLivePointSelection);
if ( convergence )
reselection = false;
Info << "RBF interpolation coarsening: 2-norm(error) = " << error << ", max(error) = " << errorMax << ", tol = " << tolLivePointSelection << ", reselection = ";
if ( reselection )
Info << "true";
else
Info << "false";
Info << endl;
}
if ( reselection )
{
greedySelection( this->values );
rbf->Hhat.conservativeResize( rbf->Hhat.rows(), rbf->Hhat.cols() - nbStaticFaceCentersRemove );
}
}
else
if ( !rbf->computed )
{
// Unit displacement of control points
matrix unitDisplacement( positions.rows(), positions.cols() );
unitDisplacement.setZero();
assert( unitDisplacement.rows() >= nbMovingFaceCenters );
if ( nbMovingFaceCenters == 0 )
unitDisplacement.fill( 1 );
else
for ( int i = 0; i < nbMovingFaceCenters; i++ )
for ( int j = 0; j < unitDisplacement.cols(); j++ )
unitDisplacement( i, j ) = 1;
greedySelection( unitDisplacement );
rbf->Hhat.conservativeResize( rbf->Hhat.rows(), rbf->Hhat.cols() - nbStaticFaceCentersRemove );
}
rbf::matrix selectedValues( selectedPositions.rows(), values.cols() );
for ( int i = 0; i < selectedValues.rows(); i++ )
selectedValues.row( i ) = values.row( selectedPositions( i ) );
usedValues = selectedValues;
}
else
{
if ( !rbf->computed )
{
rbf->compute( positions, positionsInterpolation );
rbf->Hhat.conservativeResize( rbf->Hhat.rows(), rbf->Hhat.cols() - nbStaticFaceCentersRemove );
}
}
usedValues.conservativeResize( usedValues.rows() - nbStaticFaceCentersRemove, usedValues.cols() );
rbf->interpolate( usedValues, valuesInterpolation );
// start doing correction of surface is requested
if ( livePointSelection && surfaceCorrection )
{
correctSurface( valuesInterpolation );
}
}
void RBFCoarsening::correctSurface( matrix & valuesInterpolation )
{
if ( valuesCorrection.rows() == 0 )
{
valuesCorrection.conservativeResize( valuesInterpolation.rows(), valuesInterpolation.cols() );
valuesCorrection.setZero();
}
scalar R = ratioRadiusError * ( errorInterpolationCoarse.rowwise().norm() ).maxCoeff();
if ( debug > 0 )
{
Info << nl << "RBFCoarsening::correctSurface::debug 0: ratioRadiusError = " << ratioRadiusError << ", R = " << R << endl;
}
// Find nearest boundary point for each internal point. Do this only the first time
vector closestBoundaryRadius( positionsInterpolation.rows() );
if ( closestBoundaryIndexCorrection.rows() == 0 )
{
closestBoundaryIndexCorrection.conservativeResize( positionsInterpolation.rows() );
std::clock_t t = std::clock();
scalar runTimeNN = 0;
for ( int i = 0; i < positionsInterpolation.rows(); i++ )
{
scalar smallestRadius = GREAT;
int boundaryIndex = -1;
for ( int j = 0; j < positions.rows(); j++ )
{
scalar radius = ( positions.row( j ) - positionsInterpolation.row( i ) ).norm();
if ( radius < smallestRadius )
{
boundaryIndex = j;
smallestRadius = radius;
}
}
closestBoundaryIndexCorrection( i ) = boundaryIndex;
closestBoundaryRadius( i ) = smallestRadius;
}
if ( debug > 0 )
{
t = std::clock() - t;
runTimeNN += static_cast<float>(t) / CLOCKS_PER_SEC;
Info << "RBFCoarsening::correctSurface::debug 1. nearest neighbour selection = " << runTimeNN << " s" << endl;
}
}
else
{
for ( int i = 0; i < positionsInterpolation.rows(); i++ )
{
closestBoundaryRadius( i ) = ( positions.row( closestBoundaryIndexCorrection( i ) ) - positionsInterpolation.row( i ) ).norm();
}
}
// Start doing the correction
std::clock_t t = std::clock();
scalar runTimeCorr = 0;
std::shared_ptr<rbf::RBFFunctionInterface> rbfFunction = std::shared_ptr<rbf::RBFFunctionInterface> ( new rbf::WendlandC2Function( R ) );
for ( int i = 0; i < positionsInterpolation.rows(); i++ )
{
matrix fEval = -( rbfFunction->evaluate( closestBoundaryRadius( i ) ) ) * errorInterpolationCoarse.row( closestBoundaryIndexCorrection( i ) );
valuesInterpolation.row( i ) += ( fEval - valuesCorrection.row( i ) );
valuesCorrection.row( i ) = fEval;
}
if ( debug > 0 )
{
t = std::clock() - t;
runTimeCorr += static_cast<float>(t) / CLOCKS_PER_SEC;
Info << "RBFCoarsening::correctSurface::debug 2. correction evaluation = " << runTimeCorr << " s" << endl;
}
}
void RBFCoarsening::setNbMovingAndStaticFaceCenters(
int nbMovingFaceCenters,
int nbStaticFaceCenters
)
{
nbStaticFaceCentersRemove = nbStaticFaceCenters;
this->nbMovingFaceCenters = nbMovingFaceCenters;
if ( enabled )
{
// Determine the number of selected static face centers
nbStaticFaceCentersRemove = 0;
for ( int i = 0; i < selectedPositions.rows(); i++ )
if ( selectedPositions( i ) >= nbMovingFaceCenters )
nbStaticFaceCentersRemove++;
}
}
}

View file

@ -0,0 +1,110 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef RBFCoarsening_H
#define RBFCoarsening_H
#include "RBFInterpolation.H"
#include "fvCFD.H"
#include <fstream>
namespace rbf
{
class RBFCoarsening
{
public:
RBFCoarsening();
explicit RBFCoarsening( std::shared_ptr<RBFInterpolation> rbf );
RBFCoarsening(
std::shared_ptr<RBFInterpolation> rbf,
bool enabled,
bool livePointSelection,
bool livePointSelectionSumValues,
scalar tol,
scalar tolLivePointSelection,
int coarseningMinPoints,
int coarseningMaxPoints,
bool exportTxt
);
RBFCoarsening(
std::shared_ptr<RBFInterpolation> rbf,
bool enabled,
bool livePointSelection,
bool livePointSelectionSumValues,
scalar tol,
scalar tolLivePointSelection,
int coarseningMinPoints,
int coarseningMaxPoints,
bool twoPointSelection,
bool exportTxt
);
RBFCoarsening(
std::shared_ptr<RBFInterpolation> rbf,
bool enabled,
bool livePointSelection,
bool livePointSelectionSumValues,
scalar tol,
scalar tolLivePointSelection,
int coarseningMinPoints,
int coarseningMaxPoints,
bool twoPointSelection,
bool surfaceCorrection,
scalar ratioRadiusError,
bool exportTxt
);
void greedySelection( const matrix & values );
void compute(
const matrix & positions,
const matrix & positionsInterpolation
);
void interpolate(
const matrix & values,
matrix & valuesInterpolation
);
void setNbMovingAndStaticFaceCenters(
int nbMovingFaceCenters,
int nbStaticFaceCenters
);
void correctSurface( matrix & valuesInterpolation );
std::shared_ptr<RBFInterpolation> rbf;
std::shared_ptr<RBFInterpolation> rbfCoarse;
bool enabled;
bool livePointSelection;
bool livePointSelectionSumValues;
scalar tol;
scalar tolLivePointSelection;
int coarseningMinPoints;
int coarseningMaxPoints;
bool twoPointSelection;
bool surfaceCorrection;
scalar ratioRadiusError;
bool exportTxt;
Eigen::VectorXi selectedPositions;
int nbStaticFaceCentersRemove;
matrix positions;
matrix positionsInterpolation;
matrix values;
matrix errorInterpolationCoarse;
Eigen::VectorXi closestBoundaryIndexCorrection;
matrix valuesCorrection;
int nbMovingFaceCenters;
int fileExportIndex;
static debug::debugSwitch debug;
};
}
#endif

View file

@ -0,0 +1,27 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef RBFFunctionInterface_H
#define RBFFunctionInterface_H
#include <math.h>
#include <string>
#include <memory>
#include <Eigen/Dense>
#include "fvCFD.H"
namespace rbf
{
class RBFFunctionInterface
{
public:
virtual ~RBFFunctionInterface(){}
virtual scalar evaluate( scalar value ) = 0;
};
}
#endif

View file

@ -0,0 +1,21 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "LinearFunction.H"
namespace rbf
{
LinearFunction::LinearFunction()
{}
LinearFunction::~LinearFunction()
{}
scalar LinearFunction::evaluate( scalar value )
{
return value;
}
}

View file

@ -0,0 +1,25 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef LinearFunction_H
#define LinearFunction_H
#include "RBFFunctionInterface.H"
namespace rbf
{
class LinearFunction : public RBFFunctionInterface
{
public:
LinearFunction();
virtual ~LinearFunction();
virtual scalar evaluate( scalar value );
};
}
#endif

View file

@ -0,0 +1,24 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "TPSFunction.H"
namespace rbf
{
TPSFunction::TPSFunction()
{}
TPSFunction::~TPSFunction()
{}
scalar TPSFunction::evaluate( scalar value )
{
if ( value > 0 )
return std::log( value ) * value * value;
return 0L;
}
}

View file

@ -0,0 +1,25 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef TPSFunction_H
#define TPSFunction_H
#include "RBFFunctionInterface.H"
namespace rbf
{
class TPSFunction : public RBFFunctionInterface
{
public:
TPSFunction();
virtual ~TPSFunction();
virtual scalar evaluate( scalar value );
};
}
#endif

View file

@ -0,0 +1,30 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "WendlandC0Function.H"
namespace rbf
{
WendlandC0Function::WendlandC0Function( scalar radius )
:
radius( radius )
{
assert( radius > 0 );
}
WendlandC0Function::~WendlandC0Function()
{}
scalar WendlandC0Function::evaluate( scalar value )
{
value /= radius;
if ( 1 - value < 0 )
return 0;
return std::pow( 1 - value, 2 );
}
}

View file

@ -0,0 +1,27 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef WendlandC0Function_H
#define WendlandC0Function_H
#include "RBFFunctionInterface.H"
namespace rbf
{
class WendlandC0Function : public RBFFunctionInterface
{
public:
explicit WendlandC0Function( scalar radius );
virtual ~WendlandC0Function();
virtual scalar evaluate( scalar value );
scalar radius;
};
}
#endif

View file

@ -0,0 +1,30 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "WendlandC2Function.H"
namespace rbf
{
WendlandC2Function::WendlandC2Function( scalar radius )
:
radius( radius )
{
assert( radius > 0 );
}
WendlandC2Function::~WendlandC2Function()
{}
scalar WendlandC2Function::evaluate( scalar value )
{
value /= radius;
if ( 1 - value < 0 )
return 0;
return std::pow( 1 - value, 4 ) * (4 * value + 1);
}
}

View file

@ -0,0 +1,27 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef WendlandC2Function_H
#define WendlandC2Function_H
#include "RBFFunctionInterface.H"
namespace rbf
{
class WendlandC2Function : public RBFFunctionInterface
{
public:
explicit WendlandC2Function( scalar radius );
virtual ~WendlandC2Function();
virtual scalar evaluate( scalar value );
scalar radius;
};
}
#endif

View file

@ -0,0 +1,30 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "WendlandC4Function.H"
namespace rbf
{
WendlandC4Function::WendlandC4Function( scalar radius )
:
radius( radius )
{
assert( radius > 0 );
}
WendlandC4Function::~WendlandC4Function()
{}
scalar WendlandC4Function::evaluate( scalar value )
{
value /= radius;
if ( 1 - value < 0 )
return 0;
return std::pow( 1 - value, 6 ) * (35 * std::pow( value, 2 ) + 18 * value + 3);
}
}

View file

@ -0,0 +1,27 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef WendlandC4Function_H
#define WendlandC4Function_H
#include "RBFFunctionInterface.H"
namespace rbf
{
class WendlandC4Function : public RBFFunctionInterface
{
public:
explicit WendlandC4Function( scalar radius );
virtual ~WendlandC4Function();
virtual scalar evaluate( scalar value );
scalar radius;
};
}
#endif

View file

@ -0,0 +1,30 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "WendlandC6Function.H"
namespace rbf
{
WendlandC6Function::WendlandC6Function( scalar radius )
:
radius( radius )
{
assert( radius > 0 );
}
WendlandC6Function::~WendlandC6Function()
{}
scalar WendlandC6Function::evaluate( scalar value )
{
value /= radius;
if ( 1 - value < 0 )
return 0;
return std::pow( 1 - value, 8 ) * (32 * std::pow( value, 3 ) + 25 * std::pow( value, 2 ) + 8 * value + 1);
}
}

View file

@ -0,0 +1,27 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef WendlandC6Function_H
#define WendlandC6Function_H
#include "RBFFunctionInterface.H"
namespace rbf
{
class WendlandC6Function : public RBFFunctionInterface
{
public:
explicit WendlandC6Function( scalar radius );
virtual ~WendlandC6Function();
virtual scalar evaluate( scalar value );
scalar radius;
};
}
#endif

View file

@ -0,0 +1,399 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "RBFInterpolation.H"
#include "TPSFunction.H"
namespace rbf
{
RBFInterpolation::RBFInterpolation()
:
rbfFunction( std::shared_ptr<RBFFunctionInterface> ( new TPSFunction() ) ),
polynomialTerm( true ),
cpu( false ),
computed( false ),
n_A( 0 ),
n_B( 0 ),
dimGrid( 0 ),
Hhat(),
Phi(),
lu(),
positions(),
positionsInterpolation()
{}
RBFInterpolation::RBFInterpolation( std::shared_ptr<RBFFunctionInterface> rbfFunction )
:
rbfFunction( rbfFunction ),
polynomialTerm( true ),
cpu( false ),
computed( false ),
n_A( 0 ),
n_B( 0 ),
dimGrid( 0 ),
Hhat(),
Phi(),
lu(),
positions(),
positionsInterpolation()
{
assert( rbfFunction );
}
RBFInterpolation::RBFInterpolation(
std::shared_ptr<RBFFunctionInterface> rbfFunction,
bool polynomialTerm,
bool cpu
)
:
rbfFunction( rbfFunction ),
polynomialTerm( polynomialTerm ),
cpu( cpu ),
computed( false ),
n_A( 0 ),
n_B( 0 ),
dimGrid( 0 ),
Hhat(),
Phi(),
lu(),
positions(),
positionsInterpolation()
{
assert( rbfFunction );
}
void RBFInterpolation::evaluateH(
const matrix & positions,
matrix & H
)
{
// RBF function evaluation
scalar r = 0;
for ( int i = 0; i < n_A; i++ )
{
for ( int j = i; j < n_A; j++ )
{
r = ( positions.row( i ) - positions.row( j ) ).norm();
H( j, i ) = rbfFunction->evaluate( r );
}
}
}
void RBFInterpolation::evaluatePhi(
const matrix & positions,
const matrix & positionsInterpolation,
matrix & Phi
)
{
// Evaluate Phi which contains the evaluation of the radial basis function
scalar r = 0;
for ( int i = 0; i < n_A; i++ )
{
for ( int j = 0; j < n_B; j++ )
{
r = ( positions.row( i ) - positionsInterpolation.row( j ) ).norm();
Phi( j, i ) = rbfFunction->evaluate( r );
}
}
}
void RBFInterpolation::compute(
const matrix & positions,
const matrix & positionsInterpolation
)
{
// Verify input
assert( positions.cols() == positionsInterpolation.cols() );
assert( positions.rows() > 0 );
assert( positions.cols() > 0 );
assert( positionsInterpolation.rows() > 0 );
n_A = positions.rows();
n_B = positionsInterpolation.rows();
dimGrid = positions.cols();
// Radial basis function interpolation
// Initialize matrices H and Phi
matrix H( n_A, n_A ), Phi( n_B, n_A );
if ( polynomialTerm )
{
H.resize( n_A + dimGrid + 1, n_A + dimGrid + 1 );
}
// Evaluate radial basis functions for matrix H
evaluateH( positions, H );
// Include polynomial contributions
if ( polynomialTerm )
{
for ( int i = 0; i < n_A; i++ )
H( n_A, i ) = 1;
H.bottomLeftCorner( dimGrid, n_A ) = positions.block( 0, 0, n_A, dimGrid ).transpose();
for ( int i = 0; i < dimGrid + 1; i++ )
for ( int j = 0; j < dimGrid + 1; j++ )
H( H.rows() - dimGrid - 1 + i, H.rows() - dimGrid - 1 + j ) = 0;
}
if ( cpu )
{
this->positions = positions;
this->positionsInterpolation = positionsInterpolation;
lu.compute( H.selfadjointView<Eigen::Lower>() );
}
if ( not cpu )
{
// Evaluate Phi which contains the evaluation of the radial basis function
if ( polynomialTerm )
Phi.resize( n_B, n_A + dimGrid + 1 );
evaluatePhi( positions, positionsInterpolation, Phi );
// Include polynomial contributions in matrix Phi
if ( polynomialTerm )
{
for ( int i = 0; i < Phi.rows(); i++ )
Phi( i, n_A ) = 1;
Phi.topRightCorner( n_B, dimGrid ) = positionsInterpolation.block( 0, 0, n_B, dimGrid );
}
// Compute the LU decomposition of the matrix H
Eigen::FullPivLU<matrix> lu( H.selfadjointView<Eigen::Lower>() );
// Compute interpolation matrix
Hhat.noalias() = Phi * lu.inverse();
Hhat.conservativeResize( n_B, n_A );
}
computed = true;
}
void RBFInterpolation::interpolate(
const matrix & values,
matrix & valuesInterpolation
)
{
if ( cpu && not computed )
compute( positions, positionsInterpolation );
assert( computed );
if ( cpu )
{
matrix B, valuesLU( n_A, values.cols() ), Phi( n_B, n_A );
if ( polynomialTerm )
{
Phi.resize( n_B, n_A + dimGrid + 1 );
valuesLU.resize( n_A + dimGrid + 1, values.cols() );
}
valuesLU.setZero();
valuesLU.topLeftCorner( values.rows(), values.cols() ) = values;
B = lu.solve( valuesLU );
evaluatePhi( positions, positionsInterpolation, Phi );
if ( polynomialTerm )
{
// Include polynomial contributions in matrix Phi
for ( int i = 0; i < Phi.rows(); i++ )
Phi( i, n_A ) = 1;
Phi.topRightCorner( n_B, dimGrid ) = positionsInterpolation.block( 0, 0, n_B, dimGrid );
}
valuesInterpolation.noalias() = Phi * B;
}
if ( not cpu )
{
valuesInterpolation.noalias() = Hhat * values;
}
assert( valuesInterpolation.rows() == n_B );
assert( values.cols() == valuesInterpolation.cols() );
}
/*
* Compute interpolation matrix and directly interpolate the values.
* The algorithms solves for the coefficients, and explicitly
* uses the coefficients to interpolate the data to the new positions.
*/
void RBFInterpolation::interpolate(
const matrix & positions,
const matrix & positionsInterpolation,
const matrix & values,
matrix & valuesInterpolation
)
{
// Verify input
assert( positions.cols() == positionsInterpolation.cols() );
assert( positions.rows() > 0 );
assert( positions.cols() > 0 );
assert( positionsInterpolation.rows() > 0 );
n_A = positions.rows();
n_B = positionsInterpolation.rows();
dimGrid = positions.cols();
// Radial basis function interpolation
// Initialize matrices
matrix H( n_A, n_A );
if ( polynomialTerm )
H.resize( n_A + dimGrid + 1, n_A + dimGrid + 1 );
// RBF function evaluation
evaluateH( positions, H );
// Include polynomial contributions
if ( polynomialTerm )
{
// THIJS: initialize Phi if empty
if ( Phi.cols() == 0 )
{
Phi.conservativeResize( n_B, dimGrid + 1 );
}
for ( int i = 0; i < n_A; i++ )
H( n_A, i ) = 1;
H.bottomLeftCorner( dimGrid, n_A ) = positions.block( 0, 0, n_A, dimGrid ).transpose();
for ( int i = 0; i < dimGrid + 1; i++ )
for ( int j = 0; j < dimGrid + 1; j++ )
H( H.rows() - dimGrid - 1 + i, H.rows() - dimGrid - 1 + j ) = 0;
}
// Calculate coefficients gamma and beta
matrix B;
matrix valuesLU( H.rows(), values.cols() );
valuesLU.setZero();
valuesLU.topLeftCorner( values.rows(), values.cols() ) = values;
lu.compute( H.selfadjointView<Eigen::Lower>() );
B = lu.solve( valuesLU );
// Evaluate Phi_BA which contains the evaluation of the radial basis function
// This method is only used by the greedy algorithm, and the matrix Phi
// is therefore enlarged at every greedy step.
buildPhi( positions, positionsInterpolation );
if ( polynomialTerm )
{
// Include polynomial contributions in matrix Phi
for ( int i = 0; i < Phi.rows(); i++ )
Phi( i, n_A ) = 1;
Phi.topRightCorner( n_B, dimGrid ) = positionsInterpolation.block( 0, 0, n_B, dimGrid );
}
valuesInterpolation.noalias() = Phi * B;
computed = true;
}
void RBFInterpolation::buildPhi(
const matrix & positions,
const matrix & positionsInterpolation
)
{
n_A = positions.rows();
n_B = positionsInterpolation.rows();
int phiColsOld = Phi.cols();
if ( polynomialTerm )
Phi.conservativeResize( n_B, n_A + dimGrid + 1 );
else
Phi.conservativeResize( n_B, n_A );
int nNewPoints = Phi.cols() - phiColsOld;
if ( nNewPoints == Phi.cols() )
nNewPoints = n_A;
scalar r = 0;
for ( int i = 0; i < nNewPoints; i++ )
{
int index = Phi.cols() - (i + 1);
if ( polynomialTerm )
index = Phi.cols() - 1 - dimGrid - (i + 1);
for ( int j = 0; j < n_B; j++ )
{
r = ( positions.row( index ) - positionsInterpolation.row( j ) ).norm();
Phi( j, index ) = rbfFunction->evaluate( r );
}
}
}
/*
* This function is only called by the RBFCoarsening class.
* It is assumed that the polynomial term is included in the
* interpolation, and that the fullPivLu decomposition is
* used to solve for the coefficients B.
*/
void RBFInterpolation::interpolate2(
const matrix & values,
matrix & valuesInterpolation
)
{
assert( computed );
matrix valuesLU( values.rows(), values.cols() );
// resize valuesLU if polynomial is used
if ( polynomialTerm )
{
valuesLU.conservativeResize( values.rows() + values.cols() + 1, values.cols() );
}
valuesLU.setZero(); // initialize all values zero
// Set correct part of valuesLU equal to values
if ( polynomialTerm )
{
valuesLU.topLeftCorner( values.rows(), values.cols() ) = values;
}
else
{
valuesLU = values;
}
valuesInterpolation.noalias() = Phi * lu.solve( valuesLU );
assert( valuesInterpolation.rows() == n_B );
assert( values.cols() == valuesInterpolation.cols() );
}
}

View file

@ -0,0 +1,87 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef RBFInterpolation_H
#define RBFInterpolation_H
#include <memory>
#include <Eigen/Dense>
#include "RBFFunctionInterface.H"
#include "fvCFD.H"
namespace rbf
{
typedef Eigen::Matrix<scalar, Eigen::Dynamic, Eigen::Dynamic> matrix;
typedef Eigen::Matrix<scalar, Eigen::Dynamic, 1> vector;
class RBFInterpolation
{
public:
RBFInterpolation();
explicit RBFInterpolation( std::shared_ptr<RBFFunctionInterface> rbfFunction );
RBFInterpolation(
std::shared_ptr<RBFFunctionInterface> rbfFunction,
bool polynomialTerm,
bool cpu
);
void compute(
const matrix & positions,
const matrix & positionsInterpolation
);
void interpolate(
const matrix & values,
matrix & valuesInterpolation
);
void interpolate(
const matrix & positions,
const matrix & positionsInterpolation,
const matrix & values,
matrix & valuesInterpolation
);
void interpolate2(
const matrix & values,
matrix & valuesInterpolation
);
void buildPhi(
const matrix & positions,
const matrix & positionsInterpolation
);
std::shared_ptr<RBFFunctionInterface> rbfFunction;
bool polynomialTerm;
bool cpu;
bool computed;
int n_A;
int n_B;
int dimGrid;
matrix Hhat;
matrix Phi;
Eigen::FullPivLU<matrix> lu;
matrix positions;
matrix positionsInterpolation;
private:
void evaluateH(
const matrix & positions,
matrix & H
);
void evaluatePhi(
const matrix & positions,
const matrix & positionsInterpolation,
matrix & Phi
);
};
}
#endif

View file

@ -0,0 +1,833 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#include "RBFMeshMotionSolver.H"
#include <unordered_map>
using namespace Foam;
defineTypeNameAndDebug( RBFMeshMotionSolver, 0 );
addToRunTimeSelectionTable
(
motionSolver,
RBFMeshMotionSolver,
dictionary
);
RBFMeshMotionSolver::RBFMeshMotionSolver(
const polyMesh & mesh,
Istream & msData
)
:
motionSolver( mesh ),
motionCenters( mesh.boundaryMesh().size(), vectorField( 0 ) ),
staticPatches( lookup( "staticPatches" ) ),
staticPatchIDs( staticPatches.size() ),
movingPatches( lookup( "movingPatches" ) ),
movingPatchIDs( movingPatches.size() ),
fixedPatches( lookup( "fixedPatches" ) ),
fixedPatchIDs( fixedPatches.size() ),
newPoints( mesh.points().size(), vector::zero ),
rbf( false ),
nbGlobalFaceCenters( Pstream::nProcs(), 0 ),
nbGlobalMovingFaceCenters( Pstream::nProcs(), 0 ),
nbGlobalStaticFaceCenters( Pstream::nProcs(), 0 ),
nbGlobalFixedFaceCenters( Pstream::nProcs(), 0 ),
globalMovingPointsLabelList( mesh.boundaryMesh().size(), labelList( 0 ) ),
twoDCorrector( mesh ),
nbPoints( 0 ),
faceCellCenters( true ),
cpu( false ),
// timeIntegrationScheme( false ),
corrector( false ),
k( 0 )
{
// Find IDs of staticPatches
forAll( staticPatches, patchI )
{
label patchIndex = mesh.boundaryMesh().findPatchID( staticPatches[patchI] );
assert( patchIndex >= 0 );
staticPatchIDs[patchI] = patchIndex;
}
// Find IDs of movingPatches
forAll( movingPatches, patchI )
{
label patchIndex = mesh.boundaryMesh().findPatchID( movingPatches[patchI] );
assert( patchIndex >= 0 );
movingPatchIDs[patchI] = patchIndex;
}
// Find IDs of fixedPatches
forAll( fixedPatches, patchI )
{
label patchIndex = mesh.boundaryMesh().findPatchID( fixedPatches[patchI] );
assert( patchIndex >= 0 );
fixedPatchIDs[patchI] = patchIndex;
}
// Verify that a patch is not defined as a static and a moving patch
forAll( staticPatchIDs, staticPatchI )
{
// Search the moving patches for static patchI
forAll( movingPatchIDs, movingPatchI )
{
assert( movingPatchIDs[movingPatchI] != staticPatchIDs[staticPatchI] );
}
// Search the fixed patches for static patchI
forAll( fixedPatchIDs, fixedPatchI )
{
assert( fixedPatchIDs[fixedPatchI] != staticPatchIDs[staticPatchI] );
}
}
forAll( fixedPatchIDs, fixedPatchI )
{
// Search the moving patches for fixed patchI
forAll( movingPatchIDs, movingPatchI )
{
assert( movingPatchIDs[movingPatchI] != fixedPatchIDs[fixedPatchI] );
}
}
// Initialize RBF interpolator
dictionary & dict = subDict( "interpolation" );
word function = dict.lookup( "function" );
assert( function == "TPS" || function == "WendlandC0" || function == "WendlandC2" || function == "WendlandC4" || function == "WendlandC6" );
std::shared_ptr<rbf::RBFFunctionInterface> rbfFunction;
Info << "Radial Basis Function interpolation: Selecting RBF function: " << function << endl;
if ( function == "TPS" )
rbfFunction = std::shared_ptr<rbf::RBFFunctionInterface> ( new rbf::TPSFunction() );
if ( function == "WendlandC0" )
{
scalar radius = readScalar( dict.lookup( "radius" ) );
rbfFunction = std::shared_ptr<rbf::RBFFunctionInterface> ( new rbf::WendlandC0Function( radius ) );
}
if ( function == "WendlandC2" )
{
scalar radius = readScalar( dict.lookup( "radius" ) );
rbfFunction = std::shared_ptr<rbf::RBFFunctionInterface> ( new rbf::WendlandC2Function( radius ) );
}
if ( function == "WendlandC4" )
{
scalar radius = readScalar( dict.lookup( "radius" ) );
rbfFunction = std::shared_ptr<rbf::RBFFunctionInterface> ( new rbf::WendlandC4Function( radius ) );
}
if ( function == "WendlandC6" )
{
scalar radius = readScalar( dict.lookup( "radius" ) );
rbfFunction = std::shared_ptr<rbf::RBFFunctionInterface> ( new rbf::WendlandC6Function( radius ) );
}
assert( rbfFunction );
bool polynomialTerm = dict.lookupOrDefault( "polynomial", false );
bool cpu = dict.lookupOrDefault( "cpu", false );
this->cpu = dict.lookupOrDefault( "fullCPU", false );
std::shared_ptr<rbf::RBFInterpolation> rbfInterpolator( new rbf::RBFInterpolation( rbfFunction, polynomialTerm, cpu ) );
if ( this->cpu == true )
assert( cpu == true );
bool coarsening = readBool( subDict( "coarsening" ).lookup( "enabled" ) );
scalar tol = 0.1;
scalar tolLivePointSelection = 0.1;
bool livePointSelection = false;
bool exportSelectedPoints = false;
int coarseningMinPoints = 1;
int coarseningMaxPoints = 2;
bool twoPointSelection = false;
bool surfaceCorrection = false;
scalar ratioRadiusError = 10.0;
if ( coarsening )
{
tol = readScalar( subDict( "coarsening" ).lookup( "tol" ) );
coarseningMinPoints = readLabel( subDict( "coarsening" ).lookup( "minPoints" ) );
coarseningMaxPoints = readLabel( subDict( "coarsening" ).lookup( "maxPoints" ) );
livePointSelection = readBool( subDict( "coarsening" ).lookup( "livePointSelection" ) );
exportSelectedPoints = readBool( subDict( "coarsening" ).lookup( "exportSelectedPoints" ) );
twoPointSelection = subDict( "coarsening" ).lookupOrDefault( "twoPointSelection", false );
}
if ( livePointSelection )
{
tolLivePointSelection = readScalar( subDict( "coarsening" ).lookup( "tolLivePointSelection" ) );
surfaceCorrection = subDict( "coarsening" ).lookupOrDefault( "surfaceCorrection", false );
if ( surfaceCorrection )
{
ratioRadiusError = subDict( "coarsening" ).lookupOrDefault( "ratioRadiusError", 10.0 );
}
}
rbf = std::shared_ptr<rbf::RBFCoarsening> ( new rbf::RBFCoarsening( rbfInterpolator, coarsening, livePointSelection, true, tol, tolLivePointSelection, coarseningMinPoints, coarseningMaxPoints, twoPointSelection, surfaceCorrection, ratioRadiusError, exportSelectedPoints ) );
faceCellCenters = lookupOrDefault( "faceCellCenters", true );
Info << "RBF mesh deformation settings:" << endl;
Info << " interpolation function = " << function << endl;
Info << " interpolation polynomial term = " << polynomialTerm << endl;
Info << " interpolation cpu formulation = " << cpu << endl;
Info << " coarsening = " << coarsening << endl;
Info << " coarsening tolerance = " << tol << endl;
Info << " coarsening reselection tolerance = " << tolLivePointSelection << endl;
Info << " coarsening two-point selection = " << twoPointSelection << endl;
}
RBFMeshMotionSolver::~RBFMeshMotionSolver()
{}
tmp<pointField> RBFMeshMotionSolver::curPoints() const
{
// Prepare new points: same as old point
tmp<pointField> tnewPoints
(
new vectorField( mesh().nPoints(), vector::zero )
);
pointField & newPoints = tnewPoints();
newPoints = this->newPoints;
// Add old point positions
newPoints += mesh().points();
return tnewPoints;
}
// As a first step, the motion is defined in the
void RBFMeshMotionSolver::setMotion( const Field<vectorField> & motion )
{
// Input checking
assert( motion.size() == mesh().boundaryMesh().size() );
forAll( motion, ipatch )
{
const vectorField & mpatch = motion[ipatch];
// Check whether the size of patch motion is equal to number of face centers in patch
if ( faceCellCenters && mpatch.size() > 0 )
assert( mpatch.size() == mesh().boundaryMesh()[ipatch].faceCentres().size() );
if ( not faceCellCenters && mpatch.size() > 0 )
assert( mpatch.size() == mesh().boundaryMesh()[ipatch].meshPoints().size() );
// Check whether the size of a moving patch is equal to the number of face centers in the patch
// First check if patchid is a moving patch
bool movingPatch = false;
forAll( movingPatchIDs, movingPatchI )
{
if ( movingPatchIDs[movingPatchI] == ipatch )
movingPatch = true;
}
if ( faceCellCenters && movingPatch )
assert( mpatch.size() == mesh().boundaryMesh()[ipatch].faceCentres().size() );
if ( not faceCellCenters && movingPatch )
assert( mpatch.size() == mesh().boundaryMesh()[ipatch].meshPoints().size() );
}
motionCenters = motion;
}
void RBFMeshMotionSolver::updateMesh( const mapPolyMesh & )
{
assert( false );
}
void RBFMeshMotionSolver::solve()
{
assert( motionCenters.size() == mesh().boundaryMesh().size() );
/*
* RBF interpolator from face centers to local complete mesh vertices
* The interpolation consists of the following steps:
* 1. Build a matrix with the face center positions of the static patches and the moving patches
* 2. Build a matrix with the positions of every vertex in the local mesh
* 3. Build a matrix with the displacement/motion of the face center positions of the static patches and the moving patches
* 4. Perform the interpolation from the face centers to the complete mesh
* 5. Correct the mesh vertices of the static patches. Set these displacement to zero.
* 6. Set the motion of the mesh vertices
*/
/*
* Step 1: Build a matrix with the face center positions of the static patches and the moving patches
* The order of the matrix is defined as first a list of the moving patch face centers,
* thereafter the static patch face centers. These are the control points used by the
* radial basis function interpolation.
* The control points should be exactly the same at each processor, and are therefore communicated
* to each process. As only an absolute RBF interpolation is implemented, this communication step is only
* performed once per simulation.
* The global ordering of the data is first the information of the moving patches,
* thereafter the static patches.
*/
unsigned int nbFaceCenters = 0;
unsigned int nbMovingFaceCenters = 0;
unsigned int nbStaticFaceCenters = 0;
unsigned int nbFixedFaceCenters = 0;
std::unordered_map<unsigned int, unsigned int> staticControlPointLabels;
std::unordered_map<unsigned int, unsigned int> fixedControlPointLabels;
std::vector<unsigned int> movingControlPointLabelsVector;
std::unordered_map<unsigned int, unsigned int> movingControlPointLabelsMap;
std::vector<unsigned int> movingControlPointPatchIds;
std::vector<unsigned int> movingControlPointIndices;
std::unordered_map<unsigned int, unsigned int> staticControlGlobalPointLabels;
std::unordered_map<unsigned int, unsigned int> fixedControlGlobalPointLabels;
std::unordered_map<unsigned int, unsigned int> movingControlGlobalPointLabelsMap;
labelList globalStaticPointsListEnabled( nbStaticFaceCenters, 0 );
labelList globalFixedPointsListEnabled( nbFixedFaceCenters, 0 );
labelList globalMovingPointsListEnabled( nbMovingFaceCenters, 0 );
unsigned int globalStaticOffsetNonUnique = 0;
unsigned int globalFixedOffsetNonUnique = 0;
unsigned int globalMovingOffsetNonUnique = 0;
if ( sum( nbGlobalFaceCenters ) == 0 )
{
// Determine the number of face centers
// The total number of face centers is simply the sum of the face centers
// on each processor.
nbFaceCenters = 0;
// First add the static patches, thereafter the fixed patches, and
// the moving patches as last.
forAll( staticPatchIDs, i )
{
const labelList & meshPoints = mesh().boundaryMesh()[staticPatchIDs[i]].meshPoints();
forAll( meshPoints, j )
{
if ( twoDCorrector.marker()[meshPoints[j]] != 0 )
continue;
if ( staticControlPointLabels.find( meshPoints[j] ) == staticControlPointLabels.end() )
staticControlPointLabels[meshPoints[j]] = staticControlPointLabels.size() - 1;
}
}
nbStaticFaceCenters = staticControlPointLabels.size();
forAll( fixedPatchIDs, i )
{
const labelList & meshPoints = mesh().boundaryMesh()[fixedPatchIDs[i]].meshPoints();
forAll( meshPoints, j )
{
if ( twoDCorrector.marker()[meshPoints[j]] != 0 )
continue;
if ( staticControlPointLabels.find( meshPoints[j] ) == staticControlPointLabels.end()
&& fixedControlPointLabels.find( meshPoints[j] ) == fixedControlPointLabels.end() )
fixedControlPointLabels[meshPoints[j]] = fixedControlPointLabels.size() - 1;
}
}
nbFixedFaceCenters = fixedControlPointLabels.size();
if ( faceCellCenters )
{
forAll( movingPatchIDs, i )
{
nbMovingFaceCenters += mesh().boundaryMesh()[movingPatchIDs[i]].faceCentres().size();
}
}
if ( not faceCellCenters )
{
forAll( movingPatchIDs, patchI )
{
const labelList & meshPoints = mesh().boundaryMesh()[movingPatchIDs[patchI]].meshPoints();
globalMovingPointsLabelList[movingPatchIDs[patchI]] = labelList( meshPoints.size(), 0 );
forAll( meshPoints, j )
{
if ( twoDCorrector.marker()[meshPoints[j]] != 0 )
continue;
if ( staticControlPointLabels.find( meshPoints[j] ) == staticControlPointLabels.end()
&& fixedControlPointLabels.find( meshPoints[j] ) == fixedControlPointLabels.end()
&& movingControlPointLabelsMap.find( meshPoints[j] ) == movingControlPointLabelsMap.end() )
{
movingControlPointLabelsMap[meshPoints[j]] = movingControlPointLabelsMap.size() - 1;
movingControlPointLabelsVector.push_back( meshPoints[j] );
movingControlPointPatchIds.push_back( movingPatchIDs[patchI] );
movingControlPointIndices.push_back( j );
globalMovingPointsLabelList[movingPatchIDs[patchI]][j] = 1;
}
}
}
nbMovingFaceCenters = movingControlPointLabelsVector.size();
}
if ( Pstream::nProcs() == 1 )
{
globalStaticPointsListEnabled.resize( nbStaticFaceCenters );
globalStaticPointsListEnabled = 1;
globalFixedPointsListEnabled.resize( nbFixedFaceCenters );
globalFixedPointsListEnabled = 1;
globalMovingPointsListEnabled.resize( nbMovingFaceCenters );
globalMovingPointsListEnabled = 1;
}
if ( Pstream::nProcs() > 1 )
{
IOobject addrHeader
(
"pointProcAddressing",
mesh().facesInstance(),
mesh().meshSubDir,
mesh(),
IOobject::MUST_READ
);
assert( addrHeader.headerOk() );
labelIOList pointProcAddressing( addrHeader );
assert( pointProcAddressing.size() == mesh().points().size() );
// Count the number of global static points including scalar points
nbGlobalStaticFaceCenters[Pstream::myProcNo()] = nbStaticFaceCenters;
nbGlobalFixedFaceCenters[Pstream::myProcNo()] = nbFixedFaceCenters;
nbGlobalMovingFaceCenters[Pstream::myProcNo()] = nbMovingFaceCenters;
reduce( nbGlobalStaticFaceCenters, sumOp<labelList>() );
reduce( nbGlobalFixedFaceCenters, sumOp<labelList>() );
reduce( nbGlobalMovingFaceCenters, sumOp<labelList>() );
nbStaticFaceCenters = sum( nbGlobalStaticFaceCenters );
nbFixedFaceCenters = sum( nbGlobalFixedFaceCenters );
if ( not faceCellCenters )
nbMovingFaceCenters = sum( nbGlobalMovingFaceCenters );
// Construct a list with all the global point labels, thus including
// also scalar points. Thereafter, construct a list of static control
// list which indicates whether the point is already included or not.
// Use this later to build a list of the unique static control points.
labelList globalStaticPointsList( nbStaticFaceCenters, 0 );
labelList globalFixedPointsList( nbFixedFaceCenters, 0 );
labelList globalMovingPointsList( nbMovingFaceCenters, 0 );
labelList globalMovingPointsPatchIds( nbMovingFaceCenters, 0 );
labelList globalMovingPointsIndices( nbMovingFaceCenters, 0 );
globalStaticOffsetNonUnique = 0;
for ( int i = 0; i < Pstream::myProcNo(); i++ )
globalStaticOffsetNonUnique += nbGlobalStaticFaceCenters[i];
globalFixedOffsetNonUnique = 0;
for ( int i = 0; i < Pstream::myProcNo(); i++ )
globalFixedOffsetNonUnique += nbGlobalFixedFaceCenters[i];
globalMovingOffsetNonUnique = 0;
for ( int i = 0; i < Pstream::myProcNo(); i++ )
globalMovingOffsetNonUnique += nbGlobalMovingFaceCenters[i];
for ( auto label : staticControlPointLabels )
{
globalStaticPointsList[label.second + globalStaticOffsetNonUnique] = pointProcAddressing[label.first];
}
for ( auto label : fixedControlPointLabels )
{
globalFixedPointsList[label.second + globalFixedOffsetNonUnique] = pointProcAddressing[label.first];
}
for ( unsigned int i = 0; i < movingControlPointLabelsVector.size(); ++i )
{
globalMovingPointsList[i + globalMovingOffsetNonUnique] = pointProcAddressing[movingControlPointLabelsVector[i]];
globalMovingPointsPatchIds[i + globalMovingOffsetNonUnique] = movingControlPointPatchIds[i];
globalMovingPointsIndices[i + globalMovingOffsetNonUnique] = movingControlPointIndices[i];
}
reduce( globalStaticPointsList, sumOp<labelList>() );
reduce( globalFixedPointsList, sumOp<labelList>() );
if ( not faceCellCenters )
{
reduce( globalMovingPointsList, sumOp<labelList>() );
reduce( globalMovingPointsPatchIds, sumOp<labelList>() );
reduce( globalMovingPointsIndices, sumOp<labelList>() );
}
// Construct a list of static control points which indicate whether
// should be included or not.
globalStaticPointsListEnabled.resize( nbStaticFaceCenters );
globalStaticPointsListEnabled = 0;
globalFixedPointsListEnabled.resize( nbFixedFaceCenters );
globalFixedPointsListEnabled = 0;
globalMovingPointsListEnabled.resize( nbMovingFaceCenters );
globalMovingPointsListEnabled = 0;
forAll( globalStaticPointsList, i )
{
if ( staticControlGlobalPointLabels.find( globalStaticPointsList[i] ) == staticControlGlobalPointLabels.end() )
{
staticControlGlobalPointLabels[globalStaticPointsList[i]] = staticControlGlobalPointLabels.size() - 1;
globalStaticPointsListEnabled[i] = 1;
}
}
forAll( globalFixedPointsList, i )
{
if ( staticControlGlobalPointLabels.find( globalFixedPointsList[i] ) == staticControlGlobalPointLabels.end()
&& fixedControlGlobalPointLabels.find( globalFixedPointsList[i] ) == fixedControlGlobalPointLabels.end() )
{
fixedControlGlobalPointLabels[globalFixedPointsList[i]] = fixedControlGlobalPointLabels.size() - 1;
globalFixedPointsListEnabled[i] = 1;
}
}
if ( not faceCellCenters )
{
forAll( movingPatchIDs, patchI )
{
const labelList & meshPoints = mesh().boundaryMesh()[movingPatchIDs[patchI]].meshPoints();
globalMovingPointsLabelList[movingPatchIDs[patchI]] = labelList( meshPoints.size(), 0 );
}
forAll( globalMovingPointsList, i )
{
if ( staticControlGlobalPointLabels.find( globalMovingPointsList[i] ) == staticControlGlobalPointLabels.end()
&& fixedControlGlobalPointLabels.find( globalMovingPointsList[i] ) == fixedControlGlobalPointLabels.end()
&& movingControlGlobalPointLabelsMap.find( globalMovingPointsList[i] ) == movingControlGlobalPointLabelsMap.end() )
{
movingControlGlobalPointLabelsMap[globalMovingPointsList[i]] = movingControlGlobalPointLabelsMap.size() - 1;
globalMovingPointsListEnabled[i] = 1;
if ( static_cast<unsigned int>(i) < movingControlPointLabelsVector.size() + globalMovingOffsetNonUnique
&& static_cast<unsigned int>(i) >= globalMovingOffsetNonUnique )
{
label patchId = globalMovingPointsPatchIds[i];
label index = globalMovingPointsIndices[i];
globalMovingPointsLabelList[patchId][index] = 1;
}
}
}
}
// Count the number of local unique static points
nbStaticFaceCenters = 0;
for ( auto label : staticControlPointLabels )
{
if ( globalStaticPointsListEnabled[label.second + globalStaticOffsetNonUnique] == 1 )
nbStaticFaceCenters++;
}
nbFixedFaceCenters = 0;
for ( auto label : fixedControlPointLabels )
{
if ( globalFixedPointsListEnabled[label.second + globalFixedOffsetNonUnique] == 1 )
nbFixedFaceCenters++;
}
if ( not faceCellCenters )
{
nbMovingFaceCenters = 0;
for ( unsigned int i = 0; i < movingControlPointLabelsVector.size(); ++i )
{
if ( globalMovingPointsListEnabled[i + globalMovingOffsetNonUnique] == 1 )
nbMovingFaceCenters++;
}
}
}
// Calculate sum of all faces on each processor
nbGlobalStaticFaceCenters = 0;
nbGlobalFixedFaceCenters = 0;
nbGlobalMovingFaceCenters = 0;
nbGlobalMovingFaceCenters[Pstream::myProcNo()] = nbMovingFaceCenters;
nbGlobalStaticFaceCenters[Pstream::myProcNo()] = nbStaticFaceCenters;
nbGlobalFixedFaceCenters[Pstream::myProcNo()] = nbFixedFaceCenters;
nbGlobalFaceCenters[Pstream::myProcNo()] = nbMovingFaceCenters + nbStaticFaceCenters + nbFixedFaceCenters;
reduce( nbGlobalMovingFaceCenters, sumOp<labelList>() );
reduce( nbGlobalStaticFaceCenters, sumOp<labelList>() );
reduce( nbGlobalFixedFaceCenters, sumOp<labelList>() );
reduce( nbGlobalFaceCenters, sumOp<labelList>() );
}
nbMovingFaceCenters = sum( nbGlobalMovingFaceCenters );
nbStaticFaceCenters = sum( nbGlobalStaticFaceCenters );
nbFixedFaceCenters = sum( nbGlobalFixedFaceCenters );
nbFaceCenters = sum( nbGlobalFaceCenters );
// Determine the offset taking into account multiple processors
int globalMovingOffset = 0;
for ( int i = 0; i < Pstream::myProcNo(); i++ )
globalMovingOffset += nbGlobalMovingFaceCenters[i];
int globalStaticOffset = nbMovingFaceCenters;
for ( int i = 0; i < Pstream::myProcNo(); i++ )
globalStaticOffset += nbGlobalStaticFaceCenters[i];
int globalFixedOffset = nbMovingFaceCenters + nbStaticFaceCenters;
for ( int i = 0; i < Pstream::myProcNo(); i++ )
globalFixedOffset += nbGlobalFixedFaceCenters[i];
if ( !rbf->rbf->computed )
{
rbf::matrix positions( nbFaceCenters, mesh().nGeometricD() );
positions.setZero();
const Foam::pointField & points = mesh().points();
vectorField positionsField( positions.rows(), vector::zero );
if ( faceCellCenters )
{
int offset = 0;
forAll( movingPatchIDs, i )
{
const Foam::vectorField::subField faceCentres = mesh().boundaryMesh()[movingPatchIDs[i]].faceCentres();
// Set the positions for patch i
forAll( faceCentres, j )
{
positionsField[j + offset + globalMovingOffset] = faceCentres[j];
}
offset += faceCentres.size();
}
}
int index = 0;
if ( not faceCellCenters )
{
for ( unsigned int i = 0; i < movingControlPointLabelsVector.size(); ++i )
{
if ( globalMovingPointsListEnabled[i + globalMovingOffsetNonUnique] == 1 )
{
assert( index + globalMovingOffset < positionsField.size() );
positionsField[index + globalMovingOffset] = points[movingControlPointLabelsVector[i]];
index++;
}
}
assert( index == nbGlobalMovingFaceCenters[Pstream::myProcNo()] );
}
index = 0;
for ( auto label : staticControlPointLabels )
{
if ( globalStaticPointsListEnabled[label.second + globalStaticOffsetNonUnique] == 1 )
{
positionsField[index + globalStaticOffset] = points[label.first];
index++;
}
}
assert( index == nbGlobalStaticFaceCenters[Pstream::myProcNo()] );
index = 0;
for ( auto label : fixedControlPointLabels )
{
if ( globalFixedPointsListEnabled[label.second + globalFixedOffsetNonUnique] == 1 )
{
assert( index + globalFixedOffset < positionsField.size() );
positionsField[index + globalFixedOffset] = points[label.first];
index++;
}
}
assert( index == nbGlobalFixedFaceCenters[Pstream::myProcNo()] );
reduce( positionsField, sumOp<vectorField>() );
// Copy the FOAM vector field to an Eigen matrix
for ( int i = 0; i < positions.rows(); i++ )
for ( int j = 0; j < positions.cols(); j++ )
positions( i, j ) = positionsField[i][j];
/*
* Step 2: Build a matrix with the positions of every vertex in the local mesh.
* This is only local information and does not need to be communicated to other
* processors.
*/
// Determine the number of points by using the 2d corrector
nbPoints = 0;
forAll( points, i )
{
if ( twoDCorrector.marker()[i] == 0 )
nbPoints++;
}
rbf::matrix positionsInterpolation( nbPoints, positions.cols() );
index = 0;
forAll( points, i )
{
if ( twoDCorrector.marker()[i] == 0 )
{
for ( int j = 0; j < positionsInterpolation.cols(); j++ )
positionsInterpolation( index, j ) = points[i][j];
index++;
}
}
rbf->compute( positions, positionsInterpolation );
rbf->setNbMovingAndStaticFaceCenters( nbMovingFaceCenters, nbStaticFaceCenters + nbFixedFaceCenters );
}
/*
* Step 3: Build a matrix with the displacement/motion of the face center
* positions of the static patches and the moving patches.
* The motion needs to be communicated to every process at every mesh deformation.
* This is considered to be the most expensive step with regards to parallel
* scalability of the overall algorithm.
*/
rbf::matrix values( nbFaceCenters, mesh().nGeometricD() );
values.setZero();
vectorField valuesField( values.rows(), vector::zero );
if ( faceCellCenters )
{
int offset = 0;
forAll( movingPatchIDs, i )
{
const Foam::vectorField::subField faceCentres = mesh().boundaryMesh()[movingPatchIDs[i]].faceCentres();
forAll( motionCenters[movingPatchIDs[i]], j )
{
valuesField[j + offset + globalMovingOffset] = motionCenters[movingPatchIDs[i]][j];
}
offset += faceCentres.size();
}
}
if ( not faceCellCenters )
{
int index = 0;
forAll( movingPatchIDs, patchI )
{
forAll( globalMovingPointsLabelList[movingPatchIDs[patchI]], j )
{
if ( globalMovingPointsLabelList[movingPatchIDs[patchI]][j] == 1 )
{
valuesField[index + globalMovingOffset] = motionCenters[movingPatchIDs[patchI]][j];
index++;
}
}
}
assert( index == nbGlobalMovingFaceCenters[Pstream::myProcNo()] );
}
reduce( valuesField, sumOp<vectorField>() );
// Copy the FOAM vector field to an Eigen matrix
for ( int i = 0; i < values.rows(); i++ )
for ( int j = 0; j < values.cols(); j++ )
values( i, j ) = valuesField[i][j];
/*
* Step 4: Perform the interpolation from the face centers to the complete mesh
*/
rbf::matrix valuesInterpolation( nbPoints, values.cols() );
valuesInterpolation.setZero();
if ( cpu )
rbf->rbf->computed = false;
rbf->interpolate( values, valuesInterpolation );
// Apply the 2d correction
vectorField valuesInterpolationField( mesh().points().size(), Foam::vector::zero );
int index = 0;
forAll( valuesInterpolationField, i )
{
if ( twoDCorrector.marker()[i] == 0 )
{
for ( int j = 0; j < valuesInterpolation.cols(); j++ )
valuesInterpolationField[i][j] = valuesInterpolation( index, j );
index++;
}
}
twoDCorrector.setShadowSide( valuesInterpolationField );
/*
* Step 5: Correct the mesh vertices of the fixed patches. Set these displacements to zero.
*/
// Loop over all the patches, and set the fixed patches to zero.
forAll( mesh().boundaryMesh(), i )
{
const labelList & meshPoints = mesh().boundaryMesh()[i].meshPoints();
bool isFixedPatch = false;
forAll( fixedPatchIDs, j )
{
if ( i == fixedPatchIDs[j] )
isFixedPatch = true;
}
if ( isFixedPatch )
{
for ( int j = 0; j < meshPoints.size(); j++ )
valuesInterpolationField[meshPoints[j]] = Foam::vector::zero;
}
}
/*
* Step 6: Set the motion of the mesh vertices
*/
assert( newPoints.size() == valuesInterpolationField.size() );
newPoints = valuesInterpolationField;
}

View file

@ -0,0 +1,97 @@
/*
* Author
* David Blom, TU Delft. All rights reserved.
*/
#ifndef RBFMeshMotionSolver_H
#define RBFMeshMotionSolver_H
#include "motionSolver.H"
#include "polyMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "RBFInterpolation.H"
#include "RBFCoarsening.H"
#include "TPSFunction.H"
#include "WendlandC0Function.H"
#include "WendlandC2Function.H"
#include "WendlandC4Function.H"
#include "WendlandC6Function.H"
#include "twoDPointCorrectorRBF.H"
#include <memory>
#include <assert.h>
// #include "TimeIntegrationScheme.H"
namespace Foam
{
class RBFMeshMotionSolver : public motionSolver
{
protected:
// Disallow default bitwise copy construct
RBFMeshMotionSolver( const RBFMeshMotionSolver & );
// Disallow default bitwise assignment
void operator=( const RBFMeshMotionSolver & );
Field<vectorField> motionCenters;
wordList staticPatches;
labelList staticPatchIDs;
wordList movingPatches;
labelList movingPatchIDs;
wordList fixedPatches;
labelList fixedPatchIDs;
pointField newPoints;
std::shared_ptr<rbf::RBFCoarsening> rbf;
labelList nbGlobalFaceCenters;
labelList nbGlobalMovingFaceCenters;
labelList nbGlobalStaticFaceCenters;
labelList nbGlobalFixedFaceCenters;
List<labelList> globalMovingPointsLabelList;
// 2d corrector
twoDPointCorrectorRBF twoDCorrector;
int nbPoints;
bool faceCellCenters;
bool cpu;
public:
// Runtime type information
TypeName( "RBFMeshMotionSolver" );
// Constructors
// Construct from polyMesh
RBFMeshMotionSolver(
const polyMesh & mesh,
Istream & msData
);
// Destructor
virtual ~RBFMeshMotionSolver();
// Set the motion of every boundary patch, where m is equal to number of patches and with non-empty vectorFields for moving patches.
// The motion is defined at the face centers of the boundary patch.
void setMotion( const Field<vectorField> & motion );
// Return point location obtained from the current motion field
virtual tmp<pointField> curPoints() const;
// Solve for motion
virtual void solve();
// Update the mesh corresponding to given map
virtual void updateMesh( const mapPolyMesh & );
// std::shared_ptr<sdc::TimeIntegrationScheme> timeIntegrationScheme;
bool corrector;
int k;
};
}
#endif

View file

@ -0,0 +1,98 @@
#include "twoDPointCorrectorRBF.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Set marker to -1 if is on the "back" side
void twoDPointCorrectorRBF::setMarker()
{
if ( !required() )
return;
// Change size of useablePointIDs_ and shadowPointIDs_
useablePointIDs_.setSize( mesh_.nPoints() / 2 );
shadowPointIDs_.setSize( mesh_.nPoints() / 2 );
// Get reference to edges
const edgeList & meshEdges = mesh_.edges();
const pointField & points( mesh_.points() );
const labelList & neIndices = normalEdgeIndices();
const vector & pn = planeNormal();
forAll( neIndices, edgeI )
{
const label & pStartInd = meshEdges[neIndices[edgeI]].start();
const label & pEndInd = meshEdges[neIndices[edgeI]].end();
const point & pStart = points[pStartInd];
const point & pEnd = points[pEndInd];
// calculate average point position
const point A = 0.5 * (pStart + pEnd);
// Calculate inner product with plane normal
scalar pStartInner = ( pn & (pStart - A) );
scalar pEndInner = ( pn & (pEnd - A) );
if ( pStartInner > 0 && pEndInner < 0 )
{
pointMarker_[pEndInd] = -1;
useablePointIDs_[edgeI] = pStartInd;
shadowPointIDs_[edgeI] = pEndInd;
}
else
if ( pEndInner > 0 && pStartInner < 0 )
{
pointMarker_[pStartInd] = -1;
useablePointIDs_[edgeI] = pEndInd;
shadowPointIDs_[edgeI] = pStartInd;
}
else
{
FatalErrorIn( "void twoDPointCorrectorRBF::setMarker()" )
<< "Both points give back a negative value with the inner product. Programming error?"
<< abort( FatalError );
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
twoDPointCorrectorRBF::twoDPointCorrectorRBF( const polyMesh & mesh )
:
twoDPointCorrector( mesh ),
mesh_( mesh ),
pointMarker_( mesh.nPoints(), 0 ),
useablePointIDs_( mesh.nPoints(), 0 ),
shadowPointIDs_( mesh.nPoints(), 0 )
{
setMarker();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
twoDPointCorrectorRBF::~twoDPointCorrectorRBF()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const labelList & twoDPointCorrectorRBF::marker() const
{
return pointMarker_;
}
void twoDPointCorrectorRBF::setShadowSide( vectorField & newpoints ) const
{
forAll( useablePointIDs_, ipoint )
{
newpoints[shadowPointIDs_[ipoint]] = newpoints[useablePointIDs_[ipoint]];
}
}
} // End namespace Foam

View file

@ -0,0 +1,71 @@
#ifndef twoDPointCorrectorRBF_H
#define twoDPointCorrectorRBF_H
#include "pointField.H"
#include "labelList.H"
#include "vector.H"
#include "twoDPointCorrector.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward class declarations
class polyMesh;
/*---------------------------------------------------------------------------*\
* Class twoDPointCorrectorRBF Declaration
\*---------------------------------------------------------------------------*/
class twoDPointCorrectorRBF
:
public twoDPointCorrector
{
// Private data
// - Reference to moving mesh
const polyMesh & mesh_;
// - Holder for marker value: -1 if on "back" side and 0 otherwise
labelList pointMarker_;
// - Point IDs marked with 0
labelList useablePointIDs_;
// - Point IDs marked with -1
labelList shadowPointIDs_;
// Private Member Functions
// - Disallow default bitwise copy construct
twoDPointCorrectorRBF( const twoDPointCorrectorRBF & );
// - Disallow default bitwise assignment
void operator=( const twoDPointCorrectorRBF & );
void setMarker();
public:
// Constructors
// - Construct from components
twoDPointCorrectorRBF( const polyMesh & mesh );
// Destructor
virtual ~twoDPointCorrectorRBF();
// Member Functions
const labelList & marker() const;
void setShadowSide( vectorField & newpoints ) const;
};
} // End namespace Foam
#endif

View file

@ -0,0 +1,282 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "EulerDdtScheme.H"
#include "surfaceInterpolate.H"
#include "fvcDiv.H"
#include "fvMatrices.H"
#include "slipFvPatchFields.H"
#include "symmetryFvPatchFields.H"
#include "wedgeFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fv
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<>
tmp<GeometricField<vector, fvPatchField, volMesh> >
EulerDdtScheme<vector>::fvcDdt
(
const GeometricField<vector, fvPatchField, volMesh>& vf
)
{
dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
IOobject ddtIOobject
(
"ddt("+vf.name()+')',
mesh().time().timeName(),
mesh()
);
if (mesh().moving())
{
if
(
mesh().objectRegistry::found("grad(" + vf.name() + ")")
&& mesh().objectRegistry::found("meshU")
)
{
const volTensorField& gradVf =
mesh().objectRegistry::lookupObject<volTensorField>
(
"grad(" + vf.name() + ")"
);
const volVectorField& meshU =
mesh().objectRegistry::lookupObject<volVectorField>
(
"meshU"
);
return tmp<GeometricField<vector, fvPatchField, volMesh> >
(
new GeometricField<vector, fvPatchField, volMesh>
(
ddtIOobject,
rDeltaT*(vf - vf.oldTime()) - (meshU&gradVf.oldTime())
)
);
}
else
{
return tmp<GeometricField<vector, fvPatchField, volMesh> >
(
new GeometricField<vector, fvPatchField, volMesh>
(
ddtIOobject,
rDeltaT*(vf - vf.oldTime())
)
);
}
// return tmp<GeometricField<vector, fvPatchField, volMesh> >
// (
// new GeometricField<vector, fvPatchField, volMesh>
// (
// ddtIOobject,
// mesh(),
// rDeltaT.dimensions()*vf.dimensions(),
// rDeltaT.value()*
// (
// vf.internalField()
// - vf.oldTime().internalField()
// ),
// rDeltaT.value()*
// (
// vf.boundaryField() - vf.oldTime().boundaryField()
// )
// )
// );
}
else
{
return tmp<GeometricField<vector, fvPatchField, volMesh> >
(
new GeometricField<vector, fvPatchField, volMesh>
(
ddtIOobject,
rDeltaT*(vf - vf.oldTime())
)
);
}
}
template<>
tmp<surfaceScalarField> EulerDdtScheme<vector>::fvcDdtPhiCorr
(
const volScalarField& rA,
const GeometricField<vector, fvPatchField, volMesh>& U,
const surfaceScalarField& phi
)
{
dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
IOobject ddtIOobject
(
"ddtPhiCorr(" + rA.name() + ',' + U.name() + ',' + phi.name() + ')',
mesh().time().timeName(),
mesh()
);
surfaceScalarField ddtPhiCoeff
(
IOobject
(
"ddtPhiCoeff",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensioned<scalar>("1", dimless, 1.0)
);
forAll(U.boundaryField(), patchI)
{
if
(
U.boundaryField()[patchI].fixesValue()
|| isA<symmetryFvPatchVectorField>(U.boundaryField()[patchI])
|| isA<slipFvPatchVectorField>(U.boundaryField()[patchI])
|| isA<wedgeFvPatchVectorField>(U.boundaryField()[patchI])
)
{
ddtPhiCoeff.boundaryField()[patchI] = 0.0;
}
}
if (mesh().moving())
{
Info << "Moving mesh ddtPhiCorr " << U.name() << endl;
volScalarField V0oV
(
IOobject
(
"V0oV",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimless,
zeroGradientFvPatchScalarField::typeName
);
V0oV.internalField() = mesh().V0()/mesh().V();
V0oV.correctBoundaryConditions();
const surfaceVectorField& Sf =
mesh().objectRegistry::lookupObject<surfaceVectorField>("Sf");
// Non-conservative cell-face velocity
surfaceVectorField U0 =
fvc::interpolate(V0oV*U.oldTime(), "interpolate(U)");
forAll(U0.boundaryField(), patchI)
{
if (!U.boundaryField()[patchI].coupled())
{
U0.boundaryField()[patchI] =
U.oldTime().boundaryField()[patchI]
.patchInternalField()
*V0oV.boundaryField()[patchI];
}
}
// Conservataive cell-face velocity
surfaceVectorField U0c =
fvc::interpolate(U.oldTime(), "interpolate(U)");
U0c -= (Sf.oldTime()&U0c)*Sf.oldTime()/magSqr(Sf.oldTime());
U0c += phi.oldTime()*Sf.oldTime()/magSqr(Sf.oldTime());
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
ddtIOobject,
rDeltaT*ddtPhiCoeff
*((fvc::interpolate(V0oV)*U0c - U0) & mesh().Sf())
/fvc::interpolate(1/rA, "interpolate(U)")
)
);
}
else
{
Info << "Fixed mesh ddtPhiCorr " << U.name() << endl;
// Non-conservative cell-face velocity
surfaceVectorField U0 =
fvc::interpolate(U.oldTime(), "interpolate(U)");
forAll(U0.boundaryField(), patchI)
{
if (!U.boundaryField()[patchI].coupled())
{
U0.boundaryField()[patchI] =
U.oldTime().boundaryField()[patchI]
.patchInternalField();
}
}
// Conservataive cell-face velocity
surfaceVectorField U0c = U0;
// fvc::interpolate(U.oldTime(), "interpolate(U)");
U0c -= (mesh().Sf() & U0c)*mesh().Sf()/magSqr(mesh().Sf());
U0c += phi.oldTime()*mesh().Sf()/magSqr(mesh().Sf());
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
ddtIOobject,
rDeltaT*ddtPhiCoeff
*((U0c - U0) & mesh().Sf())
/fvc::interpolate(1/rA, "interpolate(U)")
)
);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,421 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "backwardDdtScheme.H"
#include "surfaceInterpolate.H"
#include "fvcDiv.H"
#include "fvMatrices.H"
#include "symmetryFvPatchFields.H"
#include "slipFvPatchFields.H"
#include "wedgeFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fv
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// template<>
// tmp<fvMatrix<vector> >
// backwardDdtScheme<vector>::fvmDdt
// (
// GeometricField<vector, fvPatchField, volMesh>& vf
// )
// {
// tmp<fvMatrix<vector> > tfvm
// (
// new fvMatrix<vector>
// (
// vf,
// vf.dimensions()*dimVol/dimTime
// )
// );
// fvMatrix<vector>& fvm = tfvm();
// scalar rDeltaT = 1.0/deltaT_();
// scalar deltaT = deltaT_();
// scalar deltaT0 = deltaT0_(vf);
// scalar coefft = 1 + deltaT/(deltaT + deltaT0);
// scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
// scalar coefft0 = coefft + coefft00;
// fvm.diag() = rDeltaT*mesh().V();
// // fvm.diag() = (coefft*rDeltaT)*mesh().V();
// if (mesh().moving())
// {
// Info << "Corrected backward ddt" << endl;
// fvm.source() = rDeltaT*
// (
// vf.oldTime().internalField()*mesh().V0()
// - (
// // backward
// (
// coefft*vf.internalField()*mesh().V()
// - coefft0*vf.oldTime().internalField()*mesh().V0()
// + coefft00*vf.oldTime().oldTime().internalField()
// *mesh().V00()
// )
// // Euler
// - (
// vf.internalField()*mesh().V()
// - vf.oldTime().internalField()*mesh().V0()
// )
// )
// );
// }
// else
// {
// fvm.source() = rDeltaT*mesh().V()*
// (
// coefft0*vf.oldTime().internalField()
// - coefft00*vf.oldTime().oldTime().internalField()
// );
// }
// return tfvm;
// }
template<>
tmp<surfaceScalarField>
backwardDdtScheme<vector>::fvcDdtPhiCorr
(
const volScalarField& rA,
const GeometricField<vector, fvPatchField, volMesh>& U,
const surfaceScalarField& phi
)
{
Info << "Consistent backwardDdtPhiCorr" << endl;
dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
IOobject ddtIOobject
(
"ddtPhiCorr(" + rA.name() + ',' + U.name() + ',' + phi.name() + ')',
mesh().time().timeName(),
mesh()
);
scalar deltaT = deltaT_();
scalar deltaT0 = deltaT0_(U);
scalar coefft = 1 + deltaT/(deltaT + deltaT0);
scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
scalar coefft0 = coefft + coefft00;
surfaceScalarField ddtPhiCoeff
(
IOobject
(
"ddtPhiCoeff",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensioned<scalar>("1", dimless, 1.0)
);
forAll(U.boundaryField(), patchI)
{
// if (!U.boundaryField()[patchI].coupled())
// {
// ddtPhiCoeff.boundaryField()[patchI] = 0.0;
// }
if
(
U.boundaryField()[patchI].fixesValue()
|| isA<symmetryFvPatchVectorField>(U.boundaryField()[patchI])
|| isA<slipFvPatchVectorField>(U.boundaryField()[patchI])
|| isA<wedgeFvPatchVectorField>(U.boundaryField()[patchI])
)
{
ddtPhiCoeff.boundaryField()[patchI] = 0.0;
}
}
if (mesh().moving())
{
volScalarField V0oV
(
IOobject
(
"V0oV",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimless,
zeroGradientFvPatchScalarField::typeName
);
V0oV.internalField() = mesh().V0()/mesh().V();
V0oV.correctBoundaryConditions();
volScalarField V00oV
(
IOobject
(
"V00oV",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimless,
zeroGradientFvPatchScalarField::typeName
);
V00oV.internalField() = mesh().V00()/mesh().V();
V00oV.correctBoundaryConditions();
if
(
U.dimensions() == dimVelocity
&& phi.dimensions() == dimVelocity*dimArea
)
{
surfaceVectorField U0 =
fvc::interpolate(U.oldTime(), "interpolate(U)");
surfaceVectorField U00 =
fvc::interpolate(U.oldTime().oldTime(), "interpolate(U)");
// surfaceVectorField dU0 =
// fvc::interpolate(U.oldTime());
// forAll(dU0.boundaryField(), patchI)
// {
// if (!U.boundaryField()[patchI].coupled())
// {
// dU0.boundaryField()[patchI] =
// U.oldTime().boundaryField()[patchI]
// .patchInternalField();
// }
// }
// surfaceVectorField dU00 =
// fvc::interpolate(U.oldTime().oldTime());
// forAll(dU00.boundaryField(), patchI)
// {
// if (!U.boundaryField()[patchI].coupled())
// {
// dU00.boundaryField()[patchI] =
// U.oldTime().oldTime().boundaryField()[patchI]
// .patchInternalField();
// }
// }
const surfaceVectorField& Sf =
mesh().objectRegistry::lookupObject<surfaceVectorField>
(
"Sf"
);
U0 += Sf.oldTime()
*(phi.oldTime() - (Sf.oldTime()&U0))
/(
magSqr(Sf.oldTime())
+ dimensionedScalar("SMALL", sqr(dimArea), SMALL)
);
U00 += Sf.oldTime().oldTime()
*(phi.oldTime().oldTime() - (Sf.oldTime().oldTime()&U00))
/(
magSqr(Sf.oldTime().oldTime())
+ dimensionedScalar("SMALL", sqr(dimArea), SMALL)
);
// dU0 = Sf.oldTime()
// *(phi.oldTime() - (Sf.oldTime()&dU0))
// /(
// magSqr(Sf.oldTime())
// + dimensionedScalar("SMALL", sqr(dimArea), SMALL)
// );
// dU00 = Sf.oldTime().oldTime()
// *(phi.oldTime().oldTime() - (Sf.oldTime().oldTime()&dU00))
// /(
// magSqr(Sf.oldTime().oldTime())
// + dimensionedScalar("SMALL", sqr(dimArea), SMALL)
// );
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
ddtIOobject,
rDeltaT*ddtPhiCoeff
*(
(
(
coefft0*fvc::interpolate(V0oV)*U0
- coefft00*fvc::interpolate(V00oV)*U00
) & mesh().Sf()
)
- (
fvc::interpolate
(
coefft0*V0oV*U.oldTime()
- coefft00*V00oV*U.oldTime().oldTime(),
"interpolate(U)"
) & mesh().Sf()
)
)/fvc::interpolate(1/rA, "interpolate(U)")
)
);
// return tmp<surfaceScalarField>
// (
// new surfaceScalarField
// (
// ddtIOobject,
// rDeltaT*ddtPhiCoeff
// *(
// coefft0*fvc::interpolate(V0oV)
// *(mesh().Sf()&dU0)
// - coefft00
// *fvc::interpolate(V00oV)
// *(mesh().Sf()&dU00)
// )
// /fvc::interpolate(1.0/rA)
// )
// );
}
else
{
FatalErrorIn
(
"backwardDdtScheme<vector>::fvcDdtPhiCorr"
) << "dimensions of phi are not correct"
<< abort(FatalError);
return surfaceScalarField::null();
}
}
else
{
if
(
U.dimensions() == dimVelocity
&& phi.dimensions() == dimVelocity*dimArea
)
{
surfaceVectorField dU0 =
fvc::interpolate(U.oldTime(), "interpolate(U)");
forAll(dU0.boundaryField(), patchI)
{
if (!U.boundaryField()[patchI].coupled())
{
dU0.boundaryField()[patchI] =
U.oldTime().boundaryField()[patchI]
.patchInternalField();
}
}
surfaceVectorField dU00 =
fvc::interpolate(U.oldTime().oldTime(), "interpolate(U)");
forAll(dU00.boundaryField(), patchI)
{
if (!U.boundaryField()[patchI].coupled())
{
dU00.boundaryField()[patchI] =
U.oldTime().oldTime().boundaryField()[patchI]
.patchInternalField();
}
}
dU0 = mesh().Sf()
*(phi.oldTime() - (mesh().Sf()&dU0))
/(
magSqr(mesh().Sf())
+ dimensionedScalar("SMALL", sqr(dimArea), SMALL)
);
dU00 = mesh().Sf()
*(phi.oldTime().oldTime() - (mesh().Sf()&dU00))
/(
magSqr(mesh().Sf())
+ dimensionedScalar("SMALL", sqr(dimArea), SMALL)
);
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
ddtIOobject,
rDeltaT*ddtPhiCoeff
*(
coefft0*(mesh().Sf()&dU0)
- coefft00*(mesh().Sf()&dU00)
)
/fvc::interpolate(1.0/rA, "interpolate(U)")
)
);
}
else
{
FatalErrorIn
(
"backwardDdtScheme<vector>::fvcDdtPhiCorr"
) << "dimensions of phi are not correct"
<< abort(FatalError);
return surfaceScalarField::null();
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,410 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fluidSolver.H"
#include "volFields.H"
#include "wedgePolyPatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(fluidSolver, 0);
defineRunTimeSelectionTable(fluidSolver, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fluidSolver::calcGlobalFaceZones() const
{
// Find global face zones
if (globalFaceZonesPtr_)
{
FatalErrorIn
(
"void fluidSolver::calcGlobalFaceZones() const"
)
<< "Global face zones already fonud"
<< abort(FatalError);
}
SLList<label> globalFaceZonesSet;
const faceZoneMesh& faceZones = mesh().faceZones();
forAll(faceZones, zoneI)
{
const faceZone& curFaceZone = faceZones[zoneI];
bool globalFaceZone = false;
forAll(curFaceZone, faceI)
{
// if unused face exist
if (curFaceZone[faceI] >= mesh().nFaces())
{
// globalFaceZonesSet.insert(zoneI);
globalFaceZone = true;
break;
}
}
reduce(globalFaceZone, orOp<bool>());
if (globalFaceZone)
{
globalFaceZonesSet.insert(zoneI);
}
}
globalFaceZonesPtr_ = new labelList(globalFaceZonesSet);
}
void Foam::fluidSolver::calcGlobalToLocalFaceZonePointMap() const
{
// Find global face zones
if (globalToLocalFaceZonePointMapPtr_)
{
FatalErrorIn
(
"void fluidSolver::calcGlobalToLocalFaceZonePointMap() const"
)
<< "Global to local face zones point map already exists"
<< abort(FatalError);
}
globalToLocalFaceZonePointMapPtr_ =
new labelListList(globalFaceZones().size());
labelListList& globalToLocalFaceZonePointMap =
*globalToLocalFaceZonePointMapPtr_;
forAll(globalFaceZones(), zoneI)
{
label curZoneID = globalFaceZones()[zoneI];
labelList curMap(mesh().faceZones()[curZoneID]().nPoints(), -1);
vectorField fzGlobalPoints =
mesh().faceZones()[curZoneID]().localPoints();
//- set all slave points to zero because only the master order is used
if(!Pstream::master())
{
fzGlobalPoints *= 0.0;
}
//- pass points to all procs
reduce(fzGlobalPoints, sumOp<vectorField>());
//- now every proc has the master's list of FZ points
//- every proc must now find the mapping from their local FZ points to
//- the global FZ points
const vectorField& fzLocalPoints =
mesh().faceZones()[curZoneID]().localPoints();
const edgeList& fzLocalEdges =
mesh().faceZones()[curZoneID]().edges();
const labelListList& fzPointEdges =
mesh().faceZones()[curZoneID]().pointEdges();
scalarField minEdgeLength(fzLocalPoints.size(), GREAT);
forAll(minEdgeLength, pI)
{
const labelList& curPointEdges = fzPointEdges[pI];
forAll(curPointEdges, eI)
{
scalar Le = fzLocalEdges[curPointEdges[eI]].mag(fzLocalPoints);
if (Le < minEdgeLength[pI])
{
minEdgeLength[pI] = Le;
}
}
}
forAll(fzGlobalPoints, globalPointI)
{
boolList visited(fzLocalPoints.size(), false);
forAll(fzLocalPoints, procPointI)
{
if (!visited[procPointI])
{
visited[procPointI] = true;
label nextPoint = procPointI;
scalar curDist =
mag
(
fzLocalPoints[nextPoint]
- fzGlobalPoints[globalPointI]
);
if (curDist < 1e-4*minEdgeLength[nextPoint])
{
curMap[globalPointI] = nextPoint;
break;
}
label found = false;
while (nextPoint != -1)
{
const labelList& nextPointEdges =
fzPointEdges[nextPoint];
scalar minDist = GREAT;
label index = -1;
forAll(nextPointEdges, edgeI)
{
label curNgbPoint =
fzLocalEdges[nextPointEdges[edgeI]]
.otherVertex(nextPoint);
if (!visited[curNgbPoint])
{
visited[curNgbPoint] = true;
scalar curDist =
mag
(
fzLocalPoints[curNgbPoint]
- fzGlobalPoints[globalPointI]
);
if (curDist < 1e-4*minEdgeLength[curNgbPoint])
{
curMap[globalPointI] = curNgbPoint;
found = true;
break;
}
else if (curDist < minDist)
{
minDist = curDist;
index = curNgbPoint;
}
}
}
nextPoint = index;
}
if (found)
{
break;
}
}
}
}
// forAll(fzGlobalPoints, globalPointI)
// {
// forAll(fzLocalPoints, procPointI)
// {
// scalar curDist =
// mag
// (
// fzLocalPoints[procPointI]
// - fzGlobalPoints[globalPointI]
// );
// if (curDist < 1e-4*minEdgeLength[procPointI])
// {
// curMap[globalPointI] = procPointI;
// break;
// }
// }
// }
forAll(curMap, globalPointI)
{
if (curMap[globalPointI] == -1)
{
FatalErrorIn
(
"fluidSolver::calcGlobalToLocalFaceZonePointMap()"
)
<< "local to global face zone point map is not correct"
<< abort(FatalError);
}
}
globalToLocalFaceZonePointMap[zoneI] = curMap;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fluidSolver::fluidSolver
(
const word& type,
const fvMesh& mesh
)
:
IOdictionary
(
IOobject
(
"fluidProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
mesh_(mesh),
fluidProperties_(subDict(type + "Coeffs")),
globalFaceZonesPtr_(NULL),
globalToLocalFaceZonePointMapPtr_(NULL)
{
// Disabling the 3rd direction for axisymmetric cases
label nWedgePatches = 0;
vector wedgeDirVec = vector::zero;
forAll(mesh_.boundaryMesh(), patchI)
{
if (isA<wedgePolyPatch>(mesh_.boundaryMesh()[patchI]))
{
const wedgePolyPatch& wpp =
refCast<const wedgePolyPatch>
(
mesh_.boundaryMesh()[patchI]
);
nWedgePatches++;
wedgeDirVec += cmptMag(wpp.centreNormal());
}
}
reduce(nWedgePatches, maxOp<label>());
if (nWedgePatches)
{
Info<< nl << "Axisymmetric case: disabling the 3rd direction"
<< nl << endl;
// We will const_cast as it is currently the tidiest way,
// until polyMesh is modified or gives write access to solutionD
Vector<label>& solD = const_cast<Vector<label>&>(mesh_.solutionD());
reduce(wedgeDirVec, sumOp<vector>());
wedgeDirVec /= mag(wedgeDirVec);
Info << wedgeDirVec << endl;
for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
{
if (wedgeDirVec[cmpt] > 1e-6)
{
solD[cmpt] = -1;
}
else
{
solD[cmpt] = 1;
}
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fluidSolver::~fluidSolver()
{
deleteDemandDrivenData(globalFaceZonesPtr_);
deleteDemandDrivenData(globalToLocalFaceZonePointMapPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::labelList&
Foam::fluidSolver::globalFaceZones() const
{
if (!globalFaceZonesPtr_)
{
calcGlobalFaceZones();
}
return *globalFaceZonesPtr_;
}
const Foam::labelListList&
Foam::fluidSolver::globalToLocalFaceZonePointMap() const
{
if (!globalToLocalFaceZonePointMapPtr_)
{
calcGlobalToLocalFaceZonePointMap();
}
return *globalToLocalFaceZonePointMapPtr_;
}
//- Face zone point displacement
Foam::tmp<Foam::vectorField> Foam::fluidSolver::faceZoneVelocity
(
const label zoneID,
const label patchID
) const
{
tmp<vectorField> tVelocity
(
new vectorField
(
mesh().faceZones()[zoneID]().size(),
vector::zero
)
);
return tVelocity;
}
bool Foam::fluidSolver::read()
{
if (regIOobject::read())
{
fluidProperties_ = subDict(type() + "Coeffs");
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,236 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
fluidSolver
Description
Virtual base class for fluid solvers
Author
Zeljko Tukovic, Fsb Zagreb. All rights reserved.
SourceFiles
fluidSolver.C
newFluidSolver.C
\*---------------------------------------------------------------------------*/
#ifndef fluidSolver_H
#define fluidSolver_H
#include "fvMesh.H"
#include "IOdictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fluidSolver Declaration
\*---------------------------------------------------------------------------*/
class fluidSolver
:
public IOdictionary
{
// Private data
//- Reference to mesh
const fvMesh& mesh_;
//- Fluid properties dictionary
dictionary fluidProperties_;
//- Global face zones
mutable labelList* globalFaceZonesPtr_;
//- Global to local face zone poin maping
mutable labelListList* globalToLocalFaceZonePointMapPtr_;
// Private Member Functions
//- Find global face zones
void calcGlobalFaceZones() const;
//- Calculate global to local point addressing
void calcGlobalToLocalFaceZonePointMap() const;
//- Disallow default bitwise copy construct
fluidSolver(const fluidSolver&);
//- Disallow default bitwise assignment
void operator=(const fluidSolver&);
protected:
// Protected member functions
//- Return flow properties dictionary
const dictionary& fluidProperties() const
{
return fluidProperties_;
}
public:
//- Runtime type information
TypeName("fluidSolver");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
fluidSolver,
dictionary,
(
const fvMesh& mesh
),
(mesh)
);
// Constructors
//- Construct from components
fluidSolver
(
const word& type,
const fvMesh& mesh
);
// Selectors
//- Select constructed from mesh
static autoPtr<fluidSolver> New(const fvMesh& mesh);
// Destructor
virtual ~fluidSolver();
// Member Functions
// Access
//- Return mesh
const fvMesh& mesh() const
{
return mesh_;
}
//- Return time
const Time& runTime() const
{
return mesh_.time();
}
//- Return velocity field
virtual const volVectorField& U() const = 0;
//- Return pressure field
virtual const volScalarField& p() const = 0;
//- Patch viscous force (N/m2)
virtual tmp<vectorField> patchViscousForce
(
const label patchID
) const = 0;
//- Patch pressure force (N/m2)
virtual tmp<scalarField> patchPressureForce
(
const label patchID
) const = 0;
//- Face zone viscous force (N/m2)
virtual tmp<vectorField> faceZoneViscousForce
(
const label zoneID,
const label patchID
) const = 0;
//- Face zone pressure force (N/m2)
virtual tmp<scalarField> faceZonePressureForce
(
const label zoneID,
const label patchID
) const = 0;
//- Face zone velocity (m/s)
virtual tmp<vectorField> faceZoneVelocity
(
const label zoneID,
const label patchID
) const;
//- Face zone effective dynamic viscosity
virtual tmp<scalarField> faceZoneMuEff
(
const label zoneID,
const label patchID
) const = 0;
//- Get global face zones list
const labelList& globalFaceZones() const;
//- Get global to local face zone point addressing
const labelListList& globalToLocalFaceZonePointMap() const;
// Edit
//- Evolve the fluid solver
virtual void evolve() = 0;
//- Update fields
virtual void updateFields()
{}
//- Correct velocity at specified patch
virtual void correctVelocity(label patchIndex)
{}
//- Read fluidProperties dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fluidSolver.H"
#include "foamTime.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::fluidSolver> Foam::fluidSolver::New(const fvMesh& mesh)
{
word fluidSolverTypeName;
// Enclose the creation of the dictionary to ensure it is
// deleted before the flow is created otherwise the dictionary
// is entered in the database twice
{
IOdictionary fluidProperties
(
IOobject
(
"fluidProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
fluidProperties.lookup("fluidSolver") >> fluidSolverTypeName;
}
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(fluidSolverTypeName);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"fluidSolver::New(const fvMesh&)"
) << "Unknown fluidSolver type " << fluidSolverTypeName
<< endl << endl
<< "Valid fluidSolver types are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<fluidSolver>(cstrIter()(mesh));
}
// ************************************************************************* //

View file

@ -0,0 +1,342 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "elasticSlipWallVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvcMeshPhi.H"
#include "backwardDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
elasticSlipWallVelocityFvPatchVectorField::elasticSlipWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
directionMixedDisplacementFvPatchVectorField(p, iF),
myTimeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldoldFc_(p.patch().size(),vector::zero),
movingWallVelocity_(p.patch().size(),vector::zero)
{}
elasticSlipWallVelocityFvPatchVectorField::elasticSlipWallVelocityFvPatchVectorField
(
const elasticSlipWallVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
directionMixedDisplacementFvPatchVectorField(ptf, p, iF, mapper),
myTimeIndex_(ptf.myTimeIndex_),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldoldFc_(p.patch().size(),vector::zero),
movingWallVelocity_(p.patch().size(),vector::zero)
{}
elasticSlipWallVelocityFvPatchVectorField::elasticSlipWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
directionMixedDisplacementFvPatchVectorField(p, iF),
myTimeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldoldFc_(p.patch().size(),vector::zero),
movingWallVelocity_(p.patch().size(),vector::zero)
{
// fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
const fvMesh& mesh = dimensionedInternalField().mesh();
const pointField& points = mesh.allPoints();
forAll(Fc_, i)
{
Fc_[i] = patch().patch()[i].centre(points);
}
oldFc_ = Fc_;
oldoldFc_ = Fc_;
//
if (dict.found("refValue"))
{
this->refValue() = vectorField("refValue", dict, p.size());
}
else
{
this->refValue() = vector::zero;
}
if (dict.found("refGradient"))
{
this->refGrad() = vectorField("refGradient", dict, p.size());
}
else
{
this->refGrad() = vector::zero;
}
// Patch normal
vectorField n = patch().nf();
this->valueFraction() = sqr(n);
if (dict.found("value"))
{
Field<vector>::operator=(vectorField("value", dict, p.size()));
}
else
{
Field<vector> normalValue = transform(valueFraction(), refValue());
Field<vector> gradValue =
this->patchInternalField() + refGrad()/this->patch().deltaCoeffs();
Field<vector> transformGradValue =
transform(I - valueFraction(), gradValue);
Field<vector>::operator=(normalValue + transformGradValue);
}
}
elasticSlipWallVelocityFvPatchVectorField::elasticSlipWallVelocityFvPatchVectorField
(
const elasticSlipWallVelocityFvPatchVectorField& pivpvf
)
:
directionMixedDisplacementFvPatchVectorField(pivpvf),
myTimeIndex_(pivpvf.myTimeIndex_),
Fc_(pivpvf.Fc_),
oldFc_(pivpvf.oldFc_),
oldoldFc_(pivpvf.oldoldFc_),
movingWallVelocity_(pivpvf.movingWallVelocity_)
{}
elasticSlipWallVelocityFvPatchVectorField::elasticSlipWallVelocityFvPatchVectorField
(
const elasticSlipWallVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
directionMixedDisplacementFvPatchVectorField(pivpvf, iF),
myTimeIndex_(pivpvf.myTimeIndex_),
Fc_(pivpvf.oldFc_),
oldFc_(pivpvf.oldFc_),
oldoldFc_(pivpvf.oldoldFc_),
movingWallVelocity_(pivpvf.movingWallVelocity_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void elasticSlipWallVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
Info << "elasticSlipWallVelocityFvPatchVectorField::updateCoeffs" << endl;
const fvMesh& mesh = dimensionedInternalField().mesh();
const fvPatch& p = patch();
const polyPatch& pp = p.patch();
const pointField& points = mesh.allPoints();
vectorField Up(p.size(), vector::zero);
//const pointField& oldPoints = mesh.oldPoints();
const volVectorField& U =
mesh.lookupObject<volVectorField>
(
dimensionedInternalField().name()
);
word ddtScheme
(
mesh.schemesDict().ddtScheme("ddt(" + U.name() +')')
);
if (ddtScheme == fv::backwardDdtScheme<vector>::typeName)
{
if(myTimeIndex_ < mesh.time().timeIndex())
{
oldoldFc_ = oldFc_;
oldFc_ = Fc_;
// Fc_ = pp.faceCentres();
forAll(Fc_, i)
{
Fc_[i] = pp[i].centre(points);
}
myTimeIndex_ = mesh.time().timeIndex();
}
scalar deltaT = mesh.time().deltaT().value();
scalar deltaT0 = mesh.time().deltaT0().value();
if
(
U.oldTime().timeIndex() == U.oldTime().oldTime().timeIndex()
|| U.oldTime().oldTime().timeIndex() < 0
)
{
deltaT0 = GREAT;
}
//Set coefficients based on deltaT and deltaT0
scalar coefft = 1 + deltaT/(deltaT + deltaT0);
scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
// scalar coefft0 = coefft + coefft00;
// Up = (coefft*Fc_ - coefft0*oldFc_ + coefft00*oldoldFc_)
// /mesh.time().deltaT().value();
Up = coefft*(Fc_ - oldFc_)/deltaT
- coefft00*(oldFc_ - oldoldFc_)/deltaT;
// Info << max(mag(Up)) << endl;
}
else // Euler
{
if (myTimeIndex_ < mesh.time().timeIndex())
{
oldFc_ = Fc_;
forAll(Fc_, i)
{
Fc_[i] = pp[i].centre(points);
}
// Fc_ = pp.faceCentres();
myTimeIndex_ = mesh.time().timeIndex();
}
Up = (Fc_ - oldFc_)/mesh.time().deltaT().value();
}
scalarField phip =
p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U));
vectorField n = p.nf();
const scalarField& magSf = p.magSf();
scalarField Un = phip/(magSf + VSMALL);
Up += n*(Un - (n & Up));
// vectorField::operator=(Up);
movingWallVelocity_ = Up;
this->valueFraction() = sqr(n);
// this->refValue() = movingWallVelocity_;
// Info << max(Un) << endl;
if (mesh.foundObject<surfaceScalarField>("phi"))
{
const surfaceScalarField& phi =
mesh.lookupObject<surfaceScalarField>("phi");
scalarField phip = phi.boundaryField()[this->patch().index()];
Un = phip/(magSf + VSMALL);
}
else
{
const volScalarField& pressure =
mesh.lookupObject<volScalarField>("p");
scalarField nGradP =
pressure.boundaryField()[this->patch().index()].snGrad();
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar rho
(
transportProperties.lookup("rho")
);
vectorField UOld = U.oldTime().boundaryField()[this->patch().index()];
Un = (n & UOld) - nGradP*mesh.time().deltaT().value()/rho.value();
}
this->refValue() = n*Un;
// Info << max(mag(nGradP)) << endl;
directionMixedDisplacementFvPatchVectorField::updateCoeffs();
}
void elasticSlipWallVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
elasticSlipWallVelocityFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,163 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::elasticSlipWallVelocityFvPatchVectorField
Description
Foam::elasticSlipWallVelocityFvPatchVectorField
SourceFiles
elasticSlipWallVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef elasticSlipWallVelocityFvPatchVectorField_H
#define elasticSlipWallVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "directionMixedDisplacementFvPatchVectorField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class elasticSlipWallVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class elasticSlipWallVelocityFvPatchVectorField
:
public directionMixedDisplacementFvPatchVectorField
{
//To keep track when to copy patch face centres
label myTimeIndex_;
//Old face centres of patch. Needed for (second order) time integration
vectorField Fc_;
vectorField oldFc_;
vectorField oldoldFc_;
vectorField movingWallVelocity_;
public:
//- Runtime type information
TypeName("elasticSlipWallVelocity");
// Constructors
//- Construct from patch and internal field
elasticSlipWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
elasticSlipWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given elasticSlipWallVelocityFvPatchVectorField
// onto a new patch
elasticSlipWallVelocityFvPatchVectorField
(
const elasticSlipWallVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
elasticSlipWallVelocityFvPatchVectorField
(
const elasticSlipWallVelocityFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new elasticSlipWallVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
elasticSlipWallVelocityFvPatchVectorField
(
const elasticSlipWallVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new elasticSlipWallVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
// Evaluation functions
// //- Return patch-normal gradient
// virtual tmp<Field<vector> > snGrad() const;
// //- Return the matrix source coefficients corresponding to the
// // evaluation of the gradient of this patchField
// virtual tmp<Field<vector> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,405 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "elasticWallPressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fluidSolidInterface.H"
#include "backwardDdtScheme.H"
#include "EulerDdtScheme.H"
// #include "fvcMeshPhi.H"
// #include "backwardDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
elasticWallPressureFvPatchScalarField::elasticWallPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
robinFvPatchScalarField(p, iF),
timeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
prevPressure_(p.patch().size(), 0),
prevAcceleration_(p.patch().size(), vector::zero),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldOldFc_(p.patch().size(),vector::zero),
U_(p.patch().size(),vector::zero),
oldU_(p.patch().size(),vector::zero),
oldOldU_(p.patch().size(),vector::zero)
{}
elasticWallPressureFvPatchScalarField::elasticWallPressureFvPatchScalarField
(
const elasticWallPressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
robinFvPatchScalarField(ptf, p, iF, mapper),
timeIndex_(ptf.timeIndex_),
prevPressure_(p.patch().size(), 0),
prevAcceleration_(p.patch().size(), vector::zero),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldOldFc_(p.patch().size(),vector::zero),
U_(p.patch().size(),vector::zero),
oldU_(p.patch().size(),vector::zero),
oldOldU_(p.patch().size(),vector::zero)
{}
elasticWallPressureFvPatchScalarField::elasticWallPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
robinFvPatchScalarField(p, iF),
timeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
prevPressure_(p.patch().size(), 0),
prevAcceleration_(p.patch().size(), vector::zero),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldOldFc_(p.patch().size(),vector::zero),
U_(p.patch().size(),vector::zero),
oldU_(p.patch().size(),vector::zero),
oldOldU_(p.patch().size(),vector::zero)
{
if (dict.found("value"))
{
Field<scalar>::operator=(scalarField("value", dict, p.size()));
}
this->coeff0() = 1.0;
this->coeff1() = 1.0;
const fvMesh& mesh = dimensionedInternalField().mesh();
const pointField& points = mesh.allPoints();
forAll(Fc_, i)
{
Fc_[i] = patch().patch()[i].centre(points);
}
oldFc_ = Fc_;
oldOldFc_ = Fc_;
}
elasticWallPressureFvPatchScalarField::elasticWallPressureFvPatchScalarField
(
const elasticWallPressureFvPatchScalarField& pivpvf
)
:
robinFvPatchScalarField(pivpvf),
timeIndex_(pivpvf.timeIndex_),
prevPressure_(pivpvf.prevPressure_),
prevAcceleration_(pivpvf.prevAcceleration_),
Fc_(pivpvf.Fc_),
oldFc_(pivpvf.oldFc_),
oldOldFc_(pivpvf.oldOldFc_),
U_(pivpvf.U_),
oldU_(pivpvf.oldU_),
oldOldU_(pivpvf.oldOldU_)
{}
elasticWallPressureFvPatchScalarField::elasticWallPressureFvPatchScalarField
(
const elasticWallPressureFvPatchScalarField& pivpvf,
const DimensionedField<scalar, volMesh>& iF
)
:
robinFvPatchScalarField(pivpvf, iF),
timeIndex_(pivpvf.timeIndex_),
prevPressure_(pivpvf.prevPressure_),
prevAcceleration_(pivpvf.prevAcceleration_),
Fc_(pivpvf.oldFc_),
oldFc_(pivpvf.oldFc_),
oldOldFc_(pivpvf.oldOldFc_),
U_(pivpvf.oldU_),
oldU_(pivpvf.oldU_),
oldOldU_(pivpvf.oldOldU_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void elasticWallPressureFvPatchScalarField::autoMap
(
const fvPatchFieldMapper& m
)
{
fvPatchField<scalar>::autoMap(m);
}
void elasticWallPressureFvPatchScalarField::rmap
(
const fvPatchField<scalar>& ptf,
const labelList& addr
)
{
fvPatchField<scalar>::rmap(ptf, addr);
}
void elasticWallPressureFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
const fvMesh& mesh = dimensionedInternalField().mesh();
// Looking up solid solver
const fluidSolidInterface& fsi =
mesh.lookupObject<fluidSolidInterface>("fsiProperties");
// Solid properties
scalar rhoSolid =
fsi.stress().rheology().rho()()[0];
scalar mu =
fsi.stress().rheology().mu()()[0];
scalar lambda =
fsi.stress().rheology().lambda()()[0];
scalar ap = sqrt((lambda+2*mu)/rhoSolid);
scalar hs = ap*mesh.time().deltaT().value();
// Fluid properties
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar rhoFluid
(
transportProperties.lookup("rho")
);
Info << "rhoSolid = " << rhoSolid << ", hs = " << hs
<< ", rhoFluid = " << rhoFluid.value() << endl;
// Update velocity and acceleration
const fvPatch& p = patch();
const polyPatch& pp = p.patch();
const pointField& points = mesh.allPoints();
const volVectorField& U =
mesh.lookupObject<volVectorField>
(
"U"
);
scalarField phip =
p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U));
vectorField n = p.nf();
const scalarField& magSf = p.magSf();
scalarField Un = phip/(magSf + VSMALL);
word ddtScheme
(
mesh.schemesDict().ddtScheme("ddt(" + U.name() +')')
);
if (ddtScheme == fv::EulerDdtScheme<vector>::typeName)
{
if (timeIndex_ < mesh.time().timeIndex())
{
oldOldFc_ = oldFc_;
oldFc_ = Fc_;
oldOldU_ = oldU_;
oldU_ = U_;
timeIndex_ = mesh.time().timeIndex();
}
forAll(Fc_, i)
{
Fc_[i] = pp[i].centre(points);
}
U_ = (Fc_ - oldFc_)/mesh.time().deltaT().value();
U_ += n*(Un - (n & U_));
// prevAcceleration_ =
// (U_ - oldU_)/mesh.time().deltaT().value();
}
else
{
Info << "elasticWallPressureFvPatchScalarField::updateCoeffs()"
<< endl;
}
// Info << "ddtUn, max: " << max(n&prevAcceleration_)
// << ", avg: " << average(n&prevAcceleration_)
// << ", min: " << min(n&prevAcceleration_) << endl;
// Info << "p, max: " << max(prevPressure_/rhoFluid.value())
// << ", avg: " << average(prevPressure_/rhoFluid.value())
// << ", min: " << min(prevPressure_/rhoFluid.value()) << endl;
// Info << rhoSolid_ << ", " << h_ << endl;
// if(timeIndex_ < mesh.time().timeIndex())
// {
// timeIndex_ = mesh.time().timeIndex();
// }
// Info << ap << endl;
word fieldName = dimensionedInternalField().name();
const volScalarField& pressure =
mesh.lookupObject<volScalarField>(fieldName);
// const volVectorField& ddtU =
// mesh.lookupObject<volVectorField>("ddt(U)");
// scalarField ddtUn =
// (n & ddtU.boundaryField()[patch().index()]);
// Info << "ddtUn2, max: " << max(ddtUn)
// << ", avg: " << average(ddtUn)
// << ", min: " << min(ddtUn) << endl;
// const volVectorField& U =
// mesh.lookupObject<volVectorField>("U");
// vectorField n = this->patch().nf();
// scalarField prevDdtUn =
// (n & fvc::ddt(U)().boundaryField()[patch().index()]);
scalarField prevDdtUn = (n & prevAcceleration_);
if (pressure.dimensions() == dimPressure/dimDensity)
{
// p/rho
this->coeff0() = 1.0;
this->coeff1() = rhoSolid*hs/rhoFluid.value();
this->rhs() =
prevPressure_/rhoFluid.value()
- rhoSolid*hs*prevDdtUn/rhoFluid.value();
}
else
{
// p
this->coeff0() = 1.0;
this->coeff1() = rhoSolid*hs/rhoFluid.value();
this->rhs() = prevPressure_ - rhoSolid*hs*prevDdtUn;
}
// if (weak_)
// {
// this->rhs() =
// p.oldTime().boundaryField()[patch().index()]
// + rhoSolid_*h_
// *(n & ddtU.oldTime().boundaryField()[patch().index()]);
// }
// else
// {
// this->rhs() =
// p.prevIter().boundaryField()[patch().index()]
// - rhoSolid_*h_
// *(n & ddtU.prevIter().boundaryField()[patch().index()]);
// }
// scalarField dn = 1.0/this->patch().deltaCoeffs();
// Info << "pcoeff " << max(this->coeff()+dn)
// << ", " << average(this->coeff()+dn) << endl;
robinFvPatchField<scalar>::updateCoeffs();
}
void elasticWallPressureFvPatchScalarField::patchFlux
(
GeometricField<scalar, fvsPatchField, surfaceMesh>& flux,
const fvMatrix<scalar>& matrix
) const
{
const label patchI = this->patch().index();
const fvMesh& mesh =
dimensionedInternalField().mesh();
const fvsPatchField<scalar>& rAU =
patch().lookupPatchField<surfaceScalarField, scalar>
(
"rAUf"
);
flux.boundaryField()[patchI] =
rAU*this->snGrad()
*mesh.magSf().boundaryField()[patchI];
}
void elasticWallPressureFvPatchScalarField::write(Ostream& os) const
{
robinFvPatchScalarField::write(os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
elasticWallPressureFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,256 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
elasticWallPressureFvPatchScalarField
Description
elasticWallPressureFvPatchScalarField
SourceFiles
elasticWallPressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef elasticWallPressureFvPatchScalarField_H
#define elasticWallPressureFvPatchScalarField_H
#include "robinFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class elasticWallPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class elasticWallPressureFvPatchScalarField
:
public robinFvPatchField<scalar>
{
// Private data
//- Local time index
label timeIndex_;
//- Pressure applied at the solid side of the interface
// in the previous fsi iteration
scalarField prevPressure_;
//- Acceleration of the solid side of the interface
// in the previous fsi iteration
vectorField prevAcceleration_;
//- Old face centres of patch.
// Needed for (second order) time integration
vectorField Fc_;
vectorField oldFc_;
vectorField oldOldFc_;
//- Face centre velocity.
// Needed for (second order) time integration
vectorField U_;
vectorField oldU_;
vectorField oldOldU_;
public:
//- Runtime type information
TypeName("elasticWallPressure");
// Constructors
//- Construct from patch and internal field
elasticWallPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
elasticWallPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given elasticWallPressureFvPatchScalarField
// onto a new patch
elasticWallPressureFvPatchScalarField
(
const elasticWallPressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
elasticWallPressureFvPatchScalarField
(
const elasticWallPressureFvPatchScalarField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new elasticWallPressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
elasticWallPressureFvPatchScalarField
(
const elasticWallPressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new elasticWallPressureFvPatchScalarField(*this, iF)
);
}
// Member functions
// Access functions
//- Get previous pressure patch field
const scalarField& prevPressure() const
{
return prevPressure_;
}
//- Get previous pressure patch field
scalarField& prevPressure()
{
return prevPressure_;
}
//- Get previous pressure patch field
const vectorField& prevAcceleration() const
{
return prevAcceleration_;
}
//- Get previous pressure patch field
vectorField& prevAcceleration()
{
return prevAcceleration_;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<scalar>&,
const labelList&
);
// Evaluation functions
// //- Return gradient at boundary
// virtual tmp<Field<scalar> > snGrad() const
// {
// return tmp<Field<scalar> >
// (
// new scalarField(this->patch().size(), 0)
// );
// }
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Calculate patch flux
virtual void patchFlux
(
GeometricField<scalar, fvsPatchField, surfaceMesh>& flux,
const fvMatrix<scalar>& matrix
) const;
// //- Evaluate the patch field
// virtual void evaluate
// (
// const Pstream::commsTypes commsType=Pstream::blocking
// );
// //- Return the matrix diagonal coefficients corresponding to the
// // evaluation of the value of this patchField with given weights
// virtual tmp<Field<scalar> > valueInternalCoeffs
// (
// const tmp<scalarField>&
// ) const;
// //- Return the matrix source coefficients corresponding to the
// // evaluation of the value of this patchField with given weights
// virtual tmp<Field<scalar> > valueBoundaryCoeffs
// (
// const tmp<scalarField>&
// ) const;
// //- Return the matrix diagonal coefficients corresponding to the
// // evaluation of the gradient of this patchField
// virtual tmp<Field<scalar> > gradientInternalCoeffs() const;
// //- Return the matrix source coefficients corresponding to the
// // evaluation of the gradient of this patchField
// virtual tmp<Field<scalar> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,448 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "elasticWallVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvcMeshPhi.H"
#include "backwardDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
elasticWallVelocityFvPatchVectorField::elasticWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
myTimeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldOldFc_(p.patch().size(),vector::zero)
{}
elasticWallVelocityFvPatchVectorField::elasticWallVelocityFvPatchVectorField
(
const elasticWallVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
myTimeIndex_(ptf.myTimeIndex_),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldOldFc_(p.patch().size(),vector::zero)
{}
elasticWallVelocityFvPatchVectorField::elasticWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
myTimeIndex_(-1),
// myTimeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldOldFc_(p.patch().size(),vector::zero)
{
fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
const fvMesh& mesh = dimensionedInternalField().mesh();
const pointField& points = mesh.allPoints();
forAll(Fc_, i)
{
Fc_[i] = patch().patch()[i].centre(points);
}
oldFc_ = Fc_;
oldOldFc_ = Fc_;
}
elasticWallVelocityFvPatchVectorField::elasticWallVelocityFvPatchVectorField
(
const elasticWallVelocityFvPatchVectorField& pivpvf
)
:
fixedValueFvPatchVectorField(pivpvf),
myTimeIndex_(pivpvf.myTimeIndex_),
Fc_(pivpvf.Fc_),
oldFc_(pivpvf.oldFc_),
oldOldFc_(pivpvf.oldOldFc_)
{}
elasticWallVelocityFvPatchVectorField::elasticWallVelocityFvPatchVectorField
(
const elasticWallVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
myTimeIndex_(pivpvf.myTimeIndex_),
Fc_(pivpvf.oldFc_),
oldFc_(pivpvf.oldFc_),
oldOldFc_(pivpvf.oldOldFc_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void elasticWallVelocityFvPatchVectorField::updateCoeffs()
{
// Info << "elasticWallVelocityFvPatchVectorField::updateCoeffs" << endl;
if (updated())
{
return;
}
const fvMesh& mesh = dimensionedInternalField().mesh();
const fvPatch& p = patch();
const polyPatch& pp = p.patch();
const pointField& points = mesh.allPoints();
vectorField Up(p.size(), vector::zero);
//const pointField& oldPoints = mesh.oldPoints();
const volVectorField& U =
mesh.lookupObject<volVectorField>
(
dimensionedInternalField().name()
);
word ddtScheme
(
mesh.schemesDict().ddtScheme("ddt(" + U.name() +')')
);
if (ddtScheme == fv::backwardDdtScheme<vector>::typeName)
{
// Info << "void elasticWallVelocityFvPatchVectorField::updateCoeffs() - "
// << "backward"
// << endl;
if(myTimeIndex_ < mesh.time().timeIndex())
{
oldOldFc_ = oldFc_;
oldFc_ = Fc_;
// Fc_ = pp.faceCentres();
myTimeIndex_ = mesh.time().timeIndex();
}
forAll(Fc_, i)
{
Fc_[i] = pp[i].centre(points);
}
scalar deltaT = mesh.time().deltaT().value();
scalar deltaT0 = mesh.time().deltaT0().value();
if
(
U.oldTime().timeIndex() == U.oldTime().oldTime().timeIndex()
|| U.oldTime().oldTime().timeIndex() < 0
)
{
deltaT0 = GREAT;
}
//Set coefficients based on deltaT and deltaT0
scalar coefft = 1 + deltaT/(deltaT + deltaT0);
scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
// scalar coefft0 = coefft + coefft00;
Up = coefft*(Fc_ - oldFc_)/deltaT
- coefft00*(oldFc_ - oldOldFc_)/deltaT;
}
else // Euler
{
if (myTimeIndex_ < mesh.time().timeIndex())
{
oldOldFc_ = oldFc_;
oldFc_ = Fc_;
// Fc_ = pp.faceCentres();
myTimeIndex_ = mesh.time().timeIndex();
}
forAll(Fc_, i)
{
Fc_[i] = pp[i].centre(points);
}
Up = (Fc_ - oldFc_)/mesh.time().deltaT().value();
}
scalarField phip =
p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U));
vectorField n = p.nf();
const scalarField& magSf = p.magSf();
scalarField Un = phip/(magSf + VSMALL);
// Info << max(mag(Un)) << endl;
// Up += n*(Un - (n & Up));
// Info << max(mag(Up)) << endl;
if (mesh.foundObject<surfaceScalarField>("phi"))
{
const surfaceScalarField& phi =
mesh.lookupObject<surfaceScalarField>("phi");
scalarField phip =
phi.boundaryField()[this->patch().index()];
Un = phip/(magSf + VSMALL);
// Info << "Un " << max(mag(Un)) << ", "
// << average(mag(Un)) << endl;
}
else
{
const volScalarField& pressure =
mesh.lookupObject<volScalarField>("p");
scalarField nGradP =
pressure.boundaryField()[this->patch().index()].snGrad();
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar rho
(
transportProperties.lookup("rho")
);
vectorField UOld = U.oldTime().boundaryField()[this->patch().index()];
Un = (n & UOld) - nGradP*mesh.time().deltaT().value();
// Un = (n & UOld) - nGradP*mesh.time().deltaT().value()/rho.value();
}
// Info << "mwvuc " << max(mag(Up)) << ", " << average(mag(Up)) << endl;
Up += n*(Un - (n & Up));
vectorField::operator=(Up);
fixedValueFvPatchVectorField::updateCoeffs();
}
Foam::tmp<Foam::Field<vector> > elasticWallVelocityFvPatchVectorField::
snGrad() const
{
bool secondOrder_ = false;
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
vectorField dUP = (k&gradU.patchInternalField());
if (secondOrder_)
{
vectorField nGradUP = (n&gradU.patchInternalField());
tmp<Field<vector> > tnGradU
(
new vectorField(this->patch().size(), vector::zero)
);
tnGradU() =
2
*(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs()
- nGradUP;
tnGradU() -= n*(n&tnGradU());
return tnGradU;
// return
// 2
// *(
// *this
// - (patchInternalField() + dUP)
// )*this->patch().deltaCoeffs()
// - nGradUP;
}
// First order
// vectorField dUP = (k&gradU.patchInternalField());
tmp<Field<vector> > tnGradU
(
new vectorField(this->patch().size(), vector::zero)
);
tnGradU() =
(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs();
tnGradU() -= n*(n&tnGradU());
return tnGradU;
// return
// (
// *this
// - (patchInternalField() + (k&gradU.patchInternalField()))
// )*this->patch().deltaCoeffs();
}
tmp<Field<vector> > elasticWallVelocityFvPatchVectorField::
gradientBoundaryCoeffs() const
{
bool secondOrder_ = false;
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
vectorField dUP = (k&gradU.patchInternalField());
if (secondOrder_)
{
vectorField nGradUP = (n&gradU.patchInternalField());
vectorField nGradU =
2
*(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs()
- nGradUP;
vectorField nGradUn = n*(n&nGradU);
return
this->patch().deltaCoeffs()
*(
2*(*this - dUP)
- patchInternalField()
)
- nGradUP
- nGradUn;
// return
// this->patch().deltaCoeffs()
// *(
// 2*(*this - dUP)
// - patchInternalField()
// )
// - nGradUP;
}
// First order
// vectorField dUP = (k&gradU.patchInternalField());
vectorField nGradU =
(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs();
vectorField nGradUn = n*(n&nGradU);
return
this->patch().deltaCoeffs()
*(
*this - dUP
)
- nGradUn;
// return this->patch().deltaCoeffs()
// *(*this - (k&gradU.patchInternalField()));
}
void elasticWallVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
elasticWallVelocityFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::elasticWallVelocityFvPatchVectorField
Description
Foam::elasticWallVelocityFvPatchVectorField
SourceFiles
elasticWallVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef elasticWallVelocityFvPatchVectorField_H
#define elasticWallVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class elasticWallVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class elasticWallVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField
{
//To keep track when to copy patch face centres
label myTimeIndex_;
//Old face centres of patch. Needed for (second order) time integration
vectorField Fc_;
vectorField oldFc_;
vectorField oldOldFc_;
public:
//- Runtime type information
TypeName("elasticWallVelocity");
// Constructors
//- Construct from patch and internal field
elasticWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
elasticWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given elasticWallVelocityFvPatchVectorField
// onto a new patch
elasticWallVelocityFvPatchVectorField
(
const elasticWallVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
elasticWallVelocityFvPatchVectorField
(
const elasticWallVelocityFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new elasticWallVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
elasticWallVelocityFvPatchVectorField
(
const elasticWallVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new elasticWallVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
// Evaluation functions
//- Return patch-normal gradient
virtual tmp<Field<vector> > snGrad() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<vector> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,701 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "extrapolatedFvPatchField.H"
#include "surfaceFields.H"
#include "dictionary.H"
#include "emptyPolyPatch.H"
#include "cyclicPolyPatch.H"
#include "scalarMatrices.H"
#include "volFields.H"
#include "skewCorrectionVectors.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(p, iF),
iPoints_(p.size()),
zeroGradient_(true),
fixesValue_(false)
{}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchField<Type>(ptf, p, iF, mapper),
iPoints_(p.size()),
zeroGradient_(ptf.zeroGradient_),
fixesValue_(ptf.fixesValue_)
{}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchField<Type>(p, iF),
iPoints_(p.size()),
zeroGradient_(true),
fixesValue_(false)
{
if (dict.found("zeroGradient"))
{
zeroGradient_ = Switch(dict.lookup("zeroGradient"));
}
this->valueFraction() = 0;
if (dict.found("fixesValue"))
{
fixesValue_ = Switch(dict.lookup("fixesValue"));
this->valueFraction() = 1.0;
}
if (dict.found("refValue"))
{
this->refValue() = Field<Type>("refValue", dict, p.size());
}
else
{
this->refValue() = pTraits<Type>::zero;
}
if (dict.found("refGradient"))
{
this->refGrad() = Field<Type>("refGradient", dict, p.size());
}
else
{
this->refGrad() = pTraits<Type>::zero;
}
if (dict.found("value"))
{
Field<Type>::operator=(Field<Type>("value", dict, p.size()));
}
else
{
mixedFvPatchField<Type>::evaluate();
}
// this->refValue() = pTraits<Type>::zero;
// this->refGrad() = pTraits<Type>::zero;
}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>& ptf
)
:
mixedFvPatchField<Type>(ptf),
iPoints_(ptf.size()),
zeroGradient_(ptf.zeroGradient_),
fixesValue_(ptf.fixesValue_)
{}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(ptf, iF),
iPoints_(ptf.size()),
zeroGradient_(ptf.zeroGradient_),
fixesValue_(ptf.fixesValue_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void extrapolatedFvPatchField<Type>::autoMap
(
const fvPatchFieldMapper& m
)
{
mixedFvPatchField<Type>::autoMap(m);
// gradient_.autoMap(m);
}
template<class Type>
void extrapolatedFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
mixedFvPatchField<Type>::rmap(ptf, addr);
// const extrapolatedFvPatchField<Type>& fgptf =
// refCast<const extrapolatedFvPatchField<Type> >(ptf);
// gradient_.rmap(fgptf.gradient_, addr);
}
template<class Type>
void extrapolatedFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
const cellList& cells = mesh.cells();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& patchCells = this->patch().faceCells();
const surfaceScalarField& weights = mesh.weights();
const vectorField& faceCentres = mesh.faceCentres();
const vectorField& cellCentres = mesh.cellCentres();
skewCorrectionVectors scv(mesh);
vectorField n = this->patch().nf();
iPoints_.clear();
iPoints_.setSize(this->patch().size());
forAll(patchCells, faceI)
{
label curCell = patchCells[faceI];
const labelList& curCellFaces = cells[curCell];
iPoints_.set(faceI, new DynamicList<vector>());
// Add face centre points
forAll(curCellFaces, fI)
{
label curFace = curCellFaces[fI];
label patchID = mesh.boundaryMesh().whichPatch(curFace);
if(mesh.isInternalFace(curFace))
{
vector curFaceIntersection =
weights[curFace]
*(
cellCentres[owner[curFace]]
- cellCentres[neighbour[curFace]]
)
+ cellCentres[neighbour[curFace]];
iPoints_[faceI].append(curFaceIntersection);
}
else if (patchID != this->patch().index())
{
if
(
mesh.boundaryMesh()[patchID].type()
== cyclicPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& cycPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
label sizeby2 = cycPatchCells.size()/2;
if (localFaceID < sizeby2)
{
vector curFaceIntersection =
weights[curFace]
*(
cellCentres[cycPatchCells[localFaceID]]
- cellCentres
[
cycPatchCells[localFaceID + sizeby2]
]
)
+ cellCentres
[
cycPatchCells[localFaceID + sizeby2]
];
iPoints_[faceI].append(curFaceIntersection);
}
else
{
vector curFaceIntersection =
weights[curFace]
*(
cellCentres[cycPatchCells[localFaceID]]
- cellCentres
[
cycPatchCells[localFaceID - sizeby2]
]
)
+ cellCentres
[
cycPatchCells[localFaceID - sizeby2]
];
iPoints_[faceI].append(curFaceIntersection);
}
}
else if
(
mesh.boundaryMesh()[patchID].type()
== processorPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& procPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
iPoints_[faceI].append
(
weights.boundaryField()[patchID][localFaceID]
*(
cellCentres[procPatchCells[localFaceID]]
- mesh.C().boundaryField()[patchID][localFaceID]
)
+ mesh.C().boundaryField()[patchID][localFaceID]
);
}
else if
(
mesh.boundaryMesh()[patchID].type()
== emptyPolyPatch::typeName
)
{
iPoints_[faceI].append(faceCentres[curFace]);
}
else
{
// Normal patches
iPoints_[faceI].append(faceCentres[curFace]);
}
}
}
}
mixedFvPatchField<Type>::updateCoeffs();
}
template<class Type>
void extrapolatedFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
const cellList& cells = mesh.cells();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& patchCells = this->patch().faceCells();
const surfaceScalarField& weights = mesh.weights();
// const vectorField& faceCentres = mesh.faceCentres();
const vectorField& cellCentres = mesh.cellCentres();
const Field<Type>& phiI = this->internalField();
word fieldName =
this->dimensionedInternalField().name();
const GeometricField<Type, fvPatchField, volMesh>& phi =
mesh.lookupObject<GeometricField<Type, fvPatchField, volMesh> >
(
fieldName
);
vectorField n = this->patch().nf();
const vectorField& C = this->patch().Cf();
Field<Type> patchPhi(this->patch().size(), pTraits<Type>::zero);
forAll(patchCells, faceI)
{
label curCell = patchCells[faceI];
const labelList& curCellFaces = cells[curCell];
DynamicList<Type> iPhi;
// DynamicList<vector> iPoint;
// // Add first cell centre point
// iPhi.append(phiI[curCell]);
// iPoint.append(cellCentres[curCell]);
// Add face centre points
forAll(curCellFaces, fI)
{
label curFace = curCellFaces[fI];
label patchID = mesh.boundaryMesh().whichPatch(curFace);
if(mesh.isInternalFace(curFace))
{
iPhi.append
(
weights[curFace]
*(
phiI[owner[curFace]]
- phiI[neighbour[curFace]]
)
+ phiI[neighbour[curFace]]
);
// vector curFaceIntersection =
// weights[curFace]
// *(
// cellCentres[owner[curFace]]
// - cellCentres[neighbour[curFace]]
// )
// + cellCentres[neighbour[curFace]];
// iPoint.append(curFaceIntersection);
}
else if (patchID != this->patch().index())
{
if
(
mesh.boundaryMesh()[patchID].type()
== cyclicPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& cycPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
label sizeby2 = cycPatchCells.size()/2;
if (localFaceID < sizeby2)
{
iPhi.append
(
weights.boundaryField()[patchID][localFaceID]
*(
phiI[cycPatchCells[localFaceID]]
- phiI[cycPatchCells[localFaceID + sizeby2]]
)
+ phiI[cycPatchCells[localFaceID + sizeby2]]
);
// vector curFaceIntersection =
// weights[curFace]
// *(
// cellCentres[cycPatchCells[localFaceID]]
// - cellCentres
// [
// cycPatchCells[localFaceID + sizeby2]
// ]
// )
// + cellCentres
// [
// cycPatchCells[localFaceID + sizeby2]
// ];
// iPoint.append(curFaceIntersection);
}
else
{
iPhi.append
(
weights.boundaryField()[patchID][localFaceID]
*(
phiI[cycPatchCells[localFaceID]]
- phiI[cycPatchCells[localFaceID - sizeby2]]
)
+ phiI[cycPatchCells[localFaceID - sizeby2]]
);
// vector curFaceIntersection =
// weights[curFace]
// *(
// cellCentres[cycPatchCells[localFaceID]]
// - cellCentres
// [
// cycPatchCells[localFaceID - sizeby2]
// ]
// )
// + cellCentres
// [
// cycPatchCells[localFaceID - sizeby2]
// ];
// iPoint.append(curFaceIntersection);
}
}
else if
(
mesh.boundaryMesh()[patchID].type()
== processorPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& procPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
iPhi.append
(
weights.boundaryField()[patchID][localFaceID]
*(
phiI[procPatchCells[localFaceID]]
- phi.boundaryField()[patchID][localFaceID]
)
+ phi.boundaryField()[patchID][localFaceID]
);
// const processorPolyPatch& procPatch =
// refCast<const processorPolyPatch>
// (
// mesh.boundaryMesh()[patchID]
// );
// vector ngbCellCentre =
// procPatch.neighbFaceCellCentres()[localFaceID];
// vector curFaceIntersection =
// faceCentres[curFace];
// iPoint.append(curFaceIntersection);
}
else if
(
mesh.boundaryMesh()[patchID].type()
== emptyPolyPatch::typeName
)
{
iPhi.append(phiI[curCell]);
// iPoint.append(faceCentres[curFace]);
}
else
{
// Normal patches
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
iPhi.append
(
phi.boundaryField()[patchID][localFaceID]
);
// iPoint.append(faceCentres[curFace]);
}
}
}
Type avgPhi = phiI[curCell];
vector avgPoint = cellCentres[curCell];
// Type avgPhi = average(iPhi);
// vector avgPoint = average(iPoint);
// Weights
scalarField W(iPoints_[faceI].size(), 1.0);
label nCoeffs = 3;
scalarRectangularMatrix M
(
iPoints_[faceI].size(),
nCoeffs,
0.0
);
// vector origin = C[faceI];
scalar L = max(mag(iPoints_[faceI]-avgPoint));
for (label i=0; i<iPoints_[faceI].size(); i++)
{
scalar X = (iPoints_[faceI][i].x() - avgPoint.x())/L;
scalar Y = (iPoints_[faceI][i].y() - avgPoint.y())/L;
scalar Z = (iPoints_[faceI][i].z() - avgPoint.z())/L;
M[i][0] = X;
M[i][1] = Y;
M[i][2] = Z;
}
// Applying weights
for (label i=0; i<M.n(); i++)
{
for (label j=0; j<M.m(); j++)
{
M[i][j] *= W[i];
}
}
tensor lsM = tensor::zero;
for (label i=0; i<3; i++)
{
for (label j=0; j<3; j++)
{
for (label k=0; k<M.n(); k++)
{
lsM(i,j) += M[k][i]*M[k][j];
}
}
}
// Calculate inverse
// Info << M << endl;
// Info << lsM << endl;
// Info << det(lsM) << endl;
tensor invLsM = inv(lsM);
scalarRectangularMatrix curInvMatrix
(
nCoeffs,
iPoints_[faceI].size(),
0.0
);
for (label i=0; i<3; i++)
{
for (label j=0; j<M.n(); j++)
{
for (label k=0; k<3; k++)
{
curInvMatrix[i][j] += invLsM(i,k)*M[j][k]*W[j];
}
}
}
Field<Type> coeffs(nCoeffs, pTraits<Type>::zero);
Field<Type> source(iPoints_[faceI].size(), pTraits<Type>::zero);
for (label i=0; i<iPoints_[faceI].size(); i++)
{
// source[i] = iPhi[i];
source[i] = iPhi[i] - avgPhi;
}
for (label i=0; i<nCoeffs; i++)
{
for (label j=0; j<source.size(); j++)
{
coeffs[i] += curInvMatrix[i][j]*source[j];
}
}
// vector dr = C[faceI] - origin;
vector dr = (C[faceI] - avgPoint)/L;
patchPhi[faceI] =
avgPhi
+ coeffs[0]*dr.x()
+ coeffs[1]*dr.y()
+ coeffs[2]*dr.z();
}
Field<Type>::operator=(patchPhi);
this->refValue() = patchPhi;
if (!fixesValue_)
{
if (zeroGradient_)
{
this->refGrad() = pTraits<Type>::zero;
}
else
{
this->refGrad() =
(patchPhi - this->patchInternalField())
*this->patch().deltaCoeffs();
}
}
fvPatchField<Type>::evaluate();
}
template<class Type>
void extrapolatedFvPatchField<Type>::write(Ostream& os) const
{
mixedFvPatchField<Type>::write(os);
// this->writeEntry("value", os);
os.writeKeyword("zeroGradient")
<< zeroGradient_ << token::END_STATEMENT << nl;
os.writeKeyword("fixesValue")
<< fixesValue_ << token::END_STATEMENT << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,196 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::extrapolatedFvPatchField
Description
Foam::extrapolatedFvPatchField
SourceFiles
extrapolatedFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedFvPatchField_H
#define extrapolatedFvPatchField_H
#include "mixedFvPatchField.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class extrapolatedFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class extrapolatedFvPatchField
:
public mixedFvPatchField<Type>
{
// Private data
//- Interpolation points
PtrList<DynamicList<vector> > iPoints_;
//- Return zero gradient
Switch zeroGradient_;
//- Fixes value
Switch fixesValue_;
public:
//- Runtime type information
TypeName("extrapolated");
// Constructors
//- Construct from patch and internal field
extrapolatedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
extrapolatedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping the given extrapolatedFvPatchField
// onto a new patch
extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new extrapolatedFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type> > clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type> >
(
new extrapolatedFvPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
//- Return true if this patch field fixes a value.
// Needed to check if a level has to be specified while solving
// Poissons equations.
virtual bool fixesValue() const
{
return fixesValue_;
}
// Return defining fields
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
// Sets Updated to true
virtual void updateCoeffs();
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "extrapolatedFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "extrapolatedFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(extrapolated);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedFvPatchFields_H
#define extrapolatedFvPatchFields_H
#include "extrapolatedFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(extrapolated)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedFvPatchFieldsFwd_H
#define extrapolatedFvPatchFieldsFwd_H
#include "fvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class extrapolatedFvPatchField;
makePatchTypeFieldTypedefs(extrapolated)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,658 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "extrapolatedFvPatchField.H"
#include "surfaceFields.H"
#include "dictionary.H"
#include "emptyPolyPatch.H"
#include "cyclicPolyPatch.H"
#include "scalarMatrices.H"
#include "volFields.H"
#include "skewCorrectionVectors.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
fixedGradientFvPatchField<Type>(p, iF),
iPoints_(p.size()),
zeroGradient_(true)
{}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedGradientFvPatchField<Type>(ptf, p, iF, mapper),
iPoints_(p.size()),
zeroGradient_(ptf.zeroGradient_)
{}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fixedGradientFvPatchField<Type>(p, iF),
iPoints_(p.size()),
zeroGradient_(true)
{
if (dict.found("zeroGradient"))
{
zeroGradient_ = Switch(dict.lookup("zeroGradient"));
}
if (dict.found("value"))
{
Field<Type>::operator=(Field<Type>("value", dict, p.size()));
}
else
{
fixedGradientFvPatchField<Type>::evaluate();
}
}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>& ptf
)
:
fixedGradientFvPatchField<Type>(ptf),
iPoints_(ptf.size()),
zeroGradient_(ptf.zeroGradient_)
{}
template<class Type>
extrapolatedFvPatchField<Type>::extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
fixedGradientFvPatchField<Type>(ptf, iF),
iPoints_(ptf.size()),
zeroGradient_(ptf.zeroGradient_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void extrapolatedFvPatchField<Type>::autoMap
(
const fvPatchFieldMapper& m
)
{
fixedGradientFvPatchField<Type>::autoMap(m);
// gradient_.autoMap(m);
}
template<class Type>
void extrapolatedFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
fixedGradientFvPatchField<Type>::rmap(ptf, addr);
// const extrapolatedFvPatchField<Type>& fgptf =
// refCast<const extrapolatedFvPatchField<Type> >(ptf);
// gradient_.rmap(fgptf.gradient_, addr);
}
template<class Type>
void extrapolatedFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
const cellList& cells = mesh.cells();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& patchCells = this->patch().faceCells();
const surfaceScalarField& weights = mesh.weights();
const vectorField& faceCentres = mesh.faceCentres();
const vectorField& cellCentres = mesh.cellCentres();
skewCorrectionVectors scv(mesh);
vectorField n = this->patch().nf();
iPoints_.clear();
iPoints_.setSize(this->patch().size());
forAll(patchCells, faceI)
{
label curCell = patchCells[faceI];
const labelList& curCellFaces = cells[curCell];
iPoints_.set(faceI, new DynamicList<vector>());
// Add face centre points
forAll(curCellFaces, fI)
{
label curFace = curCellFaces[fI];
label patchID = mesh.boundaryMesh().whichPatch(curFace);
if(mesh.isInternalFace(curFace))
{
vector curFaceIntersection =
weights[curFace]
*(
cellCentres[owner[curFace]]
- cellCentres[neighbour[curFace]]
)
+ cellCentres[neighbour[curFace]];
iPoints_[faceI].append(curFaceIntersection);
}
else if (patchID != this->patch().index())
{
if
(
mesh.boundaryMesh()[patchID].type()
== cyclicPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& cycPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
label sizeby2 = cycPatchCells.size()/2;
if (localFaceID < sizeby2)
{
vector curFaceIntersection =
weights[curFace]
*(
cellCentres[cycPatchCells[localFaceID]]
- cellCentres
[
cycPatchCells[localFaceID + sizeby2]
]
)
+ cellCentres
[
cycPatchCells[localFaceID + sizeby2]
];
iPoints_[faceI].append(curFaceIntersection);
}
else
{
vector curFaceIntersection =
weights[curFace]
*(
cellCentres[cycPatchCells[localFaceID]]
- cellCentres
[
cycPatchCells[localFaceID - sizeby2]
]
)
+ cellCentres
[
cycPatchCells[localFaceID - sizeby2]
];
iPoints_[faceI].append(curFaceIntersection);
}
}
else if
(
mesh.boundaryMesh()[patchID].type()
== processorPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& procPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
iPoints_[faceI].append
(
weights.boundaryField()[patchID][localFaceID]
*(
cellCentres[procPatchCells[localFaceID]]
- mesh.C().boundaryField()[patchID][localFaceID]
)
+ mesh.C().boundaryField()[patchID][localFaceID]
);
}
else if
(
mesh.boundaryMesh()[patchID].type()
== emptyPolyPatch::typeName
)
{
iPoints_[faceI].append(faceCentres[curFace]);
}
else
{
// Normal patches
iPoints_[faceI].append(faceCentres[curFace]);
}
}
}
}
fixedGradientFvPatchField<Type>::updateCoeffs();
}
template<class Type>
void extrapolatedFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
const cellList& cells = mesh.cells();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
const unallocLabelList& patchCells = this->patch().faceCells();
const surfaceScalarField& weights = mesh.weights();
// const vectorField& faceCentres = mesh.faceCentres();
const vectorField& cellCentres = mesh.cellCentres();
const Field<Type>& phiI = this->internalField();
word fieldName =
this->dimensionedInternalField().name();
const GeometricField<Type, fvPatchField, volMesh>& phi =
mesh.lookupObject<GeometricField<Type, fvPatchField, volMesh> >
(
fieldName
);
vectorField n = this->patch().nf();
const vectorField& C = this->patch().Cf();
Field<Type> patchPhi(this->patch().size(), pTraits<Type>::zero);
forAll(patchCells, faceI)
{
label curCell = patchCells[faceI];
const labelList& curCellFaces = cells[curCell];
DynamicList<Type> iPhi;
// DynamicList<vector> iPoint;
// // Add first cell centre point
// iPhi.append(phiI[curCell]);
// iPoint.append(cellCentres[curCell]);
// Add face centre points
forAll(curCellFaces, fI)
{
label curFace = curCellFaces[fI];
label patchID = mesh.boundaryMesh().whichPatch(curFace);
if(mesh.isInternalFace(curFace))
{
iPhi.append
(
weights[curFace]
*(
phiI[owner[curFace]]
- phiI[neighbour[curFace]]
)
+ phiI[neighbour[curFace]]
);
// vector curFaceIntersection =
// weights[curFace]
// *(
// cellCentres[owner[curFace]]
// - cellCentres[neighbour[curFace]]
// )
// + cellCentres[neighbour[curFace]];
// iPoint.append(curFaceIntersection);
}
else if (patchID != this->patch().index())
{
if
(
mesh.boundaryMesh()[patchID].type()
== cyclicPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& cycPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
label sizeby2 = cycPatchCells.size()/2;
if (localFaceID < sizeby2)
{
iPhi.append
(
weights.boundaryField()[patchID][localFaceID]
*(
phiI[cycPatchCells[localFaceID]]
- phiI[cycPatchCells[localFaceID + sizeby2]]
)
+ phiI[cycPatchCells[localFaceID + sizeby2]]
);
// vector curFaceIntersection =
// weights[curFace]
// *(
// cellCentres[cycPatchCells[localFaceID]]
// - cellCentres
// [
// cycPatchCells[localFaceID + sizeby2]
// ]
// )
// + cellCentres
// [
// cycPatchCells[localFaceID + sizeby2]
// ];
// iPoint.append(curFaceIntersection);
}
else
{
iPhi.append
(
weights.boundaryField()[patchID][localFaceID]
*(
phiI[cycPatchCells[localFaceID]]
- phiI[cycPatchCells[localFaceID - sizeby2]]
)
+ phiI[cycPatchCells[localFaceID - sizeby2]]
);
// vector curFaceIntersection =
// weights[curFace]
// *(
// cellCentres[cycPatchCells[localFaceID]]
// - cellCentres
// [
// cycPatchCells[localFaceID - sizeby2]
// ]
// )
// + cellCentres
// [
// cycPatchCells[localFaceID - sizeby2]
// ];
// iPoint.append(curFaceIntersection);
}
}
else if
(
mesh.boundaryMesh()[patchID].type()
== processorPolyPatch::typeName
)
{
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
const unallocLabelList& procPatchCells =
mesh.boundaryMesh()[patchID].faceCells();
iPhi.append
(
weights.boundaryField()[patchID][localFaceID]
*(
phiI[procPatchCells[localFaceID]]
- phi.boundaryField()[patchID][localFaceID]
)
+ phi.boundaryField()[patchID][localFaceID]
);
// const processorPolyPatch& procPatch =
// refCast<const processorPolyPatch>
// (
// mesh.boundaryMesh()[patchID]
// );
// vector ngbCellCentre =
// procPatch.neighbFaceCellCentres()[localFaceID];
// vector curFaceIntersection =
// faceCentres[curFace];
// iPoint.append(curFaceIntersection);
}
else if
(
mesh.boundaryMesh()[patchID].type()
== emptyPolyPatch::typeName
)
{
iPhi.append(phiI[curCell]);
// iPoint.append(faceCentres[curFace]);
}
else
{
// Normal patches
label start = mesh.boundaryMesh()[patchID].start();
label localFaceID = curFace - start;
iPhi.append
(
phi.boundaryField()[patchID][localFaceID]
);
// iPoint.append(faceCentres[curFace]);
}
}
}
Type avgPhi = phiI[curCell];
vector avgPoint = cellCentres[curCell];
// Type avgPhi = average(iPhi);
// vector avgPoint = average(iPoint);
// Weights
scalarField W(iPoints_[faceI].size(), 1.0);
label nCoeffs = 3;
scalarRectangularMatrix M
(
iPoints_[faceI].size(),
nCoeffs,
0.0
);
// vector origin = C[faceI];
scalar L = max(mag(iPoints_[faceI]-avgPoint));
for (label i=0; i<iPoints_[faceI].size(); i++)
{
scalar X = (iPoints_[faceI][i].x() - avgPoint.x())/L;
scalar Y = (iPoints_[faceI][i].y() - avgPoint.y())/L;
scalar Z = (iPoints_[faceI][i].z() - avgPoint.z())/L;
M[i][0] = X;
M[i][1] = Y;
M[i][2] = Z;
}
// Applying weights
for (label i=0; i<M.n(); i++)
{
for (label j=0; j<M.m(); j++)
{
M[i][j] *= W[i];
}
}
tensor lsM = tensor::zero;
for (label i=0; i<3; i++)
{
for (label j=0; j<3; j++)
{
for (label k=0; k<M.n(); k++)
{
lsM(i,j) += M[k][i]*M[k][j];
}
}
}
// Calculate inverse
// Info << M << endl;
// Info << lsM << endl;
// Info << det(lsM) << endl;
tensor invLsM = inv(lsM);
scalarRectangularMatrix curInvMatrix
(
nCoeffs,
iPoints_[faceI].size(),
0.0
);
for (label i=0; i<3; i++)
{
for (label j=0; j<M.n(); j++)
{
for (label k=0; k<3; k++)
{
curInvMatrix[i][j] += invLsM(i,k)*M[j][k]*W[j];
}
}
}
Field<Type> coeffs(nCoeffs, pTraits<Type>::zero);
Field<Type> source(iPoints_[faceI].size(), pTraits<Type>::zero);
for (label i=0; i<iPoints_[faceI].size(); i++)
{
// source[i] = iPhi[i];
source[i] = iPhi[i] - avgPhi;
}
for (label i=0; i<nCoeffs; i++)
{
for (label j=0; j<source.size(); j++)
{
coeffs[i] += curInvMatrix[i][j]*source[j];
}
}
// vector dr = C[faceI] - origin;
vector dr = (C[faceI] - avgPoint)/L;
patchPhi[faceI] =
avgPhi
+ coeffs[0]*dr.x()
+ coeffs[1]*dr.y()
+ coeffs[2]*dr.z();
}
Field<Type>::operator=(patchPhi);
if (zeroGradient_)
{
this->gradient() = pTraits<Type>::zero;
}
else
{
this->gradient() =
(patchPhi - this->patchInternalField())
*this->patch().deltaCoeffs();
}
fvPatchField<Type>::evaluate();
}
template<class Type>
void extrapolatedFvPatchField<Type>::write(Ostream& os) const
{
fixedGradientFvPatchField<Type>::write(os);
this->writeEntry("value", os);
os.writeKeyword("zeroGradient")
<< zeroGradient_ << token::END_STATEMENT << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,185 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::extrapolatedFvPatchField
Description
Foam::extrapolatedFvPatchField
SourceFiles
extrapolatedFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedFvPatchField_H
#define extrapolatedFvPatchField_H
#include "fixedGradientFvPatchField.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class extrapolatedFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class extrapolatedFvPatchField
:
public fixedGradientFvPatchField<Type>
{
// Private data
//- Interpolation points
PtrList<DynamicList<vector> > iPoints_;
//- Return zero gradient
Switch zeroGradient_;
public:
//- Runtime type information
TypeName("extrapolated");
// Constructors
//- Construct from patch and internal field
extrapolatedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
extrapolatedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping the given extrapolatedFvPatchField
// onto a new patch
extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new extrapolatedFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
extrapolatedFvPatchField
(
const extrapolatedFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type> > clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type> >
(
new extrapolatedFvPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
// Return defining fields
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
// Sets Updated to true
virtual void updateCoeffs();
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "extrapolatedFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "extrapolatedFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(extrapolated);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedFvPatchFields_H
#define extrapolatedFvPatchFields_H
#include "extrapolatedFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(extrapolated)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedFvPatchFieldsFwd_H
#define extrapolatedFvPatchFieldsFwd_H
#include "fvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class extrapolatedFvPatchField;
makePatchTypeFieldTypedefs(extrapolated)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "extrapolatedPressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "uniformDimensionedFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
extrapolatedPressureFvPatchScalarField::
extrapolatedPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
zeroGradientFvPatchScalarField(p, iF)
{}
extrapolatedPressureFvPatchScalarField::
extrapolatedPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
zeroGradientFvPatchScalarField(p, iF)
{
fvPatchField<scalar>::operator=(patchInternalField());
}
extrapolatedPressureFvPatchScalarField::
extrapolatedPressureFvPatchScalarField
(
const extrapolatedPressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
zeroGradientFvPatchScalarField(ptf, p, iF, mapper)
{}
extrapolatedPressureFvPatchScalarField::
extrapolatedPressureFvPatchScalarField
(
const extrapolatedPressureFvPatchScalarField& ptf
)
:
zeroGradientFvPatchScalarField(ptf)
{}
extrapolatedPressureFvPatchScalarField::
extrapolatedPressureFvPatchScalarField
(
const extrapolatedPressureFvPatchScalarField& ptf,
const DimensionedField<scalar, volMesh>& iF
)
:
zeroGradientFvPatchScalarField(ptf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void extrapolatedPressureFvPatchScalarField::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}
const fvPatchField<vector>& gradP =
patch().lookupPatchField<volVectorField, vector>("grad(p)");
vectorField delta = this->patch().delta();
Field<scalar>::operator=
(
this->patchInternalField() + (delta & gradP.patchInternalField())
);
fvPatchField<scalar>::evaluate();
}
// void extrapolatedPressureFvPatchScalarField::updateCoeffs()
// {
// if (updated())
// {
// return;
// }
// const uniformDimensionedVectorField& g =
// db().lookupObject<uniformDimensionedVectorField>("g");
// const fvPatchField<scalar>& rho =
// patch().lookupPatchField<volScalarField, scalar>(rhoName_);
// // If the variable name is "p_rgh" or "pd" assume it is p - rho*g.h
// // and set the gradient appropriately.
// // Otherwise assume the variable is the static pressure.
// if
// (
// dimensionedInternalField().name() == "p_rgh"
// || dimensionedInternalField().name() == "pd"
// )
// {
// gradient() = -rho.snGrad()*(g.value() & patch().Cf());
// }
// else
// {
// gradient() = rho*(g.value() & patch().nf());
// }
// zeroGradientFvPatchScalarField::updateCoeffs();
// }
void extrapolatedPressureFvPatchScalarField::write(Ostream& os) const
{
zeroGradientFvPatchScalarField::write(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
extrapolatedPressureFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------* \
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::extrapolatedPressureFvPatchScalarField
Description
Set the pressure gradient boundary condition appropriately for buoyant flow.
If the variable name is "pd" assume it is p - rho*g.h and set the gradient
appropriately. Otherwise assume the variable is the static pressure.
SourceFiles
extrapolatedPressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedPressureFvPatchScalarFields_H
#define extrapolatedPressureFvPatchScalarFields_H
#include "fvPatchFields.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class extrapolatedPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class extrapolatedPressureFvPatchScalarField
:
public zeroGradientFvPatchScalarField
{
// Private data
public:
//- Runtime type information
TypeName("extrapolatedPressure");
// Constructors
//- Construct from patch and internal field
extrapolatedPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
extrapolatedPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// extrapolatedPressureFvPatchScalarField onto a new patch
extrapolatedPressureFvPatchScalarField
(
const extrapolatedPressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
extrapolatedPressureFvPatchScalarField
(
const extrapolatedPressureFvPatchScalarField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new extrapolatedPressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
extrapolatedPressureFvPatchScalarField
(
const extrapolatedPressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new extrapolatedPressureFvPatchScalarField(*this, iF)
);
}
// Member functions
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "extrapolatedVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "uniformDimensionedFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
extrapolatedVelocityFvPatchVectorField::
extrapolatedVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
zeroGradientFvPatchVectorField(p, iF)
{}
extrapolatedVelocityFvPatchVectorField::
extrapolatedVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
zeroGradientFvPatchVectorField(p, iF)
{
fvPatchField<vector>::operator=(patchInternalField());
}
extrapolatedVelocityFvPatchVectorField::
extrapolatedVelocityFvPatchVectorField
(
const extrapolatedVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
zeroGradientFvPatchVectorField(ptf, p, iF, mapper)
{}
extrapolatedVelocityFvPatchVectorField::
extrapolatedVelocityFvPatchVectorField
(
const extrapolatedVelocityFvPatchVectorField& ptf
)
:
zeroGradientFvPatchVectorField(ptf)
{}
extrapolatedVelocityFvPatchVectorField::
extrapolatedVelocityFvPatchVectorField
(
const extrapolatedVelocityFvPatchVectorField& ptf,
const DimensionedField<vector, volMesh>& iF
)
:
zeroGradientFvPatchVectorField(ptf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void extrapolatedVelocityFvPatchVectorField::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>("grad(U)");
vectorField delta = this->patch().delta();
Field<vector>::operator=
(
this->patchInternalField() + (delta & gradU.patchInternalField())
);
fvPatchField<vector>::evaluate();
}
// void extrapolatedVelocityFvPatchVectorField::updateCoeffs()
// {
// if (updated())
// {
// return;
// }
// const uniformDimensionedVectorField& g =
// db().lookupObject<uniformDimensionedVectorField>("g");
// const fvPatchField<vector>& rho =
// patch().lookupPatchField<volVectorField, vector>(rhoName_);
// // If the variable name is "p_rgh" or "pd" assume it is p - rho*g.h
// // and set the gradient appropriately.
// // Otherwise assume the variable is the static pressure.
// if
// (
// dimensionedInternalField().name() == "p_rgh"
// || dimensionedInternalField().name() == "pd"
// )
// {
// gradient() = -rho.snGrad()*(g.value() & patch().Cf());
// }
// else
// {
// gradient() = rho*(g.value() & patch().nf());
// }
// zeroGradientFvPatchVectorField::updateCoeffs();
// }
void extrapolatedVelocityFvPatchVectorField::write(Ostream& os) const
{
zeroGradientFvPatchVectorField::write(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
extrapolatedVelocityFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------* \
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::extrapolatedVelocityFvPatchVectorField
Description
Set the pressure gradient boundary condition appropriately for buoyant flow.
If the variable name is "pd" assume it is p - rho*g.h and set the gradient
appropriately. Otherwise assume the variable is the static pressure.
SourceFiles
extrapolatedVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef extrapolatedVelocityFvPatchVectorFields_H
#define extrapolatedVelocityFvPatchVectorFields_H
#include "fvPatchFields.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class extrapolatedPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class extrapolatedVelocityFvPatchVectorField
:
public zeroGradientFvPatchScalarField
{
// Private data
public:
//- Runtime type information
TypeName("extrapolatedPressure");
// Constructors
//- Construct from patch and internal field
extrapolatedVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
extrapolatedVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// extrapolatedVelocityFvPatchVectorField onto a new patch
extrapolatedVelocityFvPatchVectorField
(
const extrapolatedVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
extrapolatedVelocityFvPatchVectorField
(
const extrapolatedVelocityFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new extrapolatedVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
extrapolatedVelocityFvPatchVectorField
(
const extrapolatedVelocityFvPatchVectorField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new extrapolatedVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,220 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fixedVelocityPressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "uniformDimensionedFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
fixedVelocityPressureFvPatchScalarField::
fixedVelocityPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedGradientFvPatchScalarField(p, iF)
{}
fixedVelocityPressureFvPatchScalarField::
fixedVelocityPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
fixedGradientFvPatchScalarField(p, iF)
{
fvPatchField<scalar>::operator=(patchInternalField());
}
fixedVelocityPressureFvPatchScalarField::
fixedVelocityPressureFvPatchScalarField
(
const fixedVelocityPressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedGradientFvPatchScalarField(ptf, p, iF, mapper)
{}
fixedVelocityPressureFvPatchScalarField::
fixedVelocityPressureFvPatchScalarField
(
const fixedVelocityPressureFvPatchScalarField& ptf
)
:
fixedGradientFvPatchScalarField(ptf)
{}
fixedVelocityPressureFvPatchScalarField::
fixedVelocityPressureFvPatchScalarField
(
const fixedVelocityPressureFvPatchScalarField& ptf,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedGradientFvPatchScalarField(ptf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// void fixedVelocityPressureFvPatchScalarField::evaluate
// (
// const Pstream::commsTypes
// )
// {
// if (!this->updated())
// {
// this->updateCoeffs();
// }
// const fvMesh& mesh = this->patch().boundaryMesh().mesh();
// if
// (
// mesh.found("HU")
// && mesh.found("rAU")
// && mesh.found("phi")
// )
// {
// Info << "fixedVelocityPressureFvPatchScalarField::evaluate" << endl;
// const fvPatchField<vector>& HU =
// patch().lookupPatchField<volVectorField, vector>("HU");
// const fvPatchField<scalar>& rAU =
// patch().lookupPatchField<volScalarField, scalar>("rAU");
// const fvsPatchField<scalar>& phi =
// patch().lookupPatchField<surfaceScalarField, scalar>("phi");
// scalarField magS = this->patch().magSf();
// vectorField n = this->patch().nf();
// scalarField dn = 1.0/this->patch().deltaCoeffs();
// scalarField nGradP = (n & HU) - phi/rAU/magS;
// Field<scalar>::operator=
// (
// this->patchInternalField() + (dn*nGradP)
// );
// fvPatchField<scalar>::evaluate();
// }
// else
// {
// fixedGradientFvPatchField<scalar>::evaluate();
// }
// }
void fixedVelocityPressureFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
// const fvPatchField<vector>& U =
// patch().lookupPatchField<volVectorField, vector>("U");
const fvPatchField<vector>& laplacianU =
patch().lookupPatchField<volVectorField, vector>("laplacian(U)");
// const fvPatchField<tensor>& gradU =
// patch().lookupPatchField<volTensorField, tensor>("grad(U)");
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar nu(transportProperties.lookup("nu"));
scalarField dn = 1.0/this->patch().deltaCoeffs();
vectorField n = this->patch().nf();
// scalarField Un = (n & U);
// scalarField UnP = (n & U.patchInternalField());
// scalarField nGradUnP = (n & (gradU.patchInternalField() & n));
gradient() = (n & laplacianU.patchInternalField());
Info << patch().name() << ", nGradP, max: " << max(gradient())
<< ", avg: " << average(gradient())
<< ", min: " << min(gradient()) << endl;
fixedGradientFvPatchScalarField::updateCoeffs();
}
void fixedVelocityPressureFvPatchScalarField::write(Ostream& os) const
{
fixedGradientFvPatchScalarField::write(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
fixedVelocityPressureFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------* \
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::fixedVelocityPressureFvPatchScalarField
Description
Set the pressure gradient boundary condition appropriately for boundary where
velocity is fixed.
SourceFiles
fixedVelocityPressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef fixedVelocityPressureFvPatchScalarFields_H
#define fixedVelocityPressureFvPatchScalarFields_H
#include "fvPatchFields.H"
#include "fixedGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fixedVelocityPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class fixedVelocityPressureFvPatchScalarField
:
public fixedGradientFvPatchScalarField
{
// Private data
public:
//- Runtime type information
TypeName("fixedVelocityPressure");
// Constructors
//- Construct from patch and internal field
fixedVelocityPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
fixedVelocityPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// fixedVelocityPressureFvPatchScalarField onto a new patch
fixedVelocityPressureFvPatchScalarField
(
const fixedVelocityPressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
fixedVelocityPressureFvPatchScalarField
(
const fixedVelocityPressureFvPatchScalarField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new fixedVelocityPressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
fixedVelocityPressureFvPatchScalarField
(
const fixedVelocityPressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new fixedVelocityPressureFvPatchScalarField(*this, iF)
);
}
// Member functions
//-
virtual void updateCoeffs();
// //- Evaluate the patch field
// virtual void evaluate
// (
// const Pstream::commsTypes commsType=Pstream::blocking
// );
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,235 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "freeSurfacePressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::freeSurfacePressureFvPatchScalarField::
freeSurfacePressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(p, iF),
curTimeIndex_(-1)
{}
Foam::freeSurfacePressureFvPatchScalarField::
freeSurfacePressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchScalarField(p, iF),
curTimeIndex_(-1)
{
fvPatchScalarField::operator=(patchInternalField());
}
Foam::freeSurfacePressureFvPatchScalarField::
freeSurfacePressureFvPatchScalarField
(
const freeSurfacePressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchScalarField(ptf, p, iF, mapper),
curTimeIndex_(-1)
{}
Foam::freeSurfacePressureFvPatchScalarField::
freeSurfacePressureFvPatchScalarField
(
const freeSurfacePressureFvPatchScalarField& fcvpvf,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(fcvpvf, iF),
curTimeIndex_(-1)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::freeSurfacePressureFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
if (true)
// if (curTimeIndex_ != this->db().time().timeIndex())
{
curTimeIndex_ = this->db().time().timeIndex();
const fvPatchField<vector>& U =
patch().lookupPatchField<volVectorField, vector>
(
"U"
);
vectorField n = this->patch().nf();
scalarField nGradUn = (n & U.snGrad());
const fvMesh& mesh =
this->patch().boundaryMesh().mesh();
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar nu(transportProperties.lookup("nu"));
// scalarField newFsPressure = -2*nu.value()*nGradUn;
// scalarField oldFsPressure = *this;
// scalar relaxationFactor = 0.3;
// fvPatchScalarField::operator=
// (
// oldFsPressure
// + relaxationFactor*(newFsPressure - oldFsPressure)
// );
fvPatchScalarField::operator==(2*nu.value()*nGradUn);
}
fixedValueFvPatchScalarField::updateCoeffs();
}
Foam::tmp<Foam::Field<Foam::scalar> >
Foam::freeSurfacePressureFvPatchScalarField::snGrad() const
{
word pName = this->dimensionedInternalField().name();
const fvPatchField<vector>& gradp =
patch().lookupPatchField<volVectorField, vector>
(
"grad(" + pName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
bool secondOrder_ = true;
if (secondOrder_)
{
scalarField dpP = (k&gradp.patchInternalField());
scalarField nGradpP = (n&gradp.patchInternalField());
return
2
*(
*this
- (this->patchInternalField() + dpP)
)*this->patch().deltaCoeffs()
- nGradpP;
}
return
(
*this
- (patchInternalField() + (k&gradp.patchInternalField()))
)*this->patch().deltaCoeffs();
}
Foam::tmp<Foam::Field<Foam::scalar> >
Foam::freeSurfacePressureFvPatchScalarField::gradientBoundaryCoeffs() const
{
word pName = this->dimensionedInternalField().name();
const fvPatchField<vector>& gradp =
patch().lookupPatchField<volVectorField, vector>
(
"grad(" + pName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
bool secondOrder_ = true;
if (secondOrder_)
{
scalarField dpP = (k&gradp.patchInternalField());
scalarField nGradpP = (n&gradp.patchInternalField());
return
this->patch().deltaCoeffs()
*(
2*(*this - dpP)
- this->patchInternalField()
)
- nGradpP;
}
return this->patch().deltaCoeffs()
*(*this - (k&gradp.patchInternalField()));
}
void Foam::freeSurfacePressureFvPatchScalarField::write(Ostream& os) const
{
fixedValueFvPatchScalarField::write(os);
// writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchScalarField,
freeSurfacePressureFvPatchScalarField
);
}
// ************************************************************************* //

View file

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::freeSurfacePressureFvPatchScalarField
Description
Pressure outlet boundary condition for patches where the pressure is
specified. The outflow velocity is obtained by "fixedGradient" and then
corrected from the flux.
SourceFiles
freeSurfacePressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef freeSurfacePressureFvPatchScalarField_H
#define freeSurfacePressureFvPatchScalarField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class freeSurfacePressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class freeSurfacePressureFvPatchScalarField
:
public fixedValueFvPatchScalarField
{
// Private data
//- Current time index
label curTimeIndex_;
public:
//- Runtime type information
TypeName("freeSurfacePressure");
// Constructors
//- Construct from patch and internal field
freeSurfacePressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
freeSurfacePressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given freeSurfacePressureFvPatchScalarField
// onto a new patch
freeSurfacePressureFvPatchScalarField
(
const freeSurfacePressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new freeSurfacePressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
freeSurfacePressureFvPatchScalarField
(
const freeSurfacePressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new freeSurfacePressureFvPatchScalarField(*this, iF)
);
}
// Member functions
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Return patch-normal gradient
virtual tmp<Field<scalar> > snGrad() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<scalar> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,285 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "freeSurfaceVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::freeSurfaceVelocityFvPatchVectorField::
freeSurfaceVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(p, iF),
phiName_("phi"),
rhoName_("rho"),
curTimeIndex_(-1)
{}
Foam::freeSurfaceVelocityFvPatchVectorField::
freeSurfaceVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedGradientFvPatchVectorField(p, iF),
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
rhoName_(dict.lookupOrDefault<word>("rho", "rho")),
curTimeIndex_(-1)
{
fvPatchVectorField::operator=(patchInternalField());
}
Foam::freeSurfaceVelocityFvPatchVectorField::
freeSurfaceVelocityFvPatchVectorField
(
const freeSurfaceVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedGradientFvPatchVectorField(ptf, p, iF, mapper),
phiName_(ptf.phiName_),
rhoName_(ptf.rhoName_),
curTimeIndex_(-1)
{}
Foam::freeSurfaceVelocityFvPatchVectorField::
freeSurfaceVelocityFvPatchVectorField
(
const freeSurfaceVelocityFvPatchVectorField& fcvpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(fcvpvf, iF),
phiName_(fcvpvf.phiName_),
rhoName_(fcvpvf.rhoName_),
curTimeIndex_(-1)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::freeSurfaceVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
// if (curTimeIndex_ != this->db().time().timeIndex())
{
// curTimeIndex_ = this->db().time().timeIndex();
// const fvMesh& mesh =
// this->patch().boundaryMesh().mesh();
// IOdictionary transportProperties
// (
// IOobject
// (
// "transportProperties",
// mesh.time().constant(),
// mesh,
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// );
// dimensionedScalar nu(transportProperties.lookup("nu"));
vectorField n = this->patch().nf();
// const volScalarField& p =
// db().lookupObject<volScalarField>("p");
// const fvPatchField<scalar>& pfs =
// patch().patchField<volScalarField, scalar>(p);
// gradient() = (pfs/(2*nu.value()))*n;
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
// tensorField gradUP = gradU;
tensorField gradUP = gradU.patchInternalField();
vectorField sGradUn = (((I-sqr(n)) & gradUP) & n);
vectorField nGradUn = -tr(((I-sqr(n)) & gradUP) & (I-sqr(n)))*n;
gradient() = nGradUn - sGradUn;
}
fixedGradientFvPatchVectorField::updateCoeffs();
}
void Foam::freeSurfaceVelocityFvPatchVectorField::evaluate
(
const Pstream::commsTypes
)
{
if (!updated())
{
updateCoeffs();
}
// fixedGradientFvPatchVectorField::evaluate();
// Evaluate tangential component of velocity
// using second order discretisation
if (true)
{
// Info << "Evaluate free surface velocity "
// << "using second order correction"
// << endl;
vectorField n = patch().nf();
vectorField delta = patch().delta();
vectorField k = delta - n*(n&delta);
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
vectorField dUP = (k&gradU.patchInternalField());
if (true)
{
vectorField nGradUP = (n&gradU.patchInternalField());
Field<vector>::operator=
(
this->patchInternalField() + dUP
+ 0.5*(gradient() + nGradUP)
/this->patch().deltaCoeffs()
);
}
else
{
Field<vector>::operator=
(
this->patchInternalField() + dUP
+ gradient()/this->patch().deltaCoeffs()
);
}
}
if (!this->db().objectRegistry::found(phiName_))
{
// Flux not available, do not update
return;
}
const surfaceScalarField& phi =
db().lookupObject<surfaceScalarField>(phiName_);
const fvsPatchField<scalar>& phip =
patch().patchField<surfaceScalarField, scalar>(phi);
vectorField n = patch().nf();
const Field<scalar>& magS = patch().magSf();
if (phi.dimensions() == dimVelocity*dimArea)
{
operator==(*this - n*(n & *this) + n*phip/magS);
}
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
{
if (!this->db().objectRegistry::found(rhoName_))
{
// Rho not available, do not update
return;
}
const fvPatchField<scalar>& rhop =
lookupPatchField<volScalarField, scalar>(rhoName_);
operator==(*this - n*(n & *this) + n*phip/(rhop*magS));
}
else
{
FatalErrorIn
(
"freeSurfaceVelocityFvPatchVectorField::evaluate()"
)
<< "dimensions of phi are incorrect\n"
<< " on patch " << this->patch().name()
<< " of field " << this->dimensionedInternalField().name()
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalError);
}
fvPatchField<vector>::evaluate();
}
void Foam::freeSurfaceVelocityFvPatchVectorField::write(Ostream& os) const
{
fixedGradientFvPatchVectorField::write(os);
if (phiName_ != "phi")
{
os.writeKeyword("phi") << phiName_ << token::END_STATEMENT << nl;
}
if (rhoName_ != "rho")
{
os.writeKeyword("rho") << rhoName_ << token::END_STATEMENT << nl;
}
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchVectorField,
freeSurfaceVelocityFvPatchVectorField
);
}
// ************************************************************************* //

View file

@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::freeSurfaceVelocityFvPatchVectorField
Description
Velocity outlet boundary condition for patches where the pressure is
specified. The outflow velocity is obtained by "fixedGradient" and then
corrected from the flux.
SourceFiles
freeSurfaceVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef freeSurfaceVelocityFvPatchVectorField_H
#define freeSurfaceVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class freeSurfaceVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class freeSurfaceVelocityFvPatchVectorField
:
public fixedGradientFvPatchVectorField
{
// Private data
//- Name of flux field
word phiName_;
//- Name of density field
word rhoName_;
//- Current time index
label curTimeIndex_;
public:
//- Runtime type information
TypeName("freeSurfaceVelocity");
// Constructors
//- Construct from patch and internal field
freeSurfaceVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
freeSurfaceVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given freeSurfaceVelocityFvPatchVectorField
// onto a new patch
freeSurfaceVelocityFvPatchVectorField
(
const freeSurfaceVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new freeSurfaceVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
freeSurfaceVelocityFvPatchVectorField
(
const freeSurfaceVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new freeSurfaceVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,249 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "movingWallPressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "uniformDimensionedFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
movingWallPressureFvPatchScalarField::
movingWallPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedGradientFvPatchScalarField(p, iF)
{}
movingWallPressureFvPatchScalarField::
movingWallPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
fixedGradientFvPatchScalarField(p, iF)
{
fvPatchField<scalar>::operator=(patchInternalField());
}
movingWallPressureFvPatchScalarField::
movingWallPressureFvPatchScalarField
(
const movingWallPressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedGradientFvPatchScalarField(ptf, p, iF, mapper)
{}
movingWallPressureFvPatchScalarField::
movingWallPressureFvPatchScalarField
(
const movingWallPressureFvPatchScalarField& ptf
)
:
fixedGradientFvPatchScalarField(ptf)
{}
movingWallPressureFvPatchScalarField::
movingWallPressureFvPatchScalarField
(
const movingWallPressureFvPatchScalarField& ptf,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedGradientFvPatchScalarField(ptf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void movingWallPressureFvPatchScalarField::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}
const fvMesh& mesh = this->patch().boundaryMesh().mesh();
word fieldName = dimensionedInternalField().name();
const volScalarField& p =
mesh.lookupObject<volScalarField>(fieldName);
const fvPatchField<vector>& gradP =
patch().lookupPatchField<volVectorField, vector>("grad(p)");
const fvPatchField<vector>& ddtU =
patch().lookupPatchField<volVectorField, vector>("ddt(U)");
// vectorField delta = this->patch().delta();
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
scalarField dPP = (k&gradP.patchInternalField());
scalarField nGradPb(this->patch().size(), 0);
if (p.dimensions() == dimPressure)
{
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar rho
(
transportProperties.lookup("rho")
);
nGradPb = -rho.value()*(n&ddtU);
// nGradPb = -rho.value()*(n&prevAcceleration_);
}
else
{
nGradPb = -(n&ddtU);
// nGradPb = -(n&prevAcceleration_);
}
// scalarField gradPb = -(n&ddtU);
// scalarField gradPp = (n&gradP.patchInternalField());
Info << "ddtUn, max: " << max(n&ddtU)
<< ", avg: " << average(n&ddtU)
<< ", min: " << min(n&ddtU) << endl;
Field<scalar>::operator=
(
// this->patchInternalField()
this->patchInternalField() + dPP
+ nGradPb/this->patch().deltaCoeffs()
// + 0.5*(gradient() + gradPp)/this->patch().deltaCoeffs()
);
Info << "p, max: " << max(*this)
<< ", avg: " << average(*this)
<< ", min: " << min(*this) << endl;
fvPatchField<scalar>::evaluate();
}
// void movingWallPressureFvPatchScalarField::updateCoeffs()
// {
// if (updated())
// {
// return;
// }
// const fvMesh& mesh = this->patch().boundaryMesh().mesh();
// word fieldName = dimensionedInternalField().name();
// const volScalarField& p =
// mesh.lookupObject<volScalarField>(fieldName);
// const fvPatchField<vector>& ddtU =
// patch().lookupPatchField<volVectorField, vector>("ddt(U)");
// vectorField n = this->patch().nf();
// if (p.dimensions() == dimPressure)
// {
// IOdictionary transportProperties
// (
// IOobject
// (
// "transportProperties",
// mesh.time().constant(),
// mesh,
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// );
// dimensionedScalar rho
// (
// transportProperties.lookup("rho")
// );
// gradient() = -rho.value()*(n&ddtU);
// }
// else
// {
// gradient() = -(n&ddtU);
// }
// fixedGradientFvPatchScalarField::updateCoeffs();
// }
void movingWallPressureFvPatchScalarField::write(Ostream& os) const
{
fixedGradientFvPatchScalarField::write(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
movingWallPressureFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------* \
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
movingWallPressureFvPatchScalarField
Description
SourceFiles
movingWallPressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef movingWallPressureFvPatchScalarFields_H
#define movingWallPressureFvPatchScalarFields_H
#include "fvPatchFields.H"
#include "fixedGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class movingWallPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class movingWallPressureFvPatchScalarField
:
public fixedGradientFvPatchScalarField
{
// Private data
//- Acceleration of the solid side of the interface
// in the previous fsi iteration
vectorField prevAcceleration_;
public:
//- Runtime type information
TypeName("movingWallPressure");
// Constructors
//- Construct from patch and internal field
movingWallPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
movingWallPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// movingWallPressureFvPatchScalarField onto a new patch
movingWallPressureFvPatchScalarField
(
const movingWallPressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
movingWallPressureFvPatchScalarField
(
const movingWallPressureFvPatchScalarField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new movingWallPressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
movingWallPressureFvPatchScalarField
(
const movingWallPressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new movingWallPressureFvPatchScalarField(*this, iF)
);
}
// Member functions
// //- Update the coefficients associated with the patch field
// virtual void updateCoeffs();
//- Get previous pressure patch field
const vectorField& prevAcceleration() const
{
return prevAcceleration_;
}
//- Get previous pressure patch field
vectorField& prevAcceleration()
{
return prevAcceleration_;
}
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,411 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "movingWallVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvcMeshPhi.H"
#include "backwardDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
movingWallVelocityFvPatchVectorField::movingWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
myTimeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldoldFc_(p.patch().size(),vector::zero)
{}
movingWallVelocityFvPatchVectorField::movingWallVelocityFvPatchVectorField
(
const movingWallVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
myTimeIndex_(ptf.myTimeIndex_),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldoldFc_(p.patch().size(),vector::zero)
{}
movingWallVelocityFvPatchVectorField::movingWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
myTimeIndex_(dimensionedInternalField().mesh().time().timeIndex()),
Fc_(p.patch().size(),vector::zero),
oldFc_(p.patch().size(),vector::zero),
oldoldFc_(p.patch().size(),vector::zero)
{
fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
const fvMesh& mesh = dimensionedInternalField().mesh();
const pointField& points = mesh.allPoints();
forAll(Fc_, i)
{
Fc_[i] = patch().patch()[i].centre(points);
}
oldFc_ = Fc_;
oldoldFc_ = Fc_;
}
movingWallVelocityFvPatchVectorField::movingWallVelocityFvPatchVectorField
(
const movingWallVelocityFvPatchVectorField& pivpvf
)
:
fixedValueFvPatchVectorField(pivpvf),
myTimeIndex_(pivpvf.myTimeIndex_),
Fc_(pivpvf.Fc_),
oldFc_(pivpvf.oldFc_),
oldoldFc_(pivpvf.oldoldFc_)
{}
movingWallVelocityFvPatchVectorField::movingWallVelocityFvPatchVectorField
(
const movingWallVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
myTimeIndex_(pivpvf.myTimeIndex_),
Fc_(pivpvf.oldFc_),
oldFc_(pivpvf.oldFc_),
oldoldFc_(pivpvf.oldoldFc_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void movingWallVelocityFvPatchVectorField::updateCoeffs()
{
// Info << "movingWallVelocityFvPatchVectorField::updateCoeffs" << endl;
if (updated())
{
return;
}
const fvMesh& mesh = dimensionedInternalField().mesh();
const fvPatch& p = patch();
const polyPatch& pp = p.patch();
const pointField& points = mesh.allPoints();
vectorField Up(p.size(), vector::zero);
//const pointField& oldPoints = mesh.oldPoints();
const volVectorField& U =
mesh.lookupObject<volVectorField>
(
dimensionedInternalField().name()
);
word ddtScheme
(
mesh.schemesDict().ddtScheme("ddt(" + U.name() +')')
);
if (ddtScheme == fv::backwardDdtScheme<vector>::typeName)
{
// Info << "void movingWallVelocityFvPatchVectorField::updateCoeffs() - "
// << "backward"
// << endl;
if(myTimeIndex_ < mesh.time().timeIndex())
{
oldoldFc_ = oldFc_;
oldFc_ = Fc_;
// Fc_ = pp.faceCentres();
myTimeIndex_ = mesh.time().timeIndex();
}
forAll(Fc_, i)
{
Fc_[i] = pp[i].centre(points);
}
scalar deltaT = mesh.time().deltaT().value();
scalar deltaT0 = mesh.time().deltaT0().value();
if
(
U.oldTime().timeIndex() == U.oldTime().oldTime().timeIndex()
|| U.oldTime().oldTime().timeIndex() < 0
)
{
deltaT0 = GREAT;
}
//Set coefficients based on deltaT and deltaT0
scalar coefft = 1 + deltaT/(deltaT + deltaT0);
scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
// scalar coefft0 = coefft + coefft00;
// Up = (coefft*Fc_ - coefft0*oldFc_ + coefft00*oldoldFc_)
// /mesh.time().deltaT().value();
Up = coefft*(Fc_ - oldFc_)/deltaT
- coefft00*(oldFc_ - oldoldFc_)/deltaT;
// Info << max(mag(Up)) << endl;
}
else // Euler
{
// Info << "void movingWallVelocityFvPatchVectorField::updateCoeffs() - "
// << "Euler"
// << endl;
if (myTimeIndex_ < mesh.time().timeIndex())
{
oldoldFc_ = oldFc_;
oldFc_ = Fc_;
// Fc_ = pp.faceCentres();
myTimeIndex_ = mesh.time().timeIndex();
}
forAll(Fc_, i)
{
Fc_[i] = pp[i].centre(points);
}
Up = (Fc_ - oldFc_)/mesh.time().deltaT().value();
}
scalarField phip =
p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U));
vectorField n = p.nf();
const scalarField& magSf = p.magSf();
scalarField Un = phip/(magSf + VSMALL);
Up += n*(Un - (n & Up));
vectorField::operator=(Up);
// Info << "mwvuc " << max(mag(Up)) << ", " << average(mag(Up)) << endl;
fixedValueFvPatchVectorField::updateCoeffs();
}
Foam::tmp<Foam::Field<vector> > movingWallVelocityFvPatchVectorField::
snGrad() const
{
bool secondOrder_ = false;
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
vectorField dUP = (k&gradU.patchInternalField());
if (secondOrder_)
{
vectorField nGradUP = (n&gradU.patchInternalField());
tmp<Field<vector> > tnGradU
(
new vectorField(this->patch().size(), vector::zero)
);
tnGradU() =
2
*(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs()
- nGradUP;
tnGradU() -= n*(n&tnGradU());
return tnGradU;
// return
// 2
// *(
// *this
// - (patchInternalField() + dUP)
// )*this->patch().deltaCoeffs()
// - nGradUP;
}
// First order
// vectorField dUP = (k&gradU.patchInternalField());
tmp<Field<vector> > tnGradU
(
new vectorField(this->patch().size(), vector::zero)
);
tnGradU() =
(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs();
tnGradU() -= n*(n&tnGradU());
return tnGradU;
// return
// (
// *this
// - (patchInternalField() + (k&gradU.patchInternalField()))
// )*this->patch().deltaCoeffs();
}
tmp<Field<vector> > movingWallVelocityFvPatchVectorField::
gradientBoundaryCoeffs() const
{
bool secondOrder_ = false;
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
vectorField dUP = (k&gradU.patchInternalField());
if (secondOrder_)
{
vectorField nGradUP = (n&gradU.patchInternalField());
vectorField nGradU =
2
*(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs()
- nGradUP;
vectorField nGradUn = n*(n&nGradU);
return
this->patch().deltaCoeffs()
*(
2*(*this - dUP)
- patchInternalField()
)
- nGradUP
- nGradUn;
// return
// this->patch().deltaCoeffs()
// *(
// 2*(*this - dUP)
// - patchInternalField()
// )
// - nGradUP;
}
// First order
// vectorField dUP = (k&gradU.patchInternalField());
vectorField nGradU =
(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs();
vectorField nGradUn = n*(n&nGradU);
return
this->patch().deltaCoeffs()
*(
*this - dUP
)
- nGradUn;
// return this->patch().deltaCoeffs()
// *(*this - (k&gradU.patchInternalField()));
}
void movingWallVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
movingWallVelocityFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::movingWallVelocityFvPatchVectorField
Description
Foam::movingWallVelocityFvPatchVectorField
SourceFiles
movingWallVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef movingWallVelocityFvPatchVectorField_H
#define movingWallVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class movingWallVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class movingWallVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField
{
//To keep track when to copy patch face centres
label myTimeIndex_;
//Old face centres of patch. Needed for (second order) time integration
vectorField Fc_;
vectorField oldFc_;
vectorField oldoldFc_;
public:
//- Runtime type information
TypeName("movingWallVelocity");
// Constructors
//- Construct from patch and internal field
movingWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
movingWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given movingWallVelocityFvPatchVectorField
// onto a new patch
movingWallVelocityFvPatchVectorField
(
const movingWallVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
movingWallVelocityFvPatchVectorField
(
const movingWallVelocityFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new movingWallVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
movingWallVelocityFvPatchVectorField
(
const movingWallVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new movingWallVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
// Evaluation functions
//- Return patch-normal gradient
virtual tmp<Field<vector> > snGrad() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<vector> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,414 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "normalInletVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvcMeshPhi.H"
#include "backwardDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
normalInletVelocityFvPatchVectorField::normalInletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF)
{}
normalInletVelocityFvPatchVectorField::normalInletVelocityFvPatchVectorField
(
const normalInletVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper)
{}
normalInletVelocityFvPatchVectorField::normalInletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF, dict)
{
// fvPatchVectorField::operator=(vectorField("value", dict, p.size()));
// const fvMesh& mesh = dimensionedInternalField().mesh();
// const pointField& points = mesh.allPoints();
// forAll(Fc_, i)
// {
// Fc_[i] = patch().patch()[i].centre(points);
// }
// oldFc_ = Fc_;
// oldoldFc_ = Fc_;
}
normalInletVelocityFvPatchVectorField::normalInletVelocityFvPatchVectorField
(
const normalInletVelocityFvPatchVectorField& pivpvf
)
:
fixedValueFvPatchVectorField(pivpvf)
{}
normalInletVelocityFvPatchVectorField::normalInletVelocityFvPatchVectorField
(
const normalInletVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// void normalInletVelocityFvPatchVectorField::updateCoeffs()
// {
// if (updated())
// {
// return;
// }
// const fvMesh& mesh = dimensionedInternalField().mesh();
// const fvPatch& p = patch();
// const polyPatch& pp = p.patch();
// const pointField& points = mesh.allPoints();
// vectorField Up(p.size(), vector::zero);
// //const pointField& oldPoints = mesh.oldPoints();
// const volVectorField& U =
// mesh.lookupObject<volVectorField>
// (
// dimensionedInternalField().name()
// );
// word ddtScheme
// (
// mesh.schemesDict().ddtScheme("ddt(" + U.name() +')')
// );
// if (ddtScheme == fv::backwardDdtScheme<vector>::typeName)
// {
// Info << "void normalInletVelocityFvPatchVectorField::updateCoeffs()"
// << endl;
// if(myTimeIndex_ < mesh.time().timeIndex())
// {
// oldoldFc_ = oldFc_;
// oldFc_ = Fc_;
// // Fc_ = pp.faceCentres();
// forAll(Fc_, i)
// {
// Fc_[i] = pp[i].centre(points);
// }
// myTimeIndex_ = mesh.time().timeIndex();
// }
// scalar deltaT = mesh.time().deltaT().value();
// scalar deltaT0 = mesh.time().deltaT0().value();
// if
// (
// U.oldTime().timeIndex() == U.oldTime().oldTime().timeIndex()
// || U.oldTime().oldTime().timeIndex() < 0
// )
// {
// deltaT0 = GREAT;
// }
// //Set coefficients based on deltaT and deltaT0
// scalar coefft = 1 + deltaT/(deltaT + deltaT0);
// scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
// // scalar coefft0 = coefft + coefft00;
// // Up = (coefft*Fc_ - coefft0*oldFc_ + coefft00*oldoldFc_)
// // /mesh.time().deltaT().value();
// Up = coefft*(Fc_ - oldFc_)/deltaT
// + coefft00*(oldFc_ - oldoldFc_)/deltaT;
// // Info << max(mag(Up)) << endl;
// }
// else // Euler
// {
// Info << "void normalInletVelocityFvPatchVectorField::updateCoeffs()"
// << endl;
// if(myTimeIndex_ < mesh.time().timeIndex())
// {
// oldFc_ = Fc_;
// forAll(Fc_, i)
// {
// Fc_[i] = pp[i].centre(points);
// }
// // Fc_ = pp.faceCentres();
// myTimeIndex_ = mesh.time().timeIndex();
// }
// Up = (Fc_ - oldFc_)/mesh.time().deltaT().value();
// }
// scalarField phip =
// p.patchField<surfaceScalarField, scalar>(fvc::meshPhi(U));
// vectorField n = p.nf();
// const scalarField& magSf = p.magSf();
// scalarField Un = phip/(magSf + VSMALL);
// // Info << max(mag(Un)) << endl;
// Up += n*(Un - (n & Up));
// // Info << max(mag(Up)) << endl;
// vectorField::operator=(Up);
// fixedValueFvPatchVectorField::updateCoeffs();
// }
Foam::tmp<Foam::Field<vector> > normalInletVelocityFvPatchVectorField::
snGrad() const
{
// Info << "snGrad - in" << endl;
bool secondOrder_ = false;
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
if (secondOrder_)
{
vectorField dUP = (k&gradU.patchInternalField());
vectorField nGradUP = (n&gradU.patchInternalField());
tmp<Field<vector> > tnGradU
(
new vectorField(this->patch().size(), vector::zero)
);
tnGradU() =
2
*(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs()
- nGradUP;
// tnGradU() -= n*(n&tnGradU());
return tnGradU;
// return
// 2
// *(
// *this
// - (patchInternalField() + dUP)
// )*this->patch().deltaCoeffs()
// - nGradUP;
}
// Info << "snGrad - out" << endl;
// return fixedValueFvPatchVectorField::snGrad();
// First order
vectorField dUP = (k&gradU.patchInternalField());
tmp<Field<vector> > tnGradU
(
new vectorField(this->patch().size(), vector::zero)
);
tnGradU() =
(
*this
- (patchInternalField() + dUP)
)*this->patch().deltaCoeffs();
// tnGradU() -= n*(n&tnGradU());
return tnGradU;
// return
// (
// *this
// - (patchInternalField() + (k&gradU.patchInternalField()))
// )*this->patch().deltaCoeffs();
}
tmp<Field<vector> > normalInletVelocityFvPatchVectorField::
gradientBoundaryCoeffs() const
{
// Info << "gradientBoundaryCoeffs - in" << endl;
bool secondOrder_ = false;
word UName = this->dimensionedInternalField().name();
const fvPatchField<tensor>& gradU =
patch().lookupPatchField<volTensorField, tensor>
(
"grad(" + UName + ")"
);
vectorField n = this->patch().nf();
vectorField delta = this->patch().delta();
vectorField k = delta - n*(n&delta);
if (secondOrder_)
{
vectorField dUP = (k&gradU.patchInternalField());
vectorField nGradUP = (n&gradU.patchInternalField());
// vectorField nGradU =
// 2
// *(
// *this
// - (patchInternalField() + dUP)
// )*this->patch().deltaCoeffs()
// - nGradUP;
// vectorField nGradUn = n*(n&nGradU);
return
this->patch().deltaCoeffs()
*(
2*(*this - dUP)
- patchInternalField()
)
- nGradUP;
// - nGradUn;
// return
// this->patch().deltaCoeffs()
// *(
// 2*(*this - dUP)
// - patchInternalField()
// )
// - nGradUP;
}
// tmp<Field<vector> > tResult
// (
// new vectorField(this->patch().size(), vector::zero)
// );
// tResult() = this->patch().deltaCoeffs()
// *(*this - (k&gradU.patchInternalField()));
// Info << "gradientBoundaryCoeffs - out" << endl;
// return tResult;
// return fixedValueFvPatchVectorField::gradientBoundaryCoeffs();
// First order
vectorField dUP = (k&gradU.patchInternalField());
// vectorField nGradU =
// (
// *this
// - (patchInternalField() + dUP)
// )*this->patch().deltaCoeffs();
// vectorField nGradUn = n*(n&nGradU);
return
this->patch().deltaCoeffs()
*(
*this - dUP
);
// - nGradUn;
// return this->patch().deltaCoeffs()
// *(*this - (k&gradU.patchInternalField()));
}
void normalInletVelocityFvPatchVectorField::write(Ostream& os) const
{
fixedValueFvPatchVectorField::write(os);
// writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
normalInletVelocityFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::normalInletVelocityFvPatchVectorField
Description
Foam::normalInletVelocityFvPatchVectorField
SourceFiles
normalInletVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef normalInletVelocityFvPatchVectorField_H
#define normalInletVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class normalInletVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class normalInletVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField
{
// //To keep track when to copy patch face centres
// label myTimeIndex_;
// //Old face centres of patch. Needed for (second order) time integration
// vectorField Fc_;
// vectorField oldFc_;
// vectorField oldoldFc_;
public:
//- Runtime type information
TypeName("normalInletVelocity");
// Constructors
//- Construct from patch and internal field
normalInletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
normalInletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given normalInletVelocityFvPatchVectorField
// onto a new patch
normalInletVelocityFvPatchVectorField
(
const normalInletVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
normalInletVelocityFvPatchVectorField
(
const normalInletVelocityFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new normalInletVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
normalInletVelocityFvPatchVectorField
(
const normalInletVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new normalInletVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
// //- Update the coefficients associated with the patch field
// virtual void updateCoeffs();
// Evaluation functions
//- Return patch-normal gradient
virtual tmp<Field<vector> > snGrad() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<vector> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "outflowPressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvcMeshPhi.H"
#include "backwardDdtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
outflowPressureFvPatchScalarField::outflowPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(p, iF)
{}
outflowPressureFvPatchScalarField::outflowPressureFvPatchScalarField
(
const outflowPressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchScalarField(ptf, p, iF, mapper)
{}
outflowPressureFvPatchScalarField::outflowPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchScalarField(p, iF, dict)
{
// fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
// const fvMesh& mesh = dimensionedInternalField().mesh();
// const pointField& points = mesh.allPoints();
// forAll(Fc_, i)
// {
// Fc_[i] = patch().patch()[i].centre(points);
// }
// oldFc_ = Fc_;
// oldoldFc_ = Fc_;
}
outflowPressureFvPatchScalarField::outflowPressureFvPatchScalarField
(
const outflowPressureFvPatchScalarField& pivpvf
)
:
fixedValueFvPatchScalarField(pivpvf)
{}
outflowPressureFvPatchScalarField::outflowPressureFvPatchScalarField
(
const outflowPressureFvPatchScalarField& pivpvf,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(pivpvf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void outflowPressureFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
scalarField pp(this->patch().size(), 0);
const fvMesh& mesh = dimensionedInternalField().mesh();
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
dimensionedScalar nu(transportProperties.lookup("nu"));
const fvPatchField<vector>& pU =
patch().lookupPatchField<volVectorField, vector>("U");
vectorField n = this->patch().nf();
pp = nu.value()*(n & pU.snGrad());
scalarField::operator=(pp);
fixedValueFvPatchScalarField::updateCoeffs();
}
void outflowPressureFvPatchScalarField::write(Ostream& os) const
{
fixedValueFvPatchScalarField::write(os);
// writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
outflowPressureFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::outflowPressureFvPatchScalarField
Description
Foam::outflowPressureFvPatchScalarField
SourceFiles
outflowPressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef outflowPressureFvPatchScalarField_H
#define outflowPressureFvPatchScalarField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class outflowPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class outflowPressureFvPatchScalarField
:
public fixedValueFvPatchScalarField
{
// //To keep track when to copy patch face centres
// label myTimeIndex_;
// //Old face centres of patch. Needed for (second order) time integration
// scalarField Fc_;
// scalarField oldFc_;
// scalarField oldoldFc_;
public:
//- Runtime type information
TypeName("outflowPressure");
// Constructors
//- Construct from patch and internal field
outflowPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
outflowPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given outflowPressureFvPatchScalarField
// onto a new patch
outflowPressureFvPatchScalarField
(
const outflowPressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
outflowPressureFvPatchScalarField
(
const outflowPressureFvPatchScalarField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new outflowPressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
outflowPressureFvPatchScalarField
(
const outflowPressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new outflowPressureFvPatchScalarField(*this, iF)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
// Evaluation functions
// //- Return patch-normal gradient
// virtual tmp<Field<scalar> > snGrad() const;
// //- Return the matrix source coefficients corresponding to the
// // evaluation of the gradient of this patchField
// virtual tmp<Field<scalar> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,224 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "robinFvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
robinFvPatchField<Type>::robinFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
fvPatchField<Type>(p, iF),
coeff0_(p.size(), 0),
coeff1_(p.size(), 1),
rhs_(p.size(), pTraits<Type>::zero)
{}
template<class Type>
robinFvPatchField<Type>::robinFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fvPatchField<Type>(p, iF, dict),
coeff0_("coeff0", dict, p.size()),
coeff1_("coeff1", dict, p.size()),
rhs_("rhs", dict, p.size())
{
evaluate();
}
template<class Type>
robinFvPatchField<Type>::robinFvPatchField
(
const robinFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fvPatchField<Type>(ptf, p, iF, mapper),
coeff0_(ptf.coeff0_, mapper),
coeff1_(ptf.coeff1_, mapper),
rhs_(ptf.rhs_, mapper)
{}
template<class Type>
robinFvPatchField<Type>::robinFvPatchField
(
const robinFvPatchField<Type>& ptf
)
:
fvPatchField<Type>(ptf),
coeff0_(ptf.coeff0_),
coeff1_(ptf.coeff1_),
rhs_(ptf.rhs_)
{}
template<class Type>
robinFvPatchField<Type>::robinFvPatchField
(
const robinFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
fvPatchField<Type>(ptf, iF),
coeff0_(ptf.coeff0_),
coeff1_(ptf.coeff1_),
rhs_(ptf.rhs_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void robinFvPatchField<Type>::autoMap
(
const fvPatchFieldMapper& m
)
{
fvPatchField<Type>::autoMap(m);
coeff0_.autoMap(m);
coeff1_.autoMap(m);
rhs_.autoMap(m);
}
template<class Type>
void robinFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
fvPatchField<Type>::rmap(ptf, addr);
const robinFvPatchField<Type>& mptf =
refCast<const robinFvPatchField<Type> >(ptf);
coeff0_.rmap(mptf.coeff0_, addr);
coeff1_.rmap(mptf.coeff1_, addr);
rhs_.rmap(mptf.rhs_, addr);
}
template<class Type>
void robinFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}
scalarField dn = 1.0/this->patch().deltaCoeffs();
Field<Type>::operator=
(
dn*rhs_/(dn*coeff0_+coeff1_)
+ coeff1_*this->patchInternalField()
/(coeff0_*dn+coeff1_)
);
fvPatchField<Type>::evaluate();
}
template<class Type>
tmp<Field<Type> > robinFvPatchField<Type>::snGrad() const
{
return (*this - this->patchInternalField())*this->patch().deltaCoeffs();
}
template<class Type>
tmp<Field<Type> > robinFvPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
return
pTraits<Type>::one*coeff1_
/(coeff1_ + coeff0_/this->patch().deltaCoeffs());
}
template<class Type>
tmp<Field<Type> > robinFvPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
return
(rhs_/this->patch().deltaCoeffs())
/(coeff1_ + coeff0_/this->patch().deltaCoeffs());
}
template<class Type>
tmp<Field<Type> > robinFvPatchField<Type>::gradientInternalCoeffs() const
{
return -pTraits<Type>::one
*(coeff0_/(coeff1_ + coeff0_/this->patch().deltaCoeffs()));
}
template<class Type>
tmp<Field<Type> > robinFvPatchField<Type>::gradientBoundaryCoeffs() const
{
return rhs_/(coeff1_ + coeff0_/this->patch().deltaCoeffs());
}
template<class Type>
void robinFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
coeff0_.writeEntry("coeff0", os);
coeff1_.writeEntry("coeff1", os);
rhs_.writeEntry("rhs", os);
this->writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,273 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::robinFvPatchField
Description
Foam::robinFvPatchField
SourceFiles
robinFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef robinFvPatchField_H
#define robinFvPatchField_H
#include "fvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class robinFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class robinFvPatchField
:
public fvPatchField<Type>
{
// Private data
//- Coefficient by normal derivative
scalarField coeff0_;
//- Coefficient by normal derivative
scalarField coeff1_;
//- Right hand side of linear equation
Field<Type> rhs_;
public:
//- Runtime type information
TypeName("robin");
// Constructors
//- Construct from patch and internal field
robinFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
robinFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping the given robinFvPatchField onto a new patch
robinFvPatchField
(
const robinFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
robinFvPatchField
(
const robinFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new robinFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
robinFvPatchField
(
const robinFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type> > clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type> >
(
new robinFvPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
//- Return true if this patch field fixes a value.
// Needed to check if a level has to be specified while solving
// Poissons equations. ??
virtual bool fixesValue() const
{
if (max(mag(coeff0_)) < SMALL)
{
return false;
}
return true;
}
// Return defining fields
virtual scalarField& coeff0()
{
return coeff0_;
}
virtual const scalarField& coeff0() const
{
return coeff0_;
}
virtual scalarField& coeff1()
{
return coeff1_;
}
virtual const scalarField& coeff1() const
{
return coeff1_;
}
virtual Field<Type>& rhs()
{
return rhs_;
}
virtual const Field<Type>& rhs() const
{
return rhs_;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Evaluation functions
//- Return gradient at boundary
virtual tmp<Field<Type> > snGrad() const;
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
);
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type> > valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type> > valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientInternalCoeffs() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const UList<Type>&) {}
virtual void operator=(const fvPatchField<Type>&) {}
virtual void operator+=(const fvPatchField<Type>&) {}
virtual void operator-=(const fvPatchField<Type>&) {}
virtual void operator*=(const fvPatchField<scalar>&) {}
virtual void operator/=(const fvPatchField<scalar>&) {}
virtual void operator+=(const Field<Type>&) {}
virtual void operator-=(const Field<Type>&) {}
virtual void operator*=(const Field<scalar>&) {}
virtual void operator/=(const Field<scalar>&) {}
virtual void operator=(const Type&) {}
virtual void operator+=(const Type&) {}
virtual void operator-=(const Type&) {}
virtual void operator*=(const scalar) {}
virtual void operator/=(const scalar) {}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "robinFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "robinFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(robin);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef robinFvPatchFields_H
#define robinFvPatchFields_H
#include "robinFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(robin)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef robinFvPatchFieldsFwd_H
#define robinFvPatchFieldsFwd_H
#include "fvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class robinFvPatchField;
makePatchTypeFieldTypedefs(robin)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,251 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "skewCorrectedLinearDC.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::skewCorrectedLinearDC<Type>::interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
const fvMesh& mesh = this->mesh();
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsf
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
"interpolate("+vf.name()+')',
vf.instance(),
vf.db()
),
mesh,
dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero)
)
);
GeometricField<Type, fvsPatchField, surfaceMesh>& sf = tsf();
const labelList& owner = mesh.owner();
const labelList& neighbour = mesh.neighbour();
const volVectorField& C = mesh.C();
const surfaceVectorField& Cf = mesh.Cf();
GeometricField
<
typename outerProduct<vector, Type>::type,
fvPatchField,
volMesh
>
gradVf = gradScheme_().grad(vf);
// Since grad is used on coupled boundaries, correctBoundaryConditions
// needs to be called. HJ, 1/Nov/2012
gradVf.correctBoundaryConditions();
// Correction vectors
surfaceVectorField kP
(
IOobject
(
"kP",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedVector("0", dimLength, vector::zero)
);
vectorField& kPI = kP.internalField();
surfaceVectorField kN
(
IOobject
(
"kN",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedVector("0", dimLength, vector::zero)
);
vectorField& kNI = kN.internalField();
const vectorField& Sf = mesh.Sf().internalField();
const scalarField& magSf = mesh.magSf().internalField();
vectorField nf = Sf/magSf;
kPI = Cf - vectorField(C, owner);
kPI -= Sf*(Sf&kPI)/sqr(magSf);
kNI = Cf - vectorField(C, neighbour);
kNI -= Sf*(Sf&kNI)/sqr(magSf);
forAll(kP.boundaryField(), patchI)
{
if (kP.boundaryField()[patchI].coupled())
{
kP.boundaryField()[patchI] =
mesh.boundary()[patchI].Cf()
- mesh.boundary()[patchI].Cn();
kP.boundaryField()[patchI] -=
mesh.boundary()[patchI].Sf()
*(
mesh.boundary()[patchI].Sf()
& kP.boundaryField()[patchI]
)
/sqr(mesh.boundary()[patchI].magSf());
kN.boundaryField()[patchI] =
mesh.Cf().boundaryField()[patchI]
- (
mesh.boundary()[patchI].Cn()
+ mesh.boundary()[patchI].delta()
);
kN.boundaryField()[patchI] -=
mesh.boundary()[patchI].Sf()
*(
mesh.boundary()[patchI].Sf()
& kN.boundaryField()[patchI]
)
/sqr(mesh.boundary()[patchI].magSf());
}
}
// Perform skew-corrected interpolation
Field<Type>& sfI = sf.internalField();
const Field<Type>& vfI = vf.internalField();
const surfaceScalarField& w = mesh.surfaceInterpolation::weights();
const scalarField& wI = w.internalField();
forAll(sfI, faceI)
{
label own = owner[faceI];
label nei = neighbour[faceI];
Type vfOwn = vfI[own] + (kPI[faceI] & gradVf[own]);
Type vfNei = vfI[nei] + (kNI[faceI] & gradVf[nei]);
sfI[faceI] = wI[faceI]*(vfOwn - vfNei) + vfNei;
}
forAll (vf.boundaryField(), patchI)
{
const scalarField& pw =
w.boundaryField()[patchI];
if (vf.boundaryField()[patchI].coupled())
{
Field<Type> vfOwn =
vf.boundaryField()[patchI].patchInternalField()
+ (
kP.boundaryField()[patchI]
& gradVf.boundaryField()[patchI].patchInternalField()
);
Field<Type> vfNei =
vf.boundaryField()[patchI].patchNeighbourField()
+ (
kN.boundaryField()[patchI]
& gradVf.boundaryField()[patchI].patchNeighbourField()
);
sf.boundaryField()[patchI] = pw*(vfOwn - vfNei) + vfNei;
}
else
{
vf.boundaryField()[patchI].patchInterpolate(sf, pw);
}
}
return tsf;
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::skewCorrectedLinearDC<Type>::correction
(
const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
// Note: Correction is calculated by assembling the complete interpolation
// including extrapolated gradient contribution and subtracting the
// implicit contribution. HJ, 27/Mar/2010
const fvMesh& mesh = this->mesh();
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
"skewCorrectedLinearDCCorrection(" + vf.name() + ')',
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
skewCorrectedLinearDC<Type>::interpolate(vf)
- upwind<Type>::interpolate
// - surfaceInterpolationScheme<Type>::interpolate
(
vf,
this->weights()
)
)
);
return tsfCorr;
}
namespace Foam
{
//makelimitedSurfaceInterpolationScheme(skewCorrectedLinearDC)
makelimitedSurfaceInterpolationTypeScheme(skewCorrectedLinearDC, scalar)
makelimitedSurfaceInterpolationTypeScheme(skewCorrectedLinearDC, vector)
}
// ************************************************************************* //

View file

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::skewCorrectedLinearDC
Description
skewCorrectedLinearDC interpolation scheme uses extrapolated gradient-based
correction from both sides onto the face, using 1/2 weighting.
Class is derived from upwind and returns upwind weighting factors.
Correction is calculated using difference between linear and upwind interp.
Author
Zeljko Tukovic, FSB Zagreb All rights reserved.
SourceFiles
skewCorrectedLinearDC.C
\*---------------------------------------------------------------------------*/
#ifndef skewCorrectedLinearDC_H
#define skewCorrectedLinearDC_H
#include "upwind.H"
#include "gaussGrad.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class skewCorrectedLinearDC Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class skewCorrectedLinearDC
:
public upwind<Type>
{
// Private Data
tmp<fv::gradScheme<Type> > gradScheme_;
// Private Member Functions
//- Disallow default bitwise copy construct
skewCorrectedLinearDC(const skewCorrectedLinearDC&);
//- Disallow default bitwise assignment
void operator=(const skewCorrectedLinearDC&);
public:
//- Runtime type information
TypeName("skewCorrectedLinearDC");
// Constructors
//- Construct from faceFlux
skewCorrectedLinearDC
(
const fvMesh& mesh,
const surfaceScalarField& faceFlux
)
:
upwind<Type>(mesh, faceFlux),
gradScheme_
(
new fv::gaussGrad<Type>(mesh)
)
{}
//- Construct from Istream.
// The name of the flux field is read from the Istream and looked-up
// from the mesh objectRegistry
skewCorrectedLinearDC
(
const fvMesh& mesh,
Istream& schemeData
)
:
upwind<Type>(mesh, schemeData),
gradScheme_
(
fv::gradScheme<Type>::New
(
mesh,
schemeData
)
)
{}
//- Construct from faceFlux and Istream
skewCorrectedLinearDC
(
const fvMesh& mesh,
const surfaceScalarField& faceFlux,
Istream& schemeData
)
:
upwind<Type>(mesh, faceFlux, schemeData),
gradScheme_
(
fv::gradScheme<Type>::New
(
mesh,
schemeData
)
)
{}
// Member Functions
//- Return the face-interpolate of the given cell field
// with explicit correction
virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
interpolate(const GeometricField<Type, fvPatchField, volMesh>&) const;
//- Return true if this scheme uses an explicit correction
virtual bool corrected() const
{
return true;
}
//- Return the explicit correction to the face-interpolate
virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
correction
(
const GeometricField<Type, fvPatchField, volMesh>& vf
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,185 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "transitionalParabolicVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
transitionalParabolicVelocityFvPatchVectorField::transitionalParabolicVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
maxValue_(0),
n_(1, 0, 0),
y_(0, 1, 0),
transitionPeriod_(SMALL),
boundBoxMin_(0, 0, 0),
boundBoxMax_(0, 0, 0)
{}
transitionalParabolicVelocityFvPatchVectorField::transitionalParabolicVelocityFvPatchVectorField
(
const transitionalParabolicVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
maxValue_(ptf.maxValue_),
n_(ptf.n_),
y_(ptf.y_),
transitionPeriod_(ptf.transitionPeriod_),
boundBoxMin_(ptf.boundBoxMin_),
boundBoxMax_(ptf.boundBoxMax_)
{}
transitionalParabolicVelocityFvPatchVectorField::transitionalParabolicVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
maxValue_(readScalar(dict.lookup("maxValue"))),
n_(dict.lookup("n")),
y_(dict.lookup("y")),
transitionPeriod_(readScalar(dict.lookup("transitionPeriod"))),
boundBoxMin_(dict.lookup("boundBoxMin")),
boundBoxMax_(dict.lookup("boundBoxMax"))
{
if (mag(n_) < SMALL || mag(y_) < SMALL)
{
FatalErrorIn("transitionalParabolicVelocityFvPatchVectorField(dict)")
<< "n or y given with zero size not correct"
<< abort(FatalError);
}
n_ /= mag(n_);
y_ /= mag(y_);
if (transitionPeriod_ < SMALL)
{
transitionPeriod_ = SMALL;
}
evaluate();
}
transitionalParabolicVelocityFvPatchVectorField::transitionalParabolicVelocityFvPatchVectorField
(
const transitionalParabolicVelocityFvPatchVectorField& fcvpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(fcvpvf, iF),
maxValue_(fcvpvf.maxValue_),
n_(fcvpvf.n_),
y_(fcvpvf.y_),
transitionPeriod_(fcvpvf.transitionPeriod_),
boundBoxMin_(fcvpvf.boundBoxMin_),
boundBoxMax_(fcvpvf.boundBoxMax_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void transitionalParabolicVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
scalar curMaxValue = maxValue_;
if (this->db().time().value() < transitionPeriod_)
{
scalar t = this->db().time().value();
curMaxValue *= 0.5*(1.0-cos(M_PI*t/transitionPeriod_));
}
// // Get range and orientation
// boundBox bb(patch().patch().localPoints(), true);
// boundBox bb(vector(0, 0, -0.025334), vector(0, 0.41, 0.025334));
vector ctr = 0.5*(boundBoxMax_ + boundBoxMin_);
const vectorField& c = patch().Cf();
// Calculate local 1-D coordinate for the parabolic profile
scalarField coord = 2*((c - ctr) & y_)/((boundBoxMax_ - boundBoxMin_) & y_);
vectorField::operator=(n_*curMaxValue*(1.0 - sqr(coord)));
}
// Write
void transitionalParabolicVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
os.writeKeyword("maxValue")
<< maxValue_ << token::END_STATEMENT << nl;
os.writeKeyword("n")
<< n_ << token::END_STATEMENT << nl;
os.writeKeyword("y")
<< y_ << token::END_STATEMENT << nl;
os.writeKeyword("transitionPeriod")
<< transitionPeriod_ << token::END_STATEMENT << nl;
os.writeKeyword("boundBoxMin")
<< boundBoxMin_ << token::END_STATEMENT << nl;
os.writeKeyword("boundBoxMax")
<< boundBoxMax_ << token::END_STATEMENT << nl;
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField(fvPatchVectorField, transitionalParabolicVelocityFvPatchVectorField);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
parabolicVelocityFvPatchVectorField
Description
Boundary condition specifies a parabolic velocity inlet profile
(fixed value), given maximum velocity value (peak of the parabola),
flow direction n and direction of the parabolic coordinate y
SourceFiles
transitionalParabolicVelocityFvPatchVectorField.C
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef transitionalParabolicVelocityFvPatchVectorField_H
#define transitionalParabolicVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class parabolicVelocityFvPatchField Declaration
\*---------------------------------------------------------------------------*/
class transitionalParabolicVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField
{
// Private data
//- Peak velocity magnitude
scalar maxValue_;
//- Fluid direction
vector n_;
//- Direction of the y-coordinate
vector y_;
//- Transition period
scalar transitionPeriod_;
//- Bound box min (must be specified duo to bug in parallel run)
vector boundBoxMin_;
//- Bound box max (must be specified duo to bug in parallel run)
vector boundBoxMax_;
public:
//- Runtime type information
TypeName("transitionalParabolicVelocity");
// Constructors
//- Construct from patch and internal field
transitionalParabolicVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
transitionalParabolicVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// transitionalParabolicVelocityFvPatchVectorField
// onto a new patch
transitionalParabolicVelocityFvPatchVectorField
(
const transitionalParabolicVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new transitionalParabolicVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
transitionalParabolicVelocityFvPatchVectorField
(
const transitionalParabolicVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new transitionalParabolicVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Return max value
scalar& maxValue()
{
return maxValue_;
}
//- Return flow direction
vector& n()
{
return n_;
}
//- Return y direction
vector& y()
{
return y_;
}
//- Update coefficients
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,367 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "icoFluid.H"
#include "volFields.H"
#include "fvm.H"
#include "fvc.H"
#include "fvMatrices.H"
#include "addToRunTimeSelectionTable.H"
#include "findRefCell.H"
#include "adjustPhi.H"
#include "fluidSolidInterface.H"
#include "fixedGradientFvPatchFields.H"
#include "EulerDdtScheme.H"
#include "CrankNicolsonDdtScheme.H"
#include "backwardDdtScheme.H"
#include "elasticSlipWallVelocityFvPatchVectorField.H"
#include "elasticWallVelocityFvPatchVectorField.H"
#include "elasticWallPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fluidSolvers
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(icoFluid, 0);
addToRunTimeSelectionTable(fluidSolver, icoFluid, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
icoFluid::icoFluid(const fvMesh& mesh)
:
fluidSolver(this->typeName, mesh),
U_
(
IOobject
(
"U",
runTime().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
),
p_
(
IOobject
(
"p",
runTime().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
),
gradp_(fvc::grad(p_)),
gradU_(fvc::grad(U_)),
phi_
(
IOobject
(
"phi",
runTime().timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fvc::interpolate(U_) & mesh.Sf()
),
transportProperties_
(
IOobject
(
"transportProperties",
runTime().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
nu_(transportProperties_.lookup("nu")),
rho_(transportProperties_.lookup("rho"))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const volVectorField& icoFluid::U() const
{
return U_;
}
const volScalarField& icoFluid::p() const
{
return p_;
}
//- Patch viscous force (N/m2)
tmp<vectorField> icoFluid::patchViscousForce(const label patchID) const
{
tmp<vectorField> tvF
(
new vectorField(mesh().boundary()[patchID].size(), vector::zero)
);
tvF() = rho_.value()*nu_.value()*U().boundaryField()[patchID].snGrad();
vectorField n = mesh().boundary()[patchID].nf();
tvF() -= n*(n&tvF());
return tvF;
}
//- Patch pressure force (N/m2)
tmp<scalarField> icoFluid::patchPressureForce(const label patchID) const
{
tmp<scalarField> tpF
(
new scalarField(mesh().boundary()[patchID].size(), 0)
);
tpF() = rho_.value()*p().boundaryField()[patchID];
return tpF;
}
//- Patch viscous force (N/m2)
tmp<vectorField> icoFluid::faceZoneViscousForce
(
const label zoneID,
const label patchID
) const
{
vectorField pVF = patchViscousForce(patchID);
tmp<vectorField> tvF
(
new vectorField(mesh().faceZones()[zoneID].size(), vector::zero)
);
vectorField& vF = tvF();
const label patchStart =
mesh().boundaryMesh()[patchID].start();
forAll(pVF, i)
{
vF[mesh().faceZones()[zoneID].whichFace(patchStart + i)] =
pVF[i];
}
// Parallel data exchange: collect pressure field on all processors
reduce(vF, sumOp<vectorField>());
return tvF;
}
//- Patch pressure force (N/m2)
tmp<scalarField> icoFluid::faceZonePressureForce
(
const label zoneID,
const label patchID
) const
{
scalarField pPF = patchPressureForce(patchID);
tmp<scalarField> tpF
(
new scalarField(mesh().faceZones()[zoneID].size(), 0)
);
scalarField& pF = tpF();
const label patchStart =
mesh().boundaryMesh()[patchID].start();
forAll(pPF, i)
{
pF[mesh().faceZones()[zoneID].whichFace(patchStart + i)] =
pPF[i];
}
// Parallel data exchange: collect pressure field on all processors
reduce(pF, sumOp<scalarField>());
return tpF;
}
tmp<scalarField> icoFluid::faceZoneMuEff
(
const label zoneID,
const label patchID
) const
{
tmp<scalarField> tMuEff
(
new scalarField
(
mesh().faceZones()[zoneID].size(),
rho_.value()*nu_.value()
)
);
return tMuEff;
}
void icoFluid::evolve()
{
Info << "Evolving fluid solver: " << this->type() << endl;
const fvMesh& mesh = fluidSolver::mesh();
int nCorr(readInt(fluidProperties().lookup("nCorrectors")));
int nNonOrthCorr =
readInt(fluidProperties().lookup("nNonOrthogonalCorrectors"));
int nOuterCorr =
readInt(fluidProperties().lookup("nOuterCorrectors"));
// Prepare for the pressure solution
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p_, fluidProperties(), pRefCell, pRefValue);
for (int oCorr = 0; oCorr < nOuterCorr; oCorr++)
{
if(mesh.moving())
{
// Make the fluxes relative
phi_ -= fvc::meshPhi(U_);
}
// CourantNo
{
scalar CoNum = 0.0;
scalar meanCoNum = 0.0;
scalar velMag = 0.0;
if (mesh.nInternalFaces())
{
surfaceScalarField SfUfbyDelta =
mesh.surfaceInterpolation::deltaCoeffs()*mag(phi_);
CoNum = max(SfUfbyDelta/mesh.magSf())
.value()*runTime().deltaT().value();
meanCoNum = (sum(SfUfbyDelta)/sum(mesh.magSf()))
.value()*runTime().deltaT().value();
velMag = max(mag(phi_)/mesh.magSf()).value();
}
Info<< "Courant Number mean: " << meanCoNum
<< " max: " << CoNum
<< " velocity magnitude: " << velMag << endl;
}
fvVectorMatrix UEqn
(
fvm::ddt(U_)
+ fvm::div(phi_, U_)
- fvm::laplacian(nu_, U_)
);
solve(UEqn == -gradp_);
// --- PISO loop
volScalarField rAU = 1.0/UEqn.A();
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU));
for (int corr=0; corr<nCorr; corr++)
{
U_ = rAU*UEqn.H();
phi_ = (fvc::interpolate(U_) & mesh.Sf());
// + fvc::ddtPhiCorr(rUA, U_, phi_);
# include "updateRobinFsiInterface.H"
adjustPhi(phi_, U_, p_);
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix pEqn
(
fvm::laplacian
(
rAUf, p_, "laplacian((1|A(U)),p)"
)
== fvc::div(phi_)
// fvm::laplacian(rAUf, p_) == fvc::div(phi_)
);
pEqn.setReference(pRefCell, pRefValue);
pEqn.solve();
gradp_ = fvc::grad(p_);
if (nonOrth == nNonOrthCorr)
{
phi_ -= pEqn.flux();
}
}
// Continuity error
{
volScalarField contErr = fvc::div(phi_);
scalar sumLocalContErr = runTime().deltaT().value()*
mag(contErr)().weightedAverage(mesh.V()).value();
scalar globalContErr = runTime().deltaT().value()*
contErr.weightedAverage(mesh.V()).value();
Info<< "time step continuity errors : sum local = "
<< sumLocalContErr << ", global = "
<< globalContErr << endl;
}
U_ -= rAU*gradp_;
U_.correctBoundaryConditions();
gradU_ = fvc::grad(U_);
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fluidSolvers
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,223 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
icoFluid
Description
icoFoam fluid solver
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
icoFluid.C
\*---------------------------------------------------------------------------*/
#ifndef icoFluid_H
#define icoFluid_H
#include "fluidSolver.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fluidSolvers
{
/*---------------------------------------------------------------------------*\
Class icoFluid Declaration
\*---------------------------------------------------------------------------*/
class icoFluid
:
public fluidSolver
{
// Private data
//- Velocity field
volVectorField U_;
//- Pressure field
volScalarField p_;
//- Pressure gradient
volVectorField gradp_;
//- Velocity gradient
volTensorField gradU_;
//- Flux field
surfaceScalarField phi_;
// Transport properties dictionary
IOdictionary transportProperties_;
//- Kinematic viscosity
dimensionedScalar nu_;
//- Density
dimensionedScalar rho_;
// //-
// scalarField nGradUn_;
// Private Member Functions
//- Disallow default bitwise copy construct
icoFluid(const icoFluid&);
//- Disallow default bitwise assignment
void operator=(const icoFluid&);
public:
//- Runtime type information
TypeName("icoFluid");
// Constructors
//- Construct from components
icoFluid(const fvMesh& mesh);
// //- Construct from components
// icoFluid
// (
// const word& type,
// const fvMesh& mesh
// );
// Destructor
virtual ~icoFluid()
{}
// Member Functions
// Access
//- Return velocity field
virtual const volVectorField& U() const;
//- Return velocity field
volVectorField& U()
{
return U_;
}
//- Return pressure field
virtual const volScalarField& p() const;
//- Return pressure field
volScalarField& p()
{
return p_;
}
//- Return pressure gradient
volVectorField& gradp()
{
return gradp_;
}
//- Return pressure gradient
volTensorField& gradU()
{
return gradU_;
}
//- Return flux field
surfaceScalarField& phi()
{
return phi_;
}
//- Return kinematic viscosity
const dimensionedScalar& nu() const
{
return nu_;
}
//- Density
const dimensionedScalar& rho()
{
return rho_;
}
//- Patch viscous force (N/m2)
virtual tmp<vectorField> patchViscousForce
(
const label patchID
) const;
//- Patch pressure force (N/m2)
virtual tmp<scalarField> patchPressureForce
(
const label patchID
) const;
//- Patch viscous force (N/m2)
virtual tmp<vectorField> faceZoneViscousForce
(
const label zoneID,
const label patchID
) const;
//- Patch pressure force (N/m2)
virtual tmp<scalarField> faceZonePressureForce
(
const label zoneID,
const label patchID
) const;
//- Face zone effective dynamic viscosity
virtual tmp<scalarField> faceZoneMuEff
(
const label zoneID,
const label patchID
) const;
// Edit
//- Evolve the fluid solver
virtual void evolve();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fluidSolvers
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,57 @@
if(fsi.closedFluidDomain())
{
scalar inletFlux = 0;
forAll(U_.boundaryField(), patchI)
{
if (patchI != fsi.fluidPatchIndex())
{
inletFlux +=
gSum
(
U_.boundaryField()[patchI]
& mesh.Sf().boundaryField()[patchI]
);
}
}
phi_.boundaryField()[fsi.fluidPatchIndex()] =
(
U_.boundaryField()[fsi.fluidPatchIndex()]
& mesh.Sf().boundaryField()[fsi.fluidPatchIndex()]
);
Info << "Inlet flux: " << inletFlux << endl;
Info << "Global continuity error (before): "
<< gSum(phi_.boundaryField()[fsi.fluidPatchIndex()]) + inletFlux
<< endl;
scalarField weights =
mag(phi_.boundaryField()[fsi.fluidPatchIndex()]);
if(mag(gSum(weights)) > VSMALL)
{
weights /= gSum(weights) + SMALL;
}
phi_.boundaryField()[fsi.fluidPatchIndex()] -=
weights
*(gSum(phi_.boundaryField()[fsi.fluidPatchIndex()]) + inletFlux);
Info << "Global continuity error (after): "
<< gSum(phi_.boundaryField()[fsi.fluidPatchIndex()]) + inletFlux
<< endl;
// Correct velocity
const vectorField n = mesh.boundary()[fsi.fluidPatchIndex()].nf();
U_.boundaryField()[fsi.fluidPatchIndex()] ==
U_.boundaryField()[fsi.fluidPatchIndex()]
- n*(n & U_.boundaryField()[fsi.fluidPatchIndex()])
+ n
*(
phi_.boundaryField()[fsi.fluidPatchIndex()]
/mesh.magSf().boundaryField()[fsi.fluidPatchIndex()]
);
}

View file

@ -0,0 +1,34 @@
forAll(p_.boundaryField(), patchI)
{
if
(
p_.boundaryField()[patchI].type()
== fixedGradientFvPatchScalarField::typeName
)
{
Pout << "Seting interfac pressure gradient" << endl;
fixedGradientFvPatchScalarField& pInterface =
refCast<fixedGradientFvPatchScalarField>
(
p_.boundaryField()[patchI]
);
const vectorField n = mesh.boundary()[patchI].nf();
pInterface.gradient() =
(n&U_.boundaryField()[patchI])
/rUA.boundaryField()[patchI]
- phi_.boundaryField()[patchI]
/mesh.magSf().boundaryField()[patchI]
/rUA.boundaryField()[patchI]
+ nGradUn_
/mesh.deltaCoeffs().boundaryField()[patchI]
/rUA.boundaryField()[patchI];
phi_.boundaryField()[patchI] +=
pInterface.gradient()
*rUA.boundaryField()[patchI]
*mesh.magSf().boundaryField()[patchI];
}
}

View file

@ -0,0 +1,52 @@
{
Info << "Update normal derivative of normal velocity" << endl;
volVectorField phiU = fvc::reconstruct(phi_);
vectorField n = mesh.boundary()[fsi.fluidPatchIndex()].nf();
scalarField UnP =
(n&phiU.boundaryField()[fsi.fluidPatchIndex()].patchInternalField());
scalarField UnInt =
phi_.boundaryField()[fsi.fluidPatchIndex()]
/mesh.magSf().boundaryField()[fsi.fluidPatchIndex()];
nGradUn_ =
(UnInt - UnP)
*mesh.deltaCoeffs().boundaryField()[fsi.fluidPatchIndex()];
Info << "nGradUn, max: " << gMax(nGradUn_) << ", min: "
<< gMin(nGradUn_) << ", avg: " << gAverage(nGradUn_) << endl;
// bool secondOrderCorrection = true;
// if (secondOrderCorrection)
// {
// // Correct normal component of phiU
// // befor gradient calculation
// forAll(phiU.boundaryField(), patchI)
// {
// vectorField n =
// mesh().Sf().boundaryField()[patchI]
// /mesh().magSf().boundaryField()[patchI];
// phiU.boundaryField()[patchI] +=
// n
// *(
// (
// phi_.boundaryField()[patchI]
// /mesh().magSf().boundaryField()[patchI]
// )
// - (n&phiU.boundaryField()[patchI])
// );
// }
// // Calc gradient
// tensorField gradPhiUp =
// fvc::grad(phiU)().boundaryField()[aPatchID()]
// .patchInternalField();
// nGradUn() = 2*nGradUn() - (nA&(gradPhiUp&nA));
// }
}

View file

@ -0,0 +1,59 @@
forAll(p().boundaryField(), patchI)
{
if
(
(
isA<elasticWallPressureFvPatchScalarField>(p().boundaryField()[patchI])
&& isA<elasticSlipWallVelocityFvPatchVectorField>(U().boundaryField()[patchI])
)
|| (
isA<elasticWallPressureFvPatchScalarField>(p().boundaryField()[patchI])
&& isA<elasticWallVelocityFvPatchVectorField>(U().boundaryField()[patchI])
)
)
{
word ddtScheme
(
mesh.schemesDict().ddtScheme("ddt(" + U().name() +')')
);
if
(
ddtScheme
== fv::EulerDdtScheme<vector>::typeName
)
{
phi().boundaryField()[patchI] = phi().oldTime().boundaryField()[patchI];
rAUf.boundaryField()[patchI] = runTime().deltaT().value();
}
else if
(
ddtScheme
== fv::backwardDdtScheme<vector>::typeName
)
{
if(runTime().timeIndex() == 1)
{
phi().boundaryField()[patchI] = phi().oldTime().boundaryField()[patchI];
rAUf.boundaryField()[patchI] = runTime().deltaT().value();
phi().oldTime().oldTime();
}
else
{
scalar deltaT = runTime().deltaT().value();
scalar deltaT0 = runTime().deltaT0().value();
scalar Cn = 1 + deltaT/(deltaT + deltaT0);
scalar Coo = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
scalar Co = Cn + Coo;
phi().boundaryField()[patchI] =
(Co/Cn)*phi().oldTime().boundaryField()[patchI]
- (Coo/Cn)*phi().oldTime().oldTime().boundaryField()[patchI];
rAUf.boundaryField()[patchI] = runTime().deltaT().value()/Cn;
}
}
}
}

View file

@ -0,0 +1,390 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "pisoFluid.H"
#include "volFields.H"
#include "fvm.H"
#include "fvc.H"
#include "fvMatrices.H"
#include "addToRunTimeSelectionTable.H"
#include "findRefCell.H"
#include "adjustPhi.H"
#include "fluidSolidInterface.H"
#include "fixedGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fluidSolvers
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(pisoFluid, 0);
addToRunTimeSelectionTable(fluidSolver, pisoFluid, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
pisoFluid::pisoFluid(const fvMesh& mesh)
:
fluidSolver(this->typeName, mesh),
U_
(
IOobject
(
"U",
runTime().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
),
p_
(
IOobject
(
"p",
runTime().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
),
gradp_(fvc::grad(p_)),
gradU_(fvc::grad(U_)),
phi_
(
IOobject
(
"phi",
runTime().timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fvc::interpolate(U_) & mesh.Sf()
),
laminarTransport_(U_, phi_),
turbulence_
(
incompressible::turbulenceModel::New
(
U_, phi_, laminarTransport_
)
),
rho_
(
IOdictionary
(
IOobject
(
"transportProperties",
runTime().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
).lookup("rho")
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const volVectorField& pisoFluid::U() const
{
return U_;
}
const volScalarField& pisoFluid::p() const
{
return p_;
}
//- Patch viscous force (N/m2)
tmp<vectorField> pisoFluid::patchViscousForce(const label patchID) const
{
tmp<vectorField> tvF
(
new vectorField(mesh().boundary()[patchID].size(), vector::zero)
);
tvF() =
rho_.value()
*(
mesh().boundary()[patchID].nf()
& turbulence_->devReff()().boundaryField()[patchID]
);
// vectorField n = mesh().boundary()[patchID].nf();
// tvF() -= n*(n&tvF());
return tvF;
}
//- Patch pressure force (N/m2)
tmp<scalarField> pisoFluid::patchPressureForce(const label patchID) const
{
tmp<scalarField> tpF
(
new scalarField(mesh().boundary()[patchID].size(), 0)
);
tpF() = rho_.value()*p().boundaryField()[patchID];
return tpF;
}
//- Patch viscous force (N/m2)
tmp<vectorField> pisoFluid::faceZoneViscousForce
(
const label zoneID,
const label patchID
) const
{
vectorField pVF = patchViscousForce(patchID);
tmp<vectorField> tvF
(
new vectorField(mesh().faceZones()[zoneID].size(), vector::zero)
);
vectorField& vF = tvF();
const label patchStart =
mesh().boundaryMesh()[patchID].start();
forAll(pVF, i)
{
vF[mesh().faceZones()[zoneID].whichFace(patchStart + i)] =
pVF[i];
}
// Parallel data exchange: collect pressure field on all processors
reduce(vF, sumOp<vectorField>());
return tvF;
}
//- Patch pressure force (N/m2)
tmp<scalarField> pisoFluid::faceZonePressureForce
(
const label zoneID,
const label patchID
) const
{
scalarField pPF = patchPressureForce(patchID);
tmp<scalarField> tpF
(
new scalarField(mesh().faceZones()[zoneID].size(), 0)
);
scalarField& pF = tpF();
const label patchStart =
mesh().boundaryMesh()[patchID].start();
forAll(pPF, i)
{
pF[mesh().faceZones()[zoneID].whichFace(patchStart + i)] =
pPF[i];
}
// Parallel data exchange: collect pressure field on all processors
reduce(pF, sumOp<scalarField>());
return tpF;
}
tmp<scalarField> pisoFluid::faceZoneMuEff
(
const label zoneID,
const label patchID
) const
{
scalarField pMuEff =
rho_.value()*turbulence_->nuEff()().boundaryField()[patchID];
tmp<scalarField> tMuEff
(
new scalarField(mesh().faceZones()[zoneID].size(), 0)
);
scalarField& muEff = tMuEff();
const label patchStart =
mesh().boundaryMesh()[patchID].start();
forAll(pMuEff, i)
{
muEff[mesh().faceZones()[zoneID].whichFace(patchStart + i)] =
pMuEff[i];
}
// Parallel data exchange: collect pressure field on all processors
reduce(muEff, sumOp<scalarField>());
return tMuEff;
}
void pisoFluid::evolve()
{
Info << "Evolving fluid solver" << endl;
const fvMesh& mesh = fluidSolver::mesh();
int nCorr(readInt(fluidProperties().lookup("nCorrectors")));
int nNonOrthCorr =
readInt(fluidProperties().lookup("nNonOrthogonalCorrectors"));
// Prepare for the pressure solution
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p_, fluidProperties(), pRefCell, pRefValue);
// if(mesh.moving())
// {
// // Make the fluxes relative
// phi_ -= fvc::meshPhi(U_);
// }
// Make the fluxes relative to the mesh motion
fvc::makeRelative(phi_, U_);
// CourantNo
{
scalar CoNum = 0.0;
scalar meanCoNum = 0.0;
scalar velMag = 0.0;
if (mesh.nInternalFaces())
{
surfaceScalarField SfUfbyDelta =
mesh.surfaceInterpolation::deltaCoeffs()*mag(phi_);
CoNum = max(SfUfbyDelta/mesh.magSf())
.value()*runTime().deltaT().value();
meanCoNum = (sum(SfUfbyDelta)/sum(mesh.magSf()))
.value()*runTime().deltaT().value();
velMag = max(mag(phi_)/mesh.magSf()).value();
}
Info<< "Courant Number mean: " << meanCoNum
<< " max: " << CoNum
<< " velocity magnitude: " << velMag << endl;
}
fvVectorMatrix UEqn
(
fvm::ddt(U_)
+ fvm::div(phi_, U_)
+ turbulence_->divDevReff(U_)
);
solve(UEqn == -gradp_);
// --- PISO loop
volScalarField rUA = 1.0/UEqn.A();
for (int corr=0; corr<nCorr; corr++)
{
U_ = rUA*UEqn.H();
phi_ = (fvc::interpolate(U_) & mesh.Sf());
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix pEqn
(
fvm::laplacian(rUA, p_) == fvc::div(phi_)
);
pEqn.setReference(pRefCell, pRefValue);
if
(
corr == nCorr-1
&& nonOrth == nNonOrthCorr
)
{
pEqn.solve(mesh.solutionDict().solver("pFinal"));
}
else
{
pEqn.solve();
}
if (nonOrth == nNonOrthCorr)
{
phi_ -= pEqn.flux();
}
}
// Continuity error
{
volScalarField contErr = fvc::div(phi_);
scalar sumLocalContErr = runTime().deltaT().value()*
mag(contErr)().weightedAverage(mesh.V()).value();
scalar globalContErr = runTime().deltaT().value()*
contErr.weightedAverage(mesh.V()).value();
Info<< "time step continuity errors : sum local = "
<< sumLocalContErr << ", global = " << globalContErr << endl;
}
// Make the fluxes relative to the mesh motion
fvc::makeRelative(phi_, U_);
gradp_ = fvc::grad(p_);
U_ -= rUA*gradp_;
U_.correctBoundaryConditions();
gradU_ = fvc::grad(U_);
}
turbulence_->correct();
// Make the fluxes absolut to the mesh motion
fvc::makeAbsolute(phi_, U_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fluidSolvers
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,217 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
pisoFluid
Description
icoFoam fluid solver
Author
Zeljko Tukovic, FSB. All rights reserved.
SourceFiles
pisoFluid.C
\*---------------------------------------------------------------------------*/
#ifndef pisoFluid_H
#define pisoFluid_H
#include "fluidSolver.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "singlePhaseTransportModel.H"
#include "turbulenceModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fluidSolvers
{
/*---------------------------------------------------------------------------*\
Class pisoFluid Declaration
\*---------------------------------------------------------------------------*/
class pisoFluid
:
public fluidSolver
{
// Private data
//- Velocity field
volVectorField U_;
//- Pressure field
volScalarField p_;
//- Pressure field
volVectorField gradp_;
//- Velocity gradient
volTensorField gradU_;
//- Flux field
surfaceScalarField phi_;
//- Transport model
singlePhaseTransportModel laminarTransport_;
//- Turbulence model
autoPtr<incompressible::turbulenceModel> turbulence_;
//- Density
dimensionedScalar rho_;
// Private Member Functions
//- Disallow default bitwise copy construct
pisoFluid(const pisoFluid&);
//- Disallow default bitwise assignment
void operator=(const pisoFluid&);
public:
//- Runtime type information
TypeName("pisoFluid");
// Constructors
//- Construct from components
pisoFluid(const fvMesh& mesh);
// //- Construct from components
// pisoFluid
// (
// const word& type,
// const fvMesh& mesh
// );
// Destructor
virtual ~pisoFluid()
{}
// Member Functions
// Access
//- Return velocity field
virtual const volVectorField& U() const;
//- Return velocity field
volVectorField& U()
{
return U_;
}
//- Return pressure field
virtual const volScalarField& p() const;
//- Return pressure field
volScalarField& p()
{
return p_;
}
//- Return pressure gradient
volVectorField& gradp()
{
return gradp_;
}
//- Return flux field
surfaceScalarField& phi()
{
return phi_;
}
// //- Return kinematic viscosity
// const dimensionedScalar& nu() const
// {
// return nu_;
// }
//- Density
const dimensionedScalar& rho()
{
return rho_;
}
//- Patch viscous force (N/m2)
virtual tmp<vectorField> patchViscousForce
(
const label patchID
) const;
//- Patch pressure force (N/m2)
virtual tmp<scalarField> patchPressureForce
(
const label patchID
) const;
//- Patch viscous force (N/m2)
virtual tmp<vectorField> faceZoneViscousForce
(
const label zoneID,
const label patchID
) const;
//- Patch pressure force (N/m2)
virtual tmp<scalarField> faceZonePressureForce
(
const label zoneID,
const label patchID
) const;
//- Face zone effective dynamic viscosity
virtual tmp<scalarField> faceZoneMuEff
(
const label zoneID,
const label patchID
) const;
// Edit
//- Evolve the fluid solver
virtual void evolve();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fluidSolvers
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,511 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fvcCellLimitedGrad.H"
#include "Field.H"
#include "primitivePatch.H"
#include "fvc.H"
#include "fvcGradf.H"
#include "fvMesh.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "pointFields.H"
#include "gaussGrad.H"
#include "extendedLeastSquaresGrad.H"
#include "leastSquaresGrad.H"
//#include "leastSquaresBiLinearGrad.H"
#include "volMesh.H"
#include "surfaceMesh.H"
#include "fixedValueFvPatchFields.H"
#include "IStringStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fvc
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline void limitFace
(
scalar& limiter,
const scalar& maxDelta,
const scalar& minDelta,
const scalar& extrapolate
)
{
if (extrapolate > maxDelta + VSMALL)
{
limiter = min(limiter, maxDelta/extrapolate);
}
else if (extrapolate < minDelta - VSMALL)
{
limiter = min(limiter, minDelta/extrapolate);
}
}
inline void limitFace
(
vector& limiter,
const vector& maxDelta,
const vector& minDelta,
const vector& extrapolate
)
{
for(direction cmpt=0; cmpt<vector::nComponents; cmpt++)
{
limitFace
(
limiter.component(cmpt),
maxDelta.component(cmpt),
minDelta.component(cmpt),
extrapolate.component(cmpt)
);
}
}
tmp<volVectorField> cellLimitedGrad
(
const volScalarField& vsf,
const pointScalarField& pf,
const bool lsCellGrad,
const scalar k
)
{
const fvMesh& mesh = vsf.mesh();
tmp<GeometricField<vector, fvPatchField, volMesh> > tGrad
(
new GeometricField<vector, fvPatchField, volMesh>
(
IOobject
(
"grad(" + vsf.name() + ")",
vsf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<vector>
(
"0",
vsf.dimensions()/dimLength,
pTraits<vector>::zero
),
zeroGradientFvPatchField<vector>::typeName
)
);
if (lsCellGrad)
{
// Extended least squares
IStringStream stream("0");
tGrad =
fv::extendedLeastSquaresGrad<scalar>
(
mesh,
stream
).grad(vsf);
// Gauss grad
// tGrad = fv::gaussGrad<scalar>(mesh).grad(vsf);
}
else
{
tGrad = fvc::grad(vsf, pf);
}
// tmp<volVectorField> tGrad = basicGradScheme_().grad(vsf);
if (k < SMALL)
{
return tGrad;
}
volVectorField& g = tGrad();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
const volVectorField& C = mesh.C();
const surfaceVectorField& Cf = mesh.Cf();
scalarField maxVsf(vsf.internalField());
scalarField minVsf(vsf.internalField());
forAll(owner, facei)
{
label own = owner[facei];
label nei = neighbour[facei];
scalar vsfOwn = vsf[own];
scalar vsfNei = vsf[nei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
maxVsf[nei] = max(maxVsf[nei], vsfOwn);
minVsf[nei] = min(minVsf[nei], vsfOwn);
}
const volScalarField::GeometricBoundaryField& bsf = vsf.boundaryField();
forAll(bsf, patchi)
{
const fvPatchScalarField& psf = bsf[patchi];
const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
if (psf.coupled())
{
scalarField psfNei = psf.patchNeighbourField();
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
scalar vsfNei = psfNei[pFacei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
}
}
else
{
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
scalar vsfNei = psf[pFacei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
}
}
}
maxVsf -= vsf;
minVsf -= vsf;
if (k < 1.0)
{
scalarField maxMinVsf = (1.0/k - 1.0)*(maxVsf - minVsf);
maxVsf += maxMinVsf;
minVsf -= maxMinVsf;
//maxVsf *= 1.0/k_;
//minVsf *= 1.0/k_;
}
// create limiter
scalarField limiter(vsf.internalField().size(), 1.0);
forAll(owner, facei)
{
label own = owner[facei];
label nei = neighbour[facei];
// owner side
limitFace
(
limiter[own],
maxVsf[own],
minVsf[own],
(Cf[facei] - C[own]) & g[own]
);
// neighbour side
limitFace
(
limiter[nei],
maxVsf[nei],
minVsf[nei],
(Cf[facei] - C[nei]) & g[nei]
);
}
forAll(bsf, patchi)
{
const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
const vectorField& pCf = Cf.boundaryField()[patchi];
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
limitFace
(
limiter[own],
maxVsf[own],
minVsf[own],
(pCf[pFacei] - C[own]) & g[own]
);
}
}
if (fv::debug)
{
Info<< "gradient limiter for: " << vsf.name()
<< " max = " << gMax(limiter)
<< " min = " << gMin(limiter)
<< " average: " << gAverage(limiter) << endl;
}
g.internalField() *= limiter;
g.correctBoundaryConditions();
fv::gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
return tGrad;
}
tmp<volTensorField> cellLimitedGrad
(
const volVectorField& vf,
const pointVectorField& pf,
const bool lsCellGrad,
const scalar k
)
{
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<tensor, fvPatchField, volMesh> > tGrad
(
new GeometricField<tensor, fvPatchField, volMesh>
(
IOobject
(
"grad(" + vf.name() + ")",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<tensor>
(
"0",
vf.dimensions()/dimLength,
pTraits<tensor>::zero
),
zeroGradientFvPatchField<tensor>::typeName
)
);
if (lsCellGrad)
{
// // Least squares
// tGrad = fv::leastSquaresBiLinearGrad<vector>(mesh).grad(vf);
IStringStream stream("0");
tGrad =
fv::extendedLeastSquaresGrad<vector>
(
mesh,
stream
).grad(vf);
}
else
{
tGrad = fvc::grad(vf, pf);
}
// tmp<volTensorField> tGrad = fvc::grad(vf, pf);
if (k < SMALL)
{
return tGrad;
}
volTensorField& g = tGrad();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
const volVectorField& C = mesh.C();
const surfaceVectorField& Cf = mesh.Cf();
vectorField maxVsf(vf.internalField());
vectorField minVsf(vf.internalField());
forAll(owner, facei)
{
label own = owner[facei];
label nei = neighbour[facei];
const vector& vsfOwn = vf[own];
const vector& vsfNei = vf[nei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
maxVsf[nei] = max(maxVsf[nei], vsfOwn);
minVsf[nei] = min(minVsf[nei], vsfOwn);
}
const volVectorField::GeometricBoundaryField& bsf = vf.boundaryField();
forAll(bsf, patchi)
{
const fvPatchVectorField& psf = bsf[patchi];
const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
if (psf.coupled())
{
vectorField psfNei = psf.patchNeighbourField();
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
const vector& vsfNei = psfNei[pFacei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
}
}
else
{
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
const vector& vsfNei = psf[pFacei];
maxVsf[own] = max(maxVsf[own], vsfNei);
minVsf[own] = min(minVsf[own], vsfNei);
}
}
}
maxVsf -= vf;
minVsf -= vf;
if (k < 1.0)
{
vectorField maxMinVsf = (1.0/k - 1.0)*(maxVsf - minVsf);
maxVsf += maxMinVsf;
minVsf -= maxMinVsf;
//maxVsf *= 1.0/k_;
//minVsf *= 1.0/k_;
}
// create limiter
vectorField limiter(vf.internalField().size(), vector::one);
forAll(owner, facei)
{
label own = owner[facei];
label nei = neighbour[facei];
// owner side
limitFace
(
limiter[own],
maxVsf[own],
minVsf[own],
(Cf[facei] - C[own]) & g[own]
);
// neighbour side
limitFace
(
limiter[nei],
maxVsf[nei],
minVsf[nei],
(Cf[facei] - C[nei]) & g[nei]
);
}
forAll(bsf, patchi)
{
const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
const vectorField& pCf = Cf.boundaryField()[patchi];
forAll(pOwner, pFacei)
{
label own = pOwner[pFacei];
limitFace
(
limiter[own],
maxVsf[own],
minVsf[own],
((pCf[pFacei] - C[own]) & g[own])
);
}
}
if (false)
{
Info<< "gradient limiter for: " << vf.name()
<< " max = " << gMax(limiter)
<< " min = " << gMin(limiter)
<< " average: " << gAverage(limiter) << endl;
}
tensorField& gIf = g.internalField();
forAll(gIf, celli)
{
gIf[celli] = tensor
(
cmptMultiply(limiter[celli], gIf[celli].x()),
cmptMultiply(limiter[celli], gIf[celli].y()),
cmptMultiply(limiter[celli], gIf[celli].z())
);
}
g.correctBoundaryConditions();
fv::gaussGrad<vector>::correctBoundaryConditions(vf, g);
return tGrad;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fvc
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
InNamespace
Foam::fvc
Description
Calculate the surface gradient of the given field.
SourceFiles
fvcCellLimitedGrad.C
\*---------------------------------------------------------------------------*/
#ifndef fvcCellLimitedGrad_H
#define fvcCellLimitedGrad_H
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "pointFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Namespace fvc functions Declaration
\*---------------------------------------------------------------------------*/
namespace fvc
{
tmp<volTensorField> cellLimitedGrad
(
const volVectorField& vf,
const pointVectorField& pf,
const bool lsCellGrad = false,
const scalar k = 0
);
tmp<volVectorField> cellLimitedGrad
(
const volScalarField& vf,
const pointScalarField& pf,
const bool lsCellGrad = false,
const scalar k = 0
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,750 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fvcGradf.H"
#include "fvMesh.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "pointFields.H"
#include "ggiFvPatch.H"
#include "wedgeFvPatch.H"
#include "leastSquaresVolPointInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fvc
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
> fGrad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf,
bool interpolate
)
{
typedef typename outerProduct<vector, Type>::type GradType;
const fvMesh& mesh = vf.mesh();
surfaceVectorField n = mesh.Sf()/mesh.magSf();
tmp<GeometricField<GradType, fvsPatchField, surfaceMesh> > tGrad
(
new GeometricField<GradType, fvsPatchField, surfaceMesh>
(
IOobject
(
"grad" + vf.name() + "f",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<GradType>
(
"0",
vf.dimensions()/dimLength,
pTraits<GradType>::zero
)
)
);
if (interpolate)
{
const GeometricField<GradType, fvPatchField, volMesh>& gradVf =
mesh.lookupObject<GeometricField<GradType, fvPatchField, volMesh> >
(
"grad(" + vf.name() + ")"
);
// tGrad() = ((I - n*n) & linearInterpolate(gradVf));
// tGrad() += n*fvc::snGrad(vf);
tGrad() = linearInterpolate(gradVf);
}
else
{
tGrad() = fsGrad(vf, pf);
tGrad() += n*fvc::snGrad(vf);
}
return tGrad;
}
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
> fsGrad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<GradType, fvsPatchField, surfaceMesh> > tGrad
(
new GeometricField<GradType, fvsPatchField, surfaceMesh>
(
IOobject
(
"grad" + vf.name() + "f",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<GradType>
(
"0",
vf.dimensions()/dimLength,
pTraits<GradType>::zero
)
)
);
// Is it case axisymmetric?
bool axisymmetric = false;
forAll(mesh.boundaryMesh(), patchI)
{
if (isA<wedgeFvPatch>(mesh.boundary()[patchI]))
{
axisymmetric = true;
break;
}
}
reduce(axisymmetric, orOp<bool>());
// axisymmetric = false;
if (!axisymmetric)
{
Field<GradType>& gradI = tGrad().internalField();
const vectorField& points = mesh.points();
const faceList& faces = mesh.faces();
surfaceVectorField n = mesh.Sf()/mesh.magSf();
const vectorField& nI = n.internalField();
const Field<Type>& pfI = pf.internalField();
forAll(gradI, faceI)
{
const face& curFace = faces[faceI];
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
gradI[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= nI[faceI]*(nI[faceI]&e);
// Edge length vector
vector Le = (e^nI[faceI]);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre field value
Type fe =
0.5
*(
pfI[curEdge.start()]
+ pfI[curEdge.end()]
);
// Gradient
gradI[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= nI[faceI]*(nI[faceI]&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
gradI[faceI] /= mag; // faceArea; // mag
}
forAll(tGrad().boundaryField(), patchI)
{
Field<GradType>& patchGrad = tGrad().boundaryField()[patchI];
const vectorField& patchN = n.boundaryField()[patchI];
forAll(patchGrad, faceI)
{
label globalFaceID =
mesh.boundaryMesh()[patchI].start() + faceI;
const face& curFace = mesh.faces()[globalFaceID];
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
patchGrad[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= patchN[faceI]*(patchN[faceI]&e);
// Edge length vector
vector Le = (e^patchN[faceI]);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre field value
Type fe =
0.5
*(
pfI[curEdge.start()]
+ pfI[curEdge.end()]
);
// Gradient
patchGrad[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= patchN[faceI]*(patchN[faceI]&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
patchGrad[faceI] /= mag; //faceArea; //mag
}
}
}
else
{
// Info << "Axisymmetric mesh for field: " << vf.name() << endl;
const GeometricField<GradType, fvPatchField, volMesh>& gradVf =
mesh.lookupObject<GeometricField<GradType, fvPatchField, volMesh> >
(
"grad(" + vf.name() + ")"
);
surfaceVectorField n = mesh.Sf()/mesh.magSf();
tGrad() = ((I - n*n) & linearInterpolate(gradVf));
// Correct at ggi patch
forAll(mesh.boundary(), patchI)
{
if (mesh.boundary()[patchI].type() == ggiFvPatch::typeName)
{
Field<Type> ppf =
pf.boundaryField()[patchI].patchInternalField();
tGrad().boundaryField()[patchI] ==
fGrad(mesh.boundaryMesh()[patchI], ppf);
}
}
}
// // Tangential gradient mast be equal on
// // master and shadow ggi patch
// forAll(mesh.boundary(), patchI)
// {
// if (mesh.boundary()[patchI].type() == ggiFvPatch::typeName)
// {
// const ggiFvPatch& ggiPatch =
// refCast<const ggiFvPatch>(mesh.boundary()[patchI]);
// if (ggiPatch.master())
// {
// Field<GradType>& masterGrad =
// tGrad().boundaryField()[patchI];
// const Field<GradType>& slaveGrad =
// tGrad().boundaryField()[ggiPatch.shadowIndex()];
// masterGrad += ggiPatch.interpolate(slaveGrad);
// masterGrad /= 2;
// }
// else
// {
// Field<GradType>& slaveGrad =
// tGrad().boundaryField()[patchI];
// const Field<GradType>& masterGrad =
// tGrad().boundaryField()[ggiPatch.shadowIndex()];
// slaveGrad = ggiPatch.interpolate(masterGrad);
// }
// }
// }
return tGrad;
}
template<class Type, template<class> class FaceList>
tmp<Field<typename outerProduct<vector, Type>::type> > fGrad
(
const PrimitivePatch<face, FaceList, const pointField&>& patch,
const Field<Type>& ppf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
tmp<Field<GradType> > tGrad
(
new Field<GradType>
(
patch.size(),
pTraits<GradType>::zero
)
);
Field<GradType>& grad = tGrad();
const vectorField& points = patch.localPoints();
const faceList& faces = patch.localFaces();
forAll(grad, faceI)
{
const face& curFace = faces[faceI];
vector n = curFace.normal(points);
n /= mag(n);
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= n*(n&e);
// Edge length vector
vector Le = (e^n);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre displacement
Type fe =
0.5
*(
ppf[curEdge.start()]
+ ppf[curEdge.end()]
);
// Gradient
grad[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= n*(n&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
grad[faceI] /= mag; //faceArea;
}
return tGrad;
}
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvPatchField,
volMesh
>
> grad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<GradType, fvPatchField, volMesh> > tGrad
(
new GeometricField<GradType, fvPatchField, volMesh>
(
IOobject
(
"grad(" + vf.name() + ")",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<GradType>
(
"0",
vf.dimensions()/dimLength,
pTraits<GradType>::zero
),
zeroGradientFvPatchField<GradType>::typeName
)
);
Field<GradType>& iGrad = tGrad().internalField();
const vectorField& points = mesh.points();
const faceList& faces = mesh.faces();
const Field<Type>& pfI = pf.internalField();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
scalarField V(iGrad.size(), 0.0);
forAll(owner, faceI)
{
const face& curFace = faces[faceI];
// If the face is a triangle, do a direct calculation
if (curFace.size() == 3)
{
GradType SF =
curFace.normal(points)*curFace.average(points, pfI);
iGrad[owner[faceI]] += SF;
iGrad[neighbour[faceI]] -= SF;
scalar SR = (curFace.normal(points)&curFace.centre(points));
V[owner[faceI]] += SR;
V[neighbour[faceI]] -= SR;
}
else
{
label nPoints = curFace.size();
point centrePoint = point::zero;
Type cf = pTraits<Type>::zero;
for (register label pI=0; pI<nPoints; pI++)
{
centrePoint += points[curFace[pI]];
cf += pfI[curFace[pI]];
}
centrePoint /= nPoints;
cf /= nPoints;
for (register label pI=0; pI<nPoints; pI++)
{
// Calculate triangle centre field value
Type ttcf =
(
pfI[curFace[pI]]
+ pfI[curFace[(pI + 1) % nPoints]]
+ cf
);
ttcf /= 3.0;
// Calculate triangle area
vector St =
(
(points[curFace[pI]] - centrePoint)
^ (
points[curFace[(pI + 1) % nPoints]]
- centrePoint
)
);
St /= 2.0;
// Calculate triangle centre
vector Ct =
(
centrePoint
+ points[curFace[pI]]
+ points[curFace[(pI + 1) % nPoints]]
)/3;
iGrad[owner[faceI]] += St*ttcf;
iGrad[neighbour[faceI]] -= St*ttcf;
V[owner[faceI]] += (St&Ct);
V[neighbour[faceI]] -= (St&Ct);
}
}
}
forAll(mesh.boundaryMesh(), patchI)
{
const unallocLabelList& pFaceCells =
mesh.boundaryMesh()[patchI].faceCells();
// GradType test = pTraits<GradType>::zero;
forAll(mesh.boundaryMesh()[patchI], faceI)
{
label globalFaceID =
mesh.boundaryMesh()[patchI].start() + faceI;
const face& curFace = faces[globalFaceID];
if (isA<wedgeFvPatch>(mesh.boundary()[patchI]))
{
iGrad[pFaceCells[faceI]] +=
curFace.normal(points)*vf.boundaryField()[patchI][faceI];
V[pFaceCells[faceI]] +=
(curFace.normal(points)&curFace.centre(points));
}
else if (curFace.size() == 3)
{
// If the face is a triangle, do a direct calculation
iGrad[pFaceCells[faceI]] +=
curFace.normal(points)*curFace.average(points, pfI);
V[pFaceCells[faceI]] +=
(curFace.normal(points)&curFace.centre(points));
}
else
{
label nPoints = curFace.size();
point centrePoint = point::zero;
Type cf = pTraits<Type>::zero;
for (register label pI=0; pI<nPoints; pI++)
{
centrePoint += points[curFace[pI]];
cf += pfI[curFace[pI]];
}
centrePoint /= nPoints;
cf /= nPoints;
for (register label pI=0; pI<nPoints; pI++)
{
// Calculate triangle centre field value
Type ttcf =
(
pfI[curFace[pI]]
+ pfI[curFace[(pI + 1) % nPoints]]
+ cf
);
ttcf /= 3.0;
// ttcf = vf.boundaryField()[patchI][faceI];
// Calculate triangle area
vector St =
(
(points[curFace[pI]] - centrePoint)
^ (
points[curFace[(pI + 1) % nPoints]]
- centrePoint
)
);
St /= 2.0;
// Calculate triangle centre
vector Ct =
(
centrePoint
+ points[curFace[pI]]
+ points[curFace[(pI + 1) % nPoints]]
)/3;
iGrad[pFaceCells[faceI]] += St*ttcf;
// test += ttcf*St;
V[pFaceCells[faceI]] += (St&Ct);
}
}
}
// Info << mesh.boundaryMesh()[patchI].name() << ", "
// << test << endl;
}
V /= 3;
iGrad /= V;
// GradType avgGrad = sum(iGrad*V);
// Info << "sumV: " << sum(V) << endl;
// Info << "avgGrad: " << avgGrad << endl;
// iGrad /= mesh.V();
// iGrad = fv::gaussGrad<vector>(mesh).grad(vf)().internalField();
// Extrapolate to boundary
tGrad().correctBoundaryConditions();
// Calculate boundary gradient
forAll(mesh.boundary(), patchI)
{
if
(
mesh.boundary()[patchI].size()
&& !vf.boundaryField()[patchI].coupled()
&& !isA<wedgeFvPatch>(mesh.boundary()[patchI])
)
{
Field<Type> ppf =
pf.boundaryField()[patchI].patchInternalField();
tGrad().boundaryField()[patchI] ==
fGrad(mesh.boundaryMesh()[patchI], ppf);
}
else if (isA<ggiFvPatch>(mesh.boundary()[patchI]))
{
Field<Type> ppf =
pf.boundaryField()[patchI].patchInternalField();
tGrad().boundaryField()[patchI] ==
fGrad(mesh.boundaryMesh()[patchI], ppf);
}
}
// // Tangential gradient mast be equal on
// // master and shadow ggi patch
// forAll(mesh.boundary(), patchI)
// {
// if (mesh.boundary()[patchI].type() == ggiFvPatch::typeName)
// {
// const ggiFvPatch& ggiPatch =
// refCast<const ggiFvPatch>(mesh.boundary()[patchI]);
// if (ggiPatch.master())
// {
// Field<GradType>& masterGrad =
// tGrad().boundaryField()[patchI];
// const Field<GradType>& slaveGrad =
// tGrad().boundaryField()[ggiPatch.shadowIndex()];
// masterGrad += ggiPatch.interpolate(slaveGrad);
// masterGrad /= 2;
// }
// else
// {
// Field<GradType>& slaveGrad =
// tGrad().boundaryField()[patchI];
// const Field<GradType>& masterGrad =
// tGrad().boundaryField()[ggiPatch.shadowIndex()];
// slaveGrad = ggiPatch.interpolate(masterGrad);
// }
// }
// }
// Add normal gradient
// fv::gaussGrad<Type>(mesh).correctBoundaryConditions(vf, tGrad());
forAll (vf.boundaryField(), patchi)
{
if (!vf.boundaryField()[patchi].coupled())
{
vectorField n = vf.mesh().boundary()[patchi].nf();
tGrad().boundaryField()[patchi] += n*
(
vf.boundaryField()[patchi].snGrad()
- (n & tGrad().boundaryField()[patchi])
);
}
// else if (isA<ggiFvPatch>(mesh.boundary()[patchi]))
// {
// vectorField n = vf.mesh().boundary()[patchi].nf();
// tGrad().boundaryField()[patchi] += n*
// (
// vf.boundaryField()[patchi].snGrad()
// - (n & tGrad().boundaryField()[patchi])
// );
// }
}
return tGrad;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fvc
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,884 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fvcGradf.H"
#include "fvMesh.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "pointFields.H"
#include "ggiFvPatch.H"
#include "wedgeFvPatch.H"
#include "leastSquaresVolPointInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fvc
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
> fGrad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<GradType, fvsPatchField, surfaceMesh> > tGrad
(
new GeometricField<GradType, fvsPatchField, surfaceMesh>
(
IOobject
(
"grad" + vf.name() + "f",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<GradType>
(
"0",
vf.dimensions()/dimLength,
pTraits<GradType>::zero
)
)
);
Field<GradType>& gradI = tGrad().internalField();
const vectorField& points = mesh.points();
const faceList& faces = mesh.faces();
surfaceVectorField n = mesh.Sf()/mesh.magSf();
const vectorField& nI = n.internalField();
const Field<Type>& pfI = pf.internalField();
forAll(gradI, faceI)
{
const face& curFace = faces[faceI];
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
gradI[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= nI[faceI]*(nI[faceI]&e);
// Edge length vector
vector Le = (e^nI[faceI]);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre field value
Type fe =
0.5
*(
pfI[curEdge.start()]
+ pfI[curEdge.end()]
);
// Gradient
gradI[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= nI[faceI]*(nI[faceI]&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
gradI[faceI] /= mag; // faceArea; // mag
}
forAll(tGrad().boundaryField(), patchI)
{
Field<GradType>& patchGrad = tGrad().boundaryField()[patchI];
const vectorField& patchN = n.boundaryField()[patchI];
forAll(patchGrad, faceI)
{
label globalFaceID = mesh.boundaryMesh()[patchI].start() + faceI;
const face& curFace = mesh.faces()[globalFaceID];
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
patchGrad[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= patchN[faceI]*(patchN[faceI]&e);
// Edge length vector
vector Le = (e^patchN[faceI]);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre field value
Type fe =
0.5
*(
pfI[curEdge.start()]
+ pfI[curEdge.end()]
);
// Gradient
patchGrad[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= patchN[faceI]*(patchN[faceI]&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
patchGrad[faceI] /= mag; //faceArea; //mag
}
}
forAll(mesh.boundary(), patchI)
{
if (mesh.boundary()[patchI].type() == ggiFvPatch::typeName)
{
const ggiFvPatch& ggiPatch =
refCast<const ggiFvPatch>(mesh.boundary()[patchI]);
if (!ggiPatch.master())
{
Field<GradType>& slaveGrad =
tGrad().boundaryField()[patchI];
const Field<GradType>& masterGrad =
tGrad().boundaryField()[ggiPatch.shadowIndex()];
slaveGrad = ggiPatch.interpolate(masterGrad);
}
}
}
// // Calculate boundary gradient
// forAll(mesh.boundary(), patchI)
// {
// Field<Type> ppf = pf.boundaryField()[patchI].patchInternalField();
// tGrad().boundaryField()[patchI] ==
// fGrad(mesh.boundaryMesh()[patchI], ppf);
// }
// const GeometricField<GradType, fvPatchField, volMesh>& gradU =
// mesh.lookupObject<GeometricField<GradType, fvPatchField, volMesh> >
// (
// "grad(" + vf.name() + ")"
// );
// tGrad() = ((I - n*n)&fvc::interpolate(gradU));
// Add normal component of the gradient
// tGrad() -= n*(n&tGrad());
tGrad() += n*fvc::snGrad(vf);
return tGrad;
}
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
>
fGrad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const GeometricField
<
typename outerProduct<vector, Type>::type,
fvPatchField,
volMesh
>& gradVf
)
{
const fvMesh& mesh = vf.mesh();
const leastSquaresVolPointInterpolation& vpi =
mesh.lookupObject<leastSquaresVolPointInterpolation>
(
"leastSquaresVolPointInterpolation"
);
labelList axisPoints = vpi.pointAxisEdges().toc();
// const labelListList& pCells = mesh.pointCells();
// GeometricField<Type, pointPatchField, pointMesh>& pf_ =
// const_cast<GeometricField<Type, pointPatchField, pointMesh>&>(pf);
// forAll(axisPoints, pointI)
// {
// label curPoint = axisPoints[pointI];
// const labelList& curPointCells = pCells[curPoint];
// pf_[curPoint] = pTraits<Type>::zero;
// forAll (curPointCells, cellI)
// {
// label curCell = curPointCells[cellI];
// vector delta =
// mesh.points()[curPoint]
// - mesh.cellCentres()[curCell];
// pf_[curPoint] += vf[curCell] + (delta&gradVf[curCell]);
// }
// pf_[curPoint] /= curPointCells.size();
// pf_[curPoint] =
// transform
// (
// sqr(vector(0, 1, 0)),
// pf[curPoint]
// );
// }
// pf_.correctBoundaryConditions();
typedef typename outerProduct<vector, Type>::type GradType;
tmp<GeometricField<GradType, fvsPatchField, surfaceMesh> > tGrad =
fsGrad(vf, pf);
GeometricField<GradType, fvsPatchField, surfaceMesh> fGradVf =
fvc::interpolate(gradVf);
surfaceVectorField n = mesh.Sf()/mesh.magSf();
fGradVf -= n*(n & fGradVf);
// fGradVf += n*fvc::snGrad(vf);
// forAll(tGrad().internalField(), faceI)
// {
// if (mesh.faceCentres()[faceI].x() < 0.1)
// {
// tGrad()[faceI] = fGradVf[faceI];
// }
// }
// const labelListList& pFaces = mesh.pointFaces();
// forAll(axisPoints, pointI)
// {
// label curPoint = axisPoints[pointI];
// const labelList& curPointFaces = pFaces[curPoint];
// forAll(curPointFaces, faceI)
// {
// label curFace = curPointFaces[faceI];
// if (curFace < mesh.nInternalFaces())
// {
// tGrad()[curFace] = fGradVf[curFace];
// }
// }
// }
tGrad() = fGradVf;
// tGrad().internalField() = fGradVf.internalField();
// forAll(tGrad().boundaryField(), patchI)
// {
// if (isA<wedgeFvPatch>(mesh.boundary()[patchI]))
// {
// tGrad().boundaryField()[patchI] =
// fGradVf.boundaryField()[patchI];
// }
// }
tGrad() += n*fvc::snGrad(vf);
// forAll(fGradVf.internalField(), faceI)
// {
// tGrad()[faceI] = fGradVf[faceI];
// }
return tGrad;
}
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
> fsGrad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<GradType, fvsPatchField, surfaceMesh> > tGrad
(
new GeometricField<GradType, fvsPatchField, surfaceMesh>
(
IOobject
(
"grad" + vf.name() + "f",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<GradType>
(
"0",
vf.dimensions()/dimLength,
pTraits<GradType>::zero
)
)
);
Field<GradType>& gradI = tGrad().internalField();
const vectorField& points = mesh.points();
const faceList& faces = mesh.faces();
surfaceVectorField n = mesh.Sf()/mesh.magSf();
const vectorField& nI = n.internalField();
const Field<Type>& pfI = pf.internalField();
forAll(gradI, faceI)
{
const face& curFace = faces[faceI];
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
gradI[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= nI[faceI]*(nI[faceI]&e);
// Edge length vector
vector Le = (e^nI[faceI]);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre field value
Type fe =
0.5
*(
pfI[curEdge.start()]
+ pfI[curEdge.end()]
);
// Gradient
gradI[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= nI[faceI]*(nI[faceI]&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
gradI[faceI] /= mag; // faceArea; // mag
}
forAll(tGrad().boundaryField(), patchI)
{
Field<GradType>& patchGrad = tGrad().boundaryField()[patchI];
const vectorField& patchN = n.boundaryField()[patchI];
forAll(patchGrad, faceI)
{
label globalFaceID = mesh.boundaryMesh()[patchI].start() + faceI;
const face& curFace = mesh.faces()[globalFaceID];
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
patchGrad[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= patchN[faceI]*(patchN[faceI]&e);
// Edge length vector
vector Le = (e^patchN[faceI]);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre field value
Type fe =
0.5
*(
pfI[curEdge.start()]
+ pfI[curEdge.end()]
);
// Gradient
patchGrad[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= patchN[faceI]*(patchN[faceI]&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
patchGrad[faceI] /= mag; //faceArea; //mag
}
}
forAll(mesh.boundary(), patchI)
{
if (mesh.boundary()[patchI].type() == ggiFvPatch::typeName)
{
const ggiFvPatch& ggiPatch =
refCast<const ggiFvPatch>(mesh.boundary()[patchI]);
if (!ggiPatch.master())
{
Field<GradType>& slaveGrad =
tGrad().boundaryField()[patchI];
const Field<GradType>& masterGrad =
tGrad().boundaryField()[ggiPatch.shadowIndex()];
slaveGrad = ggiPatch.interpolate(masterGrad);
}
}
}
return tGrad;
}
template<class Type, template<class> class FaceList>
tmp<Field<typename outerProduct<vector, Type>::type> > fGrad
(
const PrimitivePatch<face, FaceList, const pointField&>& patch,
const Field<Type>& ppf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
tmp<Field<GradType> > tGrad
(
new Field<GradType>
(
patch.size(),
pTraits<GradType>::zero
)
);
Field<GradType>& grad = tGrad();
const vectorField& points = patch.localPoints();
const faceList& faces = patch.localFaces();
forAll(grad, faceI)
{
const face& curFace = faces[faceI];
vector n = curFace.normal(points);
n /= mag(n);
vector Rf = curFace.centre(points);
scalar mag = curFace.mag(points);
const edgeList curFaceEdges = curFace.edges();
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
// Projected edge vector
vector e = curEdge.vec(points);
e -= n*(n&e);
// Edge length vector
vector Le = (e^n);
Le *= curFace.edgeDirection(curEdge);
// Edge-centre displacement
Type fe =
0.5
*(
ppf[curEdge.start()]
+ ppf[curEdge.end()]
);
// Gradient
grad[faceI] += Le*fe;
// Area
vector Re = curEdge.centre(points) - Rf;
Re -= n*(n&Re);
faceArea += (Le&Re);
}
faceArea /= 2.0;
grad[faceI] /= mag; //faceArea;
}
return tGrad;
}
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvPatchField,
volMesh
>
> grad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<GradType, fvPatchField, volMesh> > tGrad
(
new GeometricField<GradType, fvPatchField, volMesh>
(
IOobject
(
"grad(" + vf.name() + ")",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<GradType>
(
"0",
vf.dimensions()/dimLength,
pTraits<GradType>::zero
)
)
);
Field<GradType>& iGrad = tGrad().internalField();
const vectorField& points = mesh.points();
const faceList& faces = mesh.faces();
const Field<Type>& pfI = pf.internalField();
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
scalarField V(iGrad.size(), 0.0);
forAll(owner, faceI)
{
const face& curFace = faces[faceI];
// If the face is a triangle, do a direct calculation
if (curFace.size() == 3)
{
GradType SF =
curFace.normal(points)*curFace.average(points, pfI);
iGrad[owner[faceI]] += SF;
iGrad[neighbour[faceI]] -= SF;
scalar SR = (curFace.normal(points)&curFace.centre(points));
V[owner[faceI]] += SR;
V[neighbour[faceI]] -= SR;
}
else
{
label nPoints = curFace.size();
point centrePoint = point::zero;
Type cf = pTraits<Type>::zero;
for (register label pI=0; pI<nPoints; pI++)
{
centrePoint += points[curFace[pI]];
cf += pfI[curFace[pI]];
}
centrePoint /= nPoints;
cf /= nPoints;
for (register label pI=0; pI<nPoints; pI++)
{
// Calculate triangle centre field value
Type ttcf =
(
pfI[curFace[pI]]
+ pfI[curFace[(pI + 1) % nPoints]]
+ cf
);
ttcf /= 3.0;
// Calculate triangle area
vector St =
(
(points[curFace[pI]] - centrePoint)
^ (
points[curFace[(pI + 1) % nPoints]]
- centrePoint
)
);
St /= 2.0;
// Calculate triangle centre
vector Ct =
(
centrePoint
+ points[curFace[pI]]
+ points[curFace[(pI + 1) % nPoints]]
)/3;
iGrad[owner[faceI]] += St*ttcf;
iGrad[neighbour[faceI]] -= St*ttcf;
V[owner[faceI]] += (St&Ct);
V[neighbour[faceI]] -= (St&Ct);
}
}
}
forAll(mesh.boundaryMesh(), patchI)
{
const unallocLabelList& pFaceCells =
mesh.boundaryMesh()[patchI].faceCells();
forAll(mesh.boundaryMesh()[patchI], faceI)
{
label globalFaceID =
mesh.boundaryMesh()[patchI].start() + faceI;
const face& curFace = faces[globalFaceID];
if (isA<wedgeFvPatch>(mesh.boundary()[patchI]))
{
iGrad[pFaceCells[faceI]] +=
curFace.normal(points)*vf.boundaryField()[patchI][faceI];
V[pFaceCells[faceI]] +=
(curFace.normal(points)&curFace.centre(points));
}
else if (curFace.size() == 3)
{
// If the face is a triangle, do a direct calculation
iGrad[pFaceCells[faceI]] +=
curFace.normal(points)*curFace.average(points, pfI);
V[pFaceCells[faceI]] +=
(curFace.normal(points)&curFace.centre(points));
}
else
{
label nPoints = curFace.size();
point centrePoint = point::zero;
Type cf = pTraits<Type>::zero;
for (register label pI=0; pI<nPoints; pI++)
{
centrePoint += points[curFace[pI]];
cf += pfI[curFace[pI]];
}
centrePoint /= nPoints;
cf /= nPoints;
for (register label pI=0; pI<nPoints; pI++)
{
// Calculate triangle centre field value
Type ttcf =
(
pfI[curFace[pI]]
+ pfI[curFace[(pI + 1) % nPoints]]
+ cf
);
ttcf /= 3.0;
// Calculate triangle area
vector St =
(
(points[curFace[pI]] - centrePoint)
^ (
points[curFace[(pI + 1) % nPoints]]
- centrePoint
)
);
St /= 2.0;
// Calculate triangle centre
vector Ct =
(
centrePoint
+ points[curFace[pI]]
+ points[curFace[(pI + 1) % nPoints]]
)/3;
iGrad[pFaceCells[faceI]] += St*ttcf;
V[pFaceCells[faceI]] += (St&Ct);
}
}
}
}
V /= 3;
iGrad /= V;
// iGrad /= mesh.V();
// iGrad = fv::gaussGrad<vector>(mesh).grad(vf)().internalField();
tGrad().correctBoundaryConditions();
// Calculate boundary gradient
forAll(mesh.boundary(), patchI)
{
if
(
mesh.boundary()[patchI].size()
&& !vf.boundaryField()[patchI].coupled()
&& !isA<wedgeFvPatch>(mesh.boundary()[patchI])
)
{
Field<Type> ppf =
pf.boundaryField()[patchI].patchInternalField();
tGrad().boundaryField()[patchI] ==
fGrad(mesh.boundaryMesh()[patchI], ppf);
}
}
// Normal gradient
fv::gaussGrad<Type>(mesh).correctBoundaryConditions(vf, tGrad());
return tGrad;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fvc
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,264 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fvcGradf.H"
#include "fvMesh.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fvc
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
> grad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
)
{
typedef typename outerProduct<vector, Type>::type GradType;
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<GradType, fvsPatchField, surfaceMesh> > tGrad
(
new GeometricField<GradType, fvsPatchField, surfaceMesh>
(
IOobject
(
"grad" + vf.name() + "f",
vf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<GradType>
(
"0",
vf.dimensions()/dimLength,
pTraits<GradType>::zero
)
)
);
Field<GradType>& gradI = tGrad().internalField();
const vectorField& points = mesh.points();
const faceList& faces = mesh.faces();
// const vectorField& faceCentres = mesh.faceCentres();
const labelList& owner = mesh.owner();
const labelList& neighbour = mesh.neighbour();
const volVectorField& C = mesh.C();
const surfaceVectorField& Cf = mesh.Cf();
const GeometricField<GradType, fvPatchField, volMesh>& gradVf =
mesh.lookupObject<GeometricField<GradType, fvPatchField, volMesh> >
(
"grad(" + vf.name() + ")"
);
surfaceVectorField n = mesh.Sf()/mesh.magSf();
// const vectorField& nI = n.internalField();
const Field<Type>& pfI = pf.internalField();
forAll(gradI, faceI)
{
const face& curFace = faces[faceI];
const edgeList curFaceEdges = curFace.edges();
Type curFaceFieldValue = pTraits<Type>::zero;
// Owner contribution
label own = owner[faceI];
curFaceFieldValue +=
0.5*(vf[own] + ((Cf[faceI] - C[own]) & gradVf[own]));
// Neighbour contribution
label nei = neighbour[faceI];
curFaceFieldValue +=
0.5*(vf[nei] + ((Cf[faceI] - C[nei]) & gradVf[nei]));
gradI[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
vectorField p(3, vector::zero);
p[0] = points[curEdge.start()];
p[1] = points[curEdge.end()];
p[2] = Cf[faceI];
Field<Type> f(3, pTraits<Type>::zero);
f[0] = pfI[curEdge.start()];
f[1] = pfI[curEdge.end()];
f[2] = curFaceFieldValue;
triFace tri(0, 1, 2);
vector triCentre = tri.centre(p);
vector triNormal = tri.normal(p);
triNormal /= mag(triNormal);
edgeList triEdges = tri.edges();
GradType triGrad = pTraits<GradType>::zero;
forAll(triEdges, eI)
{
vector e = triEdges[eI].vec(p);
vector Le = (e^triNormal);
Le *= tri.edgeDirection(triEdges[eI]);
// Edge-centre value of the field
Type fe =
0.5*(f[triEdges[eI].start()] + f[triEdges[eI].end()]);
// Gradient
triGrad += Le*fe;
}
// Gradient
gradI[faceI] += triGrad;
// Area
faceArea += tri.mag(p);
}
gradI[faceI] /= faceArea;
}
forAll(tGrad().boundaryField(), patchI)
{
Field<GradType>& patchGrad = tGrad().boundaryField()[patchI];
const vectorField& pCf = Cf.boundaryField()[patchI];
forAll(patchGrad, faceI)
{
label globalFaceID = mesh.boundaryMesh()[patchI].start() + faceI;
const face& curFace = mesh.faces()[globalFaceID];
const edgeList curFaceEdges = curFace.edges();
const Type& curFaceFieldValue =
vf.boundaryField()[patchI][faceI];
patchGrad[faceI] = pTraits<GradType>::zero;
scalar faceArea = 0;
forAll(curFaceEdges, edgeI)
{
const edge& curEdge = curFaceEdges[edgeI];
vectorField p(3, vector::zero);
p[0] = points[curEdge.start()];
p[1] = points[curEdge.end()];
p[2] = pCf[faceI];
Field<Type> f(3, pTraits<Type>::zero);
f[0] = pfI[curEdge.start()];
f[1] = pfI[curEdge.end()];
f[2] = curFaceFieldValue;
triFace tri(0, 1, 2);
vector triCentre = tri.centre(p);
vector triNormal = tri.normal(p);
triNormal /= mag(triNormal);
edgeList triEdges = tri.edges();
GradType triGrad = pTraits<GradType>::zero;
forAll(triEdges, eI)
{
vector e = triEdges[eI].vec(p);
vector Le = (e^triNormal);
Le *= tri.edgeDirection(triEdges[eI]);
// Edge-centre value of the field
Type fe =
0.5*(f[triEdges[eI].start()] + f[triEdges[eI].end()]);
// Gradient
triGrad += Le*fe;
}
// Gradient
patchGrad[faceI] += triGrad;
// Area
faceArea += tri.mag(p);
}
patchGrad[faceI] /= faceArea;
}
}
// Add normal component of the gradient
tGrad() += n*fvc::snGrad(vf);
return tGrad;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fvc
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,145 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
InNamespace
Foam::fvc
Description
Calculate the surface gradient of the given field.
SourceFiles
fvcGradf.C
\*---------------------------------------------------------------------------*/
#ifndef fvcGradf_H
#define fvcGradf_H
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "pointFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Namespace fvc functions Declaration
\*---------------------------------------------------------------------------*/
namespace fvc
{
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
> fGrad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf,
bool interpolate = false
);
// template<class Type>
// tmp
// <
// GeometricField
// <
// typename outerProduct<vector, Type>::type,
// fvsPatchField,
// surfaceMesh
// >
// > fGrad
// (
// const GeometricField<Type, fvPatchField, volMesh>& vf,
// const GeometricField<Type, pointPatchField, pointMesh>& pf,
// const GeometricField
// <
// typename outerProduct<vector, Type>::type,
// fvPatchField,
// volMesh
// >& gradVf
// );
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvsPatchField,
surfaceMesh
>
> fsGrad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
);
template<class Type, template<class> class FaceList>
tmp<Field<typename outerProduct<vector, Type>::type> > fGrad
(
const PrimitivePatch<face, FaceList, const pointField&>& patch,
const Field<Type>& ppf
);
template<class Type>
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvPatchField,
volMesh
>
> grad
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "fvcGradf.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,170 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "fvcGradf.H"
#include "fvMesh.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "pointFields.H"
#include "ggiFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fvc
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
)
{
const fvMesh& mesh = vf.mesh();
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tResult
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
"interpolate(" + pf.name() + ")",
pf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<Type>
(
"0",
vf.dimensions(),
pTraits<Type>::zero
)
)
);
Field<Type>& resultI = tResult().internalField();
const vectorField& points = mesh.points();
const faceList& faces = mesh.faces();
const Field<Type>& pfI = pf.internalField();
// const unallocLabelList& owner = mesh.owner();
// const unallocLabelList& neighbour = mesh.neighbour();
forAll(resultI, faceI)
{
const face& curFace = faces[faceI];
// If the face is a triangle, do a direct calculation
if (curFace.size() == 3)
{
resultI[faceI] = curFace.average(points, pfI);
}
else
{
label nPoints = curFace.size();
point centrePoint = point::zero;
Type cf = pTraits<Type>::zero;
for (register label pI=0; pI<nPoints; pI++)
{
centrePoint += points[curFace[pI]];
cf += pfI[curFace[pI]];
}
centrePoint /= nPoints;
cf /= nPoints;
resultI[faceI] = cf;
}
}
forAll(mesh.boundary(), patchI)
{
tResult().boundaryField()[patchI] =
vf.boundaryField()[patchI];
// forAll(mesh.boundary()[patchI], faceI)
// {
// label globalFaceID =
// mesh.boundaryMesh()[patchI].start() + faceI;
// const face& curFace = faces[globalFaceID];
// // If the face is a triangle, do a direct calculation
// if (curFace.size() == 3)
// {
// tResult().boundaryField()[patchI][faceI] =
// curFace.average(points, pfI);
// }
// else
// {
// label nPoints = curFace.size();
// point centrePoint = point::zero;
// Type cf = pTraits<Type>::zero;
// for (register label pI=0; pI<nPoints; pI++)
// {
// centrePoint += points[curFace[pI]];
// cf += pfI[curFace[pI]];
// }
// centrePoint /= nPoints;
// cf /= nPoints;
// tResult().boundaryField()[patchI][faceI] = cf;
// }
// }
}
return tResult;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fvc
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
InNamespace
Foam::fvc
Description
Calculate the surface gradient of the given field.
SourceFiles
fvcGradf.C
\*---------------------------------------------------------------------------*/
#ifndef fvcInterpolate_H
#define fvcInterpolate_H
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "pointFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Namespace fvc functions Declaration
\*---------------------------------------------------------------------------*/
namespace fvc
{
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const GeometricField<Type, pointPatchField, pointMesh>& pf
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "fvcInterpolate.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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