/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2019 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "fvMatrix.H" #include "cyclicFvPatchField.H" #include "transformField.H" #include "volFields.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template Foam::cyclicFvPatchField::cyclicFvPatchField ( const fvPatch& p, const DimensionedField& iF ) : coupledFvPatchField(p, iF), cyclicPatch_(refCast(p)) {} template Foam::cyclicFvPatchField::cyclicFvPatchField ( const fvPatch& p, const DimensionedField& iF, const dictionary& dict, const bool needValue ) : coupledFvPatchField(p, iF, dict, IOobjectOption::NO_READ), cyclicPatch_(refCast(p, dict)) { if (!isA(p)) { FatalIOErrorInFunction(dict) << " patch type '" << p.type() << "' not constraint type '" << typeName << "'" << "\n for patch " << p.name() << " of field " << this->internalField().name() << " in file " << this->internalField().objectPath() << exit(FatalIOError); } if (needValue) { this->evaluate(Pstream::commsTypes::buffered); } } template Foam::cyclicFvPatchField::cyclicFvPatchField ( const cyclicFvPatchField& ptf, const fvPatch& p, const DimensionedField& iF, const fvPatchFieldMapper& mapper ) : coupledFvPatchField(ptf, p, iF, mapper), cyclicPatch_(refCast(p)) { if (!isA(this->patch())) { FatalErrorInFunction << "\n patch type '" << p.type() << "' not constraint type '" << typeName << "'" << "\n for patch " << p.name() << " of field " << this->internalField().name() << " in file " << this->internalField().objectPath() << exit(FatalError); } } template Foam::cyclicFvPatchField::cyclicFvPatchField ( const cyclicFvPatchField& ptf ) : cyclicLduInterfaceField(), coupledFvPatchField(ptf), cyclicPatch_(ptf.cyclicPatch_) {} template Foam::cyclicFvPatchField::cyclicFvPatchField ( const cyclicFvPatchField& ptf, const DimensionedField& iF ) : coupledFvPatchField(ptf, iF), cyclicPatch_(ptf.cyclicPatch_) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template void Foam::cyclicFvPatchField::patchNeighbourField(UList& pnf) const { const Field& iField = this->primitiveField(); const labelUList& nbrFaceCells = cyclicPatch().cyclicPatch().neighbPatch().faceCells(); if (doTransform()) { forAll(pnf, facei) { pnf[facei] = transform ( forwardT()[0], iField[nbrFaceCells[facei]] ); } } else { forAll(pnf, facei) { pnf[facei] = iField[nbrFaceCells[facei]]; } } } template Foam::tmp> Foam::cyclicFvPatchField::patchNeighbourField() const { auto tpnf = tmp>::New(this->size()); this->patchNeighbourField(tpnf.ref()); return tpnf; } template const Foam::cyclicFvPatchField& Foam::cyclicFvPatchField::neighbourPatchField() const { const auto& fld = static_cast&> ( this->primitiveField() ); return refCast> ( fld.boundaryField()[this->cyclicPatch().neighbPatchID()] ); } template void Foam::cyclicFvPatchField::updateInterfaceMatrix ( solveScalarField& result, const bool add, const lduAddressing& lduAddr, const label patchId, const solveScalarField& psiInternal, const scalarField& coeffs, const direction cmpt, const Pstream::commsTypes commsType ) const { const labelUList& nbrFaceCells = lduAddr.patchAddr ( this->cyclicPatch().neighbPatchID() ); solveScalarField pnf(psiInternal, nbrFaceCells); // Transform according to the transformation tensors transformCoupleField(pnf, cmpt); const labelUList& faceCells = lduAddr.patchAddr(patchId); // Multiply the field by coefficients and add into the result this->addToInternalField(result, !add, faceCells, coeffs, pnf); } template void Foam::cyclicFvPatchField::updateInterfaceMatrix ( Field& result, const bool add, const lduAddressing& lduAddr, const label patchId, const Field& psiInternal, const scalarField& coeffs, const Pstream::commsTypes ) const { const labelUList& nbrFaceCells = lduAddr.patchAddr ( this->cyclicPatch().neighbPatchID() ); Field pnf(psiInternal, nbrFaceCells); // Transform according to the transformation tensors transformCoupleField(pnf); const labelUList& faceCells = lduAddr.patchAddr(patchId); // Multiply the field by coefficients and add into the result this->addToInternalField(result, !add, faceCells, coeffs, pnf); } template void Foam::cyclicFvPatchField::write(Ostream& os) const { fvPatchField::write(os); } template void Foam::cyclicFvPatchField::manipulateMatrix ( fvMatrix& matrix, const label mat, const direction cmpt ) { if (this->cyclicPatch().owner()) { label index = this->patch().index(); const label globalPatchID = matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][index]; const Field intCoeffsCmpt ( matrix.internalCoeffs()[globalPatchID].component(cmpt) ); const Field boundCoeffsCmpt ( matrix.boundaryCoeffs()[globalPatchID].component(cmpt) ); const labelUList& u = matrix.lduAddr().upperAddr(); const labelUList& l = matrix.lduAddr().lowerAddr(); const labelList& faceMap = matrix.lduMeshAssembly().faceBoundMap()[mat][index]; forAll (faceMap, faceI) { label globalFaceI = faceMap[faceI]; const scalar boundCorr = -boundCoeffsCmpt[faceI]; const scalar intCorr = -intCoeffsCmpt[faceI]; matrix.upper()[globalFaceI] += boundCorr; matrix.diag()[u[globalFaceI]] -= boundCorr; matrix.diag()[l[globalFaceI]] -= intCorr; if (matrix.asymmetric()) { matrix.lower()[globalFaceI] += intCorr; } } if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name())) { matrix.internalCoeffs().set ( globalPatchID, intCoeffsCmpt*pTraits::one ); matrix.boundaryCoeffs().set ( globalPatchID, boundCoeffsCmpt*pTraits::one ); const label nbrPathID = this->cyclicPatch().neighbPatchID(); const label nbrGlobalPatchID = matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][nbrPathID]; matrix.internalCoeffs().set ( nbrGlobalPatchID, intCoeffsCmpt*pTraits::one ); matrix.boundaryCoeffs().set ( nbrGlobalPatchID, boundCoeffsCmpt*pTraits::one ); } } } // ************************************************************************* //