Merge branch 'master' of /home/dm4/OpenFOAM/OpenFOAM-dev

This commit is contained in:
andy
2013-05-28 16:16:15 +01:00
105 changed files with 7717 additions and 373 deletions

View File

@ -18,6 +18,7 @@ $(basicFvPatches)/generic/genericFvPatch.C
constraintFvPatches = $(fvPatches)/constraint constraintFvPatches = $(fvPatches)/constraint
$(constraintFvPatches)/cyclic/cyclicFvPatch.C $(constraintFvPatches)/cyclic/cyclicFvPatch.C
$(constraintFvPatches)/cyclicAMI/cyclicAMIFvPatch.C $(constraintFvPatches)/cyclicAMI/cyclicAMIFvPatch.C
$(constraintFvPatches)/cyclicACMI/cyclicACMIFvPatch.C
$(constraintFvPatches)/cyclicSlip/cyclicSlipFvPatch.C $(constraintFvPatches)/cyclicSlip/cyclicSlipFvPatch.C
$(constraintFvPatches)/empty/emptyFvPatch.C $(constraintFvPatches)/empty/emptyFvPatch.C
$(constraintFvPatches)/nonuniformTransformCyclic/nonuniformTransformCyclicFvPatch.C $(constraintFvPatches)/nonuniformTransformCyclic/nonuniformTransformCyclicFvPatch.C
@ -109,6 +110,7 @@ $(basicFvPatchFields)/zeroGradient/zeroGradientFvPatchFields.C
constraintFvPatchFields = $(fvPatchFields)/constraint constraintFvPatchFields = $(fvPatchFields)/constraint
$(constraintFvPatchFields)/cyclic/cyclicFvPatchFields.C $(constraintFvPatchFields)/cyclic/cyclicFvPatchFields.C
$(constraintFvPatchFields)/cyclicAMI/cyclicAMIFvPatchFields.C $(constraintFvPatchFields)/cyclicAMI/cyclicAMIFvPatchFields.C
$(constraintFvPatchFields)/cyclicACMI/cyclicACMIFvPatchFields.C
$(constraintFvPatchFields)/cyclicSlip/cyclicSlipFvPatchFields.C $(constraintFvPatchFields)/cyclicSlip/cyclicSlipFvPatchFields.C
$(constraintFvPatchFields)/empty/emptyFvPatchFields.C $(constraintFvPatchFields)/empty/emptyFvPatchFields.C
$(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C $(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C
@ -203,6 +205,7 @@ $(basicFvsPatchFields)/sliced/slicedFvsPatchFields.C
constraintFvsPatchFields = $(fvsPatchFields)/constraint constraintFvsPatchFields = $(fvsPatchFields)/constraint
$(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C $(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicAMI/cyclicAMIFvsPatchFields.C $(constraintFvsPatchFields)/cyclicAMI/cyclicAMIFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicACMI/cyclicACMIFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicSlip/cyclicSlipFvsPatchFields.C $(constraintFvsPatchFields)/cyclicSlip/cyclicSlipFvsPatchFields.C
$(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C $(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C
$(constraintFvsPatchFields)/nonuniformTransformCyclic/nonuniformTransformCyclicFvsPatchFields.C $(constraintFvsPatchFields)/nonuniformTransformCyclic/nonuniformTransformCyclicFvsPatchFields.C

View File

@ -0,0 +1,387 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvPatchField.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(p, iF),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(ptf, p, iF, mapper),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(this->patch()))
{
FatalErrorIn
(
"cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField"
"("
"const cyclicACMIFvPatchField<Type>& ,"
"const fvPatch&, "
"const DimensionedField<Type, volMesh>&, "
"const fvPatchFieldMapper&"
")"
) << " patch type '" << p.type()
<< "' not constraint type '" << typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->dimensionedInternalField().name()
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(p, iF, dict),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(p))
{
FatalIOErrorIn
(
"cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField"
"("
"const fvPatch&, "
"const DimensionedField<Type, volMesh>&, "
"const dictionary&"
")",
dict
) << " patch type '" << p.type()
<< "' not constraint type '" << typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->dimensionedInternalField().name()
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalIOError);
}
if (!dict.found("value") && this->coupled())
{
this->evaluate(Pstream::blocking);
}
}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>& ptf
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(ptf),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(ptf, iF),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::cyclicACMIFvPatchField<Type>::coupled() const
{
return cyclicACMIPatch_.coupled();
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField() const
{
const Field<Type>& iField = this->internalField();
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
const labelUList& nbrFaceCellsNonOverlap =
cyclicACMIPatch_.cyclicACMIPatch().nonOverlapPatch().faceCells();
Field<Type> pnfCoupled(iField, nbrFaceCellsCoupled);
Field<Type> pnfNonOverlap(iField, nbrFaceCellsNonOverlap);
tmp<Field<Type> > tpnf
(
new Field<Type>
(
cyclicACMIPatch_.interpolate
(
pnfCoupled,
pnfNonOverlap
)
)
);
if (doTransform())
{
tpnf() = transform(forwardT(), tpnf());
}
return tpnf;
}
template<class Type>
const Foam::cyclicACMIFvPatchField<Type>&
Foam::cyclicACMIFvPatchField<Type>::neighbourPatchField() const
{
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->internalField()
);
return refCast<const cyclicACMIFvPatchField<Type> >
(
fld.boundaryField()[cyclicACMIPatch_.neighbPatchID()]
);
}
template<class Type>
const Foam::fvPatchField<Type>&
Foam::cyclicACMIFvPatchField<Type>::nonOverlapPatchField() const
{
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->internalField()
);
return fld.boundaryField()[cyclicACMIPatch_.nonOverlapPatchID()];
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
// note: only applying coupled contribution
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
scalarField pnf(psiInternal, nbrFaceCellsCoupled);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
const labelUList& faceCells = cyclicACMIPatch_.faceCells();
pnf = cyclicACMIPatch_.interpolate(pnf);
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
(
Field<Type>& result,
const Field<Type>& psiInternal,
const scalarField& coeffs,
const Pstream::commsTypes
) const
{
// note: only applying coupled contribution
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
Field<Type> pnf(psiInternal, nbrFaceCellsCoupled);
// Transform according to the transformation tensors
transformCoupleField(pnf);
const labelUList& faceCells = cyclicACMIPatch_.faceCells();
pnf = cyclicACMIPatch_.interpolate(pnf);
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::cyclicACMIFvPatchField<Type>::snGrad
(
const scalarField& deltaCoeffs
) const
{
// note: only applying coupled contribution
return coupledFvPatchField<Type>::snGrad(deltaCoeffs);
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::evaluate
(
const Pstream::commsTypes comms
)
{
// blend contrubutions from the coupled and non-overlap patches
const fvPatchField<Type>& npf = nonOverlapPatchField();
const_cast<fvPatchField<Type>&>(npf).evaluate();
coupledFvPatchField<Type>::evaluate(comms);
const Field<Type>& cpf = *this;
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
Field<Type>::operator=(mask*cpf + (1.0 - mask)*npf);
fvPatchField<Type>::evaluate();
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>& w
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::valueInternalCoeffs(w);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>& w
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::valueBoundaryCoeffs(w);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs
(
const scalarField& deltaCoeffs
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientInternalCoeffs(deltaCoeffs);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs() const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientInternalCoeffs();
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs
(
const scalarField& deltaCoeffs
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientBoundaryCoeffs(deltaCoeffs);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs() const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientBoundaryCoeffs();
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
this->writeEntry("value", os);
}
// ************************************************************************* //

View File

@ -0,0 +1,298 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIFvPatchField
Group
grpCoupledBoundaryConditions
Description
This boundary condition enforces a cyclic condition between a pair of
boundaries, whereby communication between the patches is performed using
an arbitrarily coupled mesh interface (ACMI) interpolation.
\heading Patch usage
Example of the boundary condition specification:
\verbatim
myPatch
{
type cyclicACMI;
}
\endverbatim
SeeAlso
Foam::AMIInterpolation
SourceFiles
cyclicACMIFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvPatchField_H
#define cyclicACMIFvPatchField_H
#include "coupledFvPatchField.H"
#include "cyclicACMILduInterfaceField.H"
#include "cyclicACMIFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class cyclicACMIFvPatchField
:
virtual public cyclicACMILduInterfaceField,
public coupledFvPatchField<Type>
{
// Private data
//- Local reference cast into the cyclic patch
const cyclicACMIFvPatch& cyclicACMIPatch_;
// Private Member Functions
//- Return neighbour side field given internal fields
template<class Type2>
tmp<Field<Type2> > neighbourSideField
(
const Field<Type2>&
) const;
public:
//- Runtime type information
TypeName(cyclicACMIFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
cyclicACMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
cyclicACMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given cyclicACMIFvPatchField onto a new patch
cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
cyclicACMIFvPatchField(const cyclicACMIFvPatchField<Type>&);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new cyclicACMIFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<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 cyclicACMIFvPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
//- Return local reference cast into the cyclic AMI patch
const cyclicACMIFvPatch& cyclicACMIPatch() const
{
return cyclicACMIPatch_;
}
// Evaluation functions
//- Return true if coupled. Note that the underlying patch
// is not coupled() - the points don't align.
virtual bool coupled() const;
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type> > patchNeighbourField() const;
//- Return reference to neighbour patchField
const cyclicACMIFvPatchField<Type>& neighbourPatchField() const;
//- Return reference to non-overlapping patchField
const fvPatchField<Type>& nonOverlapPatchField() const;
//- Return patch-normal gradient
virtual tmp<Field<Type> > snGrad
(
const scalarField& deltaCoeffs
) const;
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType
);
//- 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 scalarField& deltaCoeffs
) 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 scalarField& deltaCoeffs
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientBoundaryCoeffs() const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
Field<Type>&,
const Field<Type>&,
const scalarField&,
const Pstream::commsTypes commsType
) const;
// Cyclic AMI coupled interface functions
//- Does the patch field perform the transformation
virtual bool doTransform() const
{
return
!(cyclicACMIPatch_.parallel() || pTraits<Type>::rank == 0);
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return cyclicACMIPatch_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return cyclicACMIPatch_.reverseT();
}
//- Return rank of component for transform
virtual int rank() const
{
return pTraits<Type>::rank;
}
// I-O
//- Write
virtual void write(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "cyclicACMIFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 cyclicACMIFvPatchFields_H
#define cyclicACMIFvPatchFields_H
#include "cyclicACMIFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 cyclicACMIFvPatchFieldsFwd_H
#define cyclicACMIFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class cyclicACMIFvPatchField;
makePatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvsPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF
)
:
coupledFvsPatchField<Type>(p, iF),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
coupledFvsPatchField<Type>(ptf, p, iF, mapper),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(this->patch()))
{
FatalErrorIn
(
"cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField\n"
"("
"const cyclicACMIFvsPatchField<Type>&, "
"const fvPatch&, "
"const DimensionedField<Type, surfaceMesh>&, "
"const fvPatchFieldMapper&"
")"
) << "Field type does not correspond to patch type for patch "
<< this->patch().index() << "." << endl
<< "Field type: " << typeName << endl
<< "Patch type: " << this->patch().type()
<< exit(FatalError);
}
}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const dictionary& dict
)
:
coupledFvsPatchField<Type>(p, iF, dict),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(p))
{
FatalIOErrorIn
(
"cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField"
"("
"const fvPatch&, "
"const Field<Type>&, "
"const dictionary&"
")",
dict
) << "patch " << this->patch().index() << " not cyclicACMI type. "
<< "Patch type = " << p.type()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>& ptf
)
:
coupledFvsPatchField<Type>(ptf),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>& ptf,
const DimensionedField<Type, surfaceMesh>& iF
)
:
coupledFvsPatchField<Type>(ptf, iF),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::cyclicACMIFvsPatchField<Type>::coupled() const
{
if
(
Pstream::parRun()
|| (
this->cyclicACMIPatch_.size()
&& this->cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().size()
)
)
{
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIFvsPatchField
Description
Foam::cyclicACMIFvsPatchField
SourceFiles
cyclicACMIFvsPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvsPatchField_H
#define cyclicACMIFvsPatchField_H
#include "coupledFvsPatchField.H"
#include "cyclicACMIFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIFvsPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class cyclicACMIFvsPatchField
:
public coupledFvsPatchField<Type>
{
// Private data
//- Local reference cast into the cyclic patch
const cyclicACMIFvPatch& cyclicACMIPatch_;
public:
//- Runtime type information
TypeName(cyclicACMIFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
cyclicACMIFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&
);
//- Construct from patch, internal field and dictionary
cyclicACMIFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const dictionary&
);
//- Construct by mapping given cyclicACMIFvsPatchField onto a new patch
cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvsPatchField<Type> > clone() const
{
return tmp<fvsPatchField<Type> >
(
new cyclicACMIFvsPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<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 cyclicACMIFvsPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
//- Return true if running parallel
virtual bool coupled() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "cyclicACMIFvsPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvsPatchFields.H"
#include "fvsPatchFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeFvsPatchFields(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 cyclicACMIFvsPatchFields_H
#define cyclicACMIFvsPatchFields_H
#include "cyclicACMIFvsPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makeFvsPatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 cyclicACMIFvsPatchFieldsFwd_H
#define cyclicACMIFvsPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class cyclicACMIFvsPatchField;
makeFvsPatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,202 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "fvMesh.H"
#include "transform.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIFvPatch, 0);
addToRunTimeSelectionTable(fvPatch, cyclicACMIFvPatch, polyPatch);
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
void Foam::cyclicACMIFvPatch::updateAreas() const
{
if (cyclicACMIPolyPatch_.updated())
{
// Set Sf and magSf for both sides' coupled and non-overlapping patches
// owner couple
const_cast<vectorField&>(Sf()) = patch().faceAreas();
const_cast<scalarField&>(magSf()) = mag(patch().faceAreas());
// owner non-overlapping
const fvPatch& nonOverlapPatch = this->nonOverlapPatch();
const_cast<vectorField&>(nonOverlapPatch.Sf()) =
nonOverlapPatch.patch().faceAreas();
const_cast<scalarField&>(nonOverlapPatch.magSf()) =
mag(nonOverlapPatch.patch().faceAreas());
// neighbour couple
const cyclicACMIFvPatch& nbrACMI = neighbPatch();
const_cast<vectorField&>(nbrACMI.Sf()) =
nbrACMI.patch().faceAreas();
const_cast<scalarField&>(nbrACMI.magSf()) =
mag(nbrACMI.patch().faceAreas());
// neighbour non-overlapping
const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch();
const_cast<vectorField&>(nbrNonOverlapPatch.Sf()) =
nbrNonOverlapPatch.patch().faceAreas();
const_cast<scalarField&>(nbrNonOverlapPatch.magSf()) =
mag(nbrNonOverlapPatch.patch().faceAreas());
// set the updated flag
cyclicACMIPolyPatch_.setUpdated(false);
}
}
void Foam::cyclicACMIFvPatch::makeWeights(scalarField& w) const
{
if (coupled())
{
const cyclicACMIFvPatch& nbrPatch = neighbFvPatch();
const fvPatch& nbrPatchNonOverlap = nonOverlapPatch();
const scalarField deltas(nf() & fvPatch::delta());
const scalarField nbrDeltas
(
interpolate
(
nbrPatch.nf() & nbrPatch.fvPatch::delta(),
nbrPatchNonOverlap.nf() & nbrPatchNonOverlap.delta()
)
);
forAll(deltas, faceI)
{
scalar di = deltas[faceI];
scalar dni = nbrDeltas[faceI];
w[faceI] = dni/(di + dni);
}
}
else
{
// Behave as uncoupled patch
fvPatch::makeWeights(w);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::cyclicACMIFvPatch::coupled() const
{
return Pstream::parRun() || (this->size() && neighbFvPatch().size());
}
Foam::tmp<Foam::vectorField> Foam::cyclicACMIFvPatch::delta() const
{
if (coupled())
{
const cyclicACMIFvPatch& nbrPatchCoupled = neighbFvPatch();
const fvPatch& nbrPatchNonOverlap = nonOverlapPatch();
const vectorField patchD(fvPatch::delta());
vectorField nbrPatchD
(
interpolate
(
nbrPatchCoupled.fvPatch::delta(),
nbrPatchNonOverlap.delta()
)
);
const vectorField nbrPatchD0
(
interpolate
(
vectorField(nbrPatchCoupled.size(), vector::zero),
nbrPatchNonOverlap.delta()()
)
);
nbrPatchD -= nbrPatchD0;
tmp<vectorField> tpdv(new vectorField(patchD.size()));
vectorField& pdv = tpdv();
// do the transformation if necessary
if (parallel())
{
forAll(patchD, faceI)
{
const vector& ddi = patchD[faceI];
const vector& dni = nbrPatchD[faceI];
pdv[faceI] = ddi - dni;
}
}
else
{
forAll(patchD, faceI)
{
const vector& ddi = patchD[faceI];
const vector& dni = nbrPatchD[faceI];
pdv[faceI] = ddi - transform(forwardT()[0], dni);
}
}
return tpdv;
}
else
{
return fvPatch::delta();
}
}
Foam::tmp<Foam::labelField> Foam::cyclicACMIFvPatch::interfaceInternalField
(
const labelUList& internalData
) const
{
return patchInternalField(internalData);
}
Foam::tmp<Foam::labelField> Foam::cyclicACMIFvPatch::internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& iF
) const
{
return neighbFvPatch().patchInternalField(iF);
}
// ************************************************************************* //

View File

@ -0,0 +1,268 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIFvPatch
Description
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI)
SourceFiles
cyclicACMIFvPatch.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvPatch_H
#define cyclicACMIFvPatch_H
#include "coupledFvPatch.H"
#include "cyclicACMILduInterface.H"
#include "cyclicACMIPolyPatch.H"
#include "fvBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIFvPatch Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIFvPatch
:
public coupledFvPatch,
public cyclicACMILduInterface
{
// Private data
const cyclicACMIPolyPatch& cyclicACMIPolyPatch_;
protected:
// Protected Member functions
//- Update the patch areas after AMI update
void updateAreas() const;
//- Make patch weighting factors
void makeWeights(scalarField&) const;
public:
//- Runtime type information
TypeName(cyclicACMIPolyPatch::typeName_());
// Constructors
//- Construct from polyPatch
cyclicACMIFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm)
:
coupledFvPatch(patch, bm),
cyclicACMILduInterface(),
cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch))
{}
// Member functions
// Access
//- Return local reference cast into the cyclic patch
const cyclicACMIPolyPatch& cyclicACMIPatch() const
{
return cyclicACMIPolyPatch_;
}
//- Return neighbour
virtual label neighbPatchID() const
{
return cyclicACMIPolyPatch_.neighbPatchID();
}
virtual bool owner() const
{
return cyclicACMIPolyPatch_.owner();
}
//- Return neighbour fvPatch
virtual const cyclicACMIFvPatch& neighbPatch() const
{
return refCast<const cyclicACMIFvPatch>
(
this->boundaryMesh()[cyclicACMIPolyPatch_.neighbPatchID()]
);
}
//- Return neighbour
virtual label nonOverlapPatchID() const
{
return cyclicACMIPolyPatch_.nonOverlapPatchID();
}
//- Return non-overlapping fvPatch
virtual const fvPatch& nonOverlapPatch() const
{
return this->boundaryMesh()[nonOverlapPatchID()];
}
//- Return a reference to the AMI interpolator
virtual const AMIPatchToPatchInterpolation& AMI() const
{
const AMIPatchToPatchInterpolation& AMI =
cyclicACMIPolyPatch_.AMI();
updateAreas();
return AMI;
}
//- Are the cyclic planes parallel
virtual bool parallel() const
{
return cyclicACMIPolyPatch_.parallel();
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return cyclicACMIPolyPatch_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return cyclicACMIPolyPatch_.reverseT();
}
const cyclicACMIFvPatch& neighbFvPatch() const
{
return refCast<const cyclicACMIFvPatch>
(
this->boundaryMesh()[cyclicACMIPolyPatch_.neighbPatchID()]
);
}
//- Return true if this patch is coupled. This is equivalent
// to the coupledPolyPatch::coupled() if parallel running or
// both sides present, false otherwise
virtual bool coupled() const;
//- Return delta (P to N) vectors across coupled patch
virtual tmp<vectorField> delta() const;
template<class Type>
tmp<Field<Type> > interpolate
(
const Field<Type>& fldCoupled
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate
(
fldCoupled
);
}
template<class Type>
tmp<Field<Type> > interpolate
(
const tmp<Field<Type> >& tfldCoupled
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate
(
tfldCoupled
);
}
template<class Type>
tmp<Field<Type> > interpolate
(
const Field<Type>& fldCoupled,
const Field<Type>& fldNonOverlap
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.interpolate
(
fldCoupled,
fldNonOverlap
);
}
template<class Type>
tmp<Field<Type> > interpolate
(
const tmp<Field<Type> >& tFldCoupled,
const tmp<Field<Type> >& tFldNonOverlap
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.interpolate
(
tFldCoupled,
tFldNonOverlap
);
}
// Interface transfer functions
//- Return the values of the given internal data adjacent to
// the interface as a field
virtual tmp<labelField> interfaceInternalField
(
const labelUList& internalData
) const;
//- Return neighbour field
virtual tmp<labelField> internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& internalData
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -44,9 +44,7 @@ bool Foam::pairPatchAgglomeration::continueAgglomerating
{ {
// Check the need for further agglomeration on all processors // Check the need for further agglomeration on all processors
label localnCoarseFaces = nCoarseFaces; label localnCoarseFaces = nCoarseFaces;
// reduce(localnCoarseFaces, sumOp<label>());
bool contAgg = localnCoarseFaces >= nFacesInCoarsestLevel_; bool contAgg = localnCoarseFaces >= nFacesInCoarsestLevel_;
//reduce(contAgg, andOp<bool>());
return contAgg; return contAgg;
} }

View File

@ -46,9 +46,6 @@ defineTypeNameAndDebug(autoRefineDriver, 0);
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components // Construct from components
@ -97,12 +94,14 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
( (
refineParams.keepPoints()[0], // For now only use one. refineParams.keepPoints()[0], // For now only use one.
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(),
true, // featureRefinement true, // featureRefinement
false, // featureDistanceRefinement false, // featureDistanceRefinement
false, // internalRefinement false, // internalRefinement
false, // surfaceRefinement false, // surfaceRefinement
false, // curvatureRefinement false, // curvatureRefinement
false, // gapRefinement
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -208,12 +207,14 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
( (
refineParams.keepPoints()[0], refineParams.keepPoints()[0],
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement false, // featureRefinement
false, // featureDistanceRefinement false, // featureDistanceRefinement
false, // internalRefinement false, // internalRefinement
true, // surfaceRefinement true, // surfaceRefinement
true, // curvatureRefinement true, // curvatureRefinement
false, // gapRefinement
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -294,6 +295,371 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
} }
Foam::label Foam::autoRefineDriver::gapOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Determine the maximum refinement level over all surfaces. This
// determines the minumum number of surface refinement iterations.
label maxIncrement = 0;
const labelList& maxLevel = meshRefiner_.surfaces().maxLevel();
const labelList& gapLevel = meshRefiner_.surfaces().gapLevel();
forAll(maxLevel, i)
{
maxIncrement = max(maxIncrement, gapLevel[i]-maxLevel[i]);
}
label iter = 0;
if (maxIncrement == 0)
{
return iter;
}
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Gap refinement iteration " << iter << nl
<< "--------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// Only look at surface intersections (minLevel and surface curvature),
// do not do internal refinement (refinementShells)
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0],
refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement
false, // featureDistanceRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
true, // gapRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromGap." << endl;
cellSet c(mesh, "candidateCellsFromGap", candidateCells);
c.instance() = meshRefiner_.timeName();
c.write();
}
// Grow by one layer to make sure we're covering the gap
{
boolList isCandidateCell(mesh.nCells(), false);
forAll(candidateCells, i)
{
isCandidateCell[candidateCells[i]] = true;
}
for (label i=0; i<1; i++)
{
boolList newIsCandidateCell(isCandidateCell);
// Internal faces
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
{
label own = mesh.faceOwner()[faceI];
label nei = mesh.faceNeighbour()[faceI];
if (isCandidateCell[own] != isCandidateCell[nei])
{
newIsCandidateCell[own] = true;
newIsCandidateCell[nei] = true;
}
}
// Get coupled boundary condition values
boolList neiIsCandidateCell;
syncTools::swapBoundaryCellList
(
mesh,
isCandidateCell,
neiIsCandidateCell
);
// Boundary faces
for
(
label faceI = mesh.nInternalFaces();
faceI < mesh.nFaces();
faceI++
)
{
label own = mesh.faceOwner()[faceI];
label bFaceI = faceI-mesh.nInternalFaces();
if (isCandidateCell[own] != neiIsCandidateCell[bFaceI])
{
newIsCandidateCell[own] = true;
}
}
isCandidateCell.transfer(newIsCandidateCell);
}
label n = 0;
forAll(isCandidateCell, cellI)
{
if (isCandidateCell[cellI])
{
n++;
}
}
candidateCells.setSize(n);
n = 0;
forAll(isCandidateCell, cellI)
{
if (isCandidateCell[cellI])
{
candidateCells[n++] = cellI;
}
}
}
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromGapPlusBuffer." << endl;
cellSet c(mesh, "candidateCellsFromGapPlusBuffer", candidateCells);
c.instance() = meshRefiner_.timeName();
c.write();
}
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum necessary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= maxIncrement
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::danglingCellRefine
(
const refinementParameters& refineParams,
const label nFaces,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
label iter;
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Dangling coarse cells refinement iteration " << iter << nl
<< "--------------------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
const cellList& cells = mesh.cells();
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
labelList candidateCells;
{
cellSet candidateCellSet(mesh, "candidateCells", cells.size()/1000);
forAll(cells, cellI)
{
const cell& cFaces = cells[cellI];
label nIntFaces = 0;
forAll(cFaces, i)
{
label bFaceI = cFaces[i]-mesh.nInternalFaces();
if (bFaceI < 0)
{
nIntFaces++;
}
else
{
label patchI = pbm.patchID()[bFaceI];
if (pbm[patchI].coupled())
{
nIntFaces++;
}
}
}
if (nIntFaces == nFaces)
{
candidateCellSet.insert(cellI);
}
}
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCellSet.size()
<< " cells to cellSet candidateCellSet." << endl;
candidateCellSet.instance() = meshRefiner_.timeName();
candidateCellSet.write();
}
candidateCells = candidateCellSet.toc();
}
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine. No checking of minRefineCells since
// too few cells
if (nCellsToRefine == 0)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"coarse cell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"coarse cell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
void Foam::autoRefineDriver::removeInsideCells void Foam::autoRefineDriver::removeInsideCells
( (
const refinementParameters& refineParams, const refinementParameters& refineParams,
@ -371,12 +737,14 @@ Foam::label Foam::autoRefineDriver::shellRefine
( (
refineParams.keepPoints()[0], refineParams.keepPoints()[0],
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement false, // featureRefinement
true, // featureDistanceRefinement true, // featureDistanceRefinement
true, // internalRefinement true, // internalRefinement
false, // surfaceRefinement false, // surfaceRefinement
false, // curvatureRefinement false, // curvatureRefinement
false, // gapRefinement
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -653,6 +1021,16 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
// Debug:test all is still synced across proc patches // Debug:test all is still synced across proc patches
meshRefiner_.checkData(); meshRefiner_.checkData();
} }
// Remove any now dangling parts
meshRefiner_.splitMeshRegions(refineParams.keepPoints()[0]);
if (debug)
{
// Debug:test all is still synced across proc patches
meshRefiner_.checkData();
}
Info<< "Merged free-standing baffles in = " Info<< "Merged free-standing baffles in = "
<< mesh.time().cpuTimeIncrement() << " s." << endl; << mesh.time().cpuTimeIncrement() << " s." << endl;
} }
@ -732,6 +1110,12 @@ void Foam::autoRefineDriver::doRefine
100 // maxIter 100 // maxIter
); );
gapOnlyRefine
(
refineParams,
100 // maxIter
);
// Remove cells (a certain distance) beyond surface intersections // Remove cells (a certain distance) beyond surface intersections
removeInsideCells removeInsideCells
( (
@ -746,6 +1130,20 @@ void Foam::autoRefineDriver::doRefine
100 // maxIter 100 // maxIter
); );
// Refine any hexes with 5 or 6 faces refined to make smooth edges
danglingCellRefine
(
refineParams,
21, // 1 coarse face + 5 refined faces
100 // maxIter
);
danglingCellRefine
(
refineParams,
24, // 0 coarse faces + 6 refined faces
100 // maxIter
);
// Introduce baffles at surface intersections. Remove sections unreachable // Introduce baffles at surface intersections. Remove sections unreachable
// from keepPoint. // from keepPoint.
baffleAndSplitMesh(refineParams, prepareForSnapping, motionDict); baffleAndSplitMesh(refineParams, prepareForSnapping, motionDict);

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -88,6 +88,21 @@ class autoRefineDriver
const label maxIter const label maxIter
); );
//- Refine all cells in small gaps
label gapOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Refine cells with almost all sides refined
label danglingCellRefine
(
const refinementParameters& refineParams,
const label nFaces,
const label maxIter
);
//- Remove all cells within intersected region //- Remove all cells within intersected region
void removeInsideCells void removeInsideCells
( (

View File

@ -335,6 +335,48 @@ private:
label& nRefine label& nRefine
) const; ) const;
//- Is local topology a small gap?
bool isGap
(
const scalar,
const vector&,
const vector&,
const vector&,
const vector&
) const;
//- Mark cell if local a gap topology or
bool checkProximity
(
const scalar planarCos,
const label nAllowRefine,
const label surfaceLevel,
const vector& surfaceLocation,
const vector& surfaceNormal,
const label cellI,
label& cellMaxLevel,
vector& cellMaxLocation,
vector& cellMaxNormal,
labelList& refineCell,
label& nRefine
) const;
//- Mark cells for surface proximity based refinement.
label markProximityRefinement
(
const scalar curvature,
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const;
// Baffle handling // Baffle handling
//- Get faces to repatch. Returns map from face to patch. //- Get faces to repatch. Returns map from face to patch.
@ -676,12 +718,14 @@ public:
( (
const point& keepPoint, const point& keepPoint,
const scalar curvature, const scalar curvature,
const scalar planarAngle,
const bool featureRefinement, const bool featureRefinement,
const bool featureDistanceRefinement, const bool featureDistanceRefinement,
const bool internalRefinement, const bool internalRefinement,
const bool surfaceRefinement, const bool surfaceRefinement,
const bool curvatureRefinement, const bool curvatureRefinement,
const bool gapRefinement,
const label maxGlobalCells, const label maxGlobalCells,
const label maxLocalCells const label maxLocalCells
) const; ) const;

View File

@ -1965,7 +1965,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
const bool removeEdgeConnectedCells, const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle, const scalarField& perpendicularAngle,
const bool mergeFreeStanding, const bool mergeFreeStanding,
const scalar freeStandingAngle, const scalar planarAngle,
const dictionary& motionDict, const dictionary& motionDict,
Time& runTime, Time& runTime,
const labelList& globalToMasterPatch, const labelList& globalToMasterPatch,
@ -2172,7 +2172,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
identity(mesh_.nFaces()-mesh_.nInternalFaces()) identity(mesh_.nFaces()-mesh_.nInternalFaces())
+mesh_.nInternalFaces() +mesh_.nInternalFaces()
), ),
freeStandingAngle planarAngle
) )
); );

