/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2021-2022 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 "fvExpressionField.H" #include "volFields.H" #include "surfaceFields.H" #include "pointMesh.H" #include "pointFields.H" #include "volumeExprDriver.H" #include "calculatedFvPatchField.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { namespace functionObjects { defineTypeNameAndDebug(fvExpressionField, 0); addToRunTimeSelectionTable(functionObject, fvExpressionField, dictionary); } } const Foam::Enum < Foam::functionObjects::fvExpressionField::actionType > Foam::functionObjects::fvExpressionField::actionNames_ ({ { actionType::opNone, "none" }, { actionType::opNew, "new" }, { actionType::opModify, "modify" }, }); // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // namespace Foam { word fieldGeoType(const expressions::FieldAssociation geoType) { switch (geoType) { case expressions::FieldAssociation::POINT_DATA : return "points"; break; case expressions::FieldAssociation::FACE_DATA : return "faces"; break; case expressions::FieldAssociation::VOLUME_DATA : return "cells"; break; default: break; } return "unknown"; } template static void doCorrectBoundaryConditions ( bool correctBCs, VolumeField& field ) { if (correctBCs) { // Info<< "Correcting boundary conditions: " << field.name() << nl; field.correctBoundaryConditions(); // Ensure that calculated patches are updated for (auto& pf : field.boundaryFieldRef()) { if (isA>(pf)) { pf = pf.patchInternalField(); } } } } template void doCorrectBoundaryConditions ( bool correctBCs, PointField& field ) { if (correctBCs) { // Info<< "Correcting boundary conditions: " << field.name() << nl; field.correctBoundaryConditions(); } } template void doCorrectBoundaryConditions ( bool correctBCs, SurfaceField& field ) {} } // End namespace Foam // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template bool Foam::functionObjects::fvExpressionField::loadAndStore(const IOobject& io) { if (FieldType::typeName == io.headerClassName()) { // Store field on mesh database Log << " Reading " << io.name() << " (" << FieldType::typeName << ')' << endl; mesh_.objectRegistry::store(new FieldType(io, mesh_)); return true; } return false; } template bool Foam::functionObjects::fvExpressionField::loadField(const IOobject& io) { return ( loadAndStore>(io) /// || loadAndStore>(io) || loadAndStore>(io) ); } Foam::label Foam::functionObjects::fvExpressionField::loadFields ( const UList& fieldSet_ ) { label nLoaded = 0; for (const word& fieldName : fieldSet_) { // Already loaded? const auto* ptr = mesh_.cfindObject(fieldName); if (ptr) { ++nLoaded; DebugInfo << "readFields : " << ptr->name() << " (" << ptr->type() << ") already in database" << endl; continue; } // Load field as necessary IOobject io ( fieldName, mesh_.time().timeName(), mesh_, IOobject::MUST_READ, IOobject::NO_WRITE ); const bool ok = ( io.typeHeaderOk(false) // Preload header info && !io.headerClassName().empty() // Extra safety && ( loadField(io) || loadField(io) || loadField(io) || loadField(io) || loadField(io) ) ); if (ok) { ++nLoaded; } else { DebugInfo << "readFields : failed to load " << fieldName << endl; } } return nLoaded; } template bool Foam::functionObjects::fvExpressionField::setField ( GeoField& output, const GeoField& evaluated, const boolField& fieldMask ) { label numValuesChanged = 0; // Internal field if (fieldMask.empty()) { // No field-mask - set all numValuesChanged = output.size(); output.primitiveFieldRef() = evaluated; } else { auto& internal = output.primitiveFieldRef(); forAll(internal, idx) { if (fieldMask[idx]) { internal[idx] = evaluated[idx]; ++numValuesChanged; } } } // Boundary fields forAll(evaluated.boundaryField(), patchi) { auto& pf = output.boundaryFieldRef()[patchi]; if (pf.patch().coupled()) { pf == evaluated.boundaryField()[patchi]; } } doCorrectBoundaryConditions(true, output); if (action_ == actionType::opModify && log) { const label numTotal = returnReduce(output.size(), sumOp