/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2022-2023 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 "Time.H" #include "emptyPointPatchField.H" #include "IOobjectList.H" #include "mapDistributePolyMesh.H" #include "distributedFieldMapper.H" #include "distributedPointPatchFieldMapper.H" #include "pointFields.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template Foam::tmp> Foam::parPointFieldDistributor::distributeField ( const GeometricField& fld ) const { if (!tgtMeshRef_ || !distMapRef_) { FatalErrorInFunction << "Cannot map field without target mesh and/or distribution!" << abort(FatalError); } if (!hasPatchPointMaps()) { const_cast(*this).createPatchPointMaps(); } const auto& tgtMesh = tgtMeshRef_(); const auto& distMap = distMapRef_(); // Create internalField by remote mapping distributedFieldMapper mapper ( labelUList::null(), distMap.pointMap() ); DimensionedField internalField ( IOobject ( fld.name(), tgtMesh.time().timeName(), fld.local(), tgtMesh.thisDb(), IOobject::NO_READ, IOobject::NO_WRITE ), tgtMesh, fld.dimensions(), Field(fld.internalField(), mapper) ); internalField.oriented() = fld.oriented(); // Create patchFields by remote mapping PtrList> newPatchFields(tgtMesh.boundary().size()); const auto& bfld = fld.boundaryField(); forAll(bfld, patchi) { if (patchPointMaps_.set(patchi)) { // Clone local patch field const distributedPointPatchFieldMapper mapper ( labelUList::null(), patchPointMaps_[patchi] ); // Map into local copy newPatchFields.set ( patchi, pointPatchField::New ( bfld[patchi], tgtMesh.boundary()[patchi], // pointPatch DimensionedField::null(), mapper ) ); // Note: below alternative, 'clone' method will not work since // there is no clone to reset both internalField reference and // patch reference. TBD. //newPatchFields.set //( // patchi, // bfld[patchi].clone // ( // tgtMesh.boundary()[patchi], // DimensionedField::null(), // mapper // ) //); } } // Add some empty patchFields on remaining patches (this also handles // e.g. processorPatchFields or any other constraint type patches) forAll(newPatchFields, patchi) { if (!newPatchFields.set(patchi)) { newPatchFields.set ( patchi, pointPatchField::New ( emptyPointPatchField::typeName, tgtMesh.boundary()[patchi], DimensionedField::null() ) ); } } return tmp>::New ( std::move(internalField), newPatchFields ); } template Foam::tmp> Foam::parPointFieldDistributor::distributePointField ( const IOobject& fieldObject ) const { // Read field GeometricField fld ( fieldObject, srcMesh_ ); // Redistribute return distributeField(fld); } template Foam::label Foam::parPointFieldDistributor::distributePointFields ( const IOobjectList& objects, const wordRes& selectedFields ) const { typedef GeometricField fieldType; const UPtrList fieldObjects ( selectedFields.empty() ? objects.csorted() : objects.csorted(selectedFields) ); label nFields = 0; for (const IOobject& io : fieldObjects) { if (verbose_) { if (!nFields) { Info<< " Reconstructing " << fieldType::typeName << "s\n" << nl; } Info<< " " << io.name() << nl; } ++nFields; tmp tfld(distributePointField(io)); if (isWriteProc_.good()) { if (isWriteProc_) { tfld().write(); } } else if (writeHandler_ && writeHandler_->good()) { auto oldHandler = fileOperation::fileHandler(writeHandler_); const label oldComm = UPstream::commWorld(fileHandler().comm()); tfld().write(); writeHandler_ = fileOperation::fileHandler(oldHandler); UPstream::commWorld(oldComm); } } if (nFields && verbose_) Info<< endl; return nFields; } template void Foam::parPointFieldDistributor::distributeAndStore ( const PtrList>& fields ) const { for (const auto& fld : fields) { // Distribute and store auto tfld = distributeField(fld); tfld.ref().writeOpt(IOobject::AUTO_WRITE); tfld().mesh().thisDb().store(tfld); } } // ************************************************************************* //