View File

@ -38,6 +38,7 @@ License
#include "featureEdgeMesh.H" #include "featureEdgeMesh.H"
#include "Cloud.H" #include "Cloud.H"
//#include "globalIndex.H" //#include "globalIndex.H"
//#include "OBJstream.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -1022,6 +1023,9 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
end, end,
minLevel, // max level of surface has to be bigger minLevel, // max level of surface has to be bigger
// than min level of neighbouring cells // than min level of neighbouring cells
surfaces_.maxLevel(),
surfaceNormal, surfaceNormal,
surfaceLevel surfaceLevel
); );
@ -1210,6 +1214,473 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
} }
// Mark small gaps
bool Foam::meshRefinement::isGap
(
const scalar planarCos,
const vector& point0,
const vector& normal0,
const vector& point1,
const vector& normal1
) const
{
////- hits differ and angles are oppositeish
//return
// (mag(point0-point1) > mergeDistance())
// && ((normal0 & normal1) < (-1+planarCos));
//- hits differ and angles are oppositeish and
// hits have a normal distance
vector d = point1-point0;
scalar magD = mag(d);
if (magD > mergeDistance())
{
scalar cosAngle = (normal0 & normal1);
vector avg = vector::zero;
if (cosAngle < (-1+planarCos))
{
// Opposite normals
avg = 0.5*(normal0-normal1);
}
else if (cosAngle > (1-planarCos))
{
avg = 0.5*(normal0+normal1);
}
if (avg != vector::zero)
{
avg /= mag(avg);
d /= magD;
// Check average normal with respect to intersection locations
if (mag(avg&d) > Foam::cos(degToRad(45)))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
bool Foam::meshRefinement::checkProximity
(
const scalar planarCos,
const label nAllowRefine,
const label surfaceLevel, // current intersection max level
const vector& surfaceLocation, // current intersection location
const vector& surfaceNormal, // current intersection normal
const label cellI,
label& cellMaxLevel, // cached max surface level for this cell
vector& cellMaxLocation, // cached surface normal for this cell
vector& cellMaxNormal, // cached surface normal for this cell
labelList& refineCell,
label& nRefine
) const
{
const labelList& cellLevel = meshCutter_.cellLevel();
// Test if surface applicable
if (surfaceLevel > cellLevel[cellI])
{
if (cellMaxLevel == -1)
{
// First visit of cell. Store
cellMaxLevel = surfaceLevel;
cellMaxLocation = surfaceLocation;
cellMaxNormal = surfaceNormal;
}
else
{
// Second or more visit.
// Check if
// - different location
// - opposite surface
bool closeSurfaces = isGap
(
planarCos,
cellMaxLocation,
cellMaxNormal,
surfaceLocation,
surfaceNormal
);
// Set normal to that of highest surface. Not really necessary
// over here but we reuse cellMax info when doing coupled faces.
if (surfaceLevel > cellMaxLevel)
{
cellMaxLevel = surfaceLevel;
cellMaxLocation = surfaceLocation;
cellMaxNormal = surfaceNormal;
}
if (closeSurfaces)
{
//Pout<< "Found gap:" << nl
// << " location:" << surfaceLocation
// << "\tnormal :" << surfaceNormal << nl
/// << " location:" << cellMaxLocation
// << "\tnormal :" << cellMaxNormal << nl
// << "\tcos :" << (surfaceNormal&cellMaxNormal) << nl
// << endl;
return markForRefine
(
surfaceLevel, // mark with any non-neg number.
nAllowRefine,
refineCell[cellI],
nRefine
);
}
}
}
// Did not reach refinement limit.
return true;
}
Foam::label Foam::meshRefinement::markProximityRefinement
(
const scalar planarCos,
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const
{
const labelList& cellLevel = meshCutter_.cellLevel();
const pointField& cellCentres = mesh_.cellCentres();
label oldNRefine = nRefine;
// 1. local test: any cell on more than one surface gets refined
// (if its current level is < max of the surface max level)
// 2. 'global' test: any cell on only one surface with a neighbour
// on a different surface gets refined (if its current level etc.)
// Collect candidate faces (i.e. intersecting any surface and
// owner/neighbour not yet refined.
labelList testFaces(getRefineCandidateFaces(refineCell));
// Collect segments
pointField start(testFaces.size());
pointField end(testFaces.size());
labelList minLevel(testFaces.size());
forAll(testFaces, i)
{
label faceI = testFaces[i];
label own = mesh_.faceOwner()[faceI];
if (mesh_.isInternalFace(faceI))
{
label nei = mesh_.faceNeighbour()[faceI];
start[i] = cellCentres[own];
end[i] = cellCentres[nei];
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
}
else
{
label bFaceI = faceI - mesh_.nInternalFaces();
start[i] = cellCentres[own];
end[i] = neiCc[bFaceI];
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
}
}
// Extend segments a bit
{
const vectorField smallVec(Foam::sqrt(SMALL)*(end-start));
start -= smallVec;
end += smallVec;
}
// Test for all intersections (with surfaces of higher gap level than
// minLevel) and cache per cell the max surface level and the local normal
// on that surface.
labelList cellMaxLevel(mesh_.nCells(), -1);
vectorField cellMaxNormal(mesh_.nCells(), vector::zero);
pointField cellMaxLocation(mesh_.nCells(), vector::zero);
{
// Per segment the normals of the surfaces
List<vectorList> surfaceLocation;
List<vectorList> surfaceNormal;
// Per segment the list of levels of the surfaces
labelListList surfaceLevel;
surfaces_.findAllHigherIntersections
(
start,
end,
minLevel, // gap level of surface has to be bigger
// than min level of neighbouring cells
surfaces_.gapLevel(),
surfaceLocation,
surfaceNormal,
surfaceLevel
);
// Clear out unnecessary data
start.clear();
end.clear();
minLevel.clear();
//// Extract per cell information on the surface with the highest max
//OBJstream str
//(
// mesh_.time().path()
// / "findAllHigherIntersections_"
// + mesh_.time().timeName()
// + ".obj"
//);
//// All intersections
//OBJstream str2
//(
// mesh_.time().path()
// / "findAllHigherIntersections2_"
// + mesh_.time().timeName()
// + ".obj"
//);
forAll(testFaces, i)
{
label faceI = testFaces[i];
label own = mesh_.faceOwner()[faceI];
const labelList& fLevels = surfaceLevel[i];
const vectorList& fPoints = surfaceLocation[i];
const vectorList& fNormals = surfaceNormal[i];
forAll(fLevels, hitI)
{
checkProximity
(
planarCos,
nAllowRefine,
fLevels[hitI],
fPoints[hitI],
fNormals[hitI],
own,
cellMaxLevel[own],
cellMaxLocation[own],
cellMaxNormal[own],
refineCell,
nRefine
);
}
if (mesh_.isInternalFace(faceI))
{
label nei = mesh_.faceNeighbour()[faceI];
forAll(fLevels, hitI)
{
checkProximity
(
planarCos,
nAllowRefine,
fLevels[hitI],
fPoints[hitI],
fNormals[hitI],
nei,
cellMaxLevel[nei],
cellMaxLocation[nei],
cellMaxNormal[nei],
refineCell,
nRefine
);
}
}
}
}
// 2. Find out a measure of surface curvature and region edges.
// Send over surface region and surface normal to neighbour cell.
labelList neiBndMaxLevel(mesh_.nFaces()-mesh_.nInternalFaces());
pointField neiBndMaxLocation(mesh_.nFaces()-mesh_.nInternalFaces());
vectorField neiBndMaxNormal(mesh_.nFaces()-mesh_.nInternalFaces());
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
{
label bFaceI = faceI-mesh_.nInternalFaces();
label own = mesh_.faceOwner()[faceI];
neiBndMaxLevel[bFaceI] = cellMaxLevel[own];
neiBndMaxLocation[bFaceI] = cellMaxLocation[own];
neiBndMaxNormal[bFaceI] = cellMaxNormal[own];
}
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLevel);
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLocation);
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxNormal);
// Loop over all faces. Could only be checkFaces.. except if they're coupled
// Internal faces
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
{
label own = mesh_.faceOwner()[faceI];
label nei = mesh_.faceNeighbour()[faceI];
if (cellMaxLevel[own] != -1 && cellMaxLevel[nei] != -1)
{
// Have valid data on both sides. Check planarCos.
if
(
isGap
(
planarCos,
cellMaxLocation[own],
cellMaxNormal[own],
cellMaxLocation[nei],
cellMaxNormal[nei]
)
)
{
// See which side to refine
if (cellLevel[own] < cellMaxLevel[own])
{
if
(
!markForRefine
(
cellMaxLevel[own],
nAllowRefine,
refineCell[own],
nRefine
)
)
{
if (debug)
{
Pout<< "Stopped refining since reaching my cell"
<< " limit of " << mesh_.nCells()+7*nRefine
<< endl;
}
break;
}
}
if (cellLevel[nei] < cellMaxLevel[nei])
{
if
(
!markForRefine
(
cellMaxLevel[nei],
nAllowRefine,
refineCell[nei],
nRefine
)
)
{
if (debug)
{
Pout<< "Stopped refining since reaching my cell"
<< " limit of " << mesh_.nCells()+7*nRefine
<< endl;
}
break;
}
}
}
}
}
// Boundary faces
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
{
label own = mesh_.faceOwner()[faceI];
label bFaceI = faceI - mesh_.nInternalFaces();
if (cellLevel[own] < cellMaxLevel[own] && neiBndMaxLevel[bFaceI] != -1)
{
// Have valid data on both sides. Check planarCos.
if
(
isGap
(
planarCos,
cellMaxLocation[own],
cellMaxNormal[own],
neiBndMaxLocation[bFaceI],
neiBndMaxNormal[bFaceI]
)
)
{
if
(
!markForRefine
(
cellMaxLevel[own],
nAllowRefine,
refineCell[own],
nRefine
)
)
{
if (debug)
{
Pout<< "Stopped refining since reaching my cell"
<< " limit of " << mesh_.nCells()+7*nRefine
<< endl;
}
break;
}
}
}
}
if
(
returnReduce(nRefine, sumOp<label>())
> returnReduce(nAllowRefine, sumOp<label>())
)
{
Info<< "Reached refinement limit." << endl;
}
return returnReduce(nRefine-oldNRefine, sumOp<label>());
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Calculate list of cells to refine. Gets for any edge (start - end) // Calculate list of cells to refine. Gets for any edge (start - end)
@ -1221,12 +1692,14 @@ Foam::labelList Foam::meshRefinement::refineCandidates
( (
const point& keepPoint, const point& keepPoint,
const scalar curvature, const scalar curvature,
const scalar planarAngle,
const bool featureRefinement, const bool featureRefinement,
const bool featureDistanceRefinement, const bool featureDistanceRefinement,
const bool internalRefinement, const bool internalRefinement,
const bool surfaceRefinement, const bool surfaceRefinement,
const bool curvatureRefinement, const bool curvatureRefinement,
const bool gapRefinement,
const label maxGlobalCells, const label maxGlobalCells,
const label maxLocalCells const label maxLocalCells
) const ) const
@ -1370,6 +1843,35 @@ Foam::labelList Foam::meshRefinement::refineCandidates
<< ": " << nCurv << " cells." << endl; << ": " << nCurv << " cells." << endl;
} }
const scalar planarCos = Foam::cos(degToRad(planarAngle));
if
(
gapRefinement
&& (planarCos >= -1 && planarCos <= 1)
&& (max(surfaces_.gapLevel()) > -1)
)
{
Info<< "Specified gap level : " << max(surfaces_.gapLevel())
<< ", planar angle " << planarAngle << endl;
label nGap = markProximityRefinement
(
planarCos,
nAllowRefine,
neiLevel,
neiCc,
refineCell,
nRefine
);
Info<< "Marked for refinement due to close opposite surfaces "
<< ": " << nGap << " cells." << endl;
}
// Pack cells-to-refine // Pack cells-to-refine
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~

