/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org \\ / A nd | Copyright (C) 2011-2022 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 . \*---------------------------------------------------------------------------*/ #include "fvFieldReconstructor.H" #include "Time.H" #include "PtrList.H" #include "fvPatchFields.H" #include "emptyFvPatch.H" #include "emptyFvPatchField.H" #include "emptyFvsPatchField.H" #include "processorCyclicFvPatch.H" #include "stringOps.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template void Foam::fvFieldReconstructor::rmapFaceToFace ( Field& toField, const Field& fromField, const labelUList& addressing, const bool isFlux ) { forAll(addressing, i) { toField[mag(addressing[i]) - 1] = (isFlux && addressing[i] < 0 ? -1 : +1)*fromField[i]; } } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template Foam::tmp> Foam::fvFieldReconstructor::reconstructFvVolumeInternalField ( const IOobject& fieldIoObject, const PtrList>& procFields ) const { // Create the internalField Field internalField(completeMesh_.nCells()); forAll(procMeshes_, proci) { const DimensionedField& procField = procFields[proci]; // Set the cell values in the reconstructed field internalField.rmap ( procField.field(), cellProcAddressing_[proci] ); } return tmp> ( new DimensionedField ( fieldIoObject, completeMesh_, procFields[0].dimensions(), internalField ) ); } template Foam::tmp> Foam::fvFieldReconstructor::reconstructFvVolumeInternalField ( const IOobject& fieldIoObject ) const { PtrList> procFields(procMeshes_.size()); forAll(procMeshes_, proci) { procFields.set ( proci, new DimensionedField ( IOobject ( fieldIoObject.name(), procMeshes_[proci].time().name(), procMeshes_[proci], IOobject::MUST_READ, IOobject::NO_WRITE, false ), procMeshes_[proci] ) ); } return reconstructFvVolumeInternalField ( IOobject ( fieldIoObject.name(), completeMesh_.time().name(), completeMesh_, IOobject::NO_READ, IOobject::NO_WRITE, false ), procFields ); } template Foam::tmp> Foam::fvFieldReconstructor::reconstructFvVolumeField ( const IOobject& fieldIoObject, const PtrList>& procFields ) const { // Create the internalField Field internalField(completeMesh_.nCells()); // Create the patch fields PtrList> patchFields(completeMesh_.boundary().size()); forAll(procFields, proci) { const VolField& procField = procFields[proci]; // Set the cell values in the reconstructed field internalField.rmap ( procField.primitiveField(), cellProcAddressing_[proci] ); // Set the boundary patch values in the reconstructed field forAll(procField.boundaryField(), procPatchi) { const fvPatch& procPatch = procMeshes_[proci].boundary()[procPatchi]; const label completePatchi = completePatchID(proci, procPatchi); if (completePatchi == procPatchi) { if (!patchFields(completePatchi)) { patchFields.set ( completePatchi, fvPatchField::New ( procField.boundaryField()[procPatchi], completeMesh_.boundary()[completePatchi], DimensionedField::null(), fvPatchFieldReconstructor ( completeMesh_.boundary()[completePatchi].size() ) ) ); } patchFields[completePatchi].rmap ( procField.boundaryField()[procPatchi], faceProcAddressingBf_[proci][procPatchi] - 1 ); } else if (isA(procPatch)) { if (!patchFields(completePatchi)) { patchFields.set ( completePatchi, fvPatchField::New ( completeMesh_.boundary()[completePatchi].type(), completeMesh_.boundary()[completePatchi], DimensionedField::null() ) ); } if (patchFields[completePatchi].overridesConstraint()) { OStringStream str; str << "\nThe field \"" << procFields[0].name() << "\" on cyclic patch \"" << patchFields[completePatchi].patch().name() << "\" cannot be reconstructed as it is not a cyclic " << "patch field. A \"patchType cyclic;\" setting has " << "been used to override the cyclic patch type.\n\n" << "Cyclic patches like this with non-cyclic boundary " << "conditions should be confined to a single " << "processor using decomposition constraints."; FatalErrorInFunction << stringOps::breakIntoIndentedLines(str.str()).c_str() << exit(FatalError); } patchFields[completePatchi].rmap ( procField.boundaryField()[procPatchi], faceProcAddressingBf_[proci][procPatchi] - 1 ); } } } // Construct and return the field return tmp> ( new VolField ( fieldIoObject, completeMesh_, procFields[0].dimensions(), internalField, patchFields ) ); } template Foam::tmp> Foam::fvFieldReconstructor::reconstructFvVolumeField ( const IOobject& fieldIoObject ) const { PtrList> procFields(procMeshes_.size()); forAll(procMeshes_, proci) { procFields.set ( proci, new VolField ( IOobject ( fieldIoObject.name(), procMeshes_[proci].time().name(), procMeshes_[proci], IOobject::MUST_READ, IOobject::NO_WRITE, false ), procMeshes_[proci] ) ); } return reconstructFvVolumeField ( IOobject ( fieldIoObject.name(), completeMesh_.time().name(), completeMesh_, IOobject::NO_READ, IOobject::NO_WRITE, false ), procFields ); } template Foam::tmp> Foam::fvFieldReconstructor::reconstructFvSurfaceField ( const IOobject& fieldIoObject, const PtrList>& procFields ) const { // Create the internalField Field internalField(completeMesh_.nInternalFaces()); // Create the patch fields PtrList> patchFields(completeMesh_.boundary().size()); forAll(procMeshes_, proci) { const SurfaceField& procField = procFields[proci]; // Set the internal face values in the reconstructed field rmapFaceToFace ( internalField, procField.primitiveField(), SubList