fvMeshStitcher: Prevent storage of internal surface fields for mapping
This reduces the memory usage of the stitching operation, and simplifies its interaction with other mesh changers. The storage of separate original and non-conformal field parts is now done within a new "conformal" boundary condition. This condition internally stores two boundary conditions; one for the original patch values, and one for the non-conformal part. The conformal condition replaces the condition applied to the original patch on un-stitch when the non-conformal boundaries are removed. The data stored in the conformal condition is then used to restore the previous conditions during the re-stitch process. This conformal condition supports mapping of various types. This means both original and non-conformal boundary data gets mapped automatically as a result of other mesh changes such as automatic refinement.
This commit is contained in:
@ -123,6 +123,9 @@ fvMeshStitchers = fvMesh/fvMeshStitchers
|
||||
|
||||
$(fvMeshStitchers)/fvMeshStitcher/fvMeshStitcher.C
|
||||
$(fvMeshStitchers)/fvMeshStitcher/fvMeshStitcherNew.C
|
||||
$(fvMeshStitchers)/fvMeshStitcher/fvMeshStitcherTools.C
|
||||
$(fvMeshStitchers)/fvMeshStitcher/conformedFvsPatchFields.C
|
||||
#$(fvMeshStitchers)/fvMeshStitcher/conformalisingFvPatchFieldMapper.C
|
||||
$(fvMeshStitchers)/stationary/fvMeshStitchersStationary.C
|
||||
|
||||
functionObjects/fvMeshFunctionObject/fvMeshFunctionObject.C
|
||||
|
||||
@ -0,0 +1,299 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "conformedFvsPatchField.H"
|
||||
#include "fvMeshStitcherTools.H"
|
||||
#include "nonConformalBoundary.H"
|
||||
#include "nonConformalFvPatch.H"
|
||||
#include "nonConformalErrorFvPatch.H"
|
||||
#include "surfaceFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Constructors * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::conformedFvsPatchField<Type>::conformedFvsPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, surfaceMesh>& iF,
|
||||
autoPtr<fvsPatchField<Type>>&& origFieldPtr,
|
||||
autoPtr<calculatedFvsPatchField<Type>>&& ncFieldPtr
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(p, iF),
|
||||
origFieldPtr_(origFieldPtr),
|
||||
ncFieldPtr_(ncFieldPtr)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::conformedFvsPatchField<Type>::conform
|
||||
(
|
||||
typename SurfaceField<Type>::Boundary& bF
|
||||
)
|
||||
{
|
||||
const DimensionedField<Type, surfaceMesh>& iF = bF[0].internalField();
|
||||
|
||||
const fvBoundaryMesh& fvbm = iF.mesh().boundary();
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(iF.mesh()).allOrigPatchIDs();
|
||||
|
||||
// Evaluate the conformed orig and non-conformal boundary fields
|
||||
const typename SurfaceField<Type>::Boundary origBf
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fvMeshStitcherTools::conformedOrigBoundaryField(bF)
|
||||
);
|
||||
const typename SurfaceField<Type>::Boundary ncBf
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fvMeshStitcherTools::conformedNcBoundaryField(bF)
|
||||
);
|
||||
|
||||
// Replace every original patch field with a conformed patch field
|
||||
// containing the conformed orig and non-conformal fields
|
||||
forAll(origPatchIDs, i)
|
||||
{
|
||||
const label origPatchi = origPatchIDs[i];
|
||||
const fvPatch& origFvp = fvbm[origPatchi];
|
||||
|
||||
autoPtr<conformedFvsPatchField<Type>> pF
|
||||
(
|
||||
new conformedFvsPatchField<Type>
|
||||
(
|
||||
origFvp,
|
||||
iF,
|
||||
bF.set(origPatchi, nullptr),
|
||||
autoPtr<calculatedFvsPatchField<Type>>
|
||||
(
|
||||
new calculatedFvsPatchField<Type>(origFvp, iF)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
pF->origFieldPtr_() == origBf[origPatchi];
|
||||
pF->ncFieldPtr_() == ncBf[origPatchi];
|
||||
|
||||
bF.set(origPatchi, pF.ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::conformedFvsPatchField<Type>::unconform
|
||||
(
|
||||
typename SurfaceField<Type>::Boundary& bF
|
||||
)
|
||||
{
|
||||
const DimensionedField<Type, surfaceMesh>& iF = bF[0].internalField();
|
||||
|
||||
const fvBoundaryMesh& fvbm = iF.mesh().boundary();
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(iF.mesh()).allOrigPatchIDs();
|
||||
|
||||
// Extract the conformalalised orig and non-conformal boundary fields from
|
||||
// the stored conformed patch fields
|
||||
PtrList<fvsPatchField<Type>> origPFs(fvbm.size());
|
||||
PtrList<fvsPatchField<Type>> ncPFs(fvbm.size());
|
||||
forAll(origPatchIDs, i)
|
||||
{
|
||||
const label origPatchi = origPatchIDs[i];
|
||||
|
||||
conformedFvsPatchField<Type>& cpF =
|
||||
refCast<conformedFvsPatchField<Type>>(bF[origPatchi]);
|
||||
|
||||
origPFs.set(origPatchi, cpF.origFieldPtr_.ptr());
|
||||
ncPFs.set(origPatchi, cpF.ncFieldPtr_.ptr());
|
||||
}
|
||||
forAll(origPFs, patchi)
|
||||
{
|
||||
if (origPFs.set(patchi)) continue;
|
||||
|
||||
origPFs.set(patchi, bF.set(patchi, nullptr));
|
||||
ncPFs.set
|
||||
(
|
||||
patchi,
|
||||
fvsPatchField<Type>::New
|
||||
(
|
||||
calculatedFvsPatchField<Type>::typeName,
|
||||
fvbm[patchi],
|
||||
iF
|
||||
)
|
||||
);
|
||||
}
|
||||
typename SurfaceField<Type>::Boundary origBf(fvbm, iF, origPFs);
|
||||
typename SurfaceField<Type>::Boundary ncBf(fvbm, iF, ncPFs);
|
||||
|
||||
// Combine the conformed boundary fields to create the non-conformal
|
||||
// boundary field
|
||||
typename SurfaceField<Type>::Boundary result
|
||||
(
|
||||
iF,
|
||||
fvMeshStitcherTools::unconformedBoundaryField(ncBf, origBf)
|
||||
);
|
||||
bF.transfer(result);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::conformedFvsPatchField<Type>::conformedFvsPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, surfaceMesh>& iF
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(p, iF)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::conformedFvsPatchField<Type>::conformedFvsPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, surfaceMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(p, iF, dict, false),
|
||||
origFieldPtr_
|
||||
(
|
||||
fvsPatchField<Type>::New(p, iF, dict.subDict("origField")).ptr()
|
||||
),
|
||||
ncFieldPtr_
|
||||
(
|
||||
new calculatedFvsPatchField<Type>(p, iF, dict.subDict("ncField"))
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::conformedFvsPatchField<Type>::conformedFvsPatchField
|
||||
(
|
||||
const conformedFvsPatchField<Type>& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, surfaceMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(ptf, p, iF, mapper, false),
|
||||
origFieldPtr_
|
||||
(
|
||||
fvsPatchField<Type>::New(ptf.origFieldPtr_(), p, iF, mapper).ptr()
|
||||
),
|
||||
ncFieldPtr_
|
||||
(
|
||||
new calculatedFvsPatchField<Type>
|
||||
(
|
||||
ptf.ncFieldPtr_(),
|
||||
p,
|
||||
iF,
|
||||
mapper
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::conformedFvsPatchField<Type>::conformedFvsPatchField
|
||||
(
|
||||
const conformedFvsPatchField<Type>& ptf,
|
||||
const DimensionedField<Type, surfaceMesh>& iF
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(ptf, iF),
|
||||
origFieldPtr_(ptf.origFieldPtr_->clone(iF).ptr()),
|
||||
ncFieldPtr_(new calculatedFvsPatchField<Type>(ptf.ncFieldPtr_(), iF))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::conformedFvsPatchField<Type>::map
|
||||
(
|
||||
const fvsPatchField<Type>& ptf,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
{
|
||||
if (isA<conformedFvsPatchField<Type>>(ptf))
|
||||
{
|
||||
const conformedFvsPatchField<Type>& cptf =
|
||||
refCast<const conformedFvsPatchField<Type>>(ptf);
|
||||
|
||||
origFieldPtr_->map(cptf.origFieldPtr_(), mapper);
|
||||
ncFieldPtr_->map(cptf.ncFieldPtr_(), mapper);
|
||||
}
|
||||
else
|
||||
{
|
||||
origFieldPtr_->reset(ptf);
|
||||
ncFieldPtr_() == origFieldPtr_();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::conformedFvsPatchField<Type>::reset(const fvsPatchField<Type>& ptf)
|
||||
{
|
||||
if (isA<conformedFvsPatchField<Type>>(ptf))
|
||||
{
|
||||
const conformedFvsPatchField<Type>& cptf =
|
||||
refCast<const conformedFvsPatchField<Type>>(ptf);
|
||||
|
||||
origFieldPtr_->reset(cptf.origFieldPtr_());
|
||||
ncFieldPtr_->reset(cptf.ncFieldPtr_());
|
||||
}
|
||||
else
|
||||
{
|
||||
origFieldPtr_->reset(ptf);
|
||||
ncFieldPtr_() == origFieldPtr_();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::conformedFvsPatchField<Type>::write(Ostream& os) const
|
||||
{
|
||||
fvsPatchField<Type>::write(os);
|
||||
|
||||
writeKeyword(os, "origField") << nl;
|
||||
os << indent << token::BEGIN_BLOCK << incrIndent << nl;
|
||||
origFieldPtr_->write(os);
|
||||
os << decrIndent << indent << token::END_BLOCK << nl;
|
||||
|
||||
writeKeyword(os, "ncField") << nl;
|
||||
os << indent << token::BEGIN_BLOCK << incrIndent << nl;
|
||||
ncFieldPtr_->write(os);
|
||||
os << decrIndent << indent << token::END_BLOCK << nl;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,182 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::conformedFvsPatchField
|
||||
|
||||
Description
|
||||
This surface field boundary condition holds data from both the original
|
||||
faces and any associated non-conformal faces, with the latter mapped to the
|
||||
conformal faces in the original patch. It is used during mesh change
|
||||
(between the un-stitch and stitch steps) to ensure that fields relating to
|
||||
both the original and the non-conformal patches are retained and mapped.
|
||||
|
||||
SourceFiles
|
||||
conformedFvsPatchField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef conformedFvsPatchField_H
|
||||
#define conformedFvsPatchField_H
|
||||
|
||||
#include "fvsPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class conformedFvsPatch Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class conformedFvsPatchField
|
||||
:
|
||||
public fvsPatchField<Type>
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The original patch field
|
||||
autoPtr<fvsPatchField<Type>> origFieldPtr_;
|
||||
|
||||
//- The associated non-conformal patch field
|
||||
autoPtr<calculatedFvsPatchField<Type>> ncFieldPtr_;
|
||||
|
||||
|
||||
// Private Constructors
|
||||
|
||||
//- Construct from components
|
||||
conformedFvsPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, surfaceMesh>&,
|
||||
autoPtr<fvsPatchField<Type>>&& origFieldPtr,
|
||||
autoPtr<calculatedFvsPatchField<Type>>&& ncFieldPtr
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("conformed");
|
||||
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Conform the given boundary field
|
||||
static void conform(typename SurfaceField<Type>::Boundary& bF);
|
||||
|
||||
//- Un-conform the given boundary field
|
||||
static void unconform(typename SurfaceField<Type>::Boundary& bF);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
conformedFvsPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, surfaceMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
conformedFvsPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, surfaceMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping the given conformedFvsPatchField<Type>
|
||||
// onto a new patch
|
||||
conformedFvsPatchField
|
||||
(
|
||||
const conformedFvsPatchField<Type>&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, surfaceMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Disallow copy without setting internal field reference
|
||||
conformedFvsPatchField
|
||||
(
|
||||
const conformedFvsPatchField<Type>&
|
||||
) = delete;
|
||||
|
||||
//- Copy constructor setting internal field reference
|
||||
conformedFvsPatchField
|
||||
(
|
||||
const conformedFvsPatchField<Type>&,
|
||||
const DimensionedField<Type, surfaceMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvsPatchField<Type>> clone
|
||||
(
|
||||
const DimensionedField<Type, surfaceMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvsPatchField<Type>>
|
||||
(
|
||||
new conformedFvsPatchField<Type>(*this, iF)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Mapping functions
|
||||
|
||||
//- Map the given fvsPatchField onto this fvsPatchField
|
||||
virtual void map
|
||||
(
|
||||
const fvsPatchField<Type>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Reset the fvsPatchField to the given fvsPatchField
|
||||
// Used for mesh to mesh mapping
|
||||
virtual void reset(const fvsPatchField<Type>&);
|
||||
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "conformedFvsPatchField.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "conformedFvsPatchFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
makeFvsPatchFields(conformed);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef conformedFvsPatchFields_H
|
||||
#define conformedFvsPatchFields_H
|
||||
|
||||
#include "conformedFvsPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makeFvsPatchTypeFieldTypedefs(conformed);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef conformedFvsPatchFieldsFwd_H
|
||||
#define conformedFvsPatchFieldsFwd_H
|
||||
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type> class conformedFvsPatchField;
|
||||
|
||||
makeFvsPatchTypeFieldTypedefs(conformed);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -26,8 +26,11 @@ License
|
||||
#include "fvMeshStitcher.H"
|
||||
#include "globalIndex.H"
|
||||
#include "fvcSurfaceIntegrate.H"
|
||||
#include "fvMeshToFvMesh.H"
|
||||
#include "meshObjects.H"
|
||||
#include "polyTopoChangeMap.H"
|
||||
#include "polyMeshMap.H"
|
||||
#include "polyDistributionMap.H"
|
||||
#include "syncTools.H"
|
||||
#include "surfaceToVolVelocity.H"
|
||||
|
||||
@ -62,10 +65,6 @@ namespace Foam
|
||||
}
|
||||
|
||||
|
||||
const Foam::word Foam::fvMeshStitcher::nccFieldPrefix_ =
|
||||
fvMeshStitcher::typeName + ":";
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::fvMeshStitcher::intersectNonConformalCyclic
|
||||
@ -1084,6 +1083,58 @@ inline void Foam::fvMeshStitcher::createNonConformalStabilisationGeometry
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvMeshStitcher::preConformSurfaceFields()
|
||||
{
|
||||
#define PreConformSurfaceFields(Type, nullArg) \
|
||||
preConformSurfaceFields<Type>();
|
||||
FOR_ALL_FIELD_TYPES(PreConformSurfaceFields);
|
||||
#undef PreConformSurfaceFields
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvMeshStitcher::postNonConformSurfaceFields()
|
||||
{
|
||||
#define PostNonConformSurfaceFields(Type, nullArg) \
|
||||
postNonConformSurfaceFields<Type>();
|
||||
FOR_ALL_FIELD_TYPES(PostNonConformSurfaceFields);
|
||||
#undef PostNonConformSurfaceFields
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvMeshStitcher::evaluateVolFields()
|
||||
{
|
||||
#define EvaluateVolFields(Type, nullArg) \
|
||||
evaluateVolFields<Type>();
|
||||
FOR_ALL_FIELD_TYPES(EvaluateVolFields);
|
||||
#undef EvaluateVolFields
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvMeshStitcher::postNonConformSurfaceVelocities()
|
||||
{
|
||||
UPtrList<surfaceVectorField> Ufs(mesh_.fields<surfaceVectorField>());
|
||||
|
||||
forAll(Ufs, i)
|
||||
{
|
||||
surfaceVectorField& Uf = Ufs[i];
|
||||
|
||||
const volVectorField& U = surfaceToVolVelocity(Uf);
|
||||
|
||||
if (!isNull(U))
|
||||
{
|
||||
forAll(Uf.boundaryField(), patchi)
|
||||
{
|
||||
if (isA<nonConformalFvPatch>(mesh_.boundary()[patchi]))
|
||||
{
|
||||
boundaryFieldRefNoUpdate(Uf)[patchi] ==
|
||||
U.boundaryField()[patchi];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::fvMeshStitcher::geometric() const
|
||||
@ -1605,7 +1656,7 @@ void Foam::fvMeshStitcher::topoChange(const polyTopoChangeMap&)
|
||||
{}
|
||||
|
||||
|
||||
void Foam::fvMeshStitcher::mapMesh(const polyMeshMap&)
|
||||
void Foam::fvMeshStitcher::mapMesh(const polyMeshMap& map)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ SourceFiles
|
||||
#define fvMeshStitcher_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
#include "HashPtrTable.H"
|
||||
#include "intersectionPatchToPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -72,18 +73,73 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
// Private Static Data
|
||||
|
||||
//- Prefix applied to the names of non-conformal fields which are
|
||||
// stored for mapping purposes
|
||||
static const word nccFieldPrefix_;
|
||||
|
||||
|
||||
// Private Data
|
||||
|
||||
//- Non-const fvMesh reference to allow update
|
||||
fvMesh& mesh_;
|
||||
|
||||
//- Cache of the surface boundary fields with non-conformal parts
|
||||
// averaged/summed (as appropriate) into the corresponding conformal
|
||||
// faces. Maintained between disconnect and connect so that
|
||||
// non-conformal fields can be reconstructed again at the new time.
|
||||
class
|
||||
:
|
||||
#define PrivateTypeTable(Type, nullArg) \
|
||||
private HashPtrTable<SurfaceFieldBoundary<Type>>,
|
||||
FOR_ALL_FIELD_TYPES(PrivateTypeTable)
|
||||
#undef PrivateTypeTable
|
||||
private nil
|
||||
{
|
||||
private:
|
||||
|
||||
template<class Type>
|
||||
using Base = HashPtrTable<SurfaceFieldBoundary<Type>>;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
template<class Type>
|
||||
const HashPtrTable<SurfaceFieldBoundary<Type>>& table() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
HashPtrTable<SurfaceFieldBoundary<Type>>& table()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
bool insert
|
||||
(
|
||||
const word& name,
|
||||
SurfaceFieldBoundary<Type>* fieldPtr
|
||||
)
|
||||
{
|
||||
return Base<Type>::insert(name, fieldPtr);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
bool found(const word& name) const
|
||||
{
|
||||
return Base<Type>::found(name);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> remove(const word& name)
|
||||
{
|
||||
typename Base<Type>::iterator iter = Base<Type>::find(name);
|
||||
|
||||
return
|
||||
tmp<SurfaceFieldBoundary<Type>>
|
||||
(
|
||||
Base<Type>::remove(iter)
|
||||
);
|
||||
}
|
||||
|
||||
} conformalNccBoundaryFields_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -178,21 +234,12 @@ private:
|
||||
|
||||
// Field Mapping
|
||||
|
||||
//- Return the boundary field reference for the given field,
|
||||
// without updating the time index, storing old time fields,
|
||||
// etc...
|
||||
template<class GeoField>
|
||||
static typename GeoField::Boundary& boundaryFieldRefNoUpdate
|
||||
(
|
||||
GeoField& fld
|
||||
);
|
||||
|
||||
//- Resize the patch fields of a given type and class to match the
|
||||
// mesh
|
||||
// sizes of the patches in the mesh
|
||||
template<class Type, template<class> class GeoField>
|
||||
void resizePatchFields();
|
||||
|
||||
//- Resize the patch fields of a given class to match the mesh
|
||||
//- As above, for all types
|
||||
template<template<class> class GeoField>
|
||||
void resizePatchFields();
|
||||
|
||||
@ -202,10 +249,8 @@ private:
|
||||
template<class Type>
|
||||
void preConformSurfaceFields();
|
||||
|
||||
//- Pre-conform surface fields by separating NCC and original
|
||||
// parts of non-conformal couplings and storing them in the
|
||||
// database as separate fields
|
||||
inline void preConformSurfaceFields();
|
||||
//- As above, for all types
|
||||
void preConformSurfaceFields();
|
||||
|
||||
//- Post-non-conform surface fields of a given type by looking up
|
||||
// NCC and original parts of non-conformal couplings and combining
|
||||
@ -213,110 +258,31 @@ private:
|
||||
template<class Type>
|
||||
void postNonConformSurfaceFields();
|
||||
|
||||
//- Post-non-conform surface fields by looking up NCC and
|
||||
// original parts of non-conformal couplings and combining them
|
||||
// into a single non-conformal boundary field
|
||||
inline void postNonConformSurfaceFields();
|
||||
//- As above, for all types
|
||||
void postNonConformSurfaceFields();
|
||||
|
||||
//- Evaluate all non-conformal vol patch fields of a given type
|
||||
template<class Type>
|
||||
void evaluateVolFields();
|
||||
|
||||
//- Evaluate all non-conformal vol patch fields
|
||||
inline void evaluateVolFields();
|
||||
//- As above, for all types
|
||||
void evaluateVolFields();
|
||||
|
||||
//- Special post-non-conform for surface velocities
|
||||
inline void postNonConformSurfaceVelocities();
|
||||
void postNonConformSurfaceVelocities();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
// Field Mapping
|
||||
|
||||
//- Resize the patch field of a given field to match the mesh
|
||||
template<class GeoBoundaryField>
|
||||
void resizeBoundaryFieldPatchFields
|
||||
(
|
||||
const SurfaceFieldBoundary<label>& polyFacesBf,
|
||||
GeoBoundaryField& fieldBf
|
||||
);
|
||||
|
||||
//- Resize the patch field of a given field to match the mesh
|
||||
template<class GeoField>
|
||||
void resizeFieldPatchFields
|
||||
(
|
||||
const SurfaceFieldBoundary<label>& polyFacesBf,
|
||||
GeoField& field
|
||||
);
|
||||
|
||||
//- Reverse-map sum the values of a field
|
||||
template<class Type>
|
||||
static tmp<Field<Type>> fieldRMapSum
|
||||
(
|
||||
const Field<Type>& f,
|
||||
const label size,
|
||||
const labelUList& addr
|
||||
);
|
||||
|
||||
//- Reverse-map sum the values of a field
|
||||
template<class Type>
|
||||
static tmp<Field<Type>> fieldRMapSum
|
||||
(
|
||||
const tmp<Field<Type>>& f,
|
||||
const label size,
|
||||
const labelUList& addr
|
||||
);
|
||||
|
||||
//- Return the total non-conformal area associated with each
|
||||
// original face
|
||||
inline tmp<SurfaceFieldBoundary<scalar>> getOrigNccMagSfb() const;
|
||||
|
||||
//- Extract the non-conformal-coupled parts of the boundary field
|
||||
// and store it on the conformal faces
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> conformalNccBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
) const;
|
||||
|
||||
//- Extract the original parts of the boundary field and store it
|
||||
// on the conformal faces
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> conformalOrigBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
) const;
|
||||
|
||||
//- Combine non-conformal-coupled and original parts of the
|
||||
// boundary field from the conformal faces to construct the
|
||||
// complete non-conformal boundary field
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> nonConformalBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& nccFieldb,
|
||||
const SurfaceFieldBoundary<Type>& origFieldb
|
||||
) const;
|
||||
|
||||
//- Synchronise the boundary field by combining corresponding
|
||||
// values across couplings with the given weightings
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb,
|
||||
const bool flip,
|
||||
const scalar ownerWeight,
|
||||
const scalar neighbourWeight
|
||||
) const;
|
||||
|
||||
//- Synchronise the boundary field by combining corresponding
|
||||
// values across couplings with equal weightings
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
) const;
|
||||
//- Access the boundary field reference of a field, without updating
|
||||
// the time index, storing old time fields, etc...
|
||||
template<class GeoField>
|
||||
static typename GeoField::Boundary& boundaryFieldRefNoUpdate
|
||||
(
|
||||
GeoField& fld
|
||||
);
|
||||
|
||||
|
||||
// Checking
|
||||
|
||||
@ -28,6 +28,7 @@ Description
|
||||
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "conformedFvsPatchField.H"
|
||||
#include "fvPatchFieldMapper.H"
|
||||
#include "fvMeshStitcher.H"
|
||||
#include "setSizeFvPatchFieldMapper.H"
|
||||
@ -41,16 +42,6 @@ Description
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class GeoField>
|
||||
typename GeoField::Boundary& Foam::fvMeshStitcher::boundaryFieldRefNoUpdate
|
||||
(
|
||||
GeoField& fld
|
||||
)
|
||||
{
|
||||
return const_cast<typename GeoField::Boundary&>(fld.boundaryField());
|
||||
}
|
||||
|
||||
|
||||
template<class Type, template<class> class GeoField>
|
||||
void Foam::fvMeshStitcher::resizePatchFields()
|
||||
{
|
||||
@ -86,134 +77,44 @@ void Foam::fvMeshStitcher::preConformSurfaceFields()
|
||||
{
|
||||
UPtrList<SurfaceField<Type>> fields(mesh_.curFields<SurfaceField<Type>>());
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(mesh_).allOrigPatchIDs();
|
||||
|
||||
forAll(fields, i)
|
||||
{
|
||||
SurfaceField<Type>& field = fields[i];
|
||||
|
||||
autoPtr<SurfaceField<Type>> nccFieldPtr
|
||||
(
|
||||
new SurfaceField<Type>
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
nccFieldPrefix_ + field.name(),
|
||||
mesh_.time().name(),
|
||||
mesh_
|
||||
),
|
||||
field
|
||||
)
|
||||
);
|
||||
|
||||
for (label ti=0; ti<=field.nOldTimes(false); ti++)
|
||||
{
|
||||
SurfaceField<Type>& field0 = field.oldTime(ti);
|
||||
|
||||
boundaryFieldRefNoUpdate(nccFieldPtr->oldTime(ti)) =
|
||||
conformalNccBoundaryField<Type>(field0.boundaryField());
|
||||
|
||||
boundaryFieldRefNoUpdate(field0) =
|
||||
conformalOrigBoundaryField<Type>(field0.boundaryField());
|
||||
conformedFvsPatchField<Type>::conform
|
||||
(
|
||||
boundaryFieldRefNoUpdate(field.oldTime(ti))
|
||||
);
|
||||
}
|
||||
|
||||
nccFieldPtr.ptr()->store();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fvMeshStitcher::preConformSurfaceFields()
|
||||
{
|
||||
#define PreConformSurfaceFields(Type, nullArg) \
|
||||
preConformSurfaceFields<Type>();
|
||||
FOR_ALL_FIELD_TYPES(PreConformSurfaceFields);
|
||||
#undef PreConformSurfaceFields
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::fvMeshStitcher::postNonConformSurfaceFields()
|
||||
{
|
||||
UPtrList<SurfaceField<Type>> fields(mesh_.curFields<SurfaceField<Type>>());
|
||||
|
||||
if (!mesh_.topoChanged())
|
||||
{
|
||||
forAll(fields, i)
|
||||
{
|
||||
if (fields[i].name()(nccFieldPrefix_.size()) == nccFieldPrefix_)
|
||||
continue;
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(mesh_).allOrigPatchIDs();
|
||||
|
||||
SurfaceField<Type>& field = fields[i];
|
||||
|
||||
const word nccFieldName = nccFieldPrefix_ + field.name();
|
||||
|
||||
const SurfaceField<Type>& nccField =
|
||||
mesh_.lookupObject<SurfaceField<Type>>(nccFieldName);
|
||||
|
||||
for (label ti=0; ti<=field.nOldTimes(false); ti++)
|
||||
{
|
||||
SurfaceField<Type>& field0 = field.oldTime(ti);
|
||||
|
||||
boundaryFieldRefNoUpdate(field0) =
|
||||
nonConformalBoundaryField<Type>
|
||||
(
|
||||
nccField.oldTime(ti).boundaryField(),
|
||||
field0.boundaryField()
|
||||
);
|
||||
|
||||
boundaryFieldRefNoUpdate(field0) =
|
||||
synchronisedBoundaryField<Type>(field0.boundaryField());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove NCC fields after all fields have been mapped. This is so that
|
||||
// old-time fields aren't removed by current-time fields in advance of the
|
||||
// old-time field being mapped.
|
||||
|
||||
// Cache the nccField pointers
|
||||
DynamicList<SurfaceField<Type>*> nccFields;
|
||||
forAll(fields, i)
|
||||
{
|
||||
if (fields[i].name()(nccFieldPrefix_.size()) == nccFieldPrefix_)
|
||||
continue;
|
||||
|
||||
SurfaceField<Type>& field = fields[i];
|
||||
|
||||
const word nccFieldName = nccFieldPrefix_ + field.name();
|
||||
|
||||
SurfaceField<Type>& nccField =
|
||||
mesh_.lookupObjectRef<SurfaceField<Type>>(nccFieldName);
|
||||
|
||||
nccFields.append(&nccField);
|
||||
for (label ti=0; ti<=field.nOldTimes(false); ti++)
|
||||
{
|
||||
conformedFvsPatchField<Type>::unconform
|
||||
(
|
||||
boundaryFieldRefNoUpdate(field.oldTime(ti))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Checkout the nccFields after the loop over fields
|
||||
// to avoid deleting a subsequent field in the list
|
||||
forAll(nccFields, i)
|
||||
{
|
||||
nccFields[i]->checkOut();
|
||||
}
|
||||
|
||||
// Check there are no NCC fields left over
|
||||
fields = mesh_.curFields<SurfaceField<Type>>();
|
||||
forAll(fields, i)
|
||||
{
|
||||
if (fields[i].name()(nccFieldPrefix_.size()) != nccFieldPrefix_)
|
||||
continue;
|
||||
|
||||
FatalErrorInFunction
|
||||
<< "Stitching mapping field \"" << fields[i].name()
|
||||
<< "\" found, but the field it corresponds to no longer exists"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fvMeshStitcher::postNonConformSurfaceFields()
|
||||
{
|
||||
#define PostNonConformSurfaceFields(Type, nullArg) \
|
||||
postNonConformSurfaceFields<Type>();
|
||||
FOR_ALL_FIELD_TYPES(PostNonConformSurfaceFields);
|
||||
#undef PostNonConformSurfaceFields
|
||||
}
|
||||
|
||||
|
||||
@ -259,517 +160,15 @@ void Foam::fvMeshStitcher::evaluateVolFields()
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fvMeshStitcher::evaluateVolFields()
|
||||
{
|
||||
#define EvaluateVolFields(Type, nullArg) \
|
||||
evaluateVolFields<Type>();
|
||||
FOR_ALL_FIELD_TYPES(EvaluateVolFields);
|
||||
#undef EvaluateVolFields
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fvMeshStitcher::postNonConformSurfaceVelocities()
|
||||
{
|
||||
if (mesh_.topoChanged())
|
||||
{
|
||||
UPtrList<surfaceVectorField> Ufs(mesh_.fields<surfaceVectorField>());
|
||||
|
||||
forAll(Ufs, i)
|
||||
{
|
||||
surfaceVectorField& Uf = Ufs[i];
|
||||
|
||||
const volVectorField& U = surfaceToVolVelocity(Uf);
|
||||
|
||||
if (!isNull(U))
|
||||
{
|
||||
forAll(Uf.boundaryField(), patchi)
|
||||
{
|
||||
if (isA<nonConformalFvPatch>(mesh_.boundary()[patchi]))
|
||||
{
|
||||
boundaryFieldRefNoUpdate(Uf)[patchi] ==
|
||||
U.boundaryField()[patchi];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class GeoBoundaryField>
|
||||
void Foam::fvMeshStitcher::resizeBoundaryFieldPatchFields
|
||||
(
|
||||
const SurfaceFieldBoundary<label>& polyFacesBf,
|
||||
GeoBoundaryField& fieldBf
|
||||
)
|
||||
{
|
||||
forAll(polyFacesBf, nccPatchi)
|
||||
{
|
||||
if (isA<nonConformalFvPatch>(polyFacesBf[nccPatchi].patch()))
|
||||
{
|
||||
fieldBf[nccPatchi].map
|
||||
(
|
||||
fieldBf[nccPatchi],
|
||||
setSizeFvPatchFieldMapper(polyFacesBf[nccPatchi].size())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
void Foam::fvMeshStitcher::resizeFieldPatchFields
|
||||
typename GeoField::Boundary& Foam::fvMeshStitcher::boundaryFieldRefNoUpdate
|
||||
(
|
||||
const SurfaceFieldBoundary<label>& polyFacesBf,
|
||||
GeoField& field
|
||||
GeoField& fld
|
||||
)
|
||||
{
|
||||
for (label ti=0; ti<=field.nOldTimes(false); ti++)
|
||||
{
|
||||
resizeBoundaryFieldPatchFields
|
||||
(
|
||||
polyFacesBf,
|
||||
boundaryFieldRefNoUpdate(field.oldTime(ti))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::fvMeshStitcher::fieldRMapSum
|
||||
(
|
||||
const Field<Type>& f,
|
||||
const label size,
|
||||
const labelUList& addr
|
||||
)
|
||||
{
|
||||
tmp<Field<Type>> tresult(new Field<Type>(size, Zero));
|
||||
forAll(addr, i)
|
||||
{
|
||||
tresult.ref()[addr[i]] += f[i];
|
||||
}
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::fvMeshStitcher::fieldRMapSum
|
||||
(
|
||||
const tmp<Field<Type>>& f,
|
||||
const label size,
|
||||
const labelUList& addr
|
||||
)
|
||||
{
|
||||
tmp<Field<Type>> tresult = fieldRMapSum(f(), size, addr);
|
||||
f.clear();
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::surfaceScalarField::Boundary>
|
||||
Foam::fvMeshStitcher::getOrigNccMagSfb() const
|
||||
{
|
||||
const fvBoundaryMesh& fvbm = mesh_.boundary();
|
||||
|
||||
const surfaceScalarField::Boundary& magSfb =
|
||||
fvbm.mesh().magSf().boundaryField();
|
||||
|
||||
tmp<surfaceScalarField::Boundary> tOrigNccMagSfb
|
||||
(
|
||||
new surfaceScalarField::Boundary
|
||||
(
|
||||
fvbm,
|
||||
surfaceScalarField::Internal::null(),
|
||||
calculatedFvPatchField<scalar>::typeName
|
||||
)
|
||||
);
|
||||
|
||||
surfaceScalarField::Boundary& origNccMagSfb = tOrigNccMagSfb.ref();
|
||||
|
||||
origNccMagSfb == 0;
|
||||
|
||||
forAll(fvbm, nccPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[nccPatchi];
|
||||
|
||||
if (isA<nonConformalCoupledFvPatch>(fvp))
|
||||
{
|
||||
const nonConformalCoupledFvPatch& nccFvp =
|
||||
refCast<const nonConformalCoupledFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = nccFvp.origPatchID();
|
||||
const fvPatch& origFvp = nccFvp.origPatch();
|
||||
|
||||
const labelList nccOrigPatchFace =
|
||||
nccFvp.polyFaces() - origFvp.start();
|
||||
|
||||
origNccMagSfb[origPatchi] +=
|
||||
fieldRMapSum
|
||||
(
|
||||
magSfb[nccPatchi],
|
||||
origFvp.size(),
|
||||
nccOrigPatchFace
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return tOrigNccMagSfb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcher::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcher::conformalNccBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
) const
|
||||
{
|
||||
const bool isFluxField = isFlux(fieldb[0].internalField());
|
||||
|
||||
const fvBoundaryMesh& fvbm = fieldb[0].patch().boundaryMesh();
|
||||
|
||||
const surfaceScalarField::Boundary& magSfb =
|
||||
fvbm.mesh().magSf().boundaryField();
|
||||
|
||||
tmp<SurfaceFieldBoundary<Type>> tnccFieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb
|
||||
)
|
||||
);
|
||||
|
||||
SurfaceFieldBoundary<Type>& nccFieldb = tnccFieldb.ref();
|
||||
|
||||
nccFieldb == pTraits<Type>::zero;
|
||||
|
||||
const surfaceScalarField::Boundary origNccMagSfb
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
getOrigNccMagSfb()
|
||||
);
|
||||
|
||||
// Accumulate the non-conformal parts of the field into the original faces
|
||||
forAll(fvbm, nccPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[nccPatchi];
|
||||
|
||||
if (isA<nonConformalCoupledFvPatch>(fvp))
|
||||
{
|
||||
const nonConformalCoupledFvPatch& nccFvp =
|
||||
refCast<const nonConformalCoupledFvPatch>(fvbm[nccPatchi]);
|
||||
|
||||
const label origPatchi = nccFvp.origPatchID();
|
||||
const fvPatch& origFvp = nccFvp.origPatch();
|
||||
|
||||
const labelList nccOrigPatchFace =
|
||||
nccFvp.polyFaces() - origFvp.start();
|
||||
|
||||
// If this is a flux then sum
|
||||
if (isFluxField)
|
||||
{
|
||||
nccFieldb[origPatchi] +=
|
||||
fieldRMapSum
|
||||
(
|
||||
fieldb[nccPatchi],
|
||||
origFvp.size(),
|
||||
nccOrigPatchFace
|
||||
);
|
||||
}
|
||||
|
||||
// If not a flux then do an area-weighted sum
|
||||
else
|
||||
{
|
||||
nccFieldb[origPatchi] +=
|
||||
fieldRMapSum
|
||||
(
|
||||
fieldb[nccPatchi]*magSfb[nccPatchi],
|
||||
origFvp.size(),
|
||||
nccOrigPatchFace
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(mesh_).allOrigPatchIDs();
|
||||
|
||||
// Scale or average as appropriate
|
||||
forAll(origPatchIDs, i)
|
||||
{
|
||||
const label origPatchi = origPatchIDs[i];
|
||||
|
||||
// If this is a flux then scale to the total size of the face
|
||||
if (isFluxField)
|
||||
{
|
||||
const scalarField origSumMagSf
|
||||
(
|
||||
magSfb[origPatchi] + origNccMagSfb[origPatchi]
|
||||
);
|
||||
|
||||
nccFieldb[origPatchi] *=
|
||||
origSumMagSf
|
||||
/max(origNccMagSfb[origPatchi], small*origSumMagSf);
|
||||
}
|
||||
|
||||
// If this is not a flux then convert to an area-weighted average
|
||||
else
|
||||
{
|
||||
nccFieldb[origPatchi] /=
|
||||
max(origNccMagSfb[origPatchi], vSmall);
|
||||
}
|
||||
}
|
||||
|
||||
return tnccFieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcher::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcher::conformalOrigBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
) const
|
||||
{
|
||||
const bool isFluxField = isFlux(fieldb[0].internalField());
|
||||
|
||||
const fvBoundaryMesh& fvbm = fieldb[0].patch().boundaryMesh();
|
||||
|
||||
const surfaceScalarField::Boundary& magSfb =
|
||||
fvbm.mesh().magSf().boundaryField();
|
||||
|
||||
tmp<SurfaceFieldBoundary<Type>> torigFieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb
|
||||
)
|
||||
);
|
||||
|
||||
// If this is a flux then scale up to the total face areas
|
||||
if (isFluxField)
|
||||
{
|
||||
const surfaceScalarField::Boundary origNccMagSfb
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
getOrigNccMagSfb()
|
||||
);
|
||||
|
||||
SurfaceFieldBoundary<Type>& origFieldb = torigFieldb.ref();
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(mesh_).allOrigPatchIDs();
|
||||
|
||||
forAll(origPatchIDs, i)
|
||||
{
|
||||
const label origPatchi = origPatchIDs[i];
|
||||
|
||||
const scalarField origSumMagSf
|
||||
(
|
||||
magSfb[origPatchi] + origNccMagSfb[origPatchi]
|
||||
);
|
||||
|
||||
origFieldb[origPatchi] *=
|
||||
origSumMagSf
|
||||
/max(magSfb[origPatchi], small*origSumMagSf);
|
||||
}
|
||||
}
|
||||
|
||||
return torigFieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcher::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcher::nonConformalBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& nccFieldb,
|
||||
const SurfaceFieldBoundary<Type>& origFieldb
|
||||
) const
|
||||
{
|
||||
const bool isFluxField = isFlux(origFieldb[0].internalField());
|
||||
|
||||
const fvBoundaryMesh& fvbm = origFieldb[0].patch().boundaryMesh();
|
||||
|
||||
const surfaceScalarField::Boundary& magSfb =
|
||||
fvbm.mesh().magSf().boundaryField();
|
||||
|
||||
tmp<SurfaceFieldBoundary<Type>> tfieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
origFieldb
|
||||
)
|
||||
);
|
||||
|
||||
SurfaceFieldBoundary<Type>& fieldb = tfieldb.ref();
|
||||
|
||||
// Set the coupled values
|
||||
forAll(fvbm, nccPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[nccPatchi];
|
||||
|
||||
if (isA<nonConformalCoupledFvPatch>(fvp))
|
||||
{
|
||||
const nonConformalCoupledFvPatch& nccFvp =
|
||||
refCast<const nonConformalCoupledFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = nccFvp.origPatchID();
|
||||
const fvPatch& origFvp = nccFvp.origPatch();
|
||||
|
||||
const labelList nccOrigPatchFace =
|
||||
nccFvp.polyFaces() - origFvp.start();
|
||||
|
||||
// Set the cyclic values
|
||||
fieldb[nccPatchi] =
|
||||
Field<Type>(nccFieldb[origPatchi], nccOrigPatchFace);
|
||||
}
|
||||
}
|
||||
|
||||
// If a flux then scale down to the part face area
|
||||
if (isFluxField)
|
||||
{
|
||||
const surfaceScalarField::Boundary origNccMagSfb
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
getOrigNccMagSfb()
|
||||
);
|
||||
|
||||
forAll(fvbm, nccPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[nccPatchi];
|
||||
|
||||
if (isA<nonConformalCoupledFvPatch>(fvp))
|
||||
{
|
||||
const nonConformalCoupledFvPatch& nccFvp =
|
||||
refCast<const nonConformalCoupledFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = nccFvp.origPatchID();
|
||||
const fvPatch& origFvp = nccFvp.origPatch();
|
||||
|
||||
const labelList nccOrigPatchFace =
|
||||
nccFvp.polyFaces() - origFvp.start();
|
||||
|
||||
const scalarField origSumMagSf
|
||||
(
|
||||
magSfb[origPatchi] + origNccMagSfb[origPatchi]
|
||||
);
|
||||
const scalarField nccSumMagSf(origSumMagSf, nccOrigPatchFace);
|
||||
|
||||
fieldb[nccPatchi] *= magSfb[nccPatchi]/nccSumMagSf;
|
||||
|
||||
if (!isA<processorFvPatch>(fvp))
|
||||
{
|
||||
fieldb[origPatchi] *= magSfb[origPatchi]/origSumMagSf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set error values
|
||||
forAll(fvbm, patchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[patchi];
|
||||
|
||||
if (isA<nonConformalErrorFvPatch>(fvp))
|
||||
{
|
||||
const label errorPatchi = patchi;
|
||||
|
||||
const nonConformalErrorFvPatch& errorFvp =
|
||||
refCast<const nonConformalErrorFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = errorFvp.origPatchID();
|
||||
const fvPatch& origFvp = errorFvp.origPatch();
|
||||
|
||||
const labelList errorOrigPatchFace =
|
||||
errorFvp.polyFaces() - origFvp.start();
|
||||
|
||||
if (isFluxField)
|
||||
{
|
||||
fieldb[errorPatchi] = Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldb[errorPatchi] =
|
||||
Field<Type>(origFieldb[origPatchi], errorOrigPatchFace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tfieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcher::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcher::synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb,
|
||||
const bool flip,
|
||||
const scalar ownerWeight,
|
||||
const scalar neighbourWeight
|
||||
) const
|
||||
{
|
||||
const fvBoundaryMesh& fvbm = fieldb[0].patch().boundaryMesh();
|
||||
|
||||
tmp<SurfaceFieldBoundary<Type>> tsyncFieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb
|
||||
)
|
||||
);
|
||||
|
||||
SurfaceFieldBoundary<Type>& syncFieldb = tsyncFieldb.ref();
|
||||
|
||||
SurfaceFieldBoundary<Type> fieldbNbr
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb.boundaryNeighbourField()
|
||||
);
|
||||
|
||||
forAll(fvbm, patchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[patchi];
|
||||
|
||||
if (fvp.coupled())
|
||||
{
|
||||
const coupledFvPatch& cfvp = refCast<const coupledFvPatch>(fvp);
|
||||
|
||||
const scalar w = cfvp.owner() ? ownerWeight : neighbourWeight;
|
||||
const scalar v = cfvp.owner() ? neighbourWeight : ownerWeight;
|
||||
|
||||
syncFieldb[patchi] =
|
||||
w*syncFieldb[patchi] + (flip ? -v : +v)*fieldbNbr[patchi];
|
||||
}
|
||||
}
|
||||
|
||||
return tsyncFieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcher::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcher::synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
) const
|
||||
{
|
||||
const bool isFluxField = isFlux(fieldb[0].internalField());
|
||||
|
||||
return synchronisedBoundaryField<Type>
|
||||
(
|
||||
fieldb,
|
||||
isFluxField,
|
||||
0.5,
|
||||
0.5
|
||||
);
|
||||
return const_cast<typename GeoField::Boundary&>(fld.boundaryField());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvMeshStitcherTools.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "calculatedFvsPatchField.H"
|
||||
#include "nonConformalFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::surfaceScalarField::Boundary>
|
||||
Foam::fvMeshStitcherTools::origNcMagSfb(const fvMesh& mesh)
|
||||
{
|
||||
const fvBoundaryMesh& fvbm = mesh.boundary();
|
||||
|
||||
const surfaceScalarField::Boundary& magSfb =
|
||||
fvbm.mesh().magSf().boundaryField();
|
||||
|
||||
tmp<surfaceScalarField::Boundary> tresult
|
||||
(
|
||||
new surfaceScalarField::Boundary
|
||||
(
|
||||
fvbm,
|
||||
surfaceScalarField::Internal::null(),
|
||||
calculatedFvsPatchField<scalar>::typeName
|
||||
)
|
||||
);
|
||||
|
||||
surfaceScalarField::Boundary& result = tresult.ref();
|
||||
|
||||
result == 0;
|
||||
|
||||
forAll(fvbm, ncPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[ncPatchi];
|
||||
|
||||
if (!isA<nonConformalFvPatch>(fvp)) continue;
|
||||
|
||||
const nonConformalFvPatch& ncFvp =
|
||||
refCast<const nonConformalFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = ncFvp.origPatchID();
|
||||
const fvPatch& origFvp = ncFvp.origPatch();
|
||||
|
||||
result[origPatchi] +=
|
||||
fieldRMapSum
|
||||
(
|
||||
magSfb[ncPatchi],
|
||||
origFvp.size(),
|
||||
ncFvp.polyFaces(),
|
||||
origFvp.start()
|
||||
);
|
||||
}
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,153 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Namespace
|
||||
Foam::fvMeshStitcherTools
|
||||
|
||||
Description
|
||||
Collection of free functions utilised by the stitching process
|
||||
|
||||
SourceFiles
|
||||
fvMeshStitcherTools.C
|
||||
fvMeshStitcherToolsTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef fvMeshStitcherTools_H
|
||||
#define fvMeshStitcherTools_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace fvMeshStitcherTools
|
||||
{
|
||||
|
||||
//- Map a field with an (optional) addressing offset
|
||||
template<class Type>
|
||||
tmp<Field<Type>> fieldMap
|
||||
(
|
||||
const Field<Type>& f,
|
||||
const labelUList& addr,
|
||||
const label addr0 = 0
|
||||
);
|
||||
|
||||
//- Tmp variant of above
|
||||
template<class Type>
|
||||
tmp<Field<Type>> fieldMap
|
||||
(
|
||||
const tmp<Field<Type>>& f,
|
||||
const labelUList& addr,
|
||||
const label addr0 = 0
|
||||
);
|
||||
|
||||
//- Reverse map a field with an (optional) addressing offset, initialising the
|
||||
// value to zero and summing repeated indices
|
||||
template<class Type>
|
||||
tmp<Field<Type>> fieldRMapSum
|
||||
(
|
||||
const Field<Type>& f,
|
||||
const label size,
|
||||
const labelUList& addr,
|
||||
const label addr0 = 0
|
||||
);
|
||||
|
||||
//- Tmp variant of above
|
||||
template<class Type>
|
||||
tmp<Field<Type>> fieldRMapSum
|
||||
(
|
||||
const tmp<Field<Type>>& f,
|
||||
const label size,
|
||||
const labelUList& addr,
|
||||
const label addr0 = 0
|
||||
);
|
||||
|
||||
//- Alias for surface boundary fields to reduce verbosity of method
|
||||
// definitions below
|
||||
template<class Type>
|
||||
using SurfaceFieldBoundary =
|
||||
GeometricBoundaryField<Type, fvsPatchField, surfaceMesh>;
|
||||
|
||||
//- Return the total non-conformal area associated with each original face
|
||||
tmp<SurfaceFieldBoundary<scalar>> origNcMagSfb(const fvMesh& mesh);
|
||||
|
||||
//- Extract the non-conformal parts of the boundary field and store it on the
|
||||
// conformal faces
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> conformedNcBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
);
|
||||
|
||||
//- Extract the original parts of the boundary field and store it
|
||||
// on the conformal faces
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> conformedOrigBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
);
|
||||
|
||||
//- Combine non-conformal and original parts of the boundary field from the
|
||||
// conformal faces to construct the complete non-conformal boundary field
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> unconformedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& ncFieldb,
|
||||
const SurfaceFieldBoundary<Type>& origFieldb
|
||||
);
|
||||
|
||||
//- Synchronise the boundary field by combining corresponding
|
||||
// values across couplings with the given weightings
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb,
|
||||
const bool flip,
|
||||
const scalar ownerWeight,
|
||||
const scalar neighbourWeight
|
||||
);
|
||||
|
||||
//- Synchronise the boundary field by combining corresponding
|
||||
// values across couplings with equal weightings
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
);
|
||||
|
||||
} // End namespace patchToPatchTools
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "fvMeshStitcherToolsTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,444 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvMeshStitcherTools.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "coupledFvPatch.H"
|
||||
#include "nonConformalBoundary.H"
|
||||
#include "nonConformalFvPatch.H"
|
||||
#include "nonConformalErrorFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::fvMeshStitcherTools::fieldMap
|
||||
(
|
||||
const Field<Type>& f,
|
||||
const labelUList& addr,
|
||||
const label addr0
|
||||
)
|
||||
{
|
||||
tmp<Field<Type>> tresult(new Field<Type>(addr.size()));
|
||||
forAll(addr, i)
|
||||
{
|
||||
tresult.ref()[i] = f[addr[i] - addr0];
|
||||
}
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::fvMeshStitcherTools::fieldMap
|
||||
(
|
||||
const tmp<Field<Type>>& f,
|
||||
const labelUList& addr,
|
||||
const label addr0
|
||||
)
|
||||
{
|
||||
|
||||
tmp<Field<Type>> tresult = fieldMap(f(), addr, addr0);
|
||||
f.clear();
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::fvMeshStitcherTools::fieldRMapSum
|
||||
(
|
||||
const Field<Type>& f,
|
||||
const label size,
|
||||
const labelUList& addr,
|
||||
const label addr0
|
||||
)
|
||||
{
|
||||
tmp<Field<Type>> tresult(new Field<Type>(size, Zero));
|
||||
forAll(addr, i)
|
||||
{
|
||||
tresult.ref()[addr[i] - addr0] += f[i];
|
||||
}
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::fvMeshStitcherTools::fieldRMapSum
|
||||
(
|
||||
const tmp<Field<Type>>& f,
|
||||
const label size,
|
||||
const labelUList& addr,
|
||||
const label addr0
|
||||
)
|
||||
{
|
||||
tmp<Field<Type>> tresult = fieldRMapSum(f(), size, addr, addr0);
|
||||
f.clear();
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcherTools::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcherTools::conformedNcBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
)
|
||||
{
|
||||
const bool isFluxField = isFlux(fieldb[0].internalField());
|
||||
|
||||
const fvBoundaryMesh& fvbm = fieldb[0].patch().boundaryMesh();
|
||||
|
||||
tmp<SurfaceFieldBoundary<Type>> tncFieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb
|
||||
)
|
||||
);
|
||||
SurfaceFieldBoundary<Type>& ncFieldb = tncFieldb.ref();
|
||||
|
||||
ncFieldb == pTraits<Type>::zero;
|
||||
|
||||
const surfaceScalarField::Boundary origNcMagSfb
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
fvMeshStitcherTools::origNcMagSfb(fvbm.mesh())
|
||||
);
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(fvbm.mesh()).allOrigPatchIDs();
|
||||
|
||||
// Accumulate the non-conformal parts of the field into the original faces
|
||||
forAll(fvbm, ncPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[ncPatchi];
|
||||
|
||||
if (!isA<nonConformalFvPatch>(fvp)) continue;
|
||||
|
||||
const nonConformalFvPatch& ncFvp =
|
||||
refCast<const nonConformalFvPatch>(fvbm[ncPatchi]);
|
||||
|
||||
const label origPatchi = ncFvp.origPatchID();
|
||||
const fvPatch& origFvp = ncFvp.origPatch();
|
||||
|
||||
const scalarField& ncNcMagSf = ncFvp.patch().magSf();
|
||||
|
||||
// Sum properties with an area-weight, unless this is a flux. Fluxes
|
||||
// already scale with the area.
|
||||
ncFieldb[origPatchi] +=
|
||||
fvMeshStitcherTools::fieldRMapSum
|
||||
(
|
||||
isFluxField ? fieldb[ncPatchi] : ncNcMagSf*fieldb[ncPatchi],
|
||||
origFvp.size(),
|
||||
ncFvp.polyFaces(),
|
||||
origFvp.start()
|
||||
);
|
||||
}
|
||||
|
||||
// Scale or average as appropriate
|
||||
forAll(origPatchIDs, i)
|
||||
{
|
||||
const label origPatchi = origPatchIDs[i];
|
||||
const fvPatch& origFvp = fvbm[origPatchi];
|
||||
|
||||
// If this is a flux then scale to the total size of the face
|
||||
if (isFluxField)
|
||||
{
|
||||
const scalarField origTotalMagSf
|
||||
(
|
||||
origFvp.magSf() + origNcMagSfb[origPatchi]
|
||||
);
|
||||
|
||||
ncFieldb[origPatchi] *=
|
||||
origTotalMagSf
|
||||
/max(origNcMagSfb[origPatchi], small*origTotalMagSf);
|
||||
}
|
||||
// If this is not a flux then divide by the area to create an
|
||||
// area-weighted average
|
||||
else
|
||||
{
|
||||
ncFieldb[origPatchi] /=
|
||||
max(origNcMagSfb[origPatchi], vSmall);
|
||||
}
|
||||
}
|
||||
|
||||
return tncFieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcherTools::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcherTools::conformedOrigBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
)
|
||||
{
|
||||
const bool isFluxField = isFlux(fieldb[0].internalField());
|
||||
|
||||
const fvBoundaryMesh& fvbm = fieldb[0].patch().boundaryMesh();
|
||||
|
||||
tmp<SurfaceFieldBoundary<Type>> torigFieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb
|
||||
)
|
||||
);
|
||||
SurfaceFieldBoundary<Type>& origFieldb = torigFieldb.ref();
|
||||
|
||||
const surfaceScalarField::Boundary origNcMagSfb
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
fvMeshStitcherTools::origNcMagSfb(fvbm.mesh())
|
||||
);
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(fvbm.mesh()).allOrigPatchIDs();
|
||||
|
||||
// Scale or average as appropriate
|
||||
forAll(origPatchIDs, i)
|
||||
{
|
||||
const label origPatchi = origPatchIDs[i];
|
||||
const fvPatch& origFvp = fvbm[origPatchi];
|
||||
|
||||
// If this is a flux then scale to the total size of the face
|
||||
if (isFluxField)
|
||||
{
|
||||
const scalarField origTotalMagSf
|
||||
(
|
||||
origFvp.magSf() + origNcMagSfb[origPatchi]
|
||||
);
|
||||
|
||||
origFieldb[origPatchi] *=
|
||||
origTotalMagSf
|
||||
/max(origFvp.magSf(), small*origTotalMagSf);
|
||||
}
|
||||
}
|
||||
|
||||
return torigFieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcherTools::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcherTools::unconformedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& ncFieldb,
|
||||
const SurfaceFieldBoundary<Type>& origFieldb
|
||||
)
|
||||
{
|
||||
const bool isFluxField = isFlux(origFieldb[0].internalField());
|
||||
|
||||
const fvBoundaryMesh& fvbm = origFieldb[0].patch().boundaryMesh();
|
||||
|
||||
const surfaceScalarField::Boundary& magSfb =
|
||||
fvbm.mesh().magSf().boundaryField();
|
||||
|
||||
// Initialise the result and copy the original fields
|
||||
tmp<SurfaceFieldBoundary<Type>> tfieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
origFieldb
|
||||
)
|
||||
);
|
||||
SurfaceFieldBoundary<Type>& fieldb = tfieldb.ref();
|
||||
|
||||
// Map the conformed non-conformal values into the non-conformal patch
|
||||
// fields
|
||||
forAll(fvbm, ncPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[ncPatchi];
|
||||
|
||||
if (!isA<nonConformalFvPatch>(fvp)) continue;
|
||||
|
||||
const nonConformalFvPatch& ncFvp =
|
||||
refCast<const nonConformalFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = ncFvp.origPatchID();
|
||||
const fvPatch& origFvp = ncFvp.origPatch();
|
||||
|
||||
fieldb[ncPatchi] =
|
||||
fvMeshStitcherTools::fieldMap
|
||||
(
|
||||
ncFieldb[origPatchi],
|
||||
ncFvp.polyFaces(),
|
||||
origFvp.start()
|
||||
);
|
||||
}
|
||||
|
||||
const labelList origPatchIDs =
|
||||
nonConformalBoundary::New(fvbm.mesh()).allOrigPatchIDs();
|
||||
|
||||
// If a flux then scale down to the part face area
|
||||
if (isFluxField)
|
||||
{
|
||||
const surfaceScalarField::Boundary origNcMagSfb
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
fvMeshStitcherTools::origNcMagSfb(fvbm.mesh())
|
||||
);
|
||||
|
||||
// Scale the original patch fields
|
||||
forAll(origPatchIDs, i)
|
||||
{
|
||||
const label origPatchi = origPatchIDs[i];
|
||||
|
||||
const scalarField origTotalMagSf
|
||||
(
|
||||
magSfb[origPatchi] + origNcMagSfb[origPatchi]
|
||||
);
|
||||
|
||||
fieldb[origPatchi] *= magSfb[origPatchi]/origTotalMagSf;
|
||||
}
|
||||
|
||||
// Scale the non-conformal patch fields
|
||||
forAll(fvbm, ncPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[ncPatchi];
|
||||
|
||||
if (!isA<nonConformalFvPatch>(fvp)) continue;
|
||||
|
||||
const nonConformalFvPatch& ncFvp =
|
||||
refCast<const nonConformalFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = ncFvp.origPatchID();
|
||||
const fvPatch& origFvp = ncFvp.origPatch();
|
||||
|
||||
const scalarField ncTotalMagSf
|
||||
(
|
||||
fvMeshStitcherTools::fieldMap
|
||||
(
|
||||
magSfb[origPatchi] + origNcMagSfb[origPatchi],
|
||||
ncFvp.polyFaces(),
|
||||
origFvp.start()
|
||||
)
|
||||
);
|
||||
|
||||
fieldb[ncPatchi] *= magSfb[ncPatchi]/ncTotalMagSf;
|
||||
}
|
||||
}
|
||||
|
||||
// Overwrite error values
|
||||
forAll(fvbm, errorPatchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[errorPatchi];
|
||||
|
||||
if (!isA<nonConformalErrorFvPatch>(fvp)) continue;
|
||||
|
||||
const nonConformalErrorFvPatch& errorFvp =
|
||||
refCast<const nonConformalErrorFvPatch>(fvp);
|
||||
|
||||
const label origPatchi = errorFvp.origPatchID();
|
||||
const fvPatch& origFvp = errorFvp.origPatch();
|
||||
|
||||
if (isFluxField)
|
||||
{
|
||||
fieldb[errorPatchi] = Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldb[errorPatchi] =
|
||||
fvMeshStitcherTools::fieldMap
|
||||
(
|
||||
origFieldb[origPatchi],
|
||||
errorFvp.polyFaces(),
|
||||
origFvp.start()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return tfieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcherTools::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcherTools::synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb,
|
||||
const bool flip,
|
||||
const scalar ownerWeight,
|
||||
const scalar neighbourWeight
|
||||
)
|
||||
{
|
||||
const fvBoundaryMesh& fvbm = fieldb[0].patch().boundaryMesh();
|
||||
|
||||
tmp<SurfaceFieldBoundary<Type>> tsyncFieldb
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb
|
||||
)
|
||||
);
|
||||
SurfaceFieldBoundary<Type>& syncFieldb = tsyncFieldb.ref();
|
||||
|
||||
SurfaceFieldBoundary<Type> fieldbNbr
|
||||
(
|
||||
SurfaceField<Type>::Internal::null(),
|
||||
fieldb.boundaryNeighbourField()
|
||||
);
|
||||
|
||||
forAll(fvbm, patchi)
|
||||
{
|
||||
const fvPatch& fvp = fvbm[patchi];
|
||||
|
||||
if (!fvp.coupled()) continue;
|
||||
|
||||
const coupledFvPatch& cFvp = refCast<const coupledFvPatch>(fvp);
|
||||
|
||||
const scalar w = cFvp.owner() ? ownerWeight : neighbourWeight;
|
||||
const scalar v = cFvp.owner() ? neighbourWeight : ownerWeight;
|
||||
|
||||
syncFieldb[patchi] =
|
||||
w*syncFieldb[patchi] + (flip ? -v : +v)*fieldbNbr[patchi];
|
||||
}
|
||||
|
||||
return tsyncFieldb;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshStitcherTools::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshStitcherTools::synchronisedBoundaryField
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& fieldb
|
||||
)
|
||||
{
|
||||
const bool isFluxField = isFlux(fieldb[0].internalField());
|
||||
|
||||
return synchronisedBoundaryField<Type>
|
||||
(
|
||||
fieldb,
|
||||
isFluxField,
|
||||
0.5,
|
||||
0.5
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2021-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -55,6 +55,12 @@ Foam::nonConformalFvPatch::~nonConformalFvPatch()
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::fvPatch& Foam::nonConformalFvPatch::patch() const
|
||||
{
|
||||
return patch_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::nonConformalPolyPatch&
|
||||
Foam::nonConformalFvPatch::nonConformalPatch() const
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2021-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -88,7 +88,10 @@ public:
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the reference to the polyPatch
|
||||
//- Reference to the fvPatch
|
||||
const fvPatch& patch() const;
|
||||
|
||||
//- Reference to the polyPatch
|
||||
const nonConformalPolyPatch& nonConformalPatch() const;
|
||||
|
||||
//- Original patch name
|
||||
|
||||
@ -36,6 +36,7 @@ SourceFiles
|
||||
|
||||
#include "meshToMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -52,6 +53,15 @@ class fvMeshToFvMesh
|
||||
{
|
||||
private:
|
||||
|
||||
// Private Typedefs
|
||||
|
||||
//- Alias for surface boundary fields to reduce verbosity of method
|
||||
// definitions below
|
||||
template<class Type>
|
||||
using SurfaceFieldBoundary =
|
||||
GeometricBoundaryField<Type, fvsPatchField, surfaceMesh>;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Evaluate constraint types for the given vol field
|
||||
@ -118,6 +128,13 @@ public:
|
||||
const VolInternalField<Type>& srcFld,
|
||||
const VolInternalField<Type>& leftOverTgtFld
|
||||
) const;
|
||||
|
||||
//- ...
|
||||
template<class Type>
|
||||
tmp<SurfaceFieldBoundary<Type>> srcToTgt
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& srcFld
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -311,4 +311,71 @@ Foam::tmp<Foam::VolInternalField<Type>> Foam::fvMeshToFvMesh::srcToTgt
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::fvMeshToFvMesh::SurfaceFieldBoundary<Type>>
|
||||
Foam::fvMeshToFvMesh::srcToTgt
|
||||
(
|
||||
const SurfaceFieldBoundary<Type>& srcBfld
|
||||
) const
|
||||
{
|
||||
const fvMesh& tgtMesh = static_cast<const fvMesh&>(meshToMesh::tgtMesh());
|
||||
|
||||
// Map all patch fields
|
||||
PtrList<fvsPatchField<Type>> tgtPatchFields(tgtMesh.boundary().size());
|
||||
forAll(patchIDs(), i)
|
||||
{
|
||||
const label srcPatchi = patchIDs()[i].first();
|
||||
const label tgtPatchi = patchIDs()[i].second();
|
||||
|
||||
if (!tgtPatchFields.set(tgtPatchi))
|
||||
{
|
||||
tgtPatchFields.set
|
||||
(
|
||||
tgtPatchi,
|
||||
fvsPatchField<Type>::New
|
||||
(
|
||||
srcBfld[srcPatchi],
|
||||
tgtMesh.boundary()[tgtPatchi],
|
||||
DimensionedField<Type, surfaceMesh>::null(),
|
||||
patchToPatchNormalisedFvPatchFieldMapper
|
||||
(
|
||||
patchInterpolation(i),
|
||||
tgtPatchStabilisation(i)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Create any patch fields not explicitly mapped; e.g., constraints
|
||||
forAll(tgtPatchFields, tgtPatchi)
|
||||
{
|
||||
if (!tgtPatchFields.set(tgtPatchi))
|
||||
{
|
||||
tgtPatchFields.set
|
||||
(
|
||||
tgtPatchi,
|
||||
fvsPatchField<Type>::New
|
||||
(
|
||||
calculatedFvPatchField<Type>::typeName,
|
||||
tgtMesh.boundary()[tgtPatchi],
|
||||
DimensionedField<Type, surfaceMesh>::null()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
tmp<SurfaceFieldBoundary<Type>>
|
||||
(
|
||||
new SurfaceFieldBoundary<Type>
|
||||
(
|
||||
tgtMesh.boundary(),
|
||||
DimensionedField<Type, surfaceMesh>::null(),
|
||||
tgtPatchFields
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -144,17 +144,15 @@ void Foam::fvMeshStitchers::moving::conformCorrectMeshPhi
|
||||
const label origPatchi = ncFvp.origPatchID();
|
||||
const fvPatch& origFvp = ncFvp.origPatch();
|
||||
|
||||
const labelList nccOrigPatchFace =
|
||||
ncFvp.polyFaces() - origFvp.start();
|
||||
|
||||
for (label i = 0; i <= phi.nOldTimes(false); ++ i)
|
||||
{
|
||||
phi.oldTime(i).boundaryFieldRef()[origPatchi] +=
|
||||
fieldRMapSum
|
||||
fvMeshStitcherTools::fieldRMapSum
|
||||
(
|
||||
phi.oldTime(i).boundaryField()[nccPatchi],
|
||||
origFvp.size(),
|
||||
nccOrigPatchFace
|
||||
ncFvp.polyFaces(),
|
||||
origFvp.start()
|
||||
);
|
||||
|
||||
phi.oldTime(i).boundaryFieldRef()[nccPatchi].clear();
|
||||
@ -388,7 +386,7 @@ void Foam::fvMeshStitchers::moving::unconformInternalFaceCorrectMeshPhi
|
||||
surfaceScalarField::Boundary syncPhiBf
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
synchronisedBoundaryField<scalar>(phiBf, true, 0, 1)
|
||||
fvMeshStitcherTools::synchronisedBoundaryField(phiBf, true, 0, 1)
|
||||
);
|
||||
|
||||
// Determine the total mesh flux error and area magnitude for each region
|
||||
@ -863,7 +861,10 @@ void Foam::fvMeshStitchers::moving::unconformErrorFaceCorrectMeshPhi
|
||||
for (label i = 0; i <= phi.nOldTimes(false); ++ i)
|
||||
{
|
||||
tmp<surfaceScalarField::Boundary> tphib =
|
||||
synchronisedBoundaryField<scalar>(phi.oldTime(i).boundaryField());
|
||||
fvMeshStitcherTools::synchronisedBoundaryField
|
||||
(
|
||||
phi.oldTime(i).boundaryField()
|
||||
);
|
||||
|
||||
phiErrorbs.set
|
||||
(
|
||||
@ -967,7 +968,7 @@ void Foam::fvMeshStitchers::moving::unconformErrorFaceCorrectMeshPhi
|
||||
surfaceScalarField::Boundary meshMagUfb
|
||||
(
|
||||
surfaceScalarField::Internal::null(),
|
||||
conformalNccBoundaryField<scalar>(tnccMeshMagUfb)
|
||||
fvMeshStitcherTools::conformedNcBoundaryField(tnccMeshMagUfb)
|
||||
);
|
||||
tnccMeshMagUf.clear();
|
||||
|
||||
@ -1059,14 +1060,32 @@ void Foam::fvMeshStitchers::moving::unconformCorrectMeshPhi
|
||||
// and this function would only modify its arguments and leave calling
|
||||
// fvMesh::unconform to the base class.
|
||||
mesh().unconform(polyFacesBf, SfSf, CfSf);
|
||||
resizeFieldPatchFields(polyFacesBf, phi);
|
||||
|
||||
// Resize the patched in the flux field
|
||||
for (label i = 0; i <= phi.nOldTimes(false); ++ i)
|
||||
{
|
||||
surfaceScalarField::Boundary& phi0Bf =
|
||||
boundaryFieldRefNoUpdate(phi.oldTime(i));
|
||||
|
||||
forAll(polyFacesBf, ncPatchi)
|
||||
{
|
||||
if (!isA<nonConformalFvPatch>(polyFacesBf[ncPatchi].patch()))
|
||||
{
|
||||
phi0Bf[ncPatchi].map
|
||||
(
|
||||
phi0Bf[ncPatchi],
|
||||
setSizeFvPatchFieldMapper(polyFacesBf[ncPatchi].size())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set mesh fluxes on the original and cyclic faces as a proportion of
|
||||
// the area taken from the old original faces
|
||||
for (label i = 0; i <= phi.nOldTimes(false); ++ i)
|
||||
{
|
||||
phi.oldTime(i).boundaryFieldRef() =
|
||||
nonConformalBoundaryField<scalar>
|
||||
fvMeshStitcherTools::unconformedBoundaryField
|
||||
(
|
||||
phi.oldTime(i).boundaryField(),
|
||||
phi.oldTime(i).boundaryField()
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2021-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -137,6 +137,12 @@ Foam::nonConformalPolyPatch::~nonConformalPolyPatch()
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::polyPatch& Foam::nonConformalPolyPatch::patch() const
|
||||
{
|
||||
return patch_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::word& Foam::nonConformalPolyPatch::origPatchName() const
|
||||
{
|
||||
return origPatchName_;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2021-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -121,6 +121,9 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Reference to the polyPatch
|
||||
const polyPatch& patch() const;
|
||||
|
||||
//- Original patch name
|
||||
const word& origPatchName() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user