View File

@ -116,10 +116,12 @@ Foam::refinementSurfaces::refinementSurfaces
labelList globalMinLevel(surfI, 0); labelList globalMinLevel(surfI, 0);
labelList globalMaxLevel(surfI, 0); labelList globalMaxLevel(surfI, 0);
labelList globalLevelIncr(surfI, 0);
scalarField globalAngle(surfI, -GREAT); scalarField globalAngle(surfI, -GREAT);
PtrList<dictionary> globalPatchInfo(surfI); PtrList<dictionary> globalPatchInfo(surfI);
List<Map<label> > regionMinLevel(surfI); List<Map<label> > regionMinLevel(surfI);
List<Map<label> > regionMaxLevel(surfI); List<Map<label> > regionMaxLevel(surfI);
List<Map<label> > regionLevelIncr(surfI);
List<Map<scalar> > regionAngle(surfI); List<Map<scalar> > regionAngle(surfI);
List<Map<autoPtr<dictionary> > > regionPatchInfo(surfI); List<Map<autoPtr<dictionary> > > regionPatchInfo(surfI);
@ -138,6 +140,31 @@ Foam::refinementSurfaces::refinementSurfaces
const labelPair refLevel(dict.lookup("level")); const labelPair refLevel(dict.lookup("level"));
globalMinLevel[surfI] = refLevel[0]; globalMinLevel[surfI] = refLevel[0];
globalMaxLevel[surfI] = refLevel[1]; globalMaxLevel[surfI] = refLevel[1];
globalLevelIncr[surfI] = dict.lookupOrDefault
(
"gapLevelIncrement",
0
);
if
(
globalMinLevel[surfI] < 0
|| globalMaxLevel[surfI] < globalMinLevel[surfI]
|| globalLevelIncr[surfI] < 0
)
{
FatalErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&, const dictionary>&"
) << "Illegal level specification for surface "
<< names_[surfI]
<< " : minLevel:" << globalMinLevel[surfI]
<< " maxLevel:" << globalMaxLevel[surfI]
<< " levelIncrement:" << globalLevelIncr[surfI]
<< exit(FatalError);
}
// Global zone names per surface // Global zone names per surface
if (dict.readIfPresent("faceZone", faceZoneNames_[surfI])) if (dict.readIfPresent("faceZone", faceZoneNames_[surfI]))
@ -244,6 +271,34 @@ Foam::refinementSurfaces::refinementSurfaces
regionMinLevel[surfI].insert(regionI, refLevel[0]); regionMinLevel[surfI].insert(regionI, refLevel[0]);
regionMaxLevel[surfI].insert(regionI, refLevel[1]); regionMaxLevel[surfI].insert(regionI, refLevel[1]);
label levelIncr = regionDict.lookupOrDefault
(
"gapLevelIncrement",
0
);
regionLevelIncr[surfI].insert(regionI, levelIncr);
if
(
refLevel[0] < 0
|| refLevel[1] < refLevel[0]
|| levelIncr < 0
)
{
FatalErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&, const dictionary>&"
) << "Illegal level specification for surface "
<< names_[surfI] << " region "
<< regionNames[regionI]
<< " : minLevel:" << refLevel[0]
<< " maxLevel:" << refLevel[1]
<< " levelIncrement:" << levelIncr
<< exit(FatalError);
}
if (regionDict.found("perpendicularAngle")) if (regionDict.found("perpendicularAngle"))
{ {
@ -286,6 +341,8 @@ Foam::refinementSurfaces::refinementSurfaces
minLevel_ = 0; minLevel_ = 0;
maxLevel_.setSize(nRegions); maxLevel_.setSize(nRegions);
maxLevel_ = 0; maxLevel_ = 0;
gapLevel_.setSize(nRegions);
gapLevel_ = -1;
perpendicularAngle_.setSize(nRegions); perpendicularAngle_.setSize(nRegions);
perpendicularAngle_ = -GREAT; perpendicularAngle_ = -GREAT;
patchInfo_.setSize(nRegions); patchInfo_.setSize(nRegions);
@ -301,6 +358,10 @@ Foam::refinementSurfaces::refinementSurfaces
label globalRegionI = regionOffset_[surfI] + i; label globalRegionI = regionOffset_[surfI] + i;
minLevel_[globalRegionI] = globalMinLevel[surfI]; minLevel_[globalRegionI] = globalMinLevel[surfI];
maxLevel_[globalRegionI] = globalMaxLevel[surfI]; maxLevel_[globalRegionI] = globalMaxLevel[surfI];
gapLevel_[globalRegionI] =
maxLevel_[globalRegionI]
+ globalLevelIncr[surfI];
perpendicularAngle_[globalRegionI] = globalAngle[surfI]; perpendicularAngle_[globalRegionI] = globalAngle[surfI];
if (globalPatchInfo.set(surfI)) if (globalPatchInfo.set(surfI))
{ {
@ -319,24 +380,9 @@ Foam::refinementSurfaces::refinementSurfaces
minLevel_[globalRegionI] = iter(); minLevel_[globalRegionI] = iter();
maxLevel_[globalRegionI] = regionMaxLevel[surfI][iter.key()]; maxLevel_[globalRegionI] = regionMaxLevel[surfI][iter.key()];
gapLevel_[globalRegionI] =
// Check validity maxLevel_[globalRegionI]
if + regionLevelIncr[surfI][iter.key()];
(
minLevel_[globalRegionI] < 0
|| maxLevel_[globalRegionI] < minLevel_[globalRegionI]
)
{
FatalErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&, const dictionary>&"
) << "Illegal level or layer specification for surface "
<< names_[surfI]
<< " : minLevel:" << minLevel_[globalRegionI]
<< " maxLevel:" << maxLevel_[globalRegionI]
<< exit(FatalError);
}
} }
forAllConstIter(Map<scalar>, regionAngle[surfI], iter) forAllConstIter(Map<scalar>, regionAngle[surfI], iter)
{ {
@ -714,6 +760,8 @@ void Foam::refinementSurfaces::findAllHigherIntersections
const pointField& end, const pointField& end,
const labelList& currentLevel, // current cell refinement level const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel,
List<vectorList>& surfaceNormal, List<vectorList>& surfaceNormal,
labelListList& surfaceLevel labelListList& surfaceLevel
) const ) const
@ -777,7 +825,7 @@ void Foam::refinementSurfaces::findAllHigherIntersections
label region = globalRegion(surfI, surfRegion[i]); label region = globalRegion(surfI, surfRegion[i]);
label pointI = pointMap[i]; label pointI = pointMap[i];
if (maxLevel_[region] > currentLevel[pointI]) if (globalRegionLevel[region] > currentLevel[pointI])
{ {
// Append to pointI info // Append to pointI info
label sz = surfaceNormal[pointI].size(); label sz = surfaceNormal[pointI].size();
@ -785,7 +833,95 @@ void Foam::refinementSurfaces::findAllHigherIntersections
surfaceNormal[pointI][sz] = surfNormal[i]; surfaceNormal[pointI][sz] = surfNormal[i];
surfaceLevel[pointI].setSize(sz+1); surfaceLevel[pointI].setSize(sz+1);
surfaceLevel[pointI][sz] = maxLevel_[region]; surfaceLevel[pointI][sz] = globalRegionLevel[region];
}
}
}
}
void Foam::refinementSurfaces::findAllHigherIntersections
(
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel,
List<pointList>& surfaceLocation,
List<vectorList>& surfaceNormal,
labelListList& surfaceLevel
) const
{
surfaceLevel.setSize(start.size());
surfaceNormal.setSize(start.size());
surfaceLocation.setSize(start.size());
if (surfaces_.empty())
{
return;
}
// Work arrays
List<List<pointIndexHit> > hitInfo;
labelList pRegions;
vectorField pNormals;
forAll(surfaces_, surfI)
{
allGeometry_[surfaces_[surfI]].findLineAll(start, end, hitInfo);
// Repack hits for surface into flat list
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// To avoid overhead of calling getRegion for every point
label n = 0;
forAll(hitInfo, pointI)
{
n += hitInfo[pointI].size();
}
List<pointIndexHit> surfInfo(n);
labelList pointMap(n);
n = 0;
forAll(hitInfo, pointI)
{
const List<pointIndexHit>& pHits = hitInfo[pointI];
forAll(pHits, i)
{
surfInfo[n] = pHits[i];
pointMap[n] = pointI;
n++;
}
}
labelList surfRegion(n);
vectorField surfNormal(n);
allGeometry_[surfaces_[surfI]].getRegion(surfInfo, surfRegion);
allGeometry_[surfaces_[surfI]].getNormal(surfInfo, surfNormal);
// Extract back into pointwise
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
forAll(surfRegion, i)
{
label region = globalRegion(surfI, surfRegion[i]);
label pointI = pointMap[i];
if (globalRegionLevel[region] > currentLevel[pointI])
{
// Append to pointI info
label sz = surfaceNormal[pointI].size();
surfaceLocation[pointI].setSize(sz+1);
surfaceLocation[pointI][sz] = surfInfo[i].hitPoint();
surfaceNormal[pointI].setSize(sz+1);
surfaceNormal[pointI][sz] = surfNormal[i];
surfaceLevel[pointI].setSize(sz+1);
surfaceLevel[pointI][sz] = globalRegionLevel[region];
} }
} }
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -51,6 +51,8 @@ class searchableSurfaces;
class shellSurfaces; class shellSurfaces;
class triSurfaceMesh; class triSurfaceMesh;
typedef List<point> pointList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class refinementSurfaces Declaration Class refinementSurfaces Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -120,6 +122,9 @@ private:
//- From global region number to refinement level //- From global region number to refinement level
labelList maxLevel_; labelList maxLevel_;
//- From global region number to small-gap level
labelList gapLevel_;
//- From global region number to perpendicular angle //- From global region number to perpendicular angle
scalarField perpendicularAngle_; scalarField perpendicularAngle_;
@ -226,6 +231,12 @@ public:
return maxLevel_; return maxLevel_;
} }
//- From global region number to small gap refinement level
const labelList& gapLevel() const
{
return gapLevel_;
}
//- From global region number to perpendicular angle //- From global region number to perpendicular angle
const scalarField& perpendicularAngle() const const scalarField& perpendicularAngle() const
{ {
@ -295,11 +306,25 @@ public:
const pointField& start, const pointField& start,
const pointField& end, const pointField& end,
const labelList& currentLevel, // current cell refinement level const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel, // level per surfregion
List<vectorList>& surfaceNormal, List<vectorList>& surfaceNormal,
labelListList& surfaceLevel labelListList& surfaceLevel
) const; ) const;
//- Find all intersections of edge. Unsorted order.
void findAllHigherIntersections
(
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel, // level per surfregion
List<pointList>& surfaceLocation,
List<vectorList>& surfaceNormal,
labelListList& surfaceLevel
) const;
//- Find intersection nearest to the endpoints. surface1,2 are //- Find intersection nearest to the endpoints. surface1,2 are
// not indices into surfacesToTest but refinement surface indices. // not indices into surfacesToTest but refinement surface indices.
// Returns surface, region on surface (so not global surface) // Returns surface, region on surface (so not global surface)

View File

@ -56,6 +56,11 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolationMethodToWord
method = "faceAreaWeightAMI"; method = "faceAreaWeightAMI";
break; break;
} }
case imPartialFaceAreaWeight:
{
method = "partialFaceAreaWeightAMI";
break;
}
default: default:
{ {
FatalErrorIn FatalErrorIn
@ -87,7 +92,15 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::wordTointerpolationMethod
wordList methods wordList methods
( (
IStringStream("(directAMI mapNearestAMI faceAreaWeightAMI)")() IStringStream
(
"("
"directAMI "
"mapNearestAMI "
"faceAreaWeightAMI "
"partialFaceAreaWeightAMI"
")"
)()
); );
if (im == "directAMI") if (im == "directAMI")
@ -102,6 +115,10 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::wordTointerpolationMethod
{ {
method = imFaceAreaWeight; method = imFaceAreaWeight;
} }
else if (im == "partialFaceAreaWeightAMI")
{
method = imPartialFaceAreaWeight;
}
else else
{ {
FatalErrorIn FatalErrorIn
@ -183,6 +200,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
const labelListList& addr, const labelListList& addr,
scalarListList& wght, scalarListList& wght,
scalarField& wghtSum, scalarField& wghtSum,
const bool conformal,
const bool output const bool output
) )
{ {
@ -191,12 +209,19 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
forAll(wght, faceI) forAll(wght, faceI)
{ {
scalarList& w = wght[faceI]; scalarList& w = wght[faceI];
scalar denom = patchAreas[faceI];
scalar s = sum(w); scalar s = sum(w);
scalar t = s/patchAreas[faceI]; scalar t = s/denom;
if (conformal)
{
denom = s;
}
forAll(w, i) forAll(w, i)
{ {
w[i] /= s; w[i] /= denom;
} }
wghtSum[faceI] = t; wghtSum[faceI] = t;
@ -476,6 +501,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::agglomerate
srcAddress, srcAddress,
srcWeights, srcWeights,
srcWeightsSum, srcWeightsSum,
true,
false false
); );
} }
@ -749,7 +775,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points()); tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points());
} }
// Calculate if patches present on multiple processors // Calculate if patches present on multiple processors
singlePatchProc_ = calcDistribution(srcPatch, tgtPatch); singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
@ -794,32 +819,28 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
newTgtPoints newTgtPoints
); );
// calculate AMI interpolation // calculate AMI interpolation
{ autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr
autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr (
AMIMethod<SourcePatch, TargetPatch>::New
( (
AMIMethod<SourcePatch, TargetPatch>::New interpolationMethodToWord(method_),
( srcPatch,
interpolationMethodToWord(method_), newTgtPatch,
srcPatch, srcMagSf_,
newTgtPatch, tgtMagSf_,
srcMagSf_, triMode_,
tgtMagSf_, reverseTarget_
triMode_, )
reverseTarget_ );
)
);
AMIPtr->calculate
(
srcAddress_,
srcWeights_,
tgtAddress_,
tgtWeights_
);
}
AMIPtr->calculate
(
srcAddress_,
srcWeights_,
tgtAddress_,
tgtWeights_
);
// Now // Now
// ~~~ // ~~~
@ -886,6 +907,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
srcAddress_, srcAddress_,
srcWeights_, srcWeights_,
srcWeightsSum_, srcWeightsSum_,
AMIPtr->conformal(),
true true
); );
normaliseWeights normaliseWeights
@ -895,6 +917,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtAddress_, tgtAddress_,
tgtWeights_, tgtWeights_,
tgtWeightsSum_, tgtWeightsSum_,
AMIPtr->conformal(),
true true
); );
@ -903,7 +926,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap)); srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap));
tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap)); tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap));
if (debug) if (debug)
{ {
writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_); writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_);
@ -913,29 +935,27 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
{ {
// calculate AMI interpolation // calculate AMI interpolation
{ autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr
autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr (
AMIMethod<SourcePatch, TargetPatch>::New
( (
AMIMethod<SourcePatch, TargetPatch>::New interpolationMethodToWord(method_),
( srcPatch,
interpolationMethodToWord(method_), tgtPatch,
srcPatch, srcMagSf_,
tgtPatch, tgtMagSf_,
srcMagSf_, triMode_,
tgtMagSf_, reverseTarget_
triMode_, )
reverseTarget_ );
)
);
AMIPtr->calculate AMIPtr->calculate
( (
srcAddress_, srcAddress_,
srcWeights_, srcWeights_,
tgtAddress_, tgtAddress_,
tgtWeights_ tgtWeights_
); );
}
normaliseWeights normaliseWeights
( (
@ -944,6 +964,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
srcAddress_, srcAddress_,
srcWeights_, srcWeights_,
srcWeightsSum_, srcWeightsSum_,
AMIPtr->conformal(),
true true
); );
normaliseWeights normaliseWeights
@ -953,6 +974,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtAddress_, tgtAddress_,
tgtWeights_, tgtWeights_,
tgtWeightsSum_, tgtWeightsSum_,
AMIPtr->conformal(),
true true
); );
} }

View File

@ -88,7 +88,8 @@ public:
{ {
imDirect, imDirect,
imMapNearest, imMapNearest,
imFaceAreaWeight imFaceAreaWeight,
imPartialFaceAreaWeight
}; };
//- Convert interpolationMethod to word representation //- Convert interpolationMethod to word representation
@ -236,6 +237,7 @@ private:
const labelListList& addr, const labelListList& addr,
scalarListList& wght, scalarListList& wght,
scalarField& wghtSum, scalarField& wghtSum,
const bool conformal,
const bool output const bool output
); );

View File

