/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2019-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 "primitivePatchInterpolation.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template Foam::tmp> Foam::expressions::patchExpr::parseDriver::getVariableIfAvailable ( const word& name ) const { bool hasPointData = false; refPtr tvar; if (hasVariable(name) && variable(name).isType()) { tvar.cref(variable(name)); hasPointData = tvar().isPointData(); } else if (isGlobalVariable(name)) { tvar.cref(lookupGlobal(name)); } if (tvar.valid()) { const auto& var = tvar.cref(); const Field& vals = var.cref(); const label len = (hasPointData ? this->pointSize() : this->size()); if (returnReduceAnd(vals.size() == len)) { // Return a copy of the field return tmp>::New(vals); } if (!var.isUniform()) { WarningInFunction << "Variable " << name << " is nonuniform and does not fit the size" << ". Using average" << endl; } return tmp>::New(this->size(), gAverage(vals)); } return nullptr; } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::getVolField(const word& name) { return getField(name); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::getSurfaceField(const word& name) { return getField(name); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::getPointField(const word& name) { return getField(name); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::getField(const word& name) { tmp> tfield = getVariableIfAvailable(name); if (tfield.valid()) { return tfield; } const objectRegistry& obr = this->mesh().thisDb(); const label patchIndex = patch_.index(); // Local, temporary storage and/or lookup values bool found = false; tmp> vfield; tmp> sfield; tmp> pfield; for (int checki = 0; !found && checki < 2; ++checki) { // Check 0: object context (first) // Check 1: regular objectRegistry const regIOobject* ioptr = ( (checki == 0) ? exprDriver::cfindContextIOobject(name) : obr.cfindIOobject(name) ); if (!ioptr) continue; if (!found) { vfield.cref(dynamic_cast*>(ioptr)); found = vfield.valid(); } if (!found) { sfield.cref(dynamic_cast*>(ioptr)); found = sfield.valid(); } if (!found) { pfield.cref(dynamic_cast*>(ioptr)); found = pfield.valid(); } } // Finally, search files if necessary (and permitted) if (!found && searchFiles()) { const word fldType = this->getTypeOfField(name); if (fldType == VolumeField::typeName) { vfield = this->readAndRegister>(name, mesh()); } else if (fldType == SurfaceField::typeName) { sfield = this->readAndRegister>(name, mesh()); } else if (fldType == PointField::typeName) { pfield = this->readAndRegister> ( name, pointMesh::New(mesh()) ); } } if (vfield.valid()) { return tmp>::New ( vfield().boundaryField()[patchIndex] ); } if (sfield.valid()) { return tmp>::New ( sfield().boundaryField()[patchIndex] ); } if (pfield.valid()) { return pfield().boundaryField()[patchIndex].patchInternalField(); } FatalErrorInFunction << "No field '" << name << "' of type " << pTraits::typeName << nl << nl; FatalError << VolumeField::typeName << " Fields: " << flatOutput(obr.sortedNames>()) << nl; FatalError << SurfaceField::typeName << " Fields: " << flatOutput(obr.sortedNames>()) << nl; FatalError << PointField::typeName << " Fields: " << flatOutput(obr.sortedNames>()) << nl; FatalError << exit(FatalError); return tmp>::New(); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::patchInternalField ( const word& name ) { tmp> tfield = getVariableIfAvailable(name); if (tfield.valid()) { return tfield; } const objectRegistry& obr = this->mesh().thisDb(); const label patchIndex = patch_.index(); // Local, temporary storage and/or lookup values bool found = false; tmp> vfield; tmp> pfield; for (int checki = 0; !found && checki < 2; ++checki) { // Check 0: object context (first) // Check 1: regular objectRegistry const regIOobject* ioptr = ( (checki == 0) ? exprDriver::cfindContextIOobject(name) : obr.cfindIOobject(name) ); if (!ioptr) continue; if (!found) { vfield.cref(dynamic_cast*>(ioptr)); found = vfield.valid(); } if (!found) { pfield.cref(dynamic_cast*>(ioptr)); found = pfield.valid(); } } // Finally, search files if necessary (and permitted) if (!found && searchFiles()) { const word fldType = this->getTypeOfField(name); if (fldType == VolumeField::typeName) { vfield = this->readAndRegister>(name, mesh()); } else if (fldType == PointField::typeName) { pfield = this->readAndRegister> ( name, pointMesh::New(mesh()) ); } } if (vfield.valid()) { return vfield().boundaryField()[patchIndex].patchInternalField(); } if (pfield.valid()) { return pfield().boundaryField()[patchIndex].patchInternalField(); } FatalErrorInFunction << "No field '" << name << "' of type " << pTraits::typeName << nl << nl; FatalError << VolumeField::typeName << " Fields: " << flatOutput(obr.sortedNames>()) << nl; FatalError << PointField::typeName << " Fields: " << flatOutput(obr.sortedNames>()) << nl; FatalError << exit(FatalError); return tmp>::New(); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::patchNeighbourField ( const word& name ) { tmp> tfield = getVariableIfAvailable(name); if (tfield.valid()) { return tfield; } const objectRegistry& obr = this->mesh().thisDb(); const label patchIndex = patch_.index(); // Local, temporary storage and/or lookup values bool found = false; tmp> vfield; for (int checki = 0; !found && checki < 2; ++checki) { // Check 0: object context (first) // Check 1: regular objectRegistry const regIOobject* ioptr = ( (checki == 0) ? exprDriver::cfindContextIOobject(name) : obr.cfindIOobject(name) ); if (!ioptr) continue; if (!found) { vfield.cref(dynamic_cast*>(ioptr)); found = vfield.valid(); } } // Finally, search files if necessary (and permitted) if (!found && searchFiles()) { const word fldType = this->getTypeOfField(name); if (fldType == VolumeField::typeName) { vfield = this->readAndRegister>(name, mesh()); } } if (vfield.valid()) { return vfield().boundaryField()[patchIndex].patchNeighbourField(); } FatalErrorInFunction << "No field '" << name << "' of type " << pTraits::typeName << nl << nl; FatalError << VolumeField::typeName << " Fields: " << flatOutput(obr.sortedNames>()) << nl; FatalError << exit(FatalError); return tmp>::New(); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::patchNormalField ( const word& name ) { tmp> tfield = getVariableIfAvailable(name); if (tfield.valid()) { return tfield; } const objectRegistry& obr = this->mesh().thisDb(); const label patchIndex = patch_.index(); // Local, temporary storage and/or lookup values bool found = false; tmp> vfield; for (int checki = 0; !found && checki < 2; ++checki) { // Check 0: object context (first) // Check 1: regular objectRegistry const regIOobject* ioptr = ( (checki == 0) ? exprDriver::cfindContextIOobject(name) : obr.cfindIOobject(name) ); if (!ioptr) continue; if (!found) { vfield.cref(dynamic_cast*>(ioptr)); found = vfield.valid(); } } // Finally, search files if necessary (and permitted) if (!found && searchFiles()) { const word fldType = this->getTypeOfField(name); if (fldType == VolumeField::typeName) { vfield = this->readAndRegister>(name, mesh()); } } if (vfield.valid()) { return vfield().boundaryField()[patchIndex].snGrad(); } FatalErrorInFunction << "No field '" << name << "' of type " << pTraits::typeName << nl << nl; FatalError << VolumeField::typeName << " Fields: " << flatOutput(obr.sortedNames>()) << nl; FatalError << exit(FatalError); return tmp>::New(); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::faceToPoint ( const Field& field ) const { primitivePatchInterpolation interp(patch_.patch()); return interp.faceToPointInterpolate(field); } template Foam::tmp> Foam::expressions::patchExpr::parseDriver::pointToFace ( const Field& field ) const { primitivePatchInterpolation interp(patch_.patch()); return interp.pointToFaceInterpolate(field); } // ************************************************************************* //