void Foam::fvMeshTools::addPatchFields ( fvMesh& mesh, const dictionary& patchFieldDict, const word& defaultPatchFieldType, const typename GeoField::value_type& defaultPatchValue ) { HashTable<GeoField*> flds ( mesh.objectRegistry::lookupClass<GeoField>() ); forAllIter(typename HashTable<GeoField*>, flds, iter) { GeoField& fld = *iter(); typename GeoField::GeometricBoundaryField& bfld = fld.boundaryField(); label sz = bfld.size(); bfld.setSize(sz+1); if (patchFieldDict.found(fld.name())) { bfld.set ( sz, GeoField::PatchFieldType::New ( mesh.boundary()[sz], fld.dimensionedInternalField(), patchFieldDict.subDict(fld.name()) ) ); } else { bfld.set ( sz, GeoField::PatchFieldType::New ( defaultPatchFieldType, mesh.boundary()[sz], fld.dimensionedInternalField() ) ); bfld[sz] == defaultPatchValue; } } }
void calcYPlus ( const TurbulenceModel& turbulenceModel, const fvMesh& mesh, const volVectorField& U, volScalarField& yPlus ) { volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y(); const volScalarField::GeometricBoundaryField nutBf = turbulenceModel->nut()().boundaryField(); const volScalarField::GeometricBoundaryField nuEffBf = turbulenceModel->nuEff()().boundaryField(); const volScalarField::GeometricBoundaryField nuBf = turbulenceModel->nu()().boundaryField(); const fvPatchList& patches = mesh.boundary(); forAll(patches, patchi) { const fvPatch& patch = patches[patchi]; if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi])) { const nutWallFunctionFvPatchScalarField& nutPf = dynamic_cast<const nutWallFunctionFvPatchScalarField&> ( nutBf[patchi] ); yPlus.boundaryField()[patchi] = nutPf.yPlus(); const scalarField& Yp = yPlus.boundaryField()[patchi]; Info<< "Patch " << patchi << " named " << nutPf.patch().name() << ", wall-function " << nutPf.type() << ", y+ : min: " << gMin(Yp) << " max: " << gMax(Yp) << " average: " << gAverage(Yp) << nl << endl; } else if (isA<wallFvPatch>(patch)) { yPlus.boundaryField()[patchi] = d[patchi] *sqrt ( nuEffBf[patchi] *mag(U.boundaryField()[patchi].snGrad()) )/nuBf[patchi]; const scalarField& Yp = yPlus.boundaryField()[patchi]; Info<< "Patch " << patchi << " named " << patch.name() << " y+ : min: " << gMin(Yp) << " max: " << gMax(Yp) << " average: " << gAverage(Yp) << nl << endl; } } }
void Foam::fvMeshTools::setPatchFields ( fvMesh& mesh, const label patchI, const dictionary& patchFieldDict ) { HashTable<GeoField*> flds ( mesh.objectRegistry::lookupClass<GeoField>() ); forAllIter(typename HashTable<GeoField*>, flds, iter) { GeoField& fld = *iter(); typename GeoField::GeometricBoundaryField& bfld = fld.boundaryField(); if (patchFieldDict.found(fld.name())) { bfld.set ( patchI, GeoField::PatchFieldType::New ( mesh.boundary()[patchI], fld.dimensionedInternalField(), patchFieldDict.subDict(fld.name()) ) ); } } }
void printSum ( const fvMesh& mesh, const IOobject& fieldHeader, const label patchI, bool& done ) { if (!done && fieldHeader.headerClassName() == FieldType::typeName) { Info<< " Reading " << FieldType::typeName << " " << fieldHeader.name() << endl; FieldType field(fieldHeader, mesh); typename FieldType::value_type sumField = gSum ( field.boundaryField()[patchI] ); Info<< " Integral of " << fieldHeader.name() << " over patch " << mesh.boundary()[patchI].name() << '[' << patchI << ']' << " = " << sumField << nl; done = true; } }
// Inplace add mesh1 to mesh0 Foam::autoPtr<Foam::mapAddedPolyMesh> Foam::fvMeshAdder::add ( fvMesh& mesh0, const fvMesh& mesh1, const faceCoupleInfo& coupleInfo, const bool validBoundary ) { mesh0.clearOut(); // Resulting merged mesh (polyMesh only!) autoPtr<mapAddedPolyMesh> mapPtr ( polyMeshAdder::add ( mesh0, mesh1, coupleInfo, validBoundary ) ); // Adjust the fvMesh part. const polyBoundaryMesh& patches = mesh0.boundaryMesh(); fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh0.boundary()); fvPatches.setSize(patches.size()); forAll(patches, patchI) { fvPatches.set(patchI, fvPatch::New(patches[patchI], fvPatches)); }
void printIntegrate ( const fvMesh& mesh, const IOobject& fieldHeader, const label patchI, bool& done ) { if (!done && fieldHeader.headerClassName() == FieldType::typeName) { Info<< " Reading " << fieldHeader.headerClassName() << " " << fieldHeader.name() << endl; FieldType field(fieldHeader, mesh); Info<< " Integral of " << fieldHeader.name() << " over vector area of patch " << mesh.boundary()[patchI].name() << '[' << patchI << ']' << " = " << gSum ( mesh.Sf().boundaryField()[patchI] *field.boundaryField()[patchI] ) << nl; Info<< " Integral of " << fieldHeader.name() << " over area magnitude of patch " << mesh.boundary()[patchI].name() << '[' << patchI << ']' << " = " << gSum ( mesh.magSf().boundaryField()[patchI] *field.boundaryField()[patchI] ) << nl; done = true; } }
void Foam::functionObjects::yPlus::calcYPlus ( const turbulenceModel& turbModel, const fvMesh& mesh, volScalarField& yPlus ) { volScalarField::Boundary d = nearWallDist(mesh).y(); const volScalarField::Boundary nutBf = turbModel.nut()().boundaryField(); const volScalarField::Boundary nuEffBf = turbModel.nuEff()().boundaryField(); const volScalarField::Boundary nuBf = turbModel.nu()().boundaryField(); const fvPatchList& patches = mesh.boundary(); volScalarField::Boundary& yPlusBf = yPlus.boundaryFieldRef(); forAll(patches, patchi) { const fvPatch& patch = patches[patchi]; if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi])) { const nutWallFunctionFvPatchScalarField& nutPf = dynamic_cast<const nutWallFunctionFvPatchScalarField&> ( nutBf[patchi] ); yPlusBf[patchi] = nutPf.yPlus(); } else if (isA<wallFvPatch>(patch)) { yPlusBf[patchi] = d[patchi] *sqrt ( nuEffBf[patchi] *mag(turbModel.U().boundaryField()[patchi].snGrad()) )/nuBf[patchi]; } } }
void printAverage ( const fvMesh& mesh, const IOobject& fieldHeader, const scalar area, const label patchI, bool& done ) { if (!done && fieldHeader.headerClassName() == FieldType::typeName) { Info<< " Reading " << fieldHeader.headerClassName() << " " << fieldHeader.name() << endl; FieldType field(fieldHeader, mesh); typename FieldType::value_type sumField = pTraits<typename FieldType::value_type>::zero; if (area > 0) { sumField = gSum ( mesh.magSf().boundaryField()[patchI] * field.boundaryField()[patchI] ) / area; } Info<< " Average of " << fieldHeader.headerClassName() << " over patch " << mesh.boundary()[patchI].name() << '[' << patchI << ']' << " = " << sumField << endl; done = true; } }
tmp<GeometricField<Type, fvPatchField, volMesh> > fvMeshSubset::interpolate ( const GeometricField<Type, fvPatchField, volMesh>& vf, const fvMesh& sMesh, const labelList& patchMap, const labelList& cellMap, const labelList& faceMap ) { // Create and map the internal-field values Field<Type> internalField(vf.internalField(), cellMap); // Create and map the patch field values PtrList<fvPatchField<Type> > patchFields(patchMap.size()); forAll (patchFields, patchI) { // Set the first one by hand as it corresponds to the // exposed internal faces. Additional interpolation can be put here // as necessary. if (patchMap[patchI] == -1) { patchFields.set ( patchI, new emptyFvPatchField<Type> ( sMesh.boundary()[patchI], DimensionedField<Type, volMesh>::null() ) ); } else { // Construct addressing const fvPatch& subPatch = sMesh.boundary()[patchI]; const fvPatch& basePatch = vf.mesh().boundary()[patchMap[patchI]]; label baseStart = basePatch.patch().start(); label baseSize = basePatch.size(); labelList directAddressing(subPatch.size()); forAll(directAddressing, i) { label baseFaceI = faceMap[subPatch.patch().start()+i]; if (baseFaceI >= baseStart && baseFaceI < baseStart+baseSize) { directAddressing[i] = baseFaceI-baseStart; } else { // Mapped from internal face. Do what? Map from element // 0 for now. directAddressing[i] = 0; } } patchFields.set ( patchI, fvPatchField<Type>::New ( vf.boundaryField()[patchMap[patchI]], sMesh.boundary()[patchI], DimensionedField<Type, volMesh>::null(), patchFieldSubset(directAddressing) ) ); // What to do with exposed internal faces if put into this patch? } }
tmp<GeometricField<Type, fvPatchField, volMesh> > autoCreateWallFunctionField ( const word& fieldName, const fvMesh& mesh, const objectRegistry& obj ) { IOobject nutHeader ( "nut", mesh.time().timeName(), obj, IOobject::MUST_READ ); typedef GeometricField<Type, fvPatchField, volMesh> fieldType; if (nutHeader.headerOk()) { return tmp<fieldType> ( new fieldType ( IOobject ( fieldName, mesh.time().timeName(), obj, IOobject::MUST_READ, IOobject::NO_WRITE, false ), mesh ) ); } else { Info<< "--> Upgrading " << fieldName << " to employ run-time selectable wall functions" << endl; // Read existing field IOobject ioObj ( fieldName, mesh.time().timeName(), obj, IOobject::MUST_READ, IOobject::NO_WRITE, false ); tmp<fieldType> fieldOrig ( new fieldType ( ioObj, mesh ) ); // rename file Info<< " Backup original " << fieldName << " to " << fieldName << ".old" << endl; mvBak(ioObj.objectPath(), "old"); PtrList<fvPatchField<Type> > newPatchFields(mesh.boundary().size()); forAll(newPatchFields, patchI) { if (mesh.boundary()[patchI].isWall()) { newPatchFields.set ( patchI, new PatchType ( mesh.boundary()[patchI], fieldOrig().dimensionedInternalField() ) ); newPatchFields[patchI] == fieldOrig().boundaryField()[patchI]; } else { newPatchFields.set ( patchI, fieldOrig().boundaryField()[patchI].clone() ); } } tmp<fieldType> fieldNew ( new fieldType ( IOobject ( fieldName, mesh.time().timeName(), obj, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, fieldOrig().dimensions(), fieldOrig().internalField(), newPatchFields ) ); Info<< " Writing updated " << fieldName << endl; fieldNew().write(); return fieldNew; } }
void Foam::yPlus::calcYPlus ( const TurbulenceModel& turbulenceModel, const fvMesh& mesh, volScalarField& yPlus ) { volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y(); const volScalarField::GeometricBoundaryField nutBf = turbulenceModel.nut()().boundaryField(); const volScalarField::GeometricBoundaryField nuEffBf = turbulenceModel.nuEff()().boundaryField(); const volScalarField::GeometricBoundaryField nuBf = turbulenceModel.nu()().boundaryField(); const fvPatchList& patches = mesh.boundary(); forAll(patches, patchi) { const fvPatch& patch = patches[patchi]; if (isA<nutWallFunctionFvPatchScalarField>(nutBf[patchi])) { const nutWallFunctionFvPatchScalarField& nutPf = dynamic_cast<const nutWallFunctionFvPatchScalarField&> ( nutBf[patchi] ); yPlus.boundaryField()[patchi] = nutPf.yPlus(); const scalarField& yPlusp = yPlus.boundaryField()[patchi]; const scalar minYplus = gMin(yPlusp); const scalar maxYplus = gMax(yPlusp); const scalar avgYplus = gAverage(yPlusp); if (Pstream::master()) { if (log_) Info << " patch " << patch.name() << " y+ : min = " << minYplus << ", max = " << maxYplus << ", average = " << avgYplus << nl; file() << obr_.time().value() << token::TAB << patch.name() << token::TAB << minYplus << token::TAB << maxYplus << token::TAB << avgYplus << endl; } } else if (isA<wallFvPatch>(patch)) { yPlus.boundaryField()[patchi] = d[patchi] *sqrt ( nuEffBf[patchi] *mag(turbulenceModel.U().boundaryField()[patchi].snGrad()) )/nuBf[patchi]; const scalarField& yPlusp = yPlus.boundaryField()[patchi]; const scalar minYplus = gMin(yPlusp); const scalar maxYplus = gMax(yPlusp); const scalar avgYplus = gAverage(yPlusp); if (Pstream::master()) { if (log_) Info << " patch " << patch.name() << " y+ : min = " << minYplus << ", max = " << maxYplus << ", average = " << avgYplus << nl; file() << obr_.time().value() << token::TAB << patch.name() << token::TAB << minYplus << token::TAB << maxYplus << token::TAB << avgYplus << endl; } } } }
void Foam::yPlusLES::calcIncompressibleYPlus ( const fvMesh& mesh, const volVectorField& U, volScalarField& yPlus ) { const incompressible::LESModel& model = mesh.lookupObject<incompressible::LESModel>("LESProperties"); volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y(); volScalarField nuEff(model.nuEff()); const fvPatchList& patches = mesh.boundary(); const volScalarField nuLam(model.nu()); bool foundPatch = false; forAll(patches, patchI) { const fvPatch& currPatch = patches[patchI]; if (isA<wallFvPatch>(currPatch)) { foundPatch = true; yPlus.boundaryField()[patchI] = d[patchI] *sqrt ( nuEff.boundaryField()[patchI] *mag(U.boundaryField()[patchI].snGrad()) ) /nuLam.boundaryField()[patchI]; const scalarField& Yp = yPlus.boundaryField()[patchI]; scalar minYp = gMin(Yp); scalar maxYp = gMax(Yp); scalar avgYp = gAverage(Yp); if (log_) { Info<< " patch " << currPatch.name() << " y+ : min = " << minYp << ", max = " << maxYp << ", average = " << avgYp << nl; } if (Pstream::master()) { file() << obr_.time().value() << token::TAB << currPatch.name() << token::TAB << minYp << token::TAB << maxYp << token::TAB << avgYp << endl; } } } if (log_ && !foundPatch) { Info<< " no " << wallFvPatch::typeName << " patches" << endl; } }
tmp<GeometricField<Type, fvPatchField, volMesh> > fvMeshSubset::interpolate ( const GeometricField<Type, fvPatchField, volMesh>& vf, const fvMesh& sMesh, const labelList& patchMap, const labelList& cellMap, const labelList& faceMap ) { // 1. Create the complete field with dummy patch fields PtrList<fvPatchField<Type> > patchFields(patchMap.size()); forAll(patchFields, patchI) { // Set the first one by hand as it corresponds to the // exposed internal faces. Additional interpolation can be put here // as necessary. if (patchMap[patchI] == -1) { patchFields.set ( patchI, new emptyFvPatchField<Type> ( sMesh.boundary()[patchI], DimensionedField<Type, volMesh>::null() ) ); } else { patchFields.set ( patchI, fvPatchField<Type>::New ( calculatedFvPatchField<Type>::typeName, sMesh.boundary()[patchI], DimensionedField<Type, volMesh>::null() ) ); } } tmp<GeometricField<Type, fvPatchField, volMesh> > tresF ( new GeometricField<Type, fvPatchField, volMesh> ( IOobject ( "subset"+vf.name(), sMesh.time().timeName(), sMesh, IOobject::NO_READ, IOobject::NO_WRITE ), sMesh, vf.dimensions(), Field<Type>(vf.internalField(), cellMap), patchFields ) ); GeometricField<Type, fvPatchField, volMesh>& resF = tresF(); // 2. Change the fvPatchFields to the correct type using a mapper // constructor (with reference to the now correct internal field) typename GeometricField<Type, fvPatchField, volMesh>:: GeometricBoundaryField& bf = resF.boundaryField(); forAll(bf, patchI) { if (patchMap[patchI] != -1) { // Construct addressing const fvPatch& subPatch = sMesh.boundary()[patchI]; const fvPatch& basePatch = vf.mesh().boundary()[patchMap[patchI]]; const label baseStart = basePatch.start(); const label baseSize = basePatch.size(); labelList directAddressing(subPatch.size()); forAll(directAddressing, i) { label baseFaceI = faceMap[subPatch.start()+i]; if (baseFaceI >= baseStart && baseFaceI < baseStart+baseSize) { directAddressing[i] = baseFaceI-baseStart; } else { // Mapped from internal face. Do what? Leave up to // fvPatchField directAddressing[i] = -1; } } bf.set ( patchI, fvPatchField<Type>::New ( vf.boundaryField()[patchMap[patchI]], subPatch, resF.dimensionedInternalField(), directFvPatchFieldMapper(directAddressing) ) ); } }