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
            );
        }
    }
}
Exemple #2
0
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);
}
Exemple #3
0
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
        );
    }
}
Exemple #4
0
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 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);
    }