void Foam::porosityZone::addResistance ( const fvVectorMatrix& UEqn, volTensorField& AU, bool correctAUprocBC ) const { if (cellZoneID_ == -1) { return; } bool compressible = false; if (UEqn.dimensions() == dimensionSet(1, 1, -2, 0, 0)) { compressible = true; } const labelList& cells = mesh_.cellZones()[cellZoneID_]; const vectorField& U = UEqn.psi(); const tensor& D = D_.value(); const tensor& F = F_.value(); if (magSqr(D) > VSMALL || magSqr(F) > VSMALL) { if (compressible) { addViscousInertialResistance ( AU, cells, mesh_.lookupObject<volScalarField>("rho"), mesh_.lookupObject<volScalarField>("mu"), U ); } else { addViscousInertialResistance ( AU, cells, geometricOneField(), mesh_.lookupObject<volScalarField>("nu"), U ); } } if (correctAUprocBC) { // Correct the boundary conditions of the tensorial diagonal to ensure // processor boundaries are correctly handled when AU^-1 is interpolated // for the pressure equation. AU.correctBoundaryConditions(); } }
void Foam::porosityZone::addResistance(fvVectorMatrix& UEqn) const { if (cellZoneID_ == -1) { return; } bool compressible = false; if (UEqn.dimensions() == dimensionSet(1, 1, -2, 0, 0)) { compressible = true; } const labelList& cells = mesh_.cellZones()[cellZoneID_]; const scalarField& V = mesh_.V(); scalarField& Udiag = UEqn.diag(); vectorField& Usource = UEqn.source(); const vectorField& U = UEqn.psi(); const tensor& D = D_.value(); const tensor& F = F_.value(); if (magSqr(D) > VSMALL || magSqr(F) > VSMALL) { if (compressible) { addViscousInertialResistance ( Udiag, Usource, cells, V, mesh_.lookupObject<volScalarField>("rho"), mesh_.lookupObject<volScalarField>("mu"), U ); } else { addViscousInertialResistance ( Udiag, Usource, cells, V, geometricOneField(), mesh_.lookupObject<volScalarField>("nu"), U ); } } }
void Foam::porosityModels::powerLaw::correct ( fvVectorMatrix& UEqn, const volScalarField& rho, const volScalarField& mu ) const { const vectorField& U = UEqn.psi(); const scalarField& V = mesh_.V(); scalarField& Udiag = UEqn.diag(); apply(Udiag, V, rho, U); }
void Foam::porousZone::addResistance ( fvVectorMatrix& UEqn, const volScalarField& rho, const volScalarField& mu ) const { if (cellZoneIds_.empty()) { return; } const scalarField& V = mesh_.V(); scalarField& Udiag = UEqn.diag(); vectorField& Usource = UEqn.source(); const vectorField& U = UEqn.psi(); if (C0_ > VSMALL) { addPowerLawResistance ( Udiag, V, rho, U ); } const tensor& D = D_.value(); const tensor& F = F_.value(); if (magSqr(D) > VSMALL || magSqr(F) > VSMALL) { addViscousInertialResistance ( Udiag, Usource, V, rho, mu, U ); } }
void Foam::porosityModels::powerLaw::correct ( const fvVectorMatrix& UEqn, volTensorField& AU ) const { const vectorField& U = UEqn.psi(); if (UEqn.dimensions() == dimForce) { const volScalarField& rho = mesh_.lookupObject<volScalarField>(rhoName_); apply(AU, rho, U); } else { apply(AU, geometricOneField(), U); } }
void Foam::porosityModels::powerLaw::correct ( fvVectorMatrix& UEqn ) const { const vectorField& U = UEqn.psi(); const scalarField& V = mesh_.V(); scalarField& Udiag = UEqn.diag(); if (UEqn.dimensions() == dimForce) { const volScalarField& rho = mesh_.lookupObject<volScalarField>(rhoName_); apply(Udiag, V, rho, U); } else { apply(Udiag, V, geometricOneField(), U); } }
void kinematicSingleLayer::solveThickness ( const volScalarField& pu, const volScalarField& pp, const fvVectorMatrix& UEqn ) { if (debug) { InfoInFunction << endl; } volScalarField rUA(1.0/UEqn.A()); U_ = rUA*UEqn.H(); surfaceScalarField deltarUAf(fvc::interpolate(delta_*rUA)); surfaceScalarField rhof(fvc::interpolate(rho_)); surfaceScalarField phiAdd ( "phiAdd", regionMesh().magSf() * ( fvc::snGrad(pu, "snGrad(p)") + fvc::snGrad(pp, "snGrad(p)")*fvc::interpolate(delta_) ) - fvc::flux(rho_*gTan()) ); constrainFilmField(phiAdd, 0.0); surfaceScalarField phid ( "phid", fvc::flux(U_*rho_) - deltarUAf*phiAdd*rhof ); constrainFilmField(phid, 0.0); surfaceScalarField ddrhorUAppf ( "deltaCoeff", fvc::interpolate(delta_)*deltarUAf*rhof*fvc::interpolate(pp) ); regionMesh().setFluxRequired(delta_.name()); for (int nonOrth=0; nonOrth<=nNonOrthCorr_; nonOrth++) { // Film thickness equation fvScalarMatrix deltaEqn ( fvm::ddt(rho_, delta_) + fvm::div(phid, delta_) - fvm::laplacian(ddrhorUAppf, delta_) == - rhoSp_ ); deltaEqn.solve(); if (nonOrth == nNonOrthCorr_) { phiAdd += fvc::interpolate(pp) * fvc::snGrad(delta_) * regionMesh().magSf(); phi_ == deltaEqn.flux(); } } // Bound film thickness by a minimum of zero delta_.max(0.0); // Update U field U_ -= fvc::reconstruct(deltarUAf*phiAdd); // Remove any patch-normal components of velocity U_ -= nHat()*(nHat() & U_); U_.correctBoundaryConditions(); // Continuity check continuityCheck(); }
void Foam::smallStrainSolidInterface::correct(fvVectorMatrix& UEqn) { const fvMesh& mesh = solidInterface::mesh(); const unallocLabelList& owner = mesh.owner(); const unallocLabelList& neighbour = mesh.neighbour(); const volVectorField& U = UEqn.psi(); const vectorField& UI = U.internalField(); const volTensorField& gradU = mesh.lookupObject<volTensorField>("grad(" + U.name() + ')'); const tensorField& gradUI = gradU.internalField(); const volScalarField& mu = mesh.lookupObject<volScalarField>("mu"); const volScalarField& lambda = mesh.lookupObject<volScalarField>("lambda"); const vectorField& SI = mesh.Sf().internalField(); const scalarField& magSI = mesh.magSf().internalField(); const scalarField& deltaCoeffs = mesh.deltaCoeffs().internalField(); const scalarField& w = mesh.weights().internalField(); scalarField& diag = UEqn.diag(); scalarField& upper = UEqn.upper(); vectorField& source = UEqn.source(); FieldField<Field, vector>& boundaryCoeffs = UEqn.boundaryCoeffs(); vectorField& interU = interfaceDisplacement(); // FAM interfacetengential gradient // tensorField interSGradU(interU.size(), tensor::zero); // if (tangGradMethod_ == FAM) // { // faMesh aMesh(mesh); // const labelList& faceLabels = aMesh.faceLabels(); // wordList patchFieldTypes // ( // aMesh.boundary().size(), // zeroGradientFaPatchVectorField::typeName // ); // areaVectorField Us // ( // IOobject // ( // "Us", // mesh.time().timeName(), // mesh, // IOobject::NO_READ, // IOobject::AUTO_WRITE // ), // aMesh, // dimensioned<vector>("Us", dimLength, vector::zero), // patchFieldTypes // ); // forAll(globalInterFaces(), faceI) // { // label curFace = globalInterFaces()[faceI]; // label index = findIndex(faceLabels, curFace); // Us.internalField()[index] = interU[faceI]; // } // Us.correctBoundaryConditions(); // tensorField sGradU = fac::grad(Us)().internalField(); // forAll(globalInterFaces(), faceI) // { // label curFace = globalInterFaces()[faceI]; // label index = findIndex(faceLabels, curFace); // interSGradU[faceI] = sGradU[index]; // } // } // Internal faces forAll(globalInterFaces(), faceI) { label curGlobalFace = globalInterFaces()[faceI]; label curOwner = owner[curGlobalFace]; label curNeighbour = neighbour[curGlobalFace]; vector ownN = SI[curGlobalFace]/magSI[curGlobalFace]; //vector ngbN = -ownN; scalar magS = magSI[curGlobalFace]; // the interface tangential gradient may be calculated // in one of three ways: // 1) extrapolation from adjoining cell centres // 2) inteprolation from adjoining cell centres // 3) directly calculated using the finite area method tensor ownGradU = tensor::zero; tensor ngbGradU = tensor::zero; //tensor ownSGradU = tensor::zero; //tensor ngbSGradU = tensor::zero; // if (tangGradMethod_ == EXTRAP) { // extrapolate tangential gradient ownGradU = gradUI[curOwner]; ngbGradU = gradUI[curNeighbour]; } // else if (tangGradMethod_ == INTERP) // { // // interpolate tangential gradient // ownGradU = 0.5*( // gradUI[curOwner] // + // gradUI[curNeighbour] // ); // ngbGradU = ownGradU; // ownSGradU = ((I-ownN*ownN)&ownGradU); // ngbSGradU = ((I-ngbN*ngbN)&ngbGradU); // } // else if (tangGradMethod_ == FAM) // { // // finite area method tangential gradient // ownSGradU = interSGradU[faceI]; // ngbSGradU = interSGradU[faceI]; // // not exactly true but OK as full grad is only // // used for non-orthogonal corrections // ownGradU = ownSGradU; // ngbGradU = ngbSGradU; // } scalar ownTrGradU = tr(ownGradU); scalar ngbTrGradU = tr(ngbGradU); // vector ownSGradUn = (ownSGradU&ownN); // vector ngbSGradUn = (ngbSGradU&ownN); // scalar ownTrSGradUt = tr(ownSGradU&(I-ownN*ownN)); // scalar ngbTrSGradUt = tr(ngbSGradU&(I-ownN*ownN)); scalar ngbDn = w[curGlobalFace]*(1.0/deltaCoeffs[curGlobalFace]); scalar ownDn = (1.0/deltaCoeffs[curGlobalFace]) - ngbDn; scalar ownMu = mu.internalField()[curOwner]; scalar ngbMu = mu.internalField()[curNeighbour]; scalar ownLambda = lambda.internalField()[curOwner]; scalar ngbLambda = lambda.internalField()[curNeighbour]; scalar ownK = (2*ownMu + ownLambda); scalar ngbK = (2*ngbMu + ngbLambda); // Interface displacement // no decomposition of traction - philipc // explicit terms are lumped together in Q vector Qa = ownMu*(ownN&ownGradU.T()) + (ownLambda*ownTrGradU*ownN) - (ownMu+ownLambda)*(ownN&ownGradU); vector Qb = ngbMu*(ownN&ngbGradU.T()) + (ngbLambda*ngbTrGradU*ownN) - (ngbMu+ngbLambda)*(ownN&ngbGradU); vector ownU = UI[curOwner]; vector ngbU = UI[curNeighbour]; interU[faceI] = ( ownK*ngbDn*ownU + ngbK*ownDn*ngbU + (ownDn*ngbDn*(Qb - Qa)) ) /(ownK*ngbDn + ngbK*ownDn); // Implicit coupling scalar wRevLin = 1.0 - w[curGlobalFace]; // philipc: is this stiffness the best choice for convergence? // if ownK=1 and ngbK=2 then Kf=1.333 // A rational choice for Kf might be anywhere between 1 and 2 // but which gives the optimal convergence... scalar Kf = 1.0/(wRevLin/ownK + (1.0-wRevLin)/ngbK); scalar Dnf = 1.0/deltaCoeffs[curGlobalFace]; // Owner diag[curOwner] += Kf*magS/Dnf; upper[curGlobalFace] -= Kf*magS/Dnf; // philipc - no decomposition source[curOwner] += ( ownK*ngbDn*Qb + ngbK*ownDn*Qa )*magS /(ownK*ngbDn + ngbK*ownDn); // Neighbour diag[curNeighbour] += Kf*magS/Dnf; // philipc - no decomposition source[curNeighbour] -= ( ownK*ngbDn*Qb + ngbK*ownDn*Qa )*magS /(ownK*ngbDn + ngbK*ownDn); }