void Foam::swirlFlowRateInletVelocityFvPatchVectorField::updateCoeffs()
{
    if (updated())
    {
        return;
    }

    const scalar t = this->db().time().timeOutputValue();
    const scalar flowRate = flowRate_->value(t);
    const scalar rpm = rpm_->value(t);

    const scalar totArea   = gSum(patch().magSf());
    const scalar avgU = -flowRate/totArea;

    const vector avgCenter = gSum(patch().Cf()*patch().magSf())/totArea;
    const vector avgNormal = gSum(patch().Sf())/totArea;

    // Update angular velocity - convert [rpm] to [rad/s]
    tmp<vectorField> tangentialVelocity
        (
            (rpm*constant::mathematical::pi/30.0)
          * (patch().Cf() - avgCenter) ^ avgNormal
        );

    tmp<vectorField> n = patch().nf();

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

    if (phi.dimensions() == dimVelocity*dimArea)
    {
        // volumetric flow-rate
        operator==(tangentialVelocity + n*avgU);
    }
    else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
    {
        const fvPatchField<scalar>& rhop =
            patch().lookupPatchField<volScalarField, scalar>(rhoName_);

        // mass flow-rate
        operator==(tangentialVelocity + n*avgU/rhop);
    }
    else
    {
        FatalErrorIn
        (
            "swirlFlowRateInletVelocityFvPatchVectorField::updateCoeffs()"
        )   << "dimensions of " << phiName_ << " are incorrect" << nl
            << "    on patch " << this->patch().name()
            << " of field " << this->dimensionedInternalField().name()
            << " in file " << this->dimensionedInternalField().objectPath()
            << nl << exit(FatalError);
    }

    fixedValueFvPatchField<vector>::updateCoeffs();
}
void Foam::swirlFlowRateInletVelocityFvPatchVectorField::updateCoeffs()
{
    if (updated())
    {
        return;
    }
    const scalar totArea = gSum(patch().magSf());

    if (totArea > ROOTVSMALL && axis_ != vector(Zero))
    {
        const scalar t = this->db().time().timeOutputValue();
        const scalar flowRate = flowRate_->value(t);
        const scalar omega = rpmToRads(rpm_->value(t));

        const scalar avgU = -flowRate/totArea;

        const vector axisHat = axis_/mag(axis_);

        // Update angular velocity
        tmp<vectorField> tangentialVelocity
        (
            axisHat ^ omega*(patch().Cf() - origin_)
        );

        tmp<vectorField> n = patch().nf();

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

        if (phi.dimensions() == dimVelocity*dimArea)
        {
            // volumetric flow-rate
            operator==(tangentialVelocity + n*avgU);
        }
        else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
        {
            const fvPatchField<scalar>& rhop =
                patch().lookupPatchField<volScalarField, scalar>(rhoName_);

            // mass flow-rate
            operator==(tangentialVelocity + n*avgU/rhop);
        }
        else
        {
            FatalErrorInFunction
                << "dimensions of " << phiName_ << " are incorrect" << nl
                << "    on patch " << this->patch().name()
                << " of field " << this->internalField().name()
                << " in file " << this->internalField().objectPath()
                << nl << exit(FatalError);
        }
    }

    fixedValueFvPatchField<vector>::updateCoeffs();
}