void vtkFoamInterface<Type>::addPatch ( const polyPatch& p, vtkUnstructuredGrid *vtkPatch ) { if (debug) { Info<< "Adding patch " << p.name() << endl; } SetName(vtkPatch, p.name().c_str()); if (debug) { Info<< "converting points" << endl; } const Foam::pointField& points = p.localPoints(); // Convert Foam mesh vertices to VTK vtkPoints *vtkpoints = vtkPoints::New(); vtkpoints->Allocate(points.size()); forAll(points, i) { vtkFoamInsertNextPoint(vtkpoints, points[i]); }
Foam::autoPtr<Foam::fvPatch> Foam::fvPatch::New ( const polyPatch& patch, const fvBoundaryMesh& bm ) { if (debug) { Info<< "fvPatch::New(const polyPatch&, const fvBoundaryMesh&) : " << "constructing fvPatch" << endl; } polyPatchConstructorTable::iterator cstrIter = polyPatchConstructorTablePtr_->find(patch.type()); if (cstrIter == polyPatchConstructorTablePtr_->end()) { FatalErrorIn("fvPatch::New(const polyPatch&, const fvBoundaryMesh&)") << "Unknown fvPatch type " << patch.type() << ".\n" << "Valid fvPatch types are :" << polyPatchConstructorTablePtr_->sortedToc() << exit(FatalError); } return autoPtr<fvPatch>(cstrIter()(patch, bm)); }
// Return smallest true distance from p to any of wallFaces. // Note that even if normal hits face we still check other faces. // Note that wallFaces is untruncated and we explicitly pass in size. Foam::scalar Foam::cellDistFuncs::smallestDist ( const point& p, const polyPatch& patch, const label nWallFaces, const labelList& wallFaces, label& minFaceI ) const { const pointField& points = patch.points(); scalar minDist = GREAT; minFaceI = -1; for (label wallFaceI = 0; wallFaceI < nWallFaces; wallFaceI++) { label patchFaceI = wallFaces[wallFaceI]; pointHit curHit = patch[patchFaceI].nearestPoint(p, points); if (curHit.distance() < minDist) { minDist = curHit.distance(); minFaceI = patch.start() + patchFaceI; } } return minDist; }
//- Calculate map from new patch faces to old patch faces. -1 where // could not map. Foam::labelList Foam::fvMeshAdder::calcPatchMap ( const label oldStart, const label oldSize, const labelList& oldToNew, const polyPatch& newPatch, const label unmappedValue ) { labelList newToOld(newPatch.size(), unmappedValue); label newStart = newPatch.start(); label newSize = newPatch.size(); for (label i = 0; i < oldSize; i++) { label newFaceI = oldToNew[oldStart+i]; if (newFaceI >= newStart && newFaceI < newStart+newSize) { newToOld[newFaceI-newStart] = i; } } return newToOld; }
autoPtr<faceTetPolyPatchCellDecomp> faceTetPolyPatchCellDecomp::New ( const polyPatch& patch, const tetPolyBoundaryMeshCellDecomp& bm ) { if (debug) { Info<< "faceTetPolyPatchCellDecomp::New(const polyPatch&, " << " const tetPolyBoundaryMeshCellDecomp&) : " << "constructing faceTetPolyPatchCellDecomp" << endl; } polyPatchConstructorTable::iterator cstrIter = polyPatchConstructorTablePtr_->find(patch.type()); if (cstrIter == polyPatchConstructorTablePtr_->end()) { FatalErrorIn ( "faceTetPolyPatchCellDecomp::New(const polyPatch&, " "const tetPolyBoundaryMeshCellDecomp&) : " ) << "Unknown faceTetPolyPatchCellDecomp type " << patch.type() << ". Valid faceTetPolyPatchCellDecomp types are :" << endl << polyPatchConstructorTablePtr_->toc() << exit(FatalError); } return autoPtr<faceTetPolyPatchCellDecomp>(cstrIter()(patch, bm)); }
Foam::autoPtr<Foam::facePointPatch> Foam::facePointPatch::New ( const polyPatch& patch, const pointBoundaryMesh& bm ) { if (debug) { InfoInFunction << "Constructing facePointPatch" << endl; } polyPatchConstructorTable::iterator cstrIter = polyPatchConstructorTablePtr_->find(patch.type()); if (cstrIter == polyPatchConstructorTablePtr_->end()) { FatalErrorInFunction << "Unknown facePointPatch type " << patch.type() << nl << nl << "Valid facePointPatch types are :" << endl << polyPatchConstructorTablePtr_->sortedToc() << exit(FatalError); } return autoPtr<facePointPatch>(cstrIter()(patch, bm)); }
Foam::label Foam::coupleGroupIdentifier::findOtherPatchID ( const polyPatch& thisPatch, word& otherRegion ) const { const polyBoundaryMesh& pbm = thisPatch.boundaryMesh(); const polyMesh& thisMesh = pbm.mesh(); const Time& runTime = thisMesh.time(); // Loop over all regions to find other patch in coupleGroup HashTable<const polyMesh*> meshSet = runTime.lookupClass<polyMesh>(); label otherPatchID = -1; forAllConstIter(HashTable<const polyMesh*>, meshSet, iter) { const polyMesh& mesh = *iter(); label patchID = findOtherPatchID(mesh, thisPatch); if (patchID != -1) { if (otherPatchID != -1) { FatalErrorInFunction << "Couple patchGroup " << name() << " should be present on only two patches" << " in any of the meshes in " << meshSet.sortedToc() << endl << " It seems to be present on patch " << thisPatch.name() << " in region " << thisMesh.name() << ", on patch " << otherPatchID << " in region " << otherRegion << " and on patch " << patchID << " in region " << mesh.name() << exit(FatalError); } otherPatchID = patchID; otherRegion = mesh.name(); } } if (otherPatchID == -1) { FatalErrorInFunction << "Couple patchGroup " << name() << " not found in any of the other meshes " << meshSet.sortedToc() << " on patch " << thisPatch.name() << " region " << thisMesh.name() << exit(FatalError); } return otherPatchID; }
Foam::label Foam::mergePolyMesh::patchIndex(const polyPatch& p) { // Find the patch name on the list. If the patch is already there // and patch types match, return index const word& pType = p.type(); const word& pName = p.name(); bool nameFound = false; forAll (patchNames_, patchI) { if (patchNames_[patchI] == pName) { if (patchTypes_[patchI] == pType) { // Found name and types match return patchI; } else { // Found the name, but type is different nameFound = true; } } } // Patch not found. Append to the list patchTypes_.append(pType); if (nameFound) { // Duplicate name is not allowed. Create a composite name from the // patch name and case name const word& caseName = p.boundaryMesh().mesh().time().caseName(); patchNames_.append(pName + "_" + caseName); Info<< "label patchIndex(const polyPatch& p) : " << "Patch " << p.index() << " named " << pName << " in mesh " << caseName << " already exists, but patch types " << " do not match.\nCreating a composite name as " << patchNames_[patchNames_.size() - 1] << endl; } else { patchNames_.append(pName); } return patchNames_.size() - 1; }
bool Foam::KinematicParcel<ParcelType>::hitPatch ( const polyPatch& pp, TrackData& td, const label patchI, const scalar trackFraction, const tetIndices& tetIs ) { typename TrackData::cloudType::parcelType& p = static_cast<typename TrackData::cloudType::parcelType&>(*this); // Invoke post-processing model td.cloud().functions().postPatch(p, patchI, pp.whichFace(p.face())); // Invoke surface film model if (td.cloud().surfaceFilm().transferParcel(p, pp, td.keepParticle)) { // All interactions done return true; } else { // Invoke patch interaction model return td.cloud().patchInteraction().correct ( p, pp, td.keepParticle, trackFraction, tetIs ); } }
void Foam::PointEdgeWave<Type, TrackingData>::leaveDomain ( const polyPatch& patch, const labelList& patchPointLabels, List<Type>& pointInfo ) const { const labelList& meshPoints = patch.meshPoints(); forAll(patchPointLabels, i) { label patchPointI = patchPointLabels[i]; const point& pt = patch.points()[meshPoints[patchPointI]]; pointInfo[i].leaveDomain(patch, patchPointI, pt, td_); }
Foam::label Foam::coupleGroupIdentifier::findOtherPatchID ( const polyPatch& thisPatch ) const { const polyBoundaryMesh& pbm = thisPatch.boundaryMesh(); return findOtherPatchID(pbm.mesh(), thisPatch); }
Foam::polyPatch::polyPatch ( const polyPatch& pp, const polyBoundaryMesh& bm ) : patchIdentifier(pp), primitivePatch ( faceSubList ( bm.mesh().faces(), pp.size(), pp.start() ), bm.mesh().points() ), start_(pp.start()), boundaryMesh_(bm), faceCellsPtr_(NULL), mePtr_(NULL) {}
void Foam::FaceCellWave<Type, TrackingData>::checkCyclic ( const polyPatch& patch ) const { const cyclicPolyPatch& nbrPatch = refCast<const cyclicPolyPatch>(patch).neighbPatch(); forAll(patch, patchFaceI) { label i1 = patch.start() + patchFaceI; label i2 = nbrPatch.start() + patchFaceI; if ( !allFaceInfo_[i1].sameGeometry ( mesh_, allFaceInfo_[i2], geomTol_, td_ ) ) { FatalErrorIn ( "FaceCellWave<Type, TrackingData>" "::checkCyclic(const polyPatch&)" ) << "problem: i:" << i1 << " otheri:" << i2 << " faceInfo:" << allFaceInfo_[i1] << " otherfaceInfo:" << allFaceInfo_[i2] << abort(FatalError); } if (changedFace_[i1] != changedFace_[i2]) { FatalErrorIn ( "FaceCellWave<Type, TrackingData>" "::checkCyclic(const polyPatch&)" ) << " problem: i:" << i1 << " otheri:" << i2 << " faceInfo:" << allFaceInfo_[i1] << " otherfaceInfo:" << allFaceInfo_[i2] << " changedFace:" << changedFace_[i1] << " otherchangedFace:" << changedFace_[i2] << abort(FatalError); } }
void Foam::FaceCellWave<Type, TrackingData>::checkCyclic ( const polyPatch& patch ) const { // For debugging: check status on both sides of cyclic const cyclicPolyPatch& nbrPatch = refCast<const cyclicPolyPatch>(patch).neighbPatch(); forAll(patch, patchFacei) { label i1 = patch.start() + patchFacei; label i2 = nbrPatch.start() + patchFacei; if ( !allFaceInfo_[i1].sameGeometry ( mesh_, allFaceInfo_[i2], geomTol_, td_ ) ) { FatalErrorInFunction << " faceInfo:" << allFaceInfo_[i1] << " otherfaceInfo:" << allFaceInfo_[i2] << abort(FatalError); } if (changedFace_[i1] != changedFace_[i2]) { FatalErrorInFunction << " faceInfo:" << allFaceInfo_[i1] << " otherfaceInfo:" << allFaceInfo_[i2] << " changedFace:" << changedFace_[i1] << " otherchangedFace:" << changedFace_[i2] << abort(FatalError); } }
Foam::label Foam::coupleGroupIdentifier::findOtherPatchID ( const polyMesh& mesh, const polyPatch& thisPatch ) const { const polyBoundaryMesh& pbm = mesh.boundaryMesh(); if (!valid()) { FatalErrorIn ( "coupleGroupIdentifier::findOtherPatchID(const polyPatch&) const" ) << "Invalid coupleGroup patch group" << " on patch " << thisPatch.name() << " in region " << pbm.mesh().name() << exit(FatalError); } HashTable<labelList, word>::const_iterator fnd = pbm.groupPatchIDs().find(name()); if (fnd == pbm.groupPatchIDs().end()) { if (&mesh == &thisPatch.boundaryMesh().mesh()) { // thisPatch should be in patchGroup FatalErrorIn ( "coupleGroupIdentifier::findOtherPatchID" "(const polyMesh&, const polyPatch&) const" ) << "Patch " << thisPatch.name() << " should be in patchGroup " << name() << " in region " << pbm.mesh().name() << exit(FatalError); } return -1; } // Mesh has patch group const labelList& patchIDs = fnd(); if (&mesh == &thisPatch.boundaryMesh().mesh()) { if (patchIDs.size() > 2 || patchIDs.size() == 0) { FatalErrorIn ( "coupleGroupIdentifier::findOtherPatchID" "(const polyMesh&, const polyPatch&) const" ) << "Couple patchGroup " << name() << " with contents " << patchIDs << " not of size < 2" << " on patch " << thisPatch.name() << " region " << thisPatch.boundaryMesh().mesh().name() << exit(FatalError); return -1; } label index = findIndex(patchIDs, thisPatch.index()); if (index == -1) { FatalErrorIn ( "coupleGroupIdentifier::findOtherPatchID" "(const polyMesh&, const polyPatch&) const" ) << "Couple patchGroup " << name() << " with contents " << patchIDs << " does not contain patch " << thisPatch.name() << " in region " << pbm.mesh().name() << exit(FatalError); return -1; } if (patchIDs.size() == 2) { // Return the other patch return patchIDs[1-index]; } else // size == 1 { return -1; } } else { if (patchIDs.size() != 1) { FatalErrorIn ( "coupleGroupIdentifier::findOtherPatchID" "(const polyMesh&, const polyPatch&) const" ) << "Couple patchGroup " << name() << " with contents " << patchIDs << " in region " << mesh.name() << " should only contain a single patch" << " when matching patch " << thisPatch.name() << " in region " << pbm.mesh().name() << exit(FatalError); } return patchIDs[0]; } }
bool Foam::LocalInteraction<CloudType>::correct ( typename CloudType::parcelType& p, const polyPatch& pp, bool& keepParticle, const scalar trackFraction, const tetIndices& tetIs ) { label patchI = patchData_.applyToPatch(pp.index()); if (patchI >= 0) { vector& U = p.U(); bool& active = p.active(); typename PatchInteractionModel<CloudType>::interactionType it = this->wordToInteractionType ( patchData_[patchI].interactionTypeName() ); switch (it) { case PatchInteractionModel<CloudType>::itEscape: { scalar dm = p.mass()*p.nParticle(); keepParticle = false; active = false; U = vector::zero; nEscape_[patchI]++; massEscape_[patchI] += dm; if (writeFields_) { label pI = pp.index(); label fI = pp.whichFace(p.face()); massEscape().boundaryField()[pI][fI] += dm; } break; } case PatchInteractionModel<CloudType>::itStick: { scalar dm = p.mass()*p.nParticle(); keepParticle = true; active = false; U = vector::zero; nStick_[patchI]++; massStick_[patchI] += dm; if (writeFields_) { label pI = pp.index(); label fI = pp.whichFace(p.face()); massStick().boundaryField()[pI][fI] += dm; } break; } case PatchInteractionModel<CloudType>::itRebound: { keepParticle = true; active = true; vector nw; vector Up; this->owner().patchData(p, pp, trackFraction, tetIs, nw, Up); // Calculate motion relative to patch velocity U -= Up; scalar Un = U & nw; vector Ut = U - Un*nw; if (Un > 0) { U -= (1.0 + patchData_[patchI].e())*Un*nw; } U -= patchData_[patchI].mu()*Ut; // Return velocity to global space U += Up; break; } default: { FatalErrorIn ( "bool LocalInteraction<CloudType>::correct" "(" "typename CloudType::parcelType&, " "const polyPatch&, " "bool&, " "const scalar, " "const tetIndices&" ") const" ) << "Unknown interaction type " << patchData_[patchI].interactionTypeName() << "(" << it << ") for patch " << patchData_[patchI].patchName() << ". Valid selections are:" << this->interactionTypeNames_ << endl << abort(FatalError); } } return true; } return false; }
void Foam::KinematicCloud<CloudType>::patchData ( const parcelType& p, const polyPatch& pp, const scalar trackFraction, const tetIndices& tetIs, vector& nw, vector& Up ) const { label patchi = pp.index(); label patchFacei = pp.whichFace(p.face()); vector n = tetIs.faceTri(mesh_).normal(); n /= mag(n); vector U = U_.boundaryField()[patchi][patchFacei]; // Unless the face is rotating, the required normal is n; nw = n; if (!mesh_.moving()) { // Only wall patches may have a non-zero wall velocity from // the velocity field when the mesh is not moving. if (isA<wallPolyPatch>(pp)) { Up = U; } else { Up = Zero; } } else { vector U00 = U_.oldTime().boundaryField()[patchi][patchFacei]; vector n00 = tetIs.oldFaceTri(mesh_).normal(); // Difference in normal over timestep vector dn = Zero; if (mag(n00) > SMALL) { // If the old normal is zero (for example in layer // addition) then use the current normal, meaning that the // motion can only be translational, and dn remains zero, // otherwise, calculate dn: n00 /= mag(n00); dn = n - n00; } // Total fraction through the timestep of the motion, // including stepFraction before the current tracking step // and the current trackFraction // i.e. // let s = stepFraction, t = trackFraction // Motion of x in time: // |-----------------|---------|---------| // x00 x0 xi x // // where xi is the correct value of x at the required // tracking instant. // // x0 = x00 + s*(x - x00) = s*x + (1 - s)*x00 // // i.e. the motion covered by previous tracking portions // within this timestep, and // // xi = x0 + t*(x - x0) // = t*x + (1 - t)*x0 // = t*x + (1 - t)*(s*x + (1 - s)*x00) // = (s + t - s*t)*x + (1 - (s + t - s*t))*x00 // // let m = (s + t - s*t) // // xi = m*x + (1 - m)*x00 = x00 + m*(x - x00); // // In the same form as before. scalar m = p.stepFraction() + trackFraction - (p.stepFraction()*trackFraction); // When the mesh is moving, the velocity field on wall patches // will contain the velocity associated with the motion of the // mesh, in which case it is interpolated in time using m. // For other patches the face velocity will need to be // reconstructed from the face centre motion. const vector& Cf = mesh_.faceCentres()[p.face()]; vector Cf00 = mesh_.faces()[p.face()].centre(mesh_.oldPoints()); if (isA<wallPolyPatch>(pp)) { Up = U00 + m*(U - U00); } else { Up = (Cf - Cf00)/mesh_.time().deltaTValue(); } if (mag(dn) > SMALL) { // Rotational motion, nw requires interpolation and a // rotational velocity around face centre correction to Up // is required. nw = n00 + m*dn; // Cf at tracking instant vector Cfi = Cf00 + m*(Cf - Cf00); // Normal vector cross product vector omega = (n00 ^ n); scalar magOmega = mag(omega); // magOmega = sin(angle between unit normals) // Normalise omega vector by magOmega, then multiply by // angle/dt to give the correct angular velocity vector. omega *= Foam::asin(magOmega)/(magOmega*mesh_.time().deltaTValue()); // Project position onto face and calculate this position // relative to the face centre. vector facePos = p.position() - ((p.position() - Cfi) & nw)*nw - Cfi; Up += (omega ^ facePos); } // No further action is required if the motion is // translational only, nw and Up have already been set. } }
bool Foam::turbulentTemperatureCoupledBaffleFvPatchScalarField::interfaceOwner ( const polyMesh& nbrRegion, const polyPatch& nbrPatch ) const { const fvMesh& myRegion = patch().boundaryMesh().mesh(); if (nbrRegion.name() == myRegion.name()) { return patch().index() < nbrPatch.index(); } else { const regionProperties& props = myRegion.objectRegistry::parent().lookupObject<regionProperties> ( "regionProperties" ); label myIndex = findIndex(props.fluidRegionNames(), myRegion.name()); if (myIndex == -1) { label i = findIndex(props.solidRegionNames(), myRegion.name()); if (i == -1) { FatalErrorIn ( "turbulentTemperatureCoupledBaffleFvPatchScalarField" "::interfaceOwner(const polyMesh&" ", const polyPatch&)const" ) << "Cannot find region " << myRegion.name() << " neither in fluids " << props.fluidRegionNames() << " nor in solids " << props.solidRegionNames() << exit(FatalError); } myIndex = props.fluidRegionNames().size() + i; } label nbrIndex = findIndex ( props.fluidRegionNames(), nbrRegion.name() ); if (nbrIndex == -1) { label i = findIndex(props.solidRegionNames(), nbrRegion.name()); if (i == -1) { FatalErrorIn ( "coupleManager::interfaceOwner" "(const polyMesh&, const polyPatch&) const" ) << "Cannot find region " << nbrRegion.name() << " neither in fluids " << props.fluidRegionNames() << " nor in solids " << props.solidRegionNames() << exit(FatalError); } nbrIndex = props.fluidRegionNames().size() + i; } return myIndex < nbrIndex; } }
bool Foam::StandardWallInteraction<CloudType>::correct ( const polyPatch& pp, const label faceId, bool& keepParticle, vector& U ) const { if (pp.isWall()) { switch (interactionType_) { case PatchInteractionModel<CloudType>::itEscape: { keepParticle = false; U = vector::zero; break; } case PatchInteractionModel<CloudType>::itStick: { keepParticle = true; U = vector::zero; break; } case PatchInteractionModel<CloudType>::itRebound: { keepParticle = true; vector nw = pp.faceAreas()[pp.whichFace(faceId)]; nw /= mag(nw); scalar Un = U & nw; vector Ut = U - Un*nw; if (Un > 0) { U -= (1.0 + e_)*Un*nw; } U -= mu_*Ut; break; } default: { FatalErrorIn ( "bool StandardWallInteraction<CloudType>::correct" "(" "const polyPatch&, " "const label, " "bool&, " "vector&" ") const" ) << "Unknown interaction type " << this->interactionTypeToWord(interactionType_) << "(" << interactionType_ << ")" << endl << abort(FatalError); } } return true; } return false; }
Foam::ensightPartFaces::ensightPartFaces ( label partNumber, const polyMesh& pMesh, const polyPatch& pPatch ) : ensightPart(partNumber, pPatch.name(), pMesh) { isCellData_ = false; offset_ = pPatch.start(); size_ = pPatch.size(); // count the shapes label nTri = 0; label nQuad = 0; label nPoly = 0; forAll (pPatch, patchfaceI) { const face& f = pMesh.faces()[patchfaceI + offset_]; if (f.size() == 3) { nTri++; } else if (f.size() == 4) { nQuad++; } else { nPoly++; } } // we can avoid double looping, but at the cost of allocation labelList triCells(nTri); labelList quadCells(nQuad); labelList polygonCells(nPoly); nTri = 0; nQuad = 0; nPoly = 0; // classify the shapes forAll(pPatch, patchfaceI) { const face& f = pMesh.faces()[patchfaceI + offset_]; if (f.size() == 3) { triCells[nTri++] = patchfaceI; } else if (f.size() == 4) { quadCells[nQuad++] = patchfaceI; } else { polygonCells[nPoly++] = patchfaceI; } } // MUST match with elementTypes elemLists_.setSize(elementTypes().size()); elemLists_[tria3Elements].transfer( triCells ); elemLists_[quad4Elements].transfer( quadCells ); elemLists_[nsidedElements].transfer( polygonCells ); }