@ -41,24 +41,28 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
} }
const scalar maxBoundsError = 0.05; if (conformal())
// check bounds of source and target
boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true);
boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true);
boundBox bbTgtInf(bbTgt);
bbTgtInf.inflate(maxBoundsError);
if (!bbTgtInf.contains(bbSrc))
{ {
WarningIn("AMIMethod<SourcePatch, TargetPatch>::checkPatches()") const scalar maxBoundsError = 0.05;
<< "Source and target patch bounding boxes are not similar" << nl
<< " source box span : " << bbSrc.span() << nl // check bounds of source and target
<< " target box span : " << bbTgt.span() << nl boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true);
<< " source box : " << bbSrc << nl boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true);
<< " target box : " << bbTgt << nl
<< " inflated target box : " << bbTgtInf << endl; boundBox bbTgtInf(bbTgt);
bbTgtInf.inflate(maxBoundsError);
if (!bbTgtInf.contains(bbSrc))
{
WarningIn("AMIMethod<SourcePatch, TargetPatch>::checkPatches()")
<< "Source and target patch bounding boxes are not similar"
<< nl
<< " source box span : " << bbSrc.span() << nl
<< " target box span : " << bbTgt.span() << nl
<< " source box : " << bbSrc << nl
<< " target box : " << bbTgt << nl
<< " inflated target box : " << bbTgtInf << endl;
}
} }
} }
@ -74,6 +78,8 @@ bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
label& tgtFaceI label& tgtFaceI
) )
{ {
checkPatches();
// set initial sizes for weights and addressing - must be done even if // set initial sizes for weights and addressing - must be done even if
// returns false below // returns false below
srcAddress.setSize(srcPatch_.size()); srcAddress.setSize(srcPatch_.size());
@ -241,17 +247,16 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea); pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea);
if (debug)
{
Pout<< "Source point = " << srcPt << ", Sample point = "
<< sample.hitPoint() << ", Sample index = " << sample.index()
<< endl;
}
if (sample.hit()) if (sample.hit())
{ {
targetFaceI = sample.index(); targetFaceI = sample.index();
if (debug)
{
Pout<< "Source point = " << srcPt << ", Sample point = "
<< sample.hitPoint() << ", Sample index = " << sample.index()
<< endl;
}
} }
return targetFaceI; return targetFaceI;
@ -334,8 +339,6 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::AMIMethod
srcNonOverlap_(), srcNonOverlap_(),
triMode_(triMode) triMode_(triMode)
{ {
checkPatches();
label srcSize = returnReduce(srcPatch_.size(), sumOp<label>()); label srcSize = returnReduce(srcPatch_.size(), sumOp<label>());
label tgtSize = returnReduce(tgtPatch_.size(), sumOp<label>()); label tgtSize = returnReduce(tgtPatch_.size(), sumOp<label>());
@ -352,4 +355,13 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::~AMIMethod()
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
bool Foam::AMIMethod<SourcePatch, TargetPatch>::conformal() const
{
return true;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -207,6 +207,9 @@ public:
// Note: this should be empty for correct functioning // Note: this should be empty for correct functioning
inline const labelList& srcNonOverlap() const; inline const labelList& srcNonOverlap() const;
//- Flag to indicate that interpolation patches are conformal
virtual bool conformal() const;
// Manipulation // Manipulation

View File

@ -25,7 +25,85 @@ License
#include "faceAreaWeightAMI.H" #include "faceAreaWeightAMI.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
(
List<DynamicList<label> >& srcAddr,
List<DynamicList<scalar> >& srcWght,
List<DynamicList<label> >& tgtAddr,
List<DynamicList<scalar> >& tgtWght,
label srcFaceI,
label tgtFaceI
)
{
// construct weights and addressing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
label nFacesRemaining = srcAddr.size();
// list of tgt face neighbour faces
DynamicList<label> nbrFaces(10);
// list of faces currently visited for srcFaceI to avoid multiple hits
DynamicList<label> visitedFaces(10);
// list to keep track of tgt faces used to seed src faces
labelList seedFaces(nFacesRemaining, -1);
seedFaces[srcFaceI] = tgtFaceI;
// list to keep track of whether src face can be mapped
boolList mapFlag(nFacesRemaining, true);
// reset starting seed
label startSeedI = 0;
DynamicList<label> nonOverlapFaces;
do
{
// Do advancing front starting from srcFaceI,tgtFaceI
bool faceProcessed = processSourceFace
(
srcFaceI,
tgtFaceI,
nbrFaces,
visitedFaces,
srcAddr,
srcWght,
tgtAddr,
tgtWght
);
mapFlag[srcFaceI] = false;
nFacesRemaining--;
if (!faceProcessed)
{
nonOverlapFaces.append(srcFaceI);
}
// choose new src face from current src face neighbour
if (nFacesRemaining > 0)
{
setNextFaces
(
startSeedI,
srcFaceI,
tgtFaceI,
mapFlag,
seedFaces,
visitedFaces
);
}
} while (nFacesRemaining > 0);
this->srcNonOverlap_.transfer(nonOverlapFaces);
}
template<class SourcePatch, class TargetPatch> template<class SourcePatch, class TargetPatch>
bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
@ -45,6 +123,11 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
List<DynamicList<scalar> >& tgtWght List<DynamicList<scalar> >& tgtWght
) )
{ {
if (tgtStartFaceI == -1)
{
return false;
}
nbrFaces.clear(); nbrFaces.clear();
visitedFaces.clear(); visitedFaces.clear();
@ -101,11 +184,15 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
label& tgtFaceI, label& tgtFaceI,
const boolList& mapFlag, const boolList& mapFlag,
labelList& seedFaces, labelList& seedFaces,
const DynamicList<label>& visitedFaces const DynamicList<label>& visitedFaces,
bool errorOnNotFound
) const ) const
{ {
const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFaceI]; const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFaceI];
// initialise tgtFaceI
tgtFaceI = -1;
// set possible seeds for later use // set possible seeds for later use
bool valuesSet = false; bool valuesSet = false;
forAll(srcNbrFaces, i) forAll(srcNbrFaces, i)
@ -195,19 +282,23 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
} }
} }
FatalErrorIn if (errorOnNotFound)
( {
"void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::" FatalErrorIn
"setNextFaces" (
"(" "void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::"
"label&, " "setNextFaces"
"label&, " "("
"label&, " "label&, "
"const boolList&, " "label&, "
"labelList&, " "label&, "
"const DynamicList<label>&" "const boolList&, "
") const" "labelList&, "
) << "Unable to set source and target faces" << abort(FatalError); "const DynamicList<label>&, "
"bool"
") const"
) << "Unable to set source and target faces" << abort(FatalError);
}
} }
} }
@ -447,77 +538,21 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
List<DynamicList<label> > tgtAddr(this->tgtPatch_.size()); List<DynamicList<label> > tgtAddr(this->tgtPatch_.size());
List<DynamicList<scalar> > tgtWght(tgtAddr.size()); List<DynamicList<scalar> > tgtWght(tgtAddr.size());
calcAddressing
(
srcAddr,
srcWght,
tgtAddr,
tgtWght,
srcFaceI,
tgtFaceI
);
// construct weights and addressing if (this->srcNonOverlap_.size() != 0)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
label nFacesRemaining = srcAddr.size();
// list of tgt face neighbour faces
DynamicList<label> nbrFaces(10);
// list of faces currently visited for srcFaceI to avoid multiple hits
DynamicList<label> visitedFaces(10);
// list to keep track of tgt faces used to seed src faces
labelList seedFaces(nFacesRemaining, -1);
seedFaces[srcFaceI] = tgtFaceI;
// list to keep track of whether src face can be mapped
boolList mapFlag(nFacesRemaining, true);
// reset starting seed
label startSeedI = 0;
DynamicList<label> nonOverlapFaces;
do
{ {
// Do advancing front starting from srcFaceI,tgtFaceI Pout<< " AMI: " << this->srcNonOverlap_.size()
bool faceProcessed = processSourceFace
(
srcFaceI,
tgtFaceI,
nbrFaces,
visitedFaces,
srcAddr,
srcWght,
tgtAddr,
tgtWght
);
mapFlag[srcFaceI] = false;
nFacesRemaining--;
if (!faceProcessed)
{
nonOverlapFaces.append(srcFaceI);
}
// choose new src face from current src face neighbour
if (nFacesRemaining > 0)
{
setNextFaces
(
startSeedI,
srcFaceI,
tgtFaceI,
mapFlag,
seedFaces,
visitedFaces
);
}
} while (nFacesRemaining > 0);
if (nonOverlapFaces.size() != 0)
{
Pout<< " AMI: " << nonOverlapFaces.size()
<< " non-overlap faces identified" << " non-overlap faces identified"
<< endl; << endl;
this->srcNonOverlap_.transfer(nonOverlapFaces);
} }

View File

@ -52,9 +52,9 @@ class faceAreaWeightAMI
public AMIMethod<SourcePatch, TargetPatch> public AMIMethod<SourcePatch, TargetPatch>
{ {
private: protected:
// Private Member Functions // Protected Member Functions
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
faceAreaWeightAMI(const faceAreaWeightAMI&); faceAreaWeightAMI(const faceAreaWeightAMI&);
@ -64,8 +64,19 @@ private:
// Marching front // Marching front
//- Calculate addressing and weights using temporary storage
virtual void calcAddressing
(
List<DynamicList<label> >& srcAddress,
List<DynamicList<scalar> >& srcWeights,
List<DynamicList<label> >& tgtAddress,
List<DynamicList<scalar> >& tgtWeights,
label srcFaceI,
label tgtFaceI
);
//- Determine overlap contributions for source face srcFaceI //- Determine overlap contributions for source face srcFaceI
bool processSourceFace virtual bool processSourceFace
( (
const label srcFaceI, const label srcFaceI,
const label tgtStartFaceI, const label tgtStartFaceI,
@ -78,7 +89,7 @@ private:
); );
//- Attempt to re-evaluate source faces that have not been included //- Attempt to re-evaluate source faces that have not been included
void restartUncoveredSourceFace virtual void restartUncoveredSourceFace
( (
List<DynamicList<label> >& srcAddr, List<DynamicList<label> >& srcAddr,
List<DynamicList<scalar> >& srcWght, List<DynamicList<scalar> >& srcWght,
@ -87,21 +98,22 @@ private:
); );
//- Set the source and target seed faces //- Set the source and target seed faces
void setNextFaces virtual void setNextFaces
( (
label& startSeedI, label& startSeedI,
label& srcFaceI, label& srcFaceI,
label& tgtFaceI, label& tgtFaceI,
const boolList& mapFlag, const boolList& mapFlag,
labelList& seedFaces, labelList& seedFaces,
const DynamicList<label>& visitedFaces const DynamicList<label>& visitedFaces,
bool errorOnNotFound = true
) const; ) const;
// Evaluation // Evaluation
//- Area of intersection between source and target faces //- Area of intersection between source and target faces
scalar interArea virtual scalar interArea
( (
const label srcFaceI, const label srcFaceI,
const label tgtFaceI const label tgtFaceI

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "partialFaceAreaWeightAMI.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
(
label& startSeedI,
label& srcFaceI,
label& tgtFaceI,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
const bool errorOnNotFound
) const
{
faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
(
startSeedI,
srcFaceI,
tgtFaceI,
mapFlag,
seedFaces,
visitedFaces,
false // no error on not found
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::
partialFaceAreaWeightAMI
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget
)
:
faceAreaWeightAMI<SourcePatch, TargetPatch>
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::
~partialFaceAreaWeightAMI()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::conformal() const
{
return false;
}
template<class SourcePatch, class TargetPatch>
void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFaceI,
label tgtFaceI
)
{
bool ok =
this->initialise
(
srcAddress,
srcWeights,
tgtAddress,
tgtWeights,
srcFaceI,
tgtFaceI
);
if (!ok)
{
return;
}
// temporary storage for addressing and weights
List<DynamicList<label> > srcAddr(this->srcPatch_.size());
List<DynamicList<scalar> > srcWght(srcAddr.size());
List<DynamicList<label> > tgtAddr(this->tgtPatch_.size());
List<DynamicList<scalar> > tgtWght(tgtAddr.size());
faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
(
srcAddr,
srcWght,
tgtAddr,
tgtWght,
srcFaceI,
tgtFaceI
);
// transfer data to persistent storage
forAll(srcAddr, i)
{
srcAddress[i].transfer(srcAddr[i]);
srcWeights[i].transfer(srcWght[i]);
}
forAll(tgtAddr, i)
{
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i].transfer(tgtWght[i]);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::partialFaceAreaWeightAMI
Description
Partial face area weighted Arbitrary Mesh Interface (AMI) method
SourceFiles
partialFaceAreaWeightAMI.C
\*---------------------------------------------------------------------------*/
#ifndef partialFaceAreaWeightAMI_H
#define partialFaceAreaWeightAMI_H
#include "faceAreaWeightAMI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class partialFaceAreaWeightAMI Declaration
\*---------------------------------------------------------------------------*/
template<class SourcePatch, class TargetPatch>
class partialFaceAreaWeightAMI
:
public faceAreaWeightAMI<SourcePatch, TargetPatch>
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
partialFaceAreaWeightAMI(const partialFaceAreaWeightAMI&);
//- Disallow default bitwise assignment
void operator=(const partialFaceAreaWeightAMI&);
// Marching front
//- Set the source and target seed faces
virtual void setNextFaces
(
label& startSeedI,
label& srcFaceI,
label& tgtFaceI,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
bool errorOnNotFound = true
) const;
public:
//- Runtime type information
TypeName("partialFaceAreaWeightAMI");
// Constructors
//- Construct from components
partialFaceAreaWeightAMI
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget = false
);
//- Destructor
virtual ~partialFaceAreaWeightAMI();
// Member Functions
// Access
//- Flag to indicate that interpolation patches are conformal
virtual bool conformal() const;
// Manipulation
//- Update addressing and weights
virtual void calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFaceI = -1,
label tgtFaceI = -1
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "partialFaceAreaWeightAMI.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -28,6 +28,7 @@ License
#include "directAMI.H" #include "directAMI.H"
#include "mapNearestAMI.H" #include "mapNearestAMI.H"
#include "faceAreaWeightAMI.H" #include "faceAreaWeightAMI.H"
#include "partialFaceAreaWeightAMI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -38,6 +39,7 @@ namespace Foam
makeAMIMethodType(AMIPatchToPatchInterpolation, directAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, directAMI);
makeAMIMethodType(AMIPatchToPatchInterpolation, mapNearestAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, mapNearestAMI);
makeAMIMethodType(AMIPatchToPatchInterpolation, faceAreaWeightAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, faceAreaWeightAMI);
makeAMIMethodType(AMIPatchToPatchInterpolation, partialFaceAreaWeightAMI);
} }

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIGAMGInterfaceField.H"
#include "addToRunTimeSelectionTable.H"
#include "lduMatrix.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIGAMGInterfaceField, 0);
addToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicACMIGAMGInterfaceField,
lduInterface
);
addToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicACMIGAMGInterfaceField,
lduInterfaceField
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterface
)
:
GAMGInterfaceField(GAMGCp, fineInterface),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(false),
rank_(0)
{
const cyclicAMILduInterfaceField& p =
refCast<const cyclicAMILduInterfaceField>(fineInterface);
doTransform_ = p.doTransform();
rank_ = p.rank();
}
Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const bool doTransform,
const int rank
)
:
GAMGInterfaceField(GAMGCp, doTransform, rank),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(doTransform),
rank_(rank)
{}
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterfaceField::~cyclicACMIGAMGInterfaceField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
// Get neighbouring field
scalarField pnf
(
cyclicACMIInterface_.neighbPatch().interfaceInternalField(psiInternal)
);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
if (cyclicACMIInterface_.owner())
{
pnf = cyclicACMIInterface_.AMI().interpolateToSource(pnf);
}
else
{
pnf = cyclicACMIInterface_.neighbPatch().AMI().interpolateToTarget(pnf);
}
const labelUList& faceCells = cyclicACMIInterface_.faceCells();
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
// ************************************************************************* //

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIGAMGInterfaceField
Description
GAMG agglomerated cyclic interface for Arbitrarily Coupled Mesh Interface
(ACMI) fields.
SourceFiles
cyclicACMIGAMGInterfaceField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIGAMGInterfaceField_H
#define cyclicACMIGAMGInterfaceField_H
#include "GAMGInterfaceField.H"
#include "cyclicACMIGAMGInterface.H"
#include "cyclicACMILduInterfaceField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIGAMGInterfaceField Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIGAMGInterfaceField
:
public GAMGInterfaceField,
virtual public cyclicACMILduInterfaceField
{
// Private data
//- Local reference cast into the cyclic interface
const cyclicACMIGAMGInterface& cyclicACMIInterface_;
//- Is the transform required
bool doTransform_;
//- Rank of component for transformation
int rank_;
// Private Member Functions
//- Disallow default bitwise copy construct
cyclicACMIGAMGInterfaceField(const cyclicACMIGAMGInterfaceField&);
//- Disallow default bitwise assignment
void operator=(const cyclicACMIGAMGInterfaceField&);
public:
//- Runtime type information
TypeName("cyclicACMI");
// Constructors
//- Construct from GAMG interface and fine level interface field
cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterfaceField
);
//- Construct from GAMG interface and fine level interface field
cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const bool doTransform,
const int rank
);
//- Destructor
virtual ~cyclicACMIGAMGInterfaceField();
// Member Functions
// Access
//- Return size
label size() const
{
return cyclicACMIInterface_.size();
}
// Interface matrix update
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Cyclic interface functions
//- Does the interface field perform the transfromation
virtual bool doTransform() const
{
return doTransform_;
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return cyclicACMIInterface_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return cyclicACMIInterface_.reverseT();
}
//- Return rank of component for transform
virtual int rank() const
{
return rank_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,198 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "AMIInterpolation.H"
#include "cyclicACMIGAMGInterface.H"
#include "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIGAMGInterface, 0);
addToRunTimeSelectionTable
(
GAMGInterface,
cyclicACMIGAMGInterface,
lduInterface
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterface::cyclicACMIGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing,
const label fineLevelIndex,
const label coarseComm
)
:
GAMGInterface
(
index,
coarseInterfaces
),
fineCyclicACMIInterface_
(
refCast<const cyclicACMILduInterface>(fineInterface)
)
{
// Construct face agglomeration from cell agglomeration
{
// From coarse face to cell
DynamicList<label> dynFaceCells(localRestrictAddressing.size());
// From face to coarse face
DynamicList<label> dynFaceRestrictAddressing
(
localRestrictAddressing.size()
);
Map<label> masterToCoarseFace(localRestrictAddressing.size());
forAll(localRestrictAddressing, ffi)
{
label curMaster = localRestrictAddressing[ffi];
Map<label>::const_iterator fnd = masterToCoarseFace.find
(
curMaster
);
if (fnd == masterToCoarseFace.end())
{
// New coarse face
label coarseI = dynFaceCells.size();
dynFaceRestrictAddressing.append(coarseI);
dynFaceCells.append(curMaster);
masterToCoarseFace.insert(curMaster, coarseI);
}
else
{
// Already have coarse face
dynFaceRestrictAddressing.append(fnd());
}
}
faceCells_.transfer(dynFaceCells);
faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
}
// On the owner side construct the AMI
if (fineCyclicACMIInterface_.owner())
{
// Construct the neighbour side agglomeration (as the neighbour would
// do it so it the exact loop above using neighbourRestrictAddressing
// instead of localRestrictAddressing)
labelList nbrFaceRestrictAddressing;
{
// From face to coarse face
DynamicList<label> dynNbrFaceRestrictAddressing
(
neighbourRestrictAddressing.size()
);
Map<label> masterToCoarseFace(neighbourRestrictAddressing.size());
forAll(neighbourRestrictAddressing, ffi)
{
label curMaster = neighbourRestrictAddressing[ffi];
Map<label>::const_iterator fnd = masterToCoarseFace.find
(
curMaster
);
if (fnd == masterToCoarseFace.end())
{
// New coarse face
label coarseI = masterToCoarseFace.size();
dynNbrFaceRestrictAddressing.append(coarseI);
masterToCoarseFace.insert(curMaster, coarseI);
}
else
{
// Already have coarse face
dynNbrFaceRestrictAddressing.append(fnd());
}
}
nbrFaceRestrictAddressing.transfer(dynNbrFaceRestrictAddressing);
}
amiPtr_.reset
(
new AMIPatchToPatchInterpolation
(
fineCyclicACMIInterface_.AMI(),
faceRestrictAddressing_,
nbrFaceRestrictAddressing
)
);
}
}
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterface::~cyclicACMIGAMGInterface()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::labelField>
Foam::cyclicACMIGAMGInterface::internalFieldTransfer
(
const Pstream::commsTypes,
const labelUList& iF
) const
{
const cyclicACMIGAMGInterface& nbr =
dynamic_cast<const cyclicACMIGAMGInterface&>(neighbPatch());
const labelUList& nbrFaceCells = nbr.faceCells();
tmp<labelField> tpnf(new labelField(nbrFaceCells.size()));
labelField& pnf = tpnf();
forAll(pnf, facei)
{
pnf[facei] = iF[nbrFaceCells[facei]];
}
return tpnf;
}
// ************************************************************************* //

View File

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIGAMGInterface
Description
GAMG agglomerated cyclic ACMI interface.
SourceFiles
cyclicACMIGAMGInterface.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIGAMGInterface_H
#define cyclicACMIGAMGInterface_H
#include "GAMGInterface.H"
#include "cyclicACMILduInterface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIGAMGInterface Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIGAMGInterface
:
public GAMGInterface,
virtual public cyclicACMILduInterface
{
// Private data
//- Reference for the cyclicLduInterface from which this is
// agglomerated
const cyclicACMILduInterface& fineCyclicACMIInterface_;
//- AMI interface
autoPtr<AMIPatchToPatchInterpolation> amiPtr_;
// Private Member Functions
//- Disallow default bitwise copy construct
cyclicACMIGAMGInterface(const cyclicACMIGAMGInterface&);
//- Disallow default bitwise assignment
void operator=(const cyclicACMIGAMGInterface&);
public:
//- Runtime type information
TypeName("cyclicACMI");
// Constructors
//- Construct from fine level interface,
// local and neighbour restrict addressing
cyclicACMIGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing,
const label fineLevelIndex,
const label coarseComm
);
//- Destructor
virtual ~cyclicACMIGAMGInterface();
// Member Functions
// Interface transfer functions
//- Transfer and return internal field adjacent to the interface
virtual tmp<labelField> internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& iF
) const;
//- Cyclic interface functions
//- Return neigbour processor number
virtual label neighbPatchID() const
{
return fineCyclicACMIInterface_.neighbPatchID();
}
virtual bool owner() const
{
return fineCyclicACMIInterface_.owner();
}
virtual const cyclicACMIGAMGInterface& neighbPatch() const
{
return dynamic_cast<const cyclicACMIGAMGInterface&>
(
coarseInterfaces_[neighbPatchID()]
);
}
virtual const AMIPatchToPatchInterpolation& AMI() const
{
return amiPtr_();
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return fineCyclicACMIInterface_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return fineCyclicACMIInterface_.reverseT();
}
// I/O
//- Write to stream
virtual void write(Ostream&) const
{
//TBD. How to serialise the AMI such that we can stream
// cyclicACMIGAMGInterface.
notImplemented
(
"cyclicACMIGAMGInterface::write(Ostream&) const"
);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMILduInterface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMILduInterface, 0);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicACMILduInterface::~cyclicACMILduInterface()
{}
// ************************************************************************* //

View File

@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMILduInterface
Description
An abstract base class for cyclic ACMI coupled interfaces
SourceFiles
cyclicACMILduInterface.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMILduInterface_H
#define cyclicACMILduInterface_H
#include "cyclicAMILduInterface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMILduInterface Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMILduInterface
:
public cyclicAMILduInterface
{
public:
//- Runtime type information
TypeName("cyclicACMILduInterface");
// Constructors
//- Construct null
cyclicACMILduInterface()
{}
//- Destructor
virtual ~cyclicACMILduInterface();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMILduInterfaceField.H"
#include "diagTensorField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMILduInterfaceField, 0);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicACMILduInterfaceField::~cyclicACMILduInterfaceField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::cyclicACMILduInterfaceField::transformCoupleField
(
scalarField& f,
const direction cmpt
) const
{
cyclicAMILduInterfaceField::transformCoupleField(f, cmpt);
}
// ************************************************************************* //

View File

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMILduInterfaceField
Description
Abstract base class for cyclic ACMI coupled interfaces
SourceFiles
cyclicACMILduInterfaceField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMILduInterfaceField_H
#define cyclicACMILduInterfaceField_H
#include "cyclicAMILduInterfaceField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMILduInterfaceField Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMILduInterfaceField
:
public cyclicAMILduInterfaceField
{
public:
//- Runtime type information
TypeName("cyclicACMILduInterfaceField");
// Constructors
//- Construct null
cyclicACMILduInterfaceField()
{}
//- Destructor
virtual ~cyclicACMILduInterfaceField();
// Member Functions
//- Transform given patch field
template<class Type>
void transformCoupleField(Field<Type>& f) const;
//- Transform given patch internal field
void transformCoupleField
(
scalarField& psiInternal,
const direction cmpt
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "tensorField.H"
template<class Type>
void Foam::cyclicACMILduInterfaceField::transformCoupleField
(
Field<Type>& f
) const
{
cyclicAMILduInterfaceField::transformCoupleField(f);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIPointPatch.H"
#include "pointBoundaryMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIPointPatch, 0);
addToRunTimeSelectionTable
(
facePointPatch,
cyclicACMIPointPatch,
polyPatch
);
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
void Foam::cyclicACMIPointPatch::initGeometry(PstreamBuffers&)
{}
void Foam::cyclicACMIPointPatch::calcGeometry(PstreamBuffers&)
{}
void Foam::cyclicACMIPointPatch::initMovePoints
(
PstreamBuffers&,
const pointField&
)
{}
void Foam::cyclicACMIPointPatch::movePoints(PstreamBuffers&, const pointField&)
{}
void Foam::cyclicACMIPointPatch::initUpdateMesh(PstreamBuffers& pBufs)
{
facePointPatch::initUpdateMesh(pBufs);
// cyclicACMIPointPatch::initGeometry(pBufs);
}
void Foam::cyclicACMIPointPatch::updateMesh(PstreamBuffers& pBufs)
{
facePointPatch::updateMesh(pBufs);
// cyclicACMIPointPatch::calcGeometry(pBufs);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cyclicACMIPointPatch::cyclicACMIPointPatch
(
const polyPatch& patch,
const pointBoundaryMesh& bm
)
:
coupledFacePointPatch(patch, bm),
cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicACMIPointPatch::~cyclicACMIPointPatch()
{}
// ************************************************************************* //

View File

@ -0,0 +1,170 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIPointPatch
Description
Cyclic AMI point patch - place holder only
SourceFiles
cyclicACMIPointPatch.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIPointPatch_H
#define cyclicACMIPointPatch_H
#include "coupledFacePointPatch.H"
#include "cyclicACMIPolyPatch.H"
#include "pointBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIPointPatch Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIPointPatch
:
public coupledFacePointPatch
{
// Private data
//- Local reference cast into the cyclic AMI patch
const cyclicACMIPolyPatch& cyclicACMIPolyPatch_;
// Private Member Functions
//- Disallow default construct as copy
cyclicACMIPointPatch(const cyclicACMIPointPatch&);
//- Disallow default assignment
void operator=(const cyclicACMIPointPatch&);
protected:
// Protected Member Functions
//- Initialise the calculation of the patch geometry
virtual void initGeometry(PstreamBuffers&);
//- Calculate the patch geometry
virtual void calcGeometry(PstreamBuffers&);
//- Initialise the patches for moving points
virtual void initMovePoints(PstreamBuffers&, const pointField&);
//- Correct patches after moving points
virtual void movePoints(PstreamBuffers&, const pointField&);
//- Initialise the update of the patch topology
virtual void initUpdateMesh(PstreamBuffers&);
//- Update of the patch topology
virtual void updateMesh(PstreamBuffers&);
public:
//- Runtime type information
TypeName(cyclicACMIPolyPatch::typeName_());
// Constructors
//- Construct from components
cyclicACMIPointPatch
(
const polyPatch& patch,
const pointBoundaryMesh& bm
);
//- Destructor
virtual ~cyclicACMIPointPatch();
// Member Functions
//- Is patch 'coupled'. Note that on AMI the geometry is not
// coupled but the fields are!
virtual bool coupled() const
{
return false;
}
//- Return the constraint type this pointPatch implements.
virtual const word& constraintType() const
{
return type();
}
//- Return the underlying cyclicAMIPolyPatch
const cyclicACMIPolyPatch& cyclicACMIPatch() const
{
return cyclicACMIPolyPatch_;
}
//- Return neighbour point patch
const cyclicACMIPointPatch& neighbPatch() const
{
label patchI = cyclicACMIPolyPatch_.neighbPatchID();
const pointPatch& pp = this->boundaryMesh()[patchI];
return refCast<const cyclicACMIPointPatch>(pp);
}
//- Are the cyclic planes parallel
bool parallel() const
{
return cyclicACMIPolyPatch_.parallel();
}
//- Return face transformation tensor
const tensorField& forwardT() const
{
return cyclicACMIPolyPatch_.forwardT();
}
//- Return neighbour-cell transformation tensor
const tensorField& reverseT() const
{
return cyclicACMIPolyPatch_.reverseT();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,210 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIPointPatchField.H"
#include "Swap.H"
#include "transformField.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField
(
const pointPatch& p,
const DimensionedField<Type, pointMesh>& iF
)
:
coupledPointPatchField<Type>(p, iF),
cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)),
ppiPtr_(NULL),
nbrPpiPtr_(NULL)
{}
template<class Type>
Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField
(
const pointPatch& p,
const DimensionedField<Type, pointMesh>& iF,
const dictionary& dict
)
:
coupledPointPatchField<Type>(p, iF, dict),
cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)),
ppiPtr_(NULL),
nbrPpiPtr_(NULL)
{
if (!isType<cyclicACMIPointPatch>(p))
{
FatalIOErrorIn
(
"cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField\n"
"(\n"
" const pointPatch&,\n"
" const DimensionedField<Type, pointMesh>&,\n"
" const dictionary&\n"
")\n",
dict
) << "patch " << this->patch().index() << " not cyclicACMI type. "
<< "Patch type = " << p.type()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField
(
const cyclicACMIPointPatchField<Type>& ptf,
const pointPatch& p,
const DimensionedField<Type, pointMesh>& iF,
const pointPatchFieldMapper& mapper
)
:
coupledPointPatchField<Type>(ptf, p, iF, mapper),
cyclicACMIPatch_(refCast<const cyclicACMIPointPatch>(p)),
ppiPtr_(NULL),
nbrPpiPtr_(NULL)
{
if (!isType<cyclicACMIPointPatch>(this->patch()))
{
FatalErrorIn
(
"cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField\n"
"(\n"
" const cyclicACMIPointPatchField<Type>&,\n"
" const pointPatch&,\n"
" const DimensionedField<Type, pointMesh>&,\n"
" const pointPatchFieldMapper&\n"
")\n"
) << "Field type does not correspond to patch type for patch "
<< this->patch().index() << "." << endl
<< "Field type: " << typeName << endl
<< "Patch type: " << this->patch().type()
<< exit(FatalError);
}
}
template<class Type>
Foam::cyclicACMIPointPatchField<Type>::cyclicACMIPointPatchField
(
const cyclicACMIPointPatchField<Type>& ptf,
const DimensionedField<Type, pointMesh>& iF
)
:
coupledPointPatchField<Type>(ptf, iF),
cyclicACMIPatch_(ptf.cyclicACMIPatch_),
ppiPtr_(NULL),
nbrPpiPtr_(NULL)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::cyclicACMIPointPatchField<Type>::swapAddSeparated
(
const Pstream::commsTypes,
Field<Type>& pField
) const
{
if (cyclicACMIPatch_.cyclicACMIPatch().owner())
{
// We inplace modify pField. To prevent the other side (which gets
// evaluated at a later date) using already changed values we do
// all swaps on the side that gets evaluated first.
// Get neighbouring pointPatch
const cyclicACMIPointPatch& nbrPatch = cyclicACMIPatch_.neighbPatch();
// Get neighbouring pointPatchField
const GeometricField<Type, pointPatchField, pointMesh>& fld =
refCast<const GeometricField<Type, pointPatchField, pointMesh> >
(
this->dimensionedInternalField()
);
const cyclicACMIPointPatchField<Type>& nbr =
refCast<const cyclicACMIPointPatchField<Type> >
(
fld.boundaryField()[nbrPatch.index()]
);
Field<Type> ptFld(this->patchInternalField(pField));
Field<Type> nbrPtFld(nbr.patchInternalField(pField));
if (doTransform())
{
const tensor& forwardT = this->forwardT()[0];
const tensor& reverseT = this->reverseT()[0];
transform(ptFld, reverseT, ptFld);
transform(nbrPtFld, forwardT, nbrPtFld);
}
// convert point field to face field, AMI interpolate, then
// face back to point
{
// add neighbour side contribution to owner
Field<Type> nbrFcFld(nbrPpi().pointToFaceInterpolate(nbrPtFld));
const cyclicAMIPolyPatch& cami = cyclicACMIPatch_.cyclicACMIPatch();
// interpolate to owner
nbrFcFld = cami.interpolate(nbrFcFld);
// add to internal field
this->addToInternalField
(
pField,
ppi().faceToPointInterpolate(nbrFcFld)()
);
}
{
// add owner side contribution to neighbour
Field<Type> fcFld(ppi().pointToFaceInterpolate(ptFld));
const cyclicAMIPolyPatch& cami = cyclicACMIPatch_.cyclicACMIPatch();
// interpolate to neighbour
fcFld = cami.neighbPatch().cyclicAMIPolyPatch::interpolate(fcFld);
// add to internal field
nbr.addToInternalField
(
pField,
nbrPpi().faceToPointInterpolate(fcFld)()
);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,241 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIPointPatchField
Description
Cyclic ACMI front and back plane patch field
SourceFiles
cyclicACMIPointPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIPointPatchField_H
#define cyclicACMIPointPatchField_H
#include "coupledPointPatchField.H"
#include "cyclicACMIPointPatch.H"
#include "PrimitivePatchInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIPointPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class cyclicACMIPointPatchField
:
public coupledPointPatchField<Type>
{
// Private data
//- Local reference cast into the cyclicACMI patch
const cyclicACMIPointPatch& cyclicACMIPatch_;
//- Owner side patch interpolation pointer
mutable autoPtr<PrimitivePatchInterpolation<primitivePatch> > ppiPtr_;
//- Neighbour side patch interpolation pointer
mutable autoPtr<PrimitivePatchInterpolation<primitivePatch> >
nbrPpiPtr_;
// Private Member Functions
//- Owner side patch interpolation
const PrimitivePatchInterpolation<primitivePatch>& ppi() const
{
if (!ppiPtr_.valid())
{
ppiPtr_.reset
(
new PrimitivePatchInterpolation<primitivePatch>
(
cyclicACMIPatch_.cyclicACMIPatch()
)
);
}
return ppiPtr_();
}
//- Neighbour side patch interpolation
const PrimitivePatchInterpolation<primitivePatch>& nbrPpi() const
{
if (!nbrPpiPtr_.valid())
{
nbrPpiPtr_.reset
(
new PrimitivePatchInterpolation<primitivePatch>
(
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch()
)
);
}
return nbrPpiPtr_();
}
public:
//- Runtime type information
TypeName(cyclicACMIPointPatch::typeName_());
// Constructors
//- Construct from patch and internal field
cyclicACMIPointPatchField
(
const pointPatch&,
const DimensionedField<Type, pointMesh>&
);
//- Construct from patch, internal field and dictionary
cyclicACMIPointPatchField
(
const pointPatch&,
const DimensionedField<Type, pointMesh>&,
const dictionary&
);
//- Construct by mapping given patchField<Type> onto a new patch
cyclicACMIPointPatchField
(
const cyclicACMIPointPatchField<Type>&,
const pointPatch&,
const DimensionedField<Type, pointMesh>&,
const pointPatchFieldMapper&
);
//- Construct and return a clone
virtual autoPtr<pointPatchField<Type> > clone() const
{
return autoPtr<pointPatchField<Type> >
(
new cyclicACMIPointPatchField<Type>
(
*this
)
);
}
//- Construct as copy setting internal field reference
cyclicACMIPointPatchField
(
const cyclicACMIPointPatchField<Type>&,
const DimensionedField<Type, pointMesh>&
);
//- Construct and return a clone setting internal field reference
virtual autoPtr<pointPatchField<Type> > clone
(
const DimensionedField<Type, pointMesh>& iF
) const
{
return autoPtr<pointPatchField<Type> >
(
new cyclicACMIPointPatchField<Type>
(
*this, iF
)
);
}
// Member functions
// Constraint handling
//- Return the constraint type this pointPatchField implements
virtual const word& constraintType() const
{
return cyclicACMIPointPatch::typeName;
}
// Cyclic AMI coupled interface functions
//- Does the patch field perform the transfromation
virtual bool doTransform() const
{
return
!(
cyclicACMIPatch_.parallel()
|| pTraits<Type>::rank == 0
);
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return cyclicACMIPatch_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return cyclicACMIPatch_.reverseT();
}
// Evaluation functions
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
)
{}
//- Complete swap of patch point values and add to local values
virtual void swapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>&
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "cyclicACMIPointPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIPointPatchFields.H"
#include "pointPatchFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePointPatchFields(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 cyclicACMIPointPatchFields_H
#define cyclicACMIPointPatchFields_H
#include "cyclicACMIPointPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePointPatchFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,441 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIPolyPatch.H"
#include "transformField.H"
#include "SubField.H"
#include "polyMesh.H"
#include "Time.H"
#include "faceAreaIntersect.H"
#include "ops.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIPolyPatch, 0);
addToRunTimeSelectionTable(polyPatch, cyclicACMIPolyPatch, word);
addToRunTimeSelectionTable(polyPatch, cyclicACMIPolyPatch, dictionary);
}
const Foam::scalar Foam::cyclicACMIPolyPatch::tolerance_ = 1e-6;
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::cyclicACMIPolyPatch::initPatchFaceAreas() const
{
if (!empty() && faceAreas0_.empty())
{
faceAreas0_ = faceAreas();
}
const cyclicACMIPolyPatch& nbrACMI =
refCast<const cyclicACMIPolyPatch>(this->neighbPatch());
if (!nbrACMI.empty() && nbrACMI.faceAreas0().empty())
{
nbrACMI.initPatchFaceAreas();
}
}
void Foam::cyclicACMIPolyPatch::resetAMI
(
const AMIPatchToPatchInterpolation::interpolationMethod&
) const
{
if (owner())
{
const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
initPatchFaceAreas();
// reset patch face areas based on original patch for AMI calculation
vectorField::subField Sf = faceAreas();
vectorField::subField noSf = nonOverlapPatch.faceAreas();
forAll(Sf, faceI)
{
Sf[faceI] = faceAreas0_[faceI];
noSf[faceI] = faceAreas0_[faceI];
}
// calculate the AMI using partial face-area-weighted
cyclicAMIPolyPatch::resetAMI
(
AMIPatchToPatchInterpolation::imPartialFaceAreaWeight
);
const scalarField& srcWeightSum = AMI().srcWeightsSum();
// set patch face areas based on sum of AMI weights per face
forAll(Sf, faceI)
{
scalar w = srcWeightSum[faceI];
w = min(1.0 - tolerance_, max(tolerance_, w));
Sf[faceI] *= w;
noSf[faceI] *= 1.0 - w;
}
setNeighbourFaceAreas();
// set the updated flag
updated_ = true;
}
}
void Foam::cyclicACMIPolyPatch::setNeighbourFaceAreas() const
{
const cyclicACMIPolyPatch& cp =
refCast<const cyclicACMIPolyPatch>(this->neighbPatch());
const polyPatch& pp = cp.nonOverlapPatch();
const scalarField& tgtWeightSum = AMI().tgtWeightsSum();
const vectorField& faceAreas0 = cp.faceAreas0();
vectorField::subField Sf = cp.faceAreas();
vectorField::subField noSf = pp.faceAreas();
forAll(Sf, faceI)
{
scalar w = tgtWeightSum[faceI];
w = min(1.0 - tolerance_, max(tolerance_, w));
Sf[faceI] = w*faceAreas0[faceI];
noSf[faceI] = (1.0 - w)*faceAreas0[faceI];
}
}
void Foam::cyclicACMIPolyPatch::initGeometry(PstreamBuffers& pBufs)
{
cyclicAMIPolyPatch::initGeometry(pBufs);
}
void Foam::cyclicACMIPolyPatch::calcGeometry(PstreamBuffers& pBufs)
{
cyclicAMIPolyPatch::calcGeometry(pBufs);
}
void Foam::cyclicACMIPolyPatch::initMovePoints
(
PstreamBuffers& pBufs,
const pointField& p
)
{
cyclicAMIPolyPatch::initMovePoints(pBufs, p);
}
void Foam::cyclicACMIPolyPatch::movePoints
(
PstreamBuffers& pBufs,
const pointField& p
)
{
cyclicAMIPolyPatch::movePoints(pBufs, p);
}
void Foam::cyclicACMIPolyPatch::initUpdateMesh(PstreamBuffers& pBufs)
{
cyclicAMIPolyPatch::initUpdateMesh(pBufs);
}
void Foam::cyclicACMIPolyPatch::updateMesh(PstreamBuffers& pBufs)
{
cyclicAMIPolyPatch::updateMesh(pBufs);
}
void Foam::cyclicACMIPolyPatch::clearGeom()
{
cyclicAMIPolyPatch::clearGeom();
}
// * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const word& patchType,
const transformType transform
)
:
cyclicAMIPolyPatch(name, size, start, index, bm, patchType, transform),
faceAreas0_(),
nonOverlapPatchName_(word::null),
nonOverlapPatchID_(-1),
updated_(false)
{
// Non-overlapping patch might not be valid yet so cannot determine
// associated patchID
}
Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh& bm,
const word& patchType
)
:
cyclicAMIPolyPatch(name, dict, index, bm, patchType),
faceAreas0_(),
nonOverlapPatchName_(dict.lookup("nonOverlapPatch")),
nonOverlapPatchID_(-1),
updated_(false)
{
if (nonOverlapPatchName_ == name)
{
FatalIOErrorIn
(
"cyclicACMIPolyPatch::cyclicACMIPolyPatch"
"("
"const word&, "
"const dictionary&, "
"const label, "
"const polyBoundaryMesh&, "
"const word&"
")",
dict
) << "Non-overlapping patch name " << nonOverlapPatchName_
<< " cannot be the same as this patch " << name
<< exit(FatalIOError);
}
// Non-overlapping patch might not be valid yet so cannot determine
// associated patchID
}
Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
(
const cyclicACMIPolyPatch& pp,
const polyBoundaryMesh& bm
)
:
cyclicAMIPolyPatch(pp, bm),
faceAreas0_(),
nonOverlapPatchName_(pp.nonOverlapPatchName_),
nonOverlapPatchID_(-1),
updated_(false)
{
// Non-overlapping patch might not be valid yet so cannot determine
// associated patchID
}
Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
(
const cyclicACMIPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart,
const word& nbrPatchName,
const word& nonOverlapPatchName
)
:
cyclicAMIPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName),
faceAreas0_(),
nonOverlapPatchName_(nonOverlapPatchName),
nonOverlapPatchID_(-1),
updated_(false)
{
if (nonOverlapPatchName_ == name())
{
FatalErrorIn
(
"const cyclicACMIPolyPatch& "
"const polyBoundaryMesh&, "
"const label, "
"const label, "
"const label, "
"const word&, "
"const word&"
) << "Non-overlapping patch name " << nonOverlapPatchName_
<< " cannot be the same as this patch " << name()
<< exit(FatalError);
}
// Non-overlapping patch might not be valid yet so cannot determine
// associated patchID
}
Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
(
const cyclicACMIPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const labelUList& mapAddressing,
const label newStart
)
:
cyclicAMIPolyPatch(pp, bm, index, mapAddressing, newStart),
faceAreas0_(),
nonOverlapPatchName_(pp.nonOverlapPatchName_),
nonOverlapPatchID_(-1),
updated_(false)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicACMIPolyPatch::~cyclicACMIPolyPatch()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::cyclicACMIPolyPatch::nonOverlapPatchID() const
{
if (nonOverlapPatchID_ == -1)
{
nonOverlapPatchID_ =
this->boundaryMesh().findPatchID(nonOverlapPatchName_);
if (nonOverlapPatchID_ == -1)
{
FatalErrorIn("cyclicPolyAMIPatch::neighbPatchID() const")
<< "Illegal non-overlapping patch name " << nonOverlapPatchName_
<< nl << "Valid patch names are "
<< this->boundaryMesh().names()
<< exit(FatalError);
}
const polyPatch& noPp = this->boundaryMesh()[nonOverlapPatchID_];
bool ok = true;
if (size() == noPp.size())
{
const scalarField magSf(mag(faceAreas()));
const scalarField noMagSf(mag(noPp.faceAreas()));
forAll(magSf, faceI)
{
scalar ratio = mag(magSf[faceI]/(noMagSf[faceI] + ROOTVSMALL));
if (ratio - 1 > tolerance_)
{
ok = false;
break;
}
}
}
else
{
ok = false;
}
if (!ok)
{
FatalErrorIn
(
"Foam::label "
"Foam::cyclicACMIPolyPatch::nonOverlapPatchID() const"
) << "Inconsistent ACMI patches " << name() << " and "
<< noPp.name() << ". Patches should have identical topology"
<< exit(FatalError);
}
}
return nonOverlapPatchID_;
}
void Foam::cyclicACMIPolyPatch::calcGeometry
(
const primitivePatch& referPatch,
const pointField& thisCtrs,
const vectorField& thisAreas,
const pointField& thisCc,
const pointField& nbrCtrs,
const vectorField& nbrAreas,
const pointField& nbrCc
)
{
cyclicAMIPolyPatch::calcGeometry
(
referPatch,
thisCtrs,
thisAreas,
thisCc,
nbrCtrs,
nbrAreas,
nbrCc
);
}
void Foam::cyclicACMIPolyPatch::initOrder
(
PstreamBuffers& pBufs,
const primitivePatch& pp
) const
{
cyclicAMIPolyPatch::initOrder(pBufs, pp);
}
bool Foam::cyclicACMIPolyPatch::order
(
PstreamBuffers& pBufs,
const primitivePatch& pp,
labelList& faceMap,
labelList& rotation
) const
{
return cyclicAMIPolyPatch::order(pBufs, pp, faceMap, rotation);
}
void Foam::cyclicACMIPolyPatch::write(Ostream& os) const
{
cyclicAMIPolyPatch::write(os);
os.writeKeyword("nonOverlapPatch") << nonOverlapPatchName_
<< token::END_STATEMENT << nl;
}
// ************************************************************************* //

View File

@ -0,0 +1,349 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIPolyPatch
Description
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI)
SourceFiles
cyclicACMIPolyPatch.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIPolyPatch_H
#define cyclicACMIPolyPatch_H
#include "cyclicAMIPolyPatch.H"
#include "AMIPatchToPatchInterpolation.H"
#include "polyBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIPolyPatch Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIPolyPatch
:
public cyclicAMIPolyPatch
{
private:
// Private data
//- Copy of the original patch face areas
mutable vectorField faceAreas0_;
//- Name of non-overlapping patch
const word nonOverlapPatchName_;
//- Index of non-overlapping patch
mutable label nonOverlapPatchID_;
//- Flag to indicate that AMI has been updated
mutable bool updated_;
protected:
static const scalar tolerance_;
// Protected Member Functions
//- Initialise patch face areas
virtual void initPatchFaceAreas() const;
//- Reset the AMI interpolator
virtual void resetAMI
(
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod =
AMIPatchToPatchInterpolation::imFaceAreaWeight
) const;
//- Set neighbour ACMI patch areas
virtual void setNeighbourFaceAreas() const;
//- Initialise the calculation of the patch geometry
virtual void initGeometry(PstreamBuffers&);
//- Calculate the patch geometry
virtual void calcGeometry(PstreamBuffers&);
//- Initialise the patches for moving points
virtual void initMovePoints(PstreamBuffers& pBufs, const pointField&);
//- Correct patches after moving points
virtual void movePoints(PstreamBuffers& pBufs, const pointField&);
//- Initialise the update of the patch topology
virtual void initUpdateMesh(PstreamBuffers&);
//- Update of the patch topology
virtual void updateMesh(PstreamBuffers&);
//- Clear geometry
virtual void clearGeom();
public:
//- Runtime type information
TypeName("cyclicACMI");
// Constructors
//- Construct from (base couped patch) components
cyclicACMIPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const word& patchType,
const transformType transform = UNKNOWN
);
//- Construct from dictionary
cyclicACMIPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh& bm,
const word& patchType
);
//- Construct as copy, resetting the boundary mesh
cyclicACMIPolyPatch
(
const cyclicACMIPolyPatch&,
const polyBoundaryMesh&
);
//- Construct given the original patch and resetting the
// face list and boundary mesh information
cyclicACMIPolyPatch
(
const cyclicACMIPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart,
const word& nbrPatchName,
const word& nonOverlapPatchName
);
//- Construct given the original patch and a map
cyclicACMIPolyPatch
(
const cyclicACMIPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const labelUList& mapAddressing,
const label newStart
);
//- Construct and return a clone, resetting the boundary mesh
virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const
{
return autoPtr<polyPatch>(new cyclicACMIPolyPatch(*this, bm));
}
//- Construct and return a clone, resetting the face list
// and boundary mesh
virtual autoPtr<polyPatch> clone
(
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart
) const
{
return autoPtr<polyPatch>
(
new cyclicACMIPolyPatch
(
*this,
bm,
index,
newSize,
newStart,
neighbPatchName(),
nonOverlapPatchName_
)
);
}
//- Construct and return a clone, resetting the face list
// and boundary mesh
virtual autoPtr<polyPatch> clone
(
const polyBoundaryMesh& bm,
const label index,
const labelUList& mapAddressing,
const label newStart
) const
{
return autoPtr<polyPatch>
(
new cyclicACMIPolyPatch
(
*this,
bm,
index,
mapAddressing,
newStart
)
);
}
//- Destructor
virtual ~cyclicACMIPolyPatch();
// Member Functions
// Access
//- Reset the updated flag
inline void setUpdated(bool flag) const;
//- Return access to the updated flag
inline bool updated() const;
//- Return access to the original patch face areas
inline const vectorField& faceAreas0() const;
//- Non-overlapping patch name
inline const word& nonOverlapPatchName() const;
//- Non-overlapping patch ID
virtual label nonOverlapPatchID() const;
//- Return a const reference to the non-overlapping patch
inline const polyPatch& nonOverlapPatch() const;
//- Return a reference to the non-overlapping patch
inline polyPatch& nonOverlapPatch();
//- Mask field where 1 = overlap, 0 = no-overlap
inline const scalarField& mask() const;
// Interpolations
//- Interpolate field
template<class Type>
tmp<Field<Type> > interpolate
(
const Field<Type>& fldCouple,
const Field<Type>& fldNonOverlap
) const;
//- Interpolate tmp field
template<class Type>
tmp<Field<Type> > interpolate
(
const tmp<Field<Type> >& tFldCouple,
const tmp<Field<Type> >& tFldNonOverlap
) const;
//- Low-level interpolate List
template<class Type, class CombineOp>
void interpolate
(
const UList<Type>& fldCouple,
const UList<Type>& fldNonOverlap,
const CombineOp& cop,
List<Type>& result
) const;
//- Calculate the patch geometry
virtual void calcGeometry
(
const primitivePatch& referPatch,
const pointField& thisCtrs,
const vectorField& thisAreas,
const pointField& thisCc,
const pointField& nbrCtrs,
const vectorField& nbrAreas,
const pointField& nbrCc
);
//- Initialize ordering for primitivePatch. Does not
// refer to *this (except for name() and type() etc.)
virtual void initOrder
(
PstreamBuffers&,
const primitivePatch&
) const;
//- Return new ordering for primitivePatch.
// Ordering is -faceMap: for every face
// index of the new face -rotation:for every new face the clockwise
// shift of the original face. Return false if nothing changes
// (faceMap is identity, rotation is 0), true otherwise.
virtual bool order
(
PstreamBuffers&,
const primitivePatch&,
labelList& faceMap,
labelList& rotation
) const;
//- Write the polyPatch data as a dictionary
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "cyclicACMIPolyPatchI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "cyclicACMIPolyPatchTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline void Foam::cyclicACMIPolyPatch::setUpdated(const bool flag) const
{
updated_ = flag;
}
inline bool Foam::cyclicACMIPolyPatch::updated() const
{
return updated_;
}
inline const Foam::vectorField& Foam::cyclicACMIPolyPatch::faceAreas0() const
{
return faceAreas0_;
}
inline const Foam::word& Foam::cyclicACMIPolyPatch::nonOverlapPatchName() const
{
return nonOverlapPatchName_;
}
inline const Foam::polyPatch& Foam::cyclicACMIPolyPatch::nonOverlapPatch() const
{
// note: use nonOverlapPatchID() as opposed to patch name to initialise
// demand-driven data
return this->boundaryMesh()[nonOverlapPatchID()];
}
inline Foam::polyPatch& Foam::cyclicACMIPolyPatch::nonOverlapPatch()
{
// note: use nonOverlapPatchID() as opposed to patch name to initialise
// demand-driven data
return const_cast<polyPatch&>(this->boundaryMesh()[nonOverlapPatchID()]);
}
inline const Foam::scalarField& Foam::cyclicACMIPolyPatch::mask() const
{
if (owner())
{
return AMI().srcWeightsSum();
}
else
{
return neighbPatch().AMI().tgtWeightsSum();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::cyclicACMIPolyPatch::interpolate
(
const Field<Type>& fldCouple,
const Field<Type>& fldNonOverlap
) const
{
if (owner())
{
const scalarField& w = AMI().srcWeightsSum();
return
w*AMI().interpolateToSource(fldCouple)
+ (1.0 - w)*fldNonOverlap;
}
else
{
const scalarField& w = neighbPatch().AMI().tgtWeightsSum();
return
w*neighbPatch().AMI().interpolateToTarget(fldCouple)
+ (1.0 - w)*fldNonOverlap;
}
}
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::cyclicACMIPolyPatch::interpolate
(
const tmp<Field<Type> >& tFldCouple,
const tmp<Field<Type> >& tFldNonOverlap
) const
{
return interpolate(tFldCouple(), tFldNonOverlap());
}
template<class Type, class CombineOp>
void Foam::cyclicACMIPolyPatch::interpolate
(
const UList<Type>& fldCouple,
const UList<Type>& fldNonOverlap,
const CombineOp& cop,
List<Type>& result
) const
{
if (owner())
{
const scalarField& w = AMI().srcWeightsSum();
AMI().interpolateToSource(fldCouple, cop, result);
result = w*result + (1.0 - w)*fldNonOverlap;
}
else
{
const scalarField& w = neighbPatch().AMI().tgtWeightsSum();
neighbPatch().AMI().interpolateToTarget(fldCouple, cop, result);
result = w*result + (1.0 - w)*fldNonOverlap;
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -232,7 +232,12 @@ void Foam::cyclicAMIPolyPatch::calcTransforms
} }
void Foam::cyclicAMIPolyPatch::resetAMI() const // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::cyclicAMIPolyPatch::resetAMI
(
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod
) const
{ {
if (owner()) if (owner())
{ {
@ -283,7 +288,7 @@ void Foam::cyclicAMIPolyPatch::resetAMI() const
nbrPatch0, nbrPatch0,
surfPtr(), surfPtr(),
faceAreaIntersect::tmMesh, faceAreaIntersect::tmMesh,
AMIPatchToPatchInterpolation::imFaceAreaWeight, AMIMethod,
AMIReverse_ AMIReverse_
) )
); );
@ -301,8 +306,6 @@ void Foam::cyclicAMIPolyPatch::resetAMI() const
} }
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::cyclicAMIPolyPatch::initGeometry(PstreamBuffers& pBufs) void Foam::cyclicAMIPolyPatch::initGeometry(PstreamBuffers& pBufs)
{ {
polyPatch::initGeometry(pBufs); polyPatch::initGeometry(pBufs);

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -108,14 +108,18 @@ private:
const vectorField& half1Areas const vectorField& half1Areas
); );
//- Reset the AMI interpolator
void resetAMI() const;
protected: protected:
// Protected Member Functions // Protected Member Functions
//- Reset the AMI interpolator
virtual void resetAMI
(
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod =
AMIPatchToPatchInterpolation::imFaceAreaWeight
) const;
//- Recalculate the transformation tensors //- Recalculate the transformation tensors
virtual void calcTransforms(); virtual void calcTransforms();

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -175,14 +175,23 @@ $(AMI)/AMIInterpolation/AMIPatchToPatchInterpolation.C
$(AMI)/faceAreaIntersect/faceAreaIntersect.C $(AMI)/faceAreaIntersect/faceAreaIntersect.C
$(AMI)/GAMG/interfaces/cyclicAMIGAMGInterface/cyclicAMIGAMGInterface.C $(AMI)/GAMG/interfaces/cyclicAMIGAMGInterface/cyclicAMIGAMGInterface.C
$(AMI)/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C $(AMI)/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
$(AMI)/GAMG/interfaces/cyclicACMIGAMGInterface/cyclicACMIGAMGInterface.C
$(AMI)/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C
AMICycPatches=$(AMI)/patches/cyclic AMICycPatches=$(AMI)/patches/cyclicAMI
$(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterface.C $(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterface.C
$(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C $(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterfaceField.C
$(AMICycPatches)/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C $(AMICycPatches)/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C
$(AMICycPatches)/cyclicAMIPointPatch/cyclicAMIPointPatch.C $(AMICycPatches)/cyclicAMIPointPatch/cyclicAMIPointPatch.C
$(AMICycPatches)/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C $(AMICycPatches)/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C
ACMICycPatches=$(AMI)/patches/cyclicACMI
$(ACMICycPatches)/cyclicACMILduInterfaceField/cyclicACMILduInterface.C
$(ACMICycPatches)/cyclicACMILduInterfaceField/cyclicACMILduInterfaceField.C
$(ACMICycPatches)/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C
$(ACMICycPatches)/cyclicACMIPointPatch/cyclicACMIPointPatch.C
$(ACMICycPatches)/cyclicACMIPointPatchField/cyclicACMIPointPatchFields.C
mappedPatches/mappedPolyPatch/mappedPatchBase.C mappedPatches/mappedPolyPatch/mappedPatchBase.C
mappedPatches/mappedPolyPatch/mappedPolyPatch.C mappedPatches/mappedPolyPatch/mappedPolyPatch.C
mappedPatches/mappedPolyPatch/mappedWallPolyPatch.C mappedPatches/mappedPolyPatch/mappedWallPolyPatch.C

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -189,51 +189,40 @@ updateCoeffs()
} }
scalarField& Iw = *this; scalarField& Iw = *this;
const vectorField n(patch().Sf()/patch().magSf()); const vectorField n(patch().nf());
radiativeIntensityRay& ray = radiativeIntensityRay& ray =
const_cast<radiativeIntensityRay&>(dom.IRay(rayId)); const_cast<radiativeIntensityRay&>(dom.IRay(rayId));
ray.Qr().boundaryField()[patchI] += Iw*(n & ray.dAve()); const scalarField nAve(n & ray.dAve());
scalarField temissivity = emissivity(); ray.Qr().boundaryField()[patchI] += Iw*nAve;
const scalarField temissivity = emissivity();
scalarField& Qem = ray.Qem().boundaryField()[patchI];
scalarField& Qin = ray.Qin().boundaryField()[patchI];
const vector& myRayId = dom.IRay(rayId).d();
const scalarField& Ir = dom.Qin();
forAll(Iw, faceI) forAll(Iw, faceI)
{ {
scalar Ir = 0.0; if ((-n[faceI] & myRayId) > 0.0)
for (label rayI=0; rayI < dom.nRay(); rayI++)
{
const vector& d = dom.IRay(rayI).d();
const scalarField& IFace =
dom.IRay(rayI).ILambda(lambdaId).boundaryField()[patchI];
if ((-n[faceI] & d) < 0.0)
{
// q into the wall
const vector& dAve = dom.IRay(rayI).dAve();
Ir += IFace[faceI]*mag(n[faceI] & dAve);
}
}
const vector& d = dom.IRay(rayId).d();
if ((-n[faceI] & d) > 0.0)
{ {
// direction out of the wall // direction out of the wall
refGrad()[faceI] = 0.0; refGrad()[faceI] = 0.0;
valueFraction()[faceI] = 1.0; valueFraction()[faceI] = 1.0;
refValue()[faceI] = refValue()[faceI] =
( (
Ir*(scalar(1.0) - temissivity[faceI]) Ir[faceI]*(scalar(1.0) - temissivity[faceI])
+ temissivity[faceI]*physicoChemical::sigma.value() + temissivity[faceI]*physicoChemical::sigma.value()
* pow4(Tp[faceI]) * pow4(Tp[faceI])
)/pi; )/pi;
// Emmited heat flux from this ray direction // Emmited heat flux from this ray direction
ray.Qem().boundaryField()[patchI][faceI] = Qem[faceI] = refValue()[faceI]*nAve[faceI];
refValue()[faceI]*(n[faceI] & ray.dAve());
} }
else else
{ {
@ -242,9 +231,8 @@ updateCoeffs()
refGrad()[faceI] = 0.0; refGrad()[faceI] = 0.0;
refValue()[faceI] = 0.0; //not used refValue()[faceI] = 0.0; //not used
// Incident heat flux on this ray direction // Incident heat flux on this ray direction
ray.Qin().boundaryField()[patchI][faceI] = Qin[faceI] = Iw[faceI]*nAve[faceI];
Iw[faceI]*(n[faceI] & ray.dAve());
} }
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,6 +27,7 @@ License
#include "absorptionEmissionModel.H" #include "absorptionEmissionModel.H"
#include "scatterModel.H" #include "scatterModel.H"
#include "constants.H" #include "constants.H"
#include "fvm.H"
using namespace Foam::constant; using namespace Foam::constant;
using namespace Foam::constant::mathematical; using namespace Foam::constant::mathematical;
@ -172,10 +173,39 @@ void Foam::radiation::fvDOM::initialise()
Info<< "fvDOM : Allocated " << IRay_.size() Info<< "fvDOM : Allocated " << IRay_.size()
<< " rays with average orientation:" << nl; << " rays with average orientation:" << nl;
forAll(IRay_, i) if (cacheDiv_)
{ {
Info<< '\t' << IRay_[i].I().name() Info<< "Caching div fvMatrix..."<< endl;
<< '\t' << IRay_[i].dAve() << nl; for (label lambdaI = 0; lambdaI < nLambda_; lambdaI++)
{
fvRayDiv_[lambdaI].setSize(nRay_);
forAll(IRay_, rayId)
{
const surfaceScalarField Ji(IRay_[rayId].dAve() & mesh_.Sf());
const volScalarField& iRayLambdaI =
IRay_[rayId].ILambda(lambdaI);
fvRayDiv_[lambdaI].set
(
rayId,
new fvScalarMatrix
(
fvm::div(Ji, iRayLambdaI, "div(Ji,Ii_h)")
)
);
}
}
}
forAll(IRay_, rayId)
{
if (omegaMax_ < IRay_[rayId].omega())
{
omegaMax_ = IRay_[rayId].omega();
}
Info<< '\t' << IRay_[rayId].I().name() << " : " << "omega : "
<< '\t' << IRay_[rayId].omega() << nl;
} }
Info<< endl; Info<< endl;
@ -194,7 +224,7 @@ Foam::radiation::fvDOM::fvDOM(const volScalarField& T)
"G", "G",
mesh_.time().timeName(), mesh_.time().timeName(),
mesh_, mesh_,
IOobject::READ_IF_PRESENT, IOobject::NO_READ,
IOobject::AUTO_WRITE IOobject::AUTO_WRITE
), ),
mesh_, mesh_,
@ -247,7 +277,7 @@ Foam::radiation::fvDOM::fvDOM(const volScalarField& T)
mesh_.time().timeName(), mesh_.time().timeName(),
mesh_, mesh_,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::AUTO_WRITE
), ),
mesh_, mesh_,
dimensionedScalar("a", dimless/dimLength, 0.0) dimensionedScalar("a", dimless/dimLength, 0.0)
@ -260,7 +290,10 @@ Foam::radiation::fvDOM::fvDOM(const volScalarField& T)
blackBody_(nLambda_, T), blackBody_(nLambda_, T),
IRay_(0), IRay_(0),
convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)), convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)),
maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)) maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)),
fvRayDiv_(nLambda_),
cacheDiv_(coeffs_.lookupOrDefault<bool>("cacheDiv", false)),
omegaMax_(0)
{ {
initialise(); initialise();
} }
@ -346,7 +379,10 @@ Foam::radiation::fvDOM::fvDOM
blackBody_(nLambda_, T), blackBody_(nLambda_, T),
IRay_(0), IRay_(0),
convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)), convergence_(coeffs_.lookupOrDefault<scalar>("convergence", 0.0)),
maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)) maxIter_(coeffs_.lookupOrDefault<label>("maxIter", 50)),
fvRayDiv_(nLambda_),
cacheDiv_(coeffs_.lookupOrDefault<bool>("cacheDiv", false)),
omegaMax_(0)
{ {
initialise(); initialise();
} }
@ -364,7 +400,6 @@ bool Foam::radiation::fvDOM::read()
if (radiationModel::read()) if (radiationModel::read())
{ {
// Only reading solution parameters - not changing ray geometry // Only reading solution parameters - not changing ray geometry
coeffs_.readIfPresent("convergence", convergence_); coeffs_.readIfPresent("convergence", convergence_);
coeffs_.readIfPresent("maxIter", maxIter_); coeffs_.readIfPresent("maxIter", maxIter_);
@ -383,19 +418,30 @@ void Foam::radiation::fvDOM::calculate()
updateBlackBodyEmission(); updateBlackBodyEmission();
// Set rays convergence false
List<bool> rayIdConv(nRay_, false);
scalar maxResidual = 0.0; scalar maxResidual = 0.0;
label radIter = 0; label radIter = 0;
do do
{ {
Info<< "Radiation solver iter: " << radIter << endl;
radIter++; radIter++;
maxResidual = 0.0;
forAll(IRay_, rayI) forAll(IRay_, rayI)
{ {
maxResidual = 0.0; if (!rayIdConv[rayI])
scalar maxBandResidual = IRay_[rayI].correct(); {
maxResidual = max(maxBandResidual, maxResidual); scalar maxBandResidual = IRay_[rayI].correct();
} maxResidual = max(maxBandResidual, maxResidual);
Info<< "Radiation solver iter: " << radIter << endl; if (maxBandResidual < convergence_)
{
rayIdConv[rayI] = true;
}
}
}
} while (maxResidual > convergence_ && radIter < maxIter_); } while (maxResidual > convergence_ && radIter < maxIter_);
@ -433,7 +479,7 @@ Foam::radiation::fvDOM::Ru() const
const DimensionedField<scalar, volMesh> E = const DimensionedField<scalar, volMesh> E =
absorptionEmission_->ECont()().dimensionedInternalField(); absorptionEmission_->ECont()().dimensionedInternalField();
const DimensionedField<scalar, volMesh> a = const DimensionedField<scalar, volMesh> a =
a_.dimensionedInternalField(); //absorptionEmission_->aCont()() a_.dimensionedInternalField();
return a*G - E; return a*G - E;
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -30,6 +30,7 @@ Description
directions in a participating media, not including scatter. directions in a participating media, not including scatter.
Available absorption models: Available absorption models:
constantAbsorptionEmission
greyMeanAbsoprtionEmission greyMeanAbsoprtionEmission
wideBandAbsorptionEmission wideBandAbsorptionEmission
@ -37,9 +38,15 @@ Description
\verbatim \verbatim
fvDOMCoeffs fvDOMCoeffs
{ {
nPhi 1; // azimuthal angles in PI/2 on X-Y.(from Y to X) nPhi 4; // azimuthal angles in PI/2 on X-Y.
nTheta 2; // polar angles in PI (from Z to X-Y plane) //(from Y to X)
convergence 1e-4; // convergence criteria for radiation iteration nTheta 0; // polar angles in PI (from Z to X-Y plane)
convergence 1e-3; // convergence criteria for radiation
//iteration
maxIter 4; // maximum number of iterations
cacheDiv true; // cache the div of the RTE equation.
//NOTE: Caching div is "only" accurate if the upwind scheme is used
//in div(Ji,Ii_h)
} }
solverFreq 1; // Number of flow iterations per radiation iteration solverFreq 1; // Number of flow iterations per radiation iteration
@ -61,6 +68,7 @@ SourceFiles
#include "radiativeIntensityRay.H" #include "radiativeIntensityRay.H"
#include "radiationModel.H" #include "radiationModel.H"
#include "fvMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -79,6 +87,7 @@ class fvDOM
{ {
// Private data // Private data
//- Incident radiation [W/m2] //- Incident radiation [W/m2]
volScalarField G_; volScalarField G_;
@ -121,6 +130,15 @@ class fvDOM
//- Maximum number of iterations //- Maximum number of iterations
scalar maxIter_; scalar maxIter_;
//- List of cached fvMatrices for rays
List<PtrList<fvScalarMatrix> >fvRayDiv_;
//- Cache convection div matrix
bool cacheDiv_;
//- Maximum omega weight
scalar omegaMax_;
// Private Member Functions // Private Member Functions
@ -229,6 +247,19 @@ public:
//- Const access to black body //- Const access to black body
inline const blackBodyEmission& blackBody() const; inline const blackBodyEmission& blackBody() const;
//- Const access to cached fvMatrix
inline const fvScalarMatrix& fvRayDiv
(
const label lambdaI,
const label rayId
) const;
//- Caching div(Ji, Ilamda)
inline bool cacheDiv() const;
//- Return omegaMax
inline scalar omegaMax() const;
}; };

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -102,6 +102,7 @@ inline const Foam::volScalarField& Foam::radiation::fvDOM::Qem() const
return Qem_; return Qem_;
} }
inline const Foam::radiation::blackBodyEmission& inline const Foam::radiation::blackBodyEmission&
Foam::radiation::fvDOM::blackBody() const Foam::radiation::fvDOM::blackBody() const
{ {
@ -109,4 +110,26 @@ Foam::radiation::fvDOM::blackBody() const
} }
inline const Foam::fvScalarMatrix& Foam::radiation::fvDOM::fvRayDiv
(
const label rayId,
const label lambdaI
) const
{
return fvRayDiv_[lambdaI][rayId];
}
inline bool Foam::radiation::fvDOM::cacheDiv() const
{
return cacheDiv_;
}
inline Foam::scalar Foam::radiation::fvDOM::omegaMax() const
{
return omegaMax_;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -113,7 +113,8 @@ Foam::radiation::radiativeIntensityRay::radiativeIntensityRay
phi_(phi), phi_(phi),
omega_(0.0), omega_(0.0),
nLambda_(nLambda), nLambda_(nLambda),
ILambda_(nLambda) ILambda_(nLambda),
myRayId_(rayId)
{ {
scalar sinTheta = Foam::sin(theta); scalar sinTheta = Foam::sin(theta);
scalar cosTheta = Foam::cos(theta); scalar cosTheta = Foam::cos(theta);
@ -135,7 +136,6 @@ Foam::radiation::radiativeIntensityRay::radiativeIntensityRay
0.5*deltaPhi*Foam::sin(2.0*theta)*Foam::sin(deltaTheta) 0.5*deltaPhi*Foam::sin(2.0*theta)*Foam::sin(deltaTheta)
); );
autoPtr<volScalarField> IDefaultPtr; autoPtr<volScalarField> IDefaultPtr;
forAll(ILambda_, lambdaI) forAll(ILambda_, lambdaI)
@ -213,29 +213,51 @@ Foam::scalar Foam::radiation::radiativeIntensityRay::correct()
{ {
const volScalarField& k = dom_.aLambda(lambdaI); const volScalarField& k = dom_.aLambda(lambdaI);
const surfaceScalarField Ji(dAve_ & mesh_.Sf()); tmp<fvScalarMatrix> IiEq;
fvScalarMatrix IiEq if (!dom_.cacheDiv())
{
const surfaceScalarField Ji(dAve_ & mesh_.Sf());
IiEq =
(
fvm::div(Ji, ILambda_[lambdaI], "div(Ji,Ii_h)")
+ fvm::Sp(k*omega_, ILambda_[lambdaI])
==
1.0/constant::mathematical::pi*omega_
* (
k*blackBody_.bLambda(lambdaI)
+ absorptionEmission_.ECont(lambdaI)/4
)
);
}
else
{
IiEq =
(
dom_.fvRayDiv(myRayId_, lambdaI)
+ fvm::Sp(k*omega_, ILambda_[lambdaI])
==
1.0/constant::mathematical::pi*omega_
* (
k*blackBody_.bLambda(lambdaI)
+ absorptionEmission_.ECont(lambdaI)/4
)
);
}
IiEq().relax();
const solverPerformance ILambdaSol = solve
( (
fvm::div(Ji, ILambda_[lambdaI], "div(Ji,Ii_h)") IiEq(),
+ fvm::Sp(k*omega_, ILambda_[lambdaI]) mesh_.solver("Ii")
==
1.0/constant::mathematical::pi*omega_
*(
k*blackBody_.bLambda(lambdaI)
+ absorptionEmission_.ECont(lambdaI)/4
)
); );
IiEq.relax(); const scalar initialRes =
ILambdaSol.initialResidual()*omega_/dom_.omegaMax();
scalar eqnResidual = solve maxResidual = max(initialRes, maxResidual);
(
IiEq,
mesh_.solver("Ii")
).initialResidual();
maxResidual = max(eqnResidual, maxResidual);
} }
return maxResidual; return maxResidual;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -38,6 +38,7 @@ SourceFiles
#include "absorptionEmissionModel.H" #include "absorptionEmissionModel.H"
#include "blackBodyEmission.H" #include "blackBodyEmission.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -111,6 +112,9 @@ private:
//- Global ray id - incremented in constructor //- Global ray id - incremented in constructor
static label rayId; static label rayId;
//- My ray Id
label myRayId_;
// Private Member Functions // Private Member Functions
@ -209,6 +213,7 @@ public:
//- Return the radiative intensity for a given wavelength //- Return the radiative intensity for a given wavelength
inline const volScalarField& ILambda(const label lambdaI) const; inline const volScalarField& ILambda(const label lambdaI) const;
}; };

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -252,8 +252,8 @@ void Foam::radiation::absorptionEmissionModel::correct
PtrList<volScalarField>& aj PtrList<volScalarField>& aj
) const ) const
{ {
a.internalField() = this->a(); a = this->a();
aj[0].internalField() = a.internalField(); aj[0] = a;
} }

View File

@ -0,0 +1,41 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object G;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 0 -3 0 0 0 0];
internalField uniform 0;
boundaryField
{
".*"
{
type MarshakRadiation;
T T;
emissivityMode lookup;
emissivity uniform 1.0;
value uniform 0;
}
"(region0_to.*)"
{
type MarshakRadiation;
T T;
emissivityMode solidRadiation;
value uniform 0;
}
}
// ************************************************************************* //

View File

@ -24,22 +24,24 @@ fvDOMCoeffs
{ {
nPhi 3; // azimuthal angles in PI/2 on X-Y.(from Y to X) nPhi 3; // azimuthal angles in PI/2 on X-Y.(from Y to X)
nTheta 6; // polar angles in PI (from Z to X-Y plane) nTheta 6; // polar angles in PI (from Z to X-Y plane)
convergence 1e-4; // convergence criteria for radiation iteration convergence 0.05; // convergence criteria for radiation iteration
maxIter 2; // maximum number of iterations maxIter 3; // maximum number of iterations
cacheDiv true; // cache the div of the RTE equation.
// NOTE: Caching div is "only" accurate if the upwind scheme is used in
// div(Ji,Ii_h)
} }
// Number of flow iterations per radiation iteration // Number of flow iterations per radiation iteration
solverFreq 10; solverFreq 10;
absorptionEmissionModel constantAbsorptionEmission; absorptionEmissionModel constantAbsorptionEmission;
//absorptionEmissionModel greyMeanAbsorptionEmission;
constantAbsorptionEmissionCoeffs constantAbsorptionEmissionCoeffs
{ {
absorptivity absorptivity [ 0 -1 0 0 0 0 0 ] 0.01; absorptivity absorptivity [ m^-1 ] 0.01;
emissivity emissivity [ 0 -1 0 0 0 0 0 ] 0.01; emissivity emissivity [ m^-1 ] 0.01;
E E [ 1 -1 -3 0 0 0 0 ] 0; E E [ kg m^-1 s^-3 ] 0;
}
greyMeanAbsorptionEmissionCoeffs greyMeanAbsorptionEmissionCoeffs
{ {
@ -49,7 +51,7 @@ greyMeanAbsorptionEmissionCoeffs
CO2 CO2
{ {
Tcommon 300; //Common Temp Tcommon 200; //Common Temp
invTemp true; //Is the polynomio using inverse temperature. invTemp true; //Is the polynomio using inverse temperature.
Tlow 200; //Low Temp Tlow 200; //Low Temp
Thigh 2500; //High Temp Thigh 2500; //High Temp
@ -77,7 +79,7 @@ greyMeanAbsorptionEmissionCoeffs
H2O H2O
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
@ -104,7 +106,7 @@ greyMeanAbsorptionEmissionCoeffs
C3H8//CH4 C3H8//CH4
{ {
Tcommon 300; Tcommon 200;
Tlow 200; Tlow 200;
Thigh 2000; Thigh 2000;
invTemp false; invTemp false;
@ -131,7 +133,7 @@ greyMeanAbsorptionEmissionCoeffs
O2 O2
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
@ -159,7 +161,7 @@ greyMeanAbsorptionEmissionCoeffs
N2 N2
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;

View File

@ -16,7 +16,7 @@ FoamFile
application fireFoam; application fireFoam;
startFrom startTime; startFrom latestTime;
startTime 0; startTime 0;
@ -28,11 +28,11 @@ deltaT 0.03;
writeControl adjustableRunTime; writeControl adjustableRunTime;
writeInterval 1; writeInterval 0.5;
purgeWrite 0; purgeWrite 0;
writeFormat ascii; writeFormat binary;
writePrecision 12; writePrecision 12;

View File

@ -34,7 +34,7 @@ solvers
p_rgh p_rgh
{ {
solver GAMG; solver GAMG;
tolerance 1e-5; tolerance 1e-7;
relTol 0.01; relTol 0.01;
smoother GaussSeidel; smoother GaussSeidel;
cacheAgglomeration true; cacheAgglomeration true;
@ -45,28 +45,25 @@ solvers
p_rghFinal p_rghFinal
{ {
solver GAMG; $p_rgh;
tolerance 1e-6; tolerance 1e-7;
relTol 0; relTol 0;
smoother GaussSeidel;
cacheAgglomeration true;
nCellsInCoarsestLevel 10;
agglomerator faceAreaPair;
mergeLevels 1;
}; };
"(U|k)" "(U|Yi|k|h|omega)"
{ {
solver PBiCG; solver PBiCG;
preconditioner DILU; preconditioner DILU;
tolerance 1e-6; tolerance 1e-7;
relTol 0.01; relTol 0.1;
nSweeps 1;
}; };
"(U|k)Final" "(U|Yi|k|h|omega)Final"
{ {
$U; $U;
tolerance 1e-7;
relTol 0; relTol 0;
}; };
@ -84,18 +81,21 @@ solvers
solver GAMG; solver GAMG;
tolerance 1e-4; tolerance 1e-4;
relTol 0; relTol 0;
smoother DILU; smoother symGaussSeidel;
cacheAgglomeration true; cacheAgglomeration true;
nCellsInCoarsestLevel 10; nCellsInCoarsestLevel 10;
agglomerator faceAreaPair; agglomerator faceAreaPair;
mergeLevels 1; mergeLevels 1;
maxIter 1;
nPreSweeps 0;
nPostSweeps 1;
} }
G "(G)Final"
{ {
solver PCG; solver PCG;
preconditioner DIC; preconditioner DIC;
tolerance 1e-06; tolerance 1e-04;
relTol 0; relTol 0;
} }
@ -104,8 +104,8 @@ solvers
PIMPLE PIMPLE
{ {
momentumPredictor yes; momentumPredictor yes;
nOuterCorrectors 2; nOuterCorrectors 1;
nCorrectors 1; nCorrectors 3;
nNonOrthogonalCorrectors 0; nNonOrthogonalCorrectors 0;
} }
@ -117,7 +117,7 @@ relaxationFactors
equations equations
{ {
"(U|k).*" 1; "(U|k).*" 1;
"(C3H8|O2|H2O|CO2|h).*" 1; "(C3H8|O2|H2O|CO2|h).*" 1;
} }
} }

View File

@ -19,10 +19,14 @@ radiationModel fvDOM;
fvDOMCoeffs fvDOMCoeffs
{ {
nPhi 4; // azimuthal angles in PI/2 on X-Y.(from Y to X) nPhi 4; // azimuthal angles in PI/2 on X-Y.(from Y to X)
nTheta 0; // polar angles in PI (from Z to X-Y plane) nTheta 0; // polar angles in PI (from Z to X-Y plane)
convergence 1e-3; // convergence criteria for radiation iteration convergence 1e-2; // convergence criteria for radiation iteration
maxIter 1; // maximum number of iterations maxIter 4; // maximum number of iterations
cacheDiv true; // cache the div of the RTE equation.
// NOTE: Caching div is "only" accurate if the upwind scheme is used in
// div(Ji,Ii_h)
} }
// Number of flow iterations per radiation iteration // Number of flow iterations per radiation iteration
@ -32,9 +36,9 @@ absorptionEmissionModel greyMeanAbsorptionEmission;
constantAbsorptionEmissionCoeffs constantAbsorptionEmissionCoeffs
{ {
absorptivity absorptivity [ 0 -1 0 0 0 0 0 ] 0.1; absorptivity absorptivity [ m^-1 ] 0.01;
emissivity emissivity [ 0 -1 0 0 0 0 0 ] 0.1; emissivity emissivity [ m^-1 ] 0.01;
E E [ 1 -1 -3 0 0 0 0 ] 0; E E [ kg m^-1 s^-3 ] 0;
} }
greyMeanAbsorptionEmissionCoeffs greyMeanAbsorptionEmissionCoeffs
@ -45,7 +49,7 @@ greyMeanAbsorptionEmissionCoeffs
CO2 CO2
{ {
Tcommon 300; //Common Temp Tcommon 200; //Common Temp
invTemp true; //Is the polynomio using inverse temperature. invTemp true; //Is the polynomio using inverse temperature.
Tlow 200; //Low Temp Tlow 200; //Low Temp
Thigh 2500; //High Temp Thigh 2500; //High Temp
@ -73,7 +77,7 @@ greyMeanAbsorptionEmissionCoeffs
H2O H2O
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
@ -100,7 +104,7 @@ greyMeanAbsorptionEmissionCoeffs
CH4 CH4
{ {
Tcommon 300; Tcommon 200;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
invTemp false; invTemp false;
@ -127,7 +131,7 @@ greyMeanAbsorptionEmissionCoeffs
O2 O2
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
@ -155,7 +159,7 @@ greyMeanAbsorptionEmissionCoeffs
N2 N2
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;

View File

@ -48,8 +48,6 @@ runTimeModifiable yes;
adjustTimeStep yes; adjustTimeStep yes;
maxCo 0.25; maxCo 0.5;
maxDeltaT 0.1;
// ************************************************************************* // // ************************************************************************* //

View File

@ -72,21 +72,24 @@ solvers
Ii Ii
{ {
solver GAMG; solver GAMG;
tolerance 1e-4; tolerance 1e-4;
relTol 0; relTol 0.1;
smoother DILU; smoother symGaussSeidel;
cacheAgglomeration true; cacheAgglomeration true;
nCellsInCoarsestLevel 10; nCellsInCoarsestLevel 10;
agglomerator faceAreaPair; agglomerator faceAreaPair;
mergeLevels 1; mergeLevels 1;
maxIter 3;
nPreSweeps 0;
nPostSweeps 1;
} }
G G
{ {
solver PCG; solver PCG;
preconditioner DIC; preconditioner DIC;
tolerance 1e-06; tolerance 1e-04;
relTol 0; relTol 0;
} }
@ -108,7 +111,7 @@ relaxationFactors
equations equations
{ {
"(U|k).*" 1; "(U|k).*" 1;
"(C3H8|O2|H2O|CO2|h).*" 0.9; "(C3H8|O2|H2O|CO2|h).*" 1;
} }
} }

View File

@ -25,7 +25,7 @@ boundaryField
type greyDiffusiveRadiation; type greyDiffusiveRadiation;
T T; T T;
emissivityMode lookup; emissivityMode lookup;
emissivity uniform 1.0; emissivity uniform 1;
value uniform 0; value uniform 0;
} }
} }

View File

@ -20,10 +20,14 @@ radiationModel fvDOM;
fvDOMCoeffs fvDOMCoeffs
{ {
nPhi 2; // azimuthal angles in PI/2 on X-Y.(from Y to X) nPhi 2; // azimuthal angles in PI/2 on X-Y.(from Y to X)
nTheta 2; // polar angles in PI (from Z to X-Y plane) nTheta 2; // polar angles in PI (from Z to X-Y plane)
convergence 1e-3; // convergence criteria for radiation iteration convergence 1e-1; // convergence criteria for radiation iteration
maxIter 10; // maximum number of iterations maxIter 1; // maximum number of iterations
cacheDiv true; // cache the div of the RTE equation.
// NOTE: Caching div is "only" accurate if the upwind scheme is used in
// div(Ji,Ii_h)
} }
// Number of flow iterations per radiation iteration // Number of flow iterations per radiation iteration
@ -33,9 +37,9 @@ absorptionEmissionModel greyMeanAbsorptionEmission;
constantAbsorptionEmissionCoeffs constantAbsorptionEmissionCoeffs
{ {
absorptivity absorptivity [ 0 -1 0 0 0 0 0 ] 0.01; absorptivity absorptivity [ m^-1 ] 0.01;
emissivity emissivity [ 0 -1 0 0 0 0 0 ] 0.01; emissivity emissivity [ m^-1 ] 0.01;
E E [ 1 -1 -3 0 0 0 0 ] 0; E E [ kg m^-1 s^-3 ] 0;
} }
greyMeanAbsorptionEmissionCoeffs greyMeanAbsorptionEmissionCoeffs
@ -46,7 +50,7 @@ greyMeanAbsorptionEmissionCoeffs
CO2 CO2
{ {
Tcommon 300; //Common Temp Tcommon 200; //Common Temp
invTemp true; //Is the polynomio using inverse temperature. invTemp true; //Is the polynomio using inverse temperature.
Tlow 200; //Low Temp Tlow 200; //Low Temp
Thigh 2500; //High Temp Thigh 2500; //High Temp
@ -74,7 +78,7 @@ greyMeanAbsorptionEmissionCoeffs
H2O H2O
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
@ -101,7 +105,7 @@ greyMeanAbsorptionEmissionCoeffs
CH4 CH4
{ {
Tcommon 300; Tcommon 200;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
invTemp false; invTemp false;
@ -128,7 +132,7 @@ greyMeanAbsorptionEmissionCoeffs
O2 O2
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;
@ -156,7 +160,7 @@ greyMeanAbsorptionEmissionCoeffs
N2 N2
{ {
Tcommon 300; Tcommon 200;
invTemp true; invTemp true;
Tlow 200; Tlow 200;
Thigh 2500; Thigh 2500;

View File

@ -22,13 +22,13 @@ startTime 0.0;
stopAt endTime; stopAt endTime;
endTime 2.75; endTime 0.75;
deltaT 0.001; deltaT 0.001;
writeControl adjustableRunTime; writeControl adjustableRunTime;
writeInterval 0.05; writeInterval 0.5;
purgeWrite 0; purgeWrite 0;
@ -48,7 +48,7 @@ runTimeModifiable yes;
adjustTimeStep yes; adjustTimeStep yes;
maxCo 0.2; maxCo 0.5;
maxDeltaT 0.1; maxDeltaT 0.1;

View File

@ -66,12 +66,14 @@ solvers
solver GAMG; solver GAMG;
tolerance 1e-4; tolerance 1e-4;
relTol 0; relTol 0;
smoother DILU; smoother symGaussSeidel;
cacheAgglomeration true; cacheAgglomeration true;
nCellsInCoarsestLevel 10; nCellsInCoarsestLevel 10;
agglomerator faceAreaPair; agglomerator faceAreaPair;
mergeLevels 1; mergeLevels 1;
maxIter 20; maxIter 1;
nPreSweeps 0;
nPostSweeps 1;
} }
G G
@ -88,7 +90,7 @@ PIMPLE
{ {
momentumPredictor yes; momentumPredictor yes;
nOuterCorrectors 1; nOuterCorrectors 1;
nCorrectors 2; nCorrectors 3;
nNonOrthogonalCorrectors 0; nNonOrthogonalCorrectors 0;
} }

View File

@ -0,0 +1,67 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type fixedValue;
value uniform (1 0 0);
}
outlet
{
type pressureInletOutletVelocity;
value uniform (0 0 0);
}
walls
{
// type fixedValue;
type movingWallVelocity;
value uniform (0 0 0);
}
defaultFaces
{
type empty;
}
ACMI1_blockage
{
type fixedValue;
value uniform (0 0 0);
}
ACMI1_couple
{
type cyclicACMI;
value uniform (0 0 0);
}
ACMI2_blockage
{
type fixedValue;
value uniform (0 0 0);
}
ACMI2_couple
{
type cyclicACMI;
value uniform (0 0 0);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,67 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 1.8e-3;
boundaryField
{
inlet
{
type fixedValue;
value $internalField;
}
outlet
{
type inletOutlet;
inletValue $internalField;
value $internalField;
}
walls
{
type epsilonWallFunction;
value $internalField;
}
defaultFaces
{
type empty;
}
ACMI1_blockage
{
type epsilonWallFunction;
value $internalField;
}
ACMI1_couple
{
type cyclicACMI;
value $internalField;
}
ACMI2_blockage
{
type epsilonWallFunction;
value $internalField;
}
ACMI2_couple
{
type cyclicACMI;
value $internalField;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,67 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 3.75e-3;
boundaryField
{
inlet
{
type fixedValue;
value $internalField;
}
outlet
{
type inletOutlet;
inletValue $internalField;
value $internalField;
}
walls
{
type kqRWallFunction;
value $internalField;
}
defaultFaces
{
type empty;
}
ACMI1_blockage
{
type kqRWallFunction;
value $internalField;
}
ACMI1_couple
{
type cyclicACMI;
value $internalField;
}
ACMI2_blockage
{
type kqRWallFunction;
value $internalField;
}
ACMI2_couple
{
type cyclicACMI;
value $internalField;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,70 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type fixedValue;
value uniform 0;
}
walls
{
type zeroGradient;
}
couple1
{
type zeroGradient;
}
couple2
{
type zeroGradient;
}
defaultFaces
{
type empty;
}
ACMI1_blockage
{
type zeroGradient;
}
ACMI1_couple
{
type cyclicACMI;
value uniform 0;
}
ACMI2_blockage
{
type zeroGradient;
}
ACMI2_couple
{
type cyclicACMI;
value uniform 0;
}
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,9 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
./Allrun.pre
runApplication $(getApplication)

View File

@ -0,0 +1,13 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
./Allrun.pre
runApplication decomposePar
runParallel $(getApplication) 4
runApplication reconstructPar

View File

@ -0,0 +1,17 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication blockMesh
runApplication topoSet -constant
# split the mesh to generate the ACMI coupled patches
runApplication createBaffles -overwrite
# remove zero-sized patches
runApplication createPatch -overwrite
cp -rf 0.org 0

View File

@ -0,0 +1,104 @@
oscillatingInletACMI2D
This tutorial case gives an example of the Arbitrarily Coupled Mesh Interface
(ACMI) usage. The mesh is composed of two mesh regions: an inlet channel which
oscillates in the +/- Y-direction, and a fixed mesh region.
Each ACMI patch requires the specification of a 'non-overlapping' patch. In
this example, the non-overlapping patches are described as walls, e.g. taken
from the constant/polyMesh/boundary file:
1. First ACMI poatch pair applied to the inlet channel outlet
ACMI1_blockage
{
type wall;
nFaces 40;
startFace 43680;
}
ACMI1_couple
{
type cyclicACMI;
nFaces 40;
startFace 43720;
matchTolerance 0.0001;
transform noOrdering;
neighbourPatch ACMI2_couple;
nonOverlapPatch ACMI1_blockage;
}
1. Second ACMI poatch pair applied to the fixed mesh region inlet
ACMI2_blockage
{
type wall;
nFaces 96;
startFace 43760;
}
ACMI2_couple
{
type cyclicACMI;
nFaces 96;
startFace 43856;
matchTolerance 0.0001;
transform noOrdering;
neighbourPatch ACMI1_couple;
nonOverlapPatch ACMI2_blockage;
}
In the above, the ACMI1_blockage and ACMI1_couple patches occupy the same space,
with duplicate points, edges and faces. The ACMI2_blockage and ACMI2_couple
patches are created similarly.
The duplicate patches are initially created using the createBaffles utility.
Firstly, the original (non-duplicated) patch faces are collected into zones
using the topoSet utility.
Each ACMI/no-overlapping patch pair is specified using a master-slave approach.
However, since we are generating boundary patches (which are always master
patches) the slave patches are simply defined using 'dummy' entries, e.g.:
type faceZone;
zoneName couple1Faces;
patches
{
// create blockage patch
master
{
//- Master side patch
name ACMI1_blockage;
type wall;
}
slave1 // dummy entries only
{
//- Slave side patch
name ACMI1_blockage;
type wall;
}
// create cyclic ACMI patch
master2
{
//- Master side patch
name ACMI1_couple;
type cyclicACMI;
matchTolerance 0.0001;
neighbourPatch ACMI2_couple;
nonOverlapPatch ACMI1_blockage;
transform noOrdering;
}
slave2 // dummy entries only
{
//- Slave side patch
name ACMI1_couple;
type patch;
}
}
Boundary conditions must then be applied to all geometric patches in the usual,
manner, and the cases can be executed in parallel (as shown when running the
Allrun-parallel script) without any speacial treatment, i.e. the case set-up is
the same as when operating in serial mode.

View File

@ -0,0 +1,25 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object RASProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
RASModel kEpsilon;
turbulence on;
printCoeffs on;
// ************************************************************************* //

View File

@ -0,0 +1,36 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMesh solidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solidBodyMotionFvMeshCoeffs
{
cellZone inletChannel;
solidBodyMotionFunction oscillatingLinearMotion;
oscillatingLinearMotionCoeffs
{
amplitude (0 0.5 0);
omega 3.14; // rad/s (.5 rps)
}
}
// ************************************************************************* //

View File

@ -0,0 +1,103 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
vertices
(
(0 0.3 0)
(1 0.3 0)
(1 0.7 0)
(0 0.7 0)
(0 0.3 0.1)
(1 0.3 0.1)
(1 0.7 0.1)
(0 0.7 0.1)
(1 0 0)
(3 0 0)
(3 1 0)
(1 1 0)
(1 0 0.1)
(3 0 0.1)
(3 1 0.1)
(1 1 0.1)
);
blocks
(
// hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1)
// hex (8 9 10 11 12 13 14 15) (40 48 1) simpleGrading (1 1 1)
hex (0 1 2 3 4 5 6 7) (80 40 1) simpleGrading (1 1 1)
hex (8 9 10 11 12 13 14 15) (80 96 1) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
inlet
{
type patch;
faces
(
(0 4 7 3)
);
}
outlet
{
type patch;
faces
(
(10 14 13 9)
);
}
walls
{
type wall;
faces
(
(3 7 6 2)
(1 5 4 0)
(11 15 14 10)
(9 13 12 8)
);
}
couple1
{
type patch;
faces
(
(2 6 5 1)
);
}
couple2
{
type patch;
faces
(
(8 12 15 11)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,81 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class polyBoundaryMesh;
location "constant/polyMesh";
object boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
8
(
inlet
{
type patch;
nFaces 40;
startFace 21464;
}
outlet
{
type patch;
nFaces 96;
startFace 21504;
}
walls
{
type wall;
nFaces 320;
startFace 21600;
}
defaultFaces
{
type empty;
inGroups 1(empty);
nFaces 21760;
startFace 21920;
}
ACMI1_blockage
{
type wall;
nFaces 40;
startFace 43680;
}
ACMI1_couple
{
type cyclicACMI;
inGroups 1(cyclicACMI);
nFaces 40;
startFace 43720;
matchTolerance 0.0001;
transform noOrdering;
neighbourPatch ACMI2_couple;
nonOverlapPatch ACMI1_blockage;
}
ACMI2_blockage
{
type wall;
nFaces 96;
startFace 43760;
}
ACMI2_couple
{
type cyclicACMI;
inGroups 1(cyclicACMI);
nFaces 96;
startFace 43856;
matchTolerance 0.0001;
transform noOrdering;
neighbourPatch ACMI1_couple;
nonOverlapPatch ACMI2_blockage;
}
)
// ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
transportModel Newtonian;
nu nu [ 0 2 -1 0 0 0 0 ] 1e-6;
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType RASModel;
// ************************************************************************* //

View File

@ -0,0 +1,53 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application pimpleDyMFoam;
startFrom latestTime;
startTime 0;
stopAt endTime;
endTime 5;
deltaT 0.005;
writeControl adjustableRunTime;
writeInterval 0.05;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable true;
adjustTimeStep true;
maxCo 0.5;
// ************************************************************************* //

View File

@ -0,0 +1,107 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object createBafflesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Whether to convert internal faces only (so leave boundary faces intact).
// This is only relevant if your face selection type can pick up boundary
// faces.
internalFacesOnly false;
// Baffles to create.
baffles
{
ACMI1
{
//- Use predefined faceZone to select faces and orientation.
type faceZone;
zoneName couple1Faces;
patches
{
master
{
//- Master side patch
name ACMI1_blockage;
type wall;
}
slave // not used since we're manipulating a boundary patch
{
//- Slave side patch
name ACMI1_blockage;
type wall;
}
master2
{
//- Master side patch
name ACMI1_couple;
type cyclicACMI;
matchTolerance 0.0001;
neighbourPatch ACMI2_couple;
nonOverlapPatch ACMI1_blockage;
transform noOrdering;
}
slave2 // not used since we're manipulating a boundary patch
{
//- Slave side patch
name ACMI1_couple;
type patch;
}
}
}
ACMI2
{
//- Use predefined faceZone to select faces and orientation.
type faceZone;
zoneName couple2Faces;
patches
{
master
{
//- Master side patch
name ACMI2_blockage;
type wall;
}
slave // not used since we're manipulating a boundary patch
{
//- Slave side patch
name ACMI2_blockage;
type wall;
}
master2
{
//- Master side patch
name ACMI2_couple;
type cyclicACMI;
matchTolerance 0.0001;
neighbourPatch ACMI1_couple;
nonOverlapPatch ACMI2_blockage;
transform noOrdering;
}
slave2 // not used since we're manipulating a boundary patch
{
//- Slave side patch
name ACMI2_couple;
type patch;
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,54 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object createPatchDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// This application/dictionary controls:
// - optional: create new patches from boundary faces (either given as
// a set of patches or as a faceSet)
// - always: order faces on coupled patches such that they are opposite. This
// is done for all coupled faces, not just for any patches created.
// - optional: synchronise points on coupled patches.
// 1. Create cyclic:
// - specify where the faces should come from
// - specify the type of cyclic. If a rotational specify the rotationAxis
// and centre to make matching easier
// - always create both halves in one invocation with correct 'neighbourPatch'
// setting.
// - optionally pointSync true to guarantee points to line up.
// 2. Correct incorrect cyclic:
// This will usually fail upon loading:
// "face 0 area does not match neighbour 2 by 0.0100005%"
// " -- possible face ordering problem."
// - in polyMesh/boundary file:
// - loosen matchTolerance of all cyclics to get case to load
// - or change patch type from 'cyclic' to 'patch'
// and regenerate cyclic as above
// Do a synchronisation of coupled points after creation of any patches.
// Note: this does not work with points that are on multiple coupled patches
// with transformations (i.e. cyclics).
pointSync false;
// Patches to create.
patches
(
// none
);
// ************************************************************************* //

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