/*---------------------------------------------------------------------------*\ ========= | \\ / 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 . Description Set values on a selected set of cells/patchfaces through a dictionary. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Time.H" #include "fvMesh.H" #include "topoSetSource.H" #include "cellSet.H" #include "faceSet.H" #include "volFields.H" #include "systemDict.H" #include "processorFvPatch.H" #include "CompactListList.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template bool setCellFieldType ( const word& fieldTypeDesc, const fvMesh& mesh, const labelList& selectedCells, Istream& fieldValueStream ) { if (fieldTypeDesc != VolField::typeName + "Value") { return false; } word fieldName(fieldValueStream); // Check the current time directory typeIOobject> fieldHeader ( fieldName, mesh.time().name(), mesh, IOobject::MUST_READ ); // Check the "constant" directory if (!fieldHeader.headerOk()) { fieldHeader = typeIOobject> ( fieldName, mesh.time().constant(), mesh, IOobject::MUST_READ ); } // Check field exists if (fieldHeader.headerOk()) { Info<< " Setting internal values of " << fieldHeader.headerClassName() << " " << fieldName << endl; VolField field(fieldHeader, mesh); const Type value = pTraits(fieldValueStream); if (selectedCells.size() == field.size()) { field.primitiveFieldRef() = value; } else { forAll(selectedCells, celli) { field[selectedCells[celli]] = value; } } typename VolField:: Boundary& fieldBf = field.boundaryFieldRef(); forAll(field.boundaryField(), patchi) { fieldBf[patchi] = fieldBf[patchi].patchInternalField(); } if (!field.write()) { FatalErrorInFunction << "Failed writing field " << fieldName << endl; } } else { WarningInFunction << "Field " << fieldName << " not found" << endl; // Consume value (void)pTraits(fieldValueStream); } return true; } class setCellField { public: setCellField() {} autoPtr clone() const { return autoPtr(new setCellField()); } class iNew { const fvMesh& mesh_; const labelList& selectedCells_; public: iNew(const fvMesh& mesh, const labelList& selectedCells) : mesh_(mesh), selectedCells_(selectedCells) {} autoPtr operator()(Istream& fieldValues) const { word fieldType(fieldValues); if ( !( setCellFieldType (fieldType, mesh_, selectedCells_, fieldValues) || setCellFieldType (fieldType, mesh_, selectedCells_, fieldValues) || setCellFieldType (fieldType, mesh_, selectedCells_, fieldValues) || setCellFieldType (fieldType, mesh_, selectedCells_, fieldValues) || setCellFieldType (fieldType, mesh_, selectedCells_, fieldValues) ) ) { WarningInFunction << "field type " << fieldType << " not currently supported" << endl; } return autoPtr(new setCellField()); } }; }; template bool setFaceFieldType ( const word& fieldTypeDesc, const fvMesh& mesh, const labelList& selectedFaces, Istream& fieldValueStream ) { if (fieldTypeDesc != VolField::typeName + "Value") { return false; } word fieldName(fieldValueStream); // Check the current time directory typeIOobject> fieldHeader ( fieldName, mesh.time().name(), mesh, IOobject::MUST_READ ); // Check the "constant" directory if (!fieldHeader.headerOk()) { fieldHeader = typeIOobject> ( fieldName, mesh.time().constant(), mesh, IOobject::MUST_READ ); } // Check field exists if (fieldHeader.headerOk()) { Info<< " Setting patchField values of " << fieldHeader.headerClassName() << " " << fieldName << endl; // Read the field VolField field(fieldHeader, mesh); typename VolField::Boundary& fieldBf = field.boundaryFieldRef(); // Read the value const Type value = pTraits(fieldValueStream); // Determine the number of non-processor patches label nNonProcPatches = 0; forAll(fieldBf, patchi) { nNonProcPatches = patchi; if (isA(mesh.boundary()[patchi])) { break; } } // Create a copy of the boundary field typename VolField::Boundary fieldBfCopy ( VolField::Internal::null(), fieldBf ); // Loop selected faces and set values in the copied boundary field bool haveWarnedInternal = false, haveWarnedProc = false; labelList nonProcPatchNChangedFaces(nNonProcPatches, 0); forAll(selectedFaces, i) { const label facei = selectedFaces[i]; if (mesh.isInternalFace(facei)) { if (!haveWarnedInternal) { WarningInFunction << "Ignoring internal face " << facei << ". Suppressing further warnings." << endl; haveWarnedInternal = true; } } else { const labelUList patches = mesh.polyBFacePatches()[facei - mesh.nInternalFaces()]; const labelUList patchFaces = mesh.polyBFacePatchFaces()[facei - mesh.nInternalFaces()]; forAll(patches, i) { if (patches[i] >= nNonProcPatches) { if (!haveWarnedProc) { WarningInFunction << "Ignoring face " << patchFaces[i] << " of processor patch " << patches[i] << ". Suppressing further warnings." << endl; haveWarnedProc = true; } } else { fieldBfCopy[patches[i]][patchFaces[i]] = value; nonProcPatchNChangedFaces[patches[i]] ++; } } } } Pstream::listCombineGather ( nonProcPatchNChangedFaces, plusEqOp