void contactProblem::correct()
{
    contactPatchPairList& contacts = *this;

    // Create fields for accumulation
    volVectorField::GeometricBoundaryField& Upatches = U().boundaryField();

    FieldField<Field, vector> curTraction(Upatches.size());
    FieldField<Field, vector> newTraction(Upatches.size());
    FieldField<Field, vector> refValue(Upatches.size());
    FieldField<Field, scalar> valueFraction(Upatches.size());

    forAll (Upatches, patchI)
    {
        curTraction.set
        (
            patchI,
            new vectorField(Upatches[patchI].size(), vector::zero)
        );

        newTraction.set
        (
            patchI,
            new vectorField(Upatches[patchI].size(), vector::zero)
        );

        refValue.set
        (
            patchI,
            new vectorField(Upatches[patchI].size(), vector::zero)
        );

        valueFraction.set
        (
            patchI,
            new scalarField(Upatches[patchI].size(), 0)
        );
    }
void Foam::SRFFreestreamVelocityFvPatchVectorField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    // Get reference to the SRF model
    const SRF::SRFModel& srf =
        db().lookupObject<SRF::SRFModel>("SRFProperties");

    scalar time = this->db().time().value();
    scalar theta = time*mag(srf.omega().value());

    refValue() =
        cos(theta)*UInf_ + sin(theta)*(srf.axis() ^ UInf_)
      - srf.velocity(patch().Cf());

    // Set the inlet-outlet choice based on the direction of the freestream
    valueFraction() = 1.0 - pos(refValue() & patch().Sf());

    mixedFvPatchField<vector>::updateCoeffs();
}
void thermalBaffle1DFvPatchScalarField<solidType>::updateCoeffs()
{
    if (updated())
    {
        return;
    }
    // Since we're inside initEvaluate/evaluate there might be processor
    // comms underway. Change the tag we use.
    int oldTag = UPstream::msgType();
    UPstream::msgType() = oldTag+1;


    const mapDistribute& mapDist = this->mappedPatchBase::map();

    const label patchi = patch().index();

    const label nbrPatchi = samplePolyPatch().index();

    if (baffleActivated_)
    {
        const fvPatch& nbrPatch = patch().boundaryMesh()[nbrPatchi];

        const compressible::turbulenceModel& turbModel =
            db().template lookupObject<compressible::turbulenceModel>
            (
                "turbulenceModel"
            );

        // local properties
        const scalarField kappaw(turbModel.kappaEff(patchi));

        const fvPatchScalarField& Tp =
            patch().template lookupPatchField<volScalarField, scalar>(TName_);


        scalarField Qr(Tp.size(), 0.0);

        if (QrName_ != "none")
        {
            Qr = patch().template lookupPatchField<volScalarField, scalar>
                (QrName_);

            Qr = QrRelaxation_*Qr + (1.0 - QrRelaxation_)*QrPrevious_;
            QrPrevious_ = Qr;
        }

        tmp<scalarField> Ti = patchInternalField();

        scalarField myKDelta(patch().deltaCoeffs()*kappaw);

        // nrb properties
        scalarField nbrTp =
            turbModel.thermo().T().boundaryField()[nbrPatchi];
        mapDist.distribute(nbrTp);

        // solid properties
        scalarField kappas(patch().size(), 0.0);
        forAll(kappas, i)
        {
            kappas[i] = solid().kappa(0.0, (Tp[i] + nbrTp[i])/2.0);
        }

        const scalarField KDeltaSolid(kappas/baffleThickness());

        const scalarField alpha(KDeltaSolid - Qr/Tp);

        valueFraction() = alpha/(alpha + myKDelta);

        refValue() = (KDeltaSolid*nbrTp + Qs()/2.0)/alpha;

        if (debug)
        {
            scalar Q = gAverage(kappaw*snGrad());
            Info<< patch().boundaryMesh().mesh().name() << ':'
                << patch().name() << ':'
                << this->dimensionedInternalField().name() << " <- "
                << nbrPatch.name() << ':'
                << this->dimensionedInternalField().name() << " :"
                << " heat[W]:" << Q
                << " walltemperature "
                << " min:" << gMin(*this)
                << " max:" << gMax(*this)
                << " avg:" << gAverage(*this)
                << endl;
        }
    }
void pressureDirectedInletOutletVelocityFvPatchVectorField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    if (!this->db().objectRegistry::found(phiName_))
    {
        // Flux not available, do not update
        InfoIn
        (
            "void pressureDirectedInletOutletVelocityFvPatchVectorField::"
            "updateCoeffs()"
        )   << "Flux field " << phiName_ << " not found.  "
            << "Performing mixed update" << endl;

        mixedFvPatchVectorField::updateCoeffs();

        return;
    }

    const surfaceScalarField& phi =
        db().lookupObject<surfaceScalarField>(phiName_);

    const fvsPatchField<scalar>& phip =
        patch().patchField<surfaceScalarField, scalar>(phi);

    vectorField n = patch().nf();
    scalarField ndmagS = (n & inletDir_)*patch().magSf();

    if (phi.dimensions() == dimVelocity*dimArea)
    {
        refValue() = inletDir_*phip/ndmagS;
    }
    else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
    {
        if (!this->db().objectRegistry::found(rhoName_))
        {
            // Rho not available, do not update
            mixedFvPatchVectorField::updateCoeffs();

            return;
        }

        const fvPatchField<scalar>& rhop =
            lookupPatchField<volScalarField, scalar>(rhoName_);

        refValue() = inletDir_*phip/(rhop*ndmagS);
    }
    else
    {
        FatalErrorIn
        (
            "pressureDirectedInletOutletVelocityFvPatchVectorField::"
            "updateCoeffs()"
        )   << "dimensions of phi are not correct"
            << "\n    on patch " << this->patch().name()
            << " of field " << this->dimensionedInternalField().name()
            << " in file " << this->dimensionedInternalField().objectPath()
            << exit(FatalError);
    }

    valueFraction() = 1.0 - pos(phip);

    mixedFvPatchVectorField::updateCoeffs();
}
void turbulentTemperatureCoupledMixedSTFvPatchScalarField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    // Get the coupling information from the directMappedPatchBase
    const directMappedPatchBase& mpp =
        refCast<const directMappedPatchBase>(patch().patch());
    const polyMesh& nbrMesh = mpp.sampleMesh();
    const label samplePatchI = mpp.samplePolyPatch().index();
    const fvPatch& nbrPatch =
        refCast<const fvMesh>(nbrMesh).boundary()[samplePatchI];

    // Force recalculation of mapping and schedule
    const mapDistribute& distMap = mpp.map();

    scalarField Tc = patchInternalField();
    scalarField& Tp = *this;

    const turbulentTemperatureCoupledMixedSTFvPatchScalarField&
        nbrField = refCast
            <const turbulentTemperatureCoupledMixedSTFvPatchScalarField>
            (
                nbrPatch.lookupPatchField<volScalarField, scalar>(TnbrName_)
            );

    // Swap to obtain full local values of neighbour internal field
    scalarField TcNbr = nbrField.patchInternalField();
    mapDistribute::distribute
    (
        Pstream::defaultCommsType,
        distMap.schedule(),
        distMap.constructSize(),
        distMap.subMap(),           // what to send
        distMap.constructMap(),     // what to receive
        TcNbr
    );

    // Swap to obtain full local values of neighbour K*delta
    scalarField KDeltaNbr = nbrField.K()*nbrPatch.deltaCoeffs();
    mapDistribute::distribute
    (
        Pstream::defaultCommsType,
        distMap.schedule(),
        distMap.constructSize(),
        distMap.subMap(),           // what to send
        distMap.constructMap(),     // what to receive
        KDeltaNbr
    );

    scalarField KDelta = K()*patch().deltaCoeffs();

    scalarField Qr(Tp.size(), 0.0);
    if (QrName_ != "none")
    {
        Qr = patch().lookupPatchField<volScalarField, scalar>(QrName_);
    }

    scalarField QrNbr(Tp.size(), 0.0);
    if (QrNbrName_ != "none")
    {
        QrNbr = nbrPatch.lookupPatchField<volScalarField, scalar>(QrNbrName_);
    }

    scalarField alpha(KDeltaNbr - (Qr + QrNbr)/Tp);

    valueFraction() = alpha/(alpha + KDelta);

    refValue() = (KDeltaNbr*TcNbr)/alpha;

    mixedFvPatchScalarField::updateCoeffs();
}
void CFDHAMfluidMoistureCoupledMixedFvPatchScalarField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    // Since we're inside initEvaluate/evaluate there might be processor
    // comms underway. Change the tag we use.
    int oldTag = UPstream::msgType();
    UPstream::msgType() = oldTag+1;

    // Get the coupling information from the mappedPatchBase
    const mappedPatchBase& mpp =
        refCast<const mappedPatchBase>(patch().patch());
    const polyMesh& nbrMesh = mpp.sampleMesh();
    const label samplePatchI = mpp.samplePolyPatch().index();
    const fvPatch& nbrPatch =
        refCast<const fvMesh>(nbrMesh).boundary()[samplePatchI];

//    scalarField Tc(patchInternalField());
    scalarField& Tp = *this;

/*    const mixedFvPatchScalarField& //CFDHAMfluidMoistureCoupledMixedFvPatchScalarField&
        nbrField = refCast
            <const mixedFvPatchScalarField>
            (
                nbrPatch.lookupPatchField<volScalarField, scalar>(wnbrName_)
            );   */

    const mixedFvPatchScalarField& //CFDHAMfluidMoistureCoupledMixedFvPatchScalarField&
        nbrTField = refCast
            <const mixedFvPatchScalarField>
            (
                nbrPatch.lookupPatchField<volScalarField, scalar>(TnbrName_)
            );   

    const mixedFvPatchScalarField& //CFDHAMfluidMoistureCoupledMixedFvPatchScalarField&
        nbrpcField = refCast
            <const mixedFvPatchScalarField>
            (
                nbrPatch.lookupPatchField<volScalarField, scalar>("pc")
            );                       

    // Swap to obtain full local values of neighbour internal field
//    scalarField wcNbr(nbrField.patchInternalField());
//    mpp.distribute(wcNbr);

    scalarField TNbr(nbrTField.patchInternalField());
    mpp.distribute(TNbr);  

    scalarField pcNbr(nbrpcField.patchInternalField());
    mpp.distribute(pcNbr); 

    scalarField p(Tp.size(), 0.0);
        p = patch().lookupPatchField<volScalarField, scalar>("p");    

    scalarField rhoair(Tp.size(), 0.0);
        rhoair = patch().lookupPatchField<volScalarField, scalar>("rho");            

    scalar rhol=1.0e3; scalar Rv=8.31451*1000/(18.01534);
    scalarField pvsat_s = exp(6.58094e1-7.06627e3/TNbr-5.976*log(TNbr));
    
    scalarField pv_s = pvsat_s*exp((pcNbr)/(rhol*Rv*TNbr));
    
    valueFraction() = 1.0;//KDeltaNbr/(KDeltaNbr + KDelta);
    refValue() = 0.62198*pv_s/p;//pv_s/pvsat_s;
    refGrad() = 0.0;//(Qr + QrNbr + Qs + QsNbr)/(kappa(Tp));

    mixedFvPatchScalarField::updateCoeffs();

/*    if (debug)
    {
        scalar Q = gSum(kappa(Tp)*patch().magSf()*snGrad());

        Info<< patch().boundaryMesh().mesh().name() << ':'
            << patch().name() << ':'
            << this->dimensionedInternalField().name() << " <- "
            << nbrMesh.name() << ':'
            << nbrPatch.name() << ':'
            << this->dimensionedInternalField().name() << " :"
            << " heat transfer rate:" << Q
            << " walltemperature "
            << " min:" << gMin(Tp)
            << " max:" << gMax(Tp)
            << " avg:" << gAverage(Tp)
            << endl;
    } */

    // Restore tag
    UPstream::msgType() = oldTag;

}
void filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    // Get the coupling information from the mappedPatchBase
    const mappedPatchBase& mpp =
        refCast<const mappedPatchBase>(patch().patch());

    const label patchI = patch().index();
    const label nbrPatchI = mpp.samplePolyPatch().index();
    const polyMesh& mesh = patch().boundaryMesh().mesh();
    const polyMesh& nbrMesh = mpp.sampleMesh();
    const fvPatch& nbrPatch =
        refCast<const fvMesh>(nbrMesh).boundary()[nbrPatchI];

    scalarField intFld(patchInternalField());

    const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField&
        nbrField =
        refCast
        <
            const filmPyrolysisRadiativeCoupledMixedFvPatchScalarField
        >
        (
            nbrPatch.lookupPatchField<volScalarField, scalar>(TnbrName_)
        );

    // Swap to obtain full local values of neighbour internal field
    scalarField nbrIntFld(nbrField.patchInternalField());
    mpp.distribute(nbrIntFld);

    scalarField& Tp = *this;

    const scalarField K(this->kappa(*this));
    const scalarField nbrK(nbrField.kappa(*this));

    // Swap to obtain full local values of neighbour K*delta
    scalarField KDeltaNbr(nbrK*nbrPatch.deltaCoeffs());
    mpp.distribute(KDeltaNbr);

    scalarField myKDelta(K*patch().deltaCoeffs());

    scalarList Tfilm(patch().size(), 0.0);
    scalarList htcwfilm(patch().size(), 0.0);
    scalarList filmDelta(patch().size(), 0.0);

    const pyrolysisModelType& pyrolysis = pyrModel();
    const filmModelType& film = filmModel();

    // Obtain Rad heat (Qr)
    scalarField Qr(patch().size(), 0.0);

    label coupledPatchI = -1;
    if (pyrolysisRegionName_ == mesh.name())
    {
        coupledPatchI = patchI;
        if (QrName_ != "none")
        {
            Qr = nbrPatch.lookupPatchField<volScalarField, scalar>(QrName_);
            mpp.distribute(Qr);
        }
    }
    else if (pyrolysis.primaryMesh().name() == mesh.name())
    {
        coupledPatchI = nbrPatch.index();
        if (QrName_ != "none")
        {
            Qr = patch().lookupPatchField<volScalarField, scalar>(QrName_);
        }
    }
    else
    {
        FatalErrorIn
        (
            "void filmPyrolysisRadiativeCoupledMixedFvPatchScalarField::"
            "updateCoeffs()"
        )
            << type() << " condition is intended to be applied to either the "
            << "primary or pyrolysis regions only"
            << exit(FatalError);
    }

    const label filmPatchI = pyrolysis.nbrCoupledPatchID(film, coupledPatchI);

    const scalarField htcw(film.htcw().h()().boundaryField()[filmPatchI]);

    // Obtain htcw
    htcwfilm =
        pyrolysis.mapRegionPatchField
        (
            film,
            coupledPatchI,
            filmPatchI,
            htcw,
            true
        );


    // Obtain Tfilm at the boundary through Ts.
    // NOTE: Tf is not good as at the boundary it will retrieve Tp
    Tfilm = film.Ts().boundaryField()[filmPatchI];
    film.toPrimary(filmPatchI, Tfilm);

    // Obtain delta
    filmDelta =
        pyrolysis.mapRegionPatchField<scalar>
        (
            film,
            "deltaf",
            coupledPatchI,
            true
        );

     // Estimate wetness of the film (1: wet , 0: dry)
     scalarField ratio
     (
        min
        (
            max
            (
                (filmDelta - filmDeltaDry_)/(filmDeltaWet_ - filmDeltaDry_),
                scalar(0.0)
            ),
            scalar(1.0)
        )
     );

    scalarField qConv(ratio*htcwfilm*(Tfilm - Tp)*convectiveScaling_);

    scalarField qRad((1.0 - ratio)*Qr);

    scalarField alpha(KDeltaNbr - (qRad + qConv)/Tp);

    valueFraction() = alpha/(alpha + (1.0 - ratio)*myKDelta);

    refValue() = ratio*Tfilm + (1.0 - ratio)*(KDeltaNbr*nbrIntFld)/alpha;

    mixedFvPatchScalarField::updateCoeffs();

    if (debug)
    {
        scalar Qc = gSum(qConv*patch().magSf());
        scalar Qr = gSum(qRad*patch().magSf());
        scalar Qt = gSum((qConv + qRad)*patch().magSf());

        Info<< mesh.name() << ':'
            << patch().name() << ':'
            << this->dimensionedInternalField().name() << " <- "
            << nbrMesh.name() << ':'
            << nbrPatch.name() << ':'
            << this->dimensionedInternalField().name() << " :" << nl
            << "     convective heat[W] : " << Qc << nl
            << "     radiative heat [W] : " << Qr << nl
            << "     total heat     [W] : " << Qt << nl
            << "     wall temperature "
            << " min:" << gMin(*this)
            << " max:" << gMax(*this)
            << " avg:" << gAverage(*this)
            << endl;
    }
}
void turbulentTemperatureRadCoupledMixedFvPatchScalarField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    // Since we're inside initEvaluate/evaluate there might be processor
    // comms underway. Change the tag we use.
    int oldTag = UPstream::msgType();
    UPstream::msgType() = oldTag+1;

    // Get the coupling information from the mappedPatchBase
    const mappedPatchBase& mpp =
        refCast<const mappedPatchBase>(patch().patch());
    const polyMesh& nbrMesh = mpp.sampleMesh();
    const label samplePatchi = mpp.samplePolyPatch().index();
    const fvPatch& nbrPatch =
        refCast<const fvMesh>(nbrMesh).boundary()[samplePatchi];


    scalarField Tc(patchInternalField());
    scalarField& Tp = *this;

    const turbulentTemperatureRadCoupledMixedFvPatchScalarField&
        nbrField = refCast
            <const turbulentTemperatureRadCoupledMixedFvPatchScalarField>
            (
                nbrPatch.lookupPatchField<volScalarField, scalar>(TnbrName_)
            );

    // Swap to obtain full local values of neighbour internal field
    scalarField TcNbr(nbrField.patchInternalField());
    mpp.distribute(TcNbr);


    // Swap to obtain full local values of neighbour K*delta
    scalarField KDeltaNbr;
    if (contactRes_ == 0.0)
    {
        KDeltaNbr = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs();
    }
    else
    {
        KDeltaNbr.setSize(nbrField.size(), contactRes_);
    }
    mpp.distribute(KDeltaNbr);

    scalarField KDelta(kappa(Tp)*patch().deltaCoeffs());

    scalarField Qr(Tp.size(), 0.0);
    if (QrName_ != "none")
    {
        Qr = patch().lookupPatchField<volScalarField, scalar>(QrName_);
    }

    scalarField QrNbr(Tp.size(), 0.0);
    if (QrNbrName_ != "none")
    {
        QrNbr = nbrPatch.lookupPatchField<volScalarField, scalar>(QrNbrName_);
        mpp.distribute(QrNbr);
    }

    valueFraction() = KDeltaNbr/(KDeltaNbr + KDelta);
    refValue() = TcNbr;
    refGrad() = (Qr + QrNbr)/kappa(Tp);

    mixedFvPatchScalarField::updateCoeffs();

    if (debug)
    {
        scalar Q = gSum(kappa(Tp)*patch().magSf()*snGrad());

        Info<< patch().boundaryMesh().mesh().name() << ':'
            << patch().name() << ':'
            << this->internalField().name() << " <- "
            << nbrMesh.name() << ':'
            << nbrPatch.name() << ':'
            << this->internalField().name() << " :"
            << " heat transfer rate:" << Q
            << " walltemperature "
            << " min:" << gMin(Tp)
            << " max:" << gMax(Tp)
            << " avg:" << gAverage(Tp)
            << endl;
    }

    // Restore tag
    UPstream::msgType() = oldTag;
}
void Foam::supersonicFreestreamFvPatchVectorField::updateCoeffs()
{
    if (!size() || updated())
    {
        return;
    }

    const fvPatchField<scalar>& pT =
        patch().lookupPatchField<volScalarField, scalar>("T");

    const fvPatchField<scalar>& pp =
        patch().lookupPatchField<volScalarField, scalar>("p");

    const fvPatchField<scalar>& ppsi =
        patch().lookupPatchField<volScalarField, scalar>("psi");

    // Need R of the free-stream flow.  Assume R is independent of location
    // along patch so use face 0
    scalar R = 1.0/(ppsi[0]*pT[0]);

    scalar MachInf = mag(UInf_)/sqrt(gamma_*R*TInf_);

    if (MachInf < 1.0)
    {
        FatalErrorIn
        (
            "supersonicFreestreamFvPatchVectorField::updateCoeffs()"
        )   << "    MachInf < 1.0, free stream must be supersonic"
            << "\n    on patch " << this->patch().name()
            << " of field " << this->dimensionedInternalField().name()
            << " in file " << this->dimensionedInternalField().objectPath()
            << exit(FatalError);
    }

    vectorField& Up = refValue();
    valueFraction() = 1;

    // get the near patch internal cell values
    const vectorField U(patchInternalField());


    // Find the component of U normal to the free-stream flow and in the
    // plane of the free-stream flow and the patch normal

    // Direction of the free-stream flow
    vector UInfHat = UInf_/mag(UInf_);

    // Normal to the plane defined by the free-stream and the patch normal
    tmp<vectorField> nnInfHat = UInfHat ^ patch().nf();

    // Normal to the free-stream in the plane defined by the free-stream
    // and the patch normal
    const vectorField nHatInf(nnInfHat ^ UInfHat);

    // Component of U normal to the free-stream in the plane defined by the
    // free-stream and the patch normal
    const vectorField Un(nHatInf*(nHatInf & U));

    // The tangential component is
    const vectorField Ut(U - Un);

    // Calculate the Prandtl-Meyer function of the free-stream
    scalar nuMachInf =
        sqrt((gamma_ + 1)/(gamma_ - 1))
       *atan(sqrt((gamma_ - 1)/(gamma_ + 1)*(sqr(MachInf) - 1)))
      - atan(sqr(MachInf) - 1);


    // Set the patch boundary condition based on the Mach number and direction
    // of the flow dictated by the boundary/free-stream pressure difference

    forAll(Up, facei)
    {
        if (pp[facei] >= pInf_) // If outflow
        {
            // Assume supersonic outflow and calculate the boundary velocity
            // according to ???

            scalar fpp =
                sqrt(sqr(MachInf) - 1)
               /(gamma_*sqr(MachInf))*mag(Ut[facei])*log(pp[facei]/pInf_);

            Up[facei] = Ut[facei] + fpp*nHatInf[facei];

            // Calculate the Mach number of the boundary velocity
            scalar Mach = mag(Up[facei])/sqrt(gamma_/ppsi[facei]);

            if (Mach <= 1) // If subsonic
            {
                // Zero-gradient subsonic outflow

                Up[facei] = U[facei];
                valueFraction()[facei] = 0;
            }
        }
        else // if inflow
        {
            // Calculate the Mach number of the boundary velocity
            // from the boundary pressure assuming constant total pressure
            // expansion from the free-stream
            scalar Mach =
                sqrt
                (
                    (2/(gamma_ - 1))*(1 + ((gamma_ - 1)/2)*sqr(MachInf))
                   *pow(pp[facei]/pInf_, (1 - gamma_)/gamma_)
                  - 2/(gamma_ - 1)
                );

            if (Mach > 1) // If supersonic
            {
                // Supersonic inflow is assumed to occur according to the
                // Prandtl-Meyer expansion process

                scalar nuMachf =
                    sqrt((gamma_ + 1)/(gamma_ - 1))
                   *atan(sqrt((gamma_ - 1)/(gamma_ + 1)*(sqr(Mach) - 1)))
                  - atan(sqr(Mach) - 1);

                scalar fpp = (nuMachInf - nuMachf)*mag(Ut[facei]);

                Up[facei] = Ut[facei] + fpp*nHatInf[facei];
            }
            else // If subsonic
            {
                FatalErrorIn
                (
                    "supersonicFreestreamFvPatchVectorField::updateCoeffs()"
                )   << "unphysical subsonic inflow has been generated"
                    << "\n    on patch " << this->patch().name()
                    << " of field " << this->dimensionedInternalField().name()
                    << " in file "
                    << this->dimensionedInternalField().objectPath()
                    << exit(FatalError);
            }
        }
    }

    mixedFvPatchVectorField::updateCoeffs();
}
timeVaryingFixedDisplacementZeroShearFvPatchVectorField::
timeVaryingFixedDisplacementZeroShearFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const dictionary& dict
)
:
    directionMixedFvPatchVectorField(p, iF),
    fieldName_(dimensionedInternalField().name()),
    nonLinear_(nonLinearGeometry::OFF),
    orthotropic_(false),
    timeSeries_(dict)
{
    //- check if traction boundary is for non linear solver
    if (dict.found("nonLinear"))
    {
        nonLinear_ = nonLinearGeometry::nonLinearNames_.read
        (
            dict.lookup("nonLinear")
        );

        if (nonLinear_ == nonLinearGeometry::UPDATED_LAGRANGIAN)
        {
            Info << "\tnonLinear set to updated Lagrangian"
                 << endl;
        }
        else if (nonLinear_ == nonLinearGeometry::TOTAL_LAGRANGIAN)
        {
            Info << "\tnonLinear set to total Lagrangian"
                 << endl;
        }
    }

    if (dict.found("orthotropic"))
    {
        orthotropic_ = Switch(dict.lookup("orthotropic"));
        Info << "\t\torthotropic set to " << orthotropic_ << endl;
    }

    //- the leastSquares has zero non-orthogonal correction
    //- on the boundary
    //- so the gradient scheme should be extendedLeastSquares
    if
    (
        Foam::word
        (
            dimensionedInternalField().mesh().schemesDict().gradScheme
            (
                "grad(" + fieldName_ + ")"
            )
        ) != "extendedLeastSquares"
    )
    {
        Warning << "The gradScheme for " << fieldName_
            << " should be \"extendedLeastSquares 0\" for the boundary "
            << "non-orthogonal correction to be right" << endl;
    }

    this->refGrad() = vector::zero;

    vectorField n = patch().nf();
    this->valueFraction() = sqr(n);

    if (dict.found("value"))
    {
        Field<vector>::operator=(vectorField("value", dict, p.size()));
    }
    else
    {
        FatalError
            << "value entry not found for patch " << patch().name() << endl;
    }

    this->refValue() = timeSeries_(this->db().time().timeOutputValue());

    Field<vector> normalValue = transform(valueFraction(), refValue());

    Field<vector> gradValue =
        this->patchInternalField() + refGrad()/this->patch().deltaCoeffs();

    Field<vector> transformGradValue =
        transform(I - valueFraction(), gradValue);

    Field<vector>::operator=(normalValue + transformGradValue);
}
void Foam::radiation::greyDiffusiveRadiationMixedFvPatchScalarField::
updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    const scalarField& Tp =
        patch().lookupPatchField<volScalarField, scalar>(TName_);

    const radiationModel& radiation =
        db().lookupObject<radiationModel>("radiationProperties");

    const fvDOM& dom(refCast<const fvDOM>(radiation));

    label rayId = -1;
    label lambdaId = -1;
    dom.setRayIdLambdaId(dimensionedInternalField().name(), rayId, lambdaId);

    const label patchI = patch().index();

    if (dom.nLambda() != 1)
    {
        FatalErrorIn
        (
            "Foam::radiation::"
            "greyDiffusiveRadiationMixedFvPatchScalarField::updateCoeffs"
        )   << " a grey boundary condition is used with a non-grey "
            << "absorption model" << nl << exit(FatalError);
    }

    scalarField& Iw = *this;
    vectorField n = patch().Sf()/patch().magSf();

    radiativeIntensityRay& ray =
        const_cast<radiativeIntensityRay&>(dom.IRay(rayId));

    ray.Qr().boundaryField()[patchI] += Iw*(n & ray.dAve());

    forAll(Iw, faceI)
    {
        scalar Ir = 0.0;

        for (label rayI=0; rayI < dom.nRay(); rayI++)
        {
            const vector& d = dom.IRay(rayI).d();

            const scalarField& IFace =
                dom.IRay(rayI).ILambda(lambdaId).boundaryField()[patchI];

            if ((-n[faceI] & d) < 0.0)
            {
                // q into the wall
                const vector& dAve = dom.IRay(rayI).dAve();
                Ir += IFace[faceI]*mag(n[faceI] & dAve);
            }
        }

        const vector& d = dom.IRay(rayId).d();

        if ((-n[faceI] & d) > 0.0)
        {
            // direction out of the wall
            refGrad()[faceI] = 0.0;
            valueFraction()[faceI] = 1.0;
            refValue()[faceI] =
                (
                    Ir*(1.0 - emissivity_)
                    + emissivity_*radiation::sigmaSB.value()*pow4(Tp[faceI])
                )
                /mathematicalConstant::pi;

            // Emmited heat flux from this ray direction
            ray.Qem().boundaryField()[patchI][faceI] =
                refValue()[faceI]*(n[faceI] & ray.dAve());

        }
        else
        {
            // direction into the wall
            valueFraction()[faceI] = 0.0;
            refGrad()[faceI] = 0.0;
            refValue()[faceI] = 0.0; //not used

            // Incident heat flux on this ray direction
            ray.Qin().boundaryField()[patchI][faceI] =
                Iw[faceI]*(n[faceI] & ray.dAve());
        }
    }
Foam::semiTransSurfaceCoupledFvPatchScalarField::
semiTransSurfaceCoupledFvPatchScalarField
(
    const fvPatch& p,
    const DimensionedField<scalar, volMesh>& iF,
    const dictionary& dict
)
:
    mixedFvPatchScalarField(p, iF),
    neighbourFieldName_(dict.lookup("neighbourFieldName")),
{
	
	
    if (!isA<directMappedPatchBase>(this->patch().patch()))
    {
        FatalErrorIn
        (
            "semiTransSurfaceCoupledFvPatchScalarField::"
            "semiTransSurfaceCoupledFvPatchScalarField\n"
            "(\n"
            "    const fvPatch& p,\n"
            "    const DimensionedField<scalar, volMesh>& iF,\n"
            "    const dictionary& dict\n"
            ")\n"
        )   << "\n    patch type '" << p.type()
            << "' not type '" << directMappedPatchBase::typeName << "'"
            << "\n    for patch " << p.name()
            << " of field " << dimensionedInternalField().name()
            << " in file " << dimensionedInternalField().objectPath()
            << exit(FatalError);
    }
    
    
    

    fvPatchScalarField::operator=(scalarField("value", dict, p.size()));

    if (dict.found("refValue"))
    {
		
		
        // Full restart
        refValue() = scalarField("refValue", dict, p.size());
        refGrad()  = scalarField("refGradient", dict, p.size());
        valueFraction() = scalarField("valueFraction", dict, p.size());
        
        
    }
    else
    {
    
        // Start from user entered data. Assume fixedValue.
        refValue() = *this;
        refGrad() = 0.0;
        valueFraction() = 1.0;
        
        
    }
    
    
}