void MixtureFugacityTP::setState_TR(doublereal T, doublereal rho)
{
    getMoleFractions(DATA_PTR(moleFractions_));
    Phase::setTemperature(T);
    _updateReferenceStateThermo();
    Phase::setDensity(rho);
    doublereal mv = molarVolume();
    // depends on mole fraction and temperature
    updateMixingExpressions();

    m_Pcurrent = pressureCalc(T, mv);
    iState_ = phaseState(true);
}
void MixtureFugacityTP::setState_TP(doublereal t, doublereal pres)
{
    /*
     *  A pretty tricky algorithm is needed here, due to problems involving
     *  standard states of real fluids. For those cases you need
     *  to combine the T and P specification for the standard state, or else
     *  you may venture into the forbidden zone, especially when nearing the
     *  triple point.
     *     Therefore, we need to do the standard state thermo calc with the
     *  (t, pres) combo.
     */
    getMoleFractions(DATA_PTR(moleFractions_));


    Phase::setTemperature(t);
    _updateReferenceStateThermo();
    // Depends on the mole fractions and the temperature
    updateMixingExpressions();
    m_Pcurrent = pres;

    if (forcedState_ ==  FLUID_UNDEFINED) {
        double rhoNow = Phase::density();
        double rho = densityCalc(t, pres, iState_, rhoNow);
        if (rho > 0.0) {
            Phase::setDensity(rho);
            m_Pcurrent = pres;
            iState_ = phaseState(true);
        } else {
            if (rho < -1.5) {
                rho = densityCalc(t, pres, FLUID_UNDEFINED , rhoNow);
                if (rho > 0.0) {
                    Phase::setDensity(rho);
                    m_Pcurrent = pres;
                    iState_ = phaseState(true);
                } else {
                    throw CanteraError("MixtureFugacityTP::setState_TP()", "neg rho");
                }
            } else {
                throw CanteraError("MixtureFugacityTP::setState_TP()", "neg rho");
            }
        }



    } else if (forcedState_ == FLUID_GAS) {
        // Normal density calculation
        if (iState_ < FLUID_LIQUID_0) {
            double rhoNow = Phase::density();
            double rho = densityCalc(t, pres, iState_, rhoNow);
            if (rho > 0.0) {
                Phase::setDensity(rho);
                m_Pcurrent = pres;
                iState_ = phaseState(true);
                if (iState_ >= FLUID_LIQUID_0) {
                    throw CanteraError("MixtureFugacityTP::setState_TP()", "wrong state");
                }
            } else {
                throw CanteraError("MixtureFugacityTP::setState_TP()", "neg rho");
            }

        }


    } else if (forcedState_ > FLUID_LIQUID_0) {
        if (iState_ >= FLUID_LIQUID_0) {
            double rhoNow = Phase::density();
            double rho = densityCalc(t, pres, iState_, rhoNow);
            if (rho > 0.0) {
                Phase::setDensity(rho);
                m_Pcurrent = pres;
                iState_ = phaseState(true);
                if (iState_ == FLUID_GAS) {
                    throw CanteraError("MixtureFugacityTP::setState_TP()", "wrong state");
                }
            } else {
                throw CanteraError("MixtureFugacityTP::setState_TP()", "neg rho");
            }

        }
    }
}
예제 #3
0
void
PorousFlowWaterNCG::massFractions(Real pressure,
                                  Real temperature,
                                  Real Z,
                                  FluidStatePhaseEnum & phase_state,
                                  std::vector<FluidStateProperties> & fsp) const
{
  FluidStateProperties & liquid = fsp[_aqueous_phase_number];
  FluidStateProperties & gas = fsp[_gas_phase_number];

  // Equilibrium mass fraction of NCG in liquid and H2O in gas phases
  Real Xncg, dXncg_dp, dXncg_dT, Yh2o, dYh2o_dp, dYh2o_dT;
  equilibriumMassFractions(
      pressure, temperature, Xncg, dXncg_dp, dXncg_dT, Yh2o, dYh2o_dp, dYh2o_dT);

  Real Yncg = 1.0 - Yh2o;
  Real dYncg_dp = -dYh2o_dp;
  Real dYncg_dT = -dYh2o_dT;

  // Determine which phases are present based on the value of Z
  phaseState(Z, Xncg, Yncg, phase_state);

  // The equilibrium mass fractions calculated above are only correct in the two phase
  // state. If only liquid or gas phases are present, the mass fractions are given by
  // the total mass fraction Z.
  Real Xh2o = 0.0;
  Real dXncg_dZ = 0.0, dYncg_dZ = 0.0;

  switch (phase_state)
  {
    case FluidStatePhaseEnum::LIQUID:
    {
      Xncg = Z;
      Yncg = 0.0;
      Xh2o = 1.0 - Z;
      Yh2o = 0.0;
      dXncg_dp = 0.0;
      dXncg_dT = 0.0;
      dXncg_dZ = 1.0;
      dYncg_dp = 0.0;
      dYncg_dT = 0.0;
      break;
    }

    case FluidStatePhaseEnum::GAS:
    {
      Xncg = 0.0;
      Yncg = Z;
      Yh2o = 1.0 - Z;
      dXncg_dp = 0.0;
      dXncg_dT = 0.0;
      dYncg_dZ = 1.0;
      dYncg_dp = 0.0;
      dYncg_dT = 0.0;
      break;
    }

    case FluidStatePhaseEnum::TWOPHASE:
    {
      // Keep equilibrium mass fractions
      Xh2o = 1.0 - Xncg;
      break;
    }
  }

  // Save the mass fractions in the FluidStateMassFractions object
  liquid.mass_fraction[_aqueous_fluid_component] = Xh2o;
  liquid.mass_fraction[_gas_fluid_component] = Xncg;
  gas.mass_fraction[_aqueous_fluid_component] = Yh2o;
  gas.mass_fraction[_gas_fluid_component] = Yncg;

  // Save the derivatives wrt PorousFlow variables
  liquid.dmass_fraction_dp[_aqueous_fluid_component] = -dXncg_dp;
  liquid.dmass_fraction_dp[_gas_fluid_component] = dXncg_dp;
  liquid.dmass_fraction_dT[_aqueous_fluid_component] = -dXncg_dT;
  liquid.dmass_fraction_dT[_gas_fluid_component] = dXncg_dT;
  liquid.dmass_fraction_dZ[_aqueous_fluid_component] = -dXncg_dZ;
  liquid.dmass_fraction_dZ[_gas_fluid_component] = dXncg_dZ;

  gas.dmass_fraction_dp[_aqueous_fluid_component] = -dYncg_dp;
  gas.dmass_fraction_dp[_gas_fluid_component] = dYncg_dp;
  gas.dmass_fraction_dT[_aqueous_fluid_component] = -dYncg_dT;
  gas.dmass_fraction_dT[_gas_fluid_component] = dYncg_dT;
  gas.dmass_fraction_dZ[_aqueous_fluid_component] = -dYncg_dZ;
  gas.dmass_fraction_dZ[_gas_fluid_component] = dYncg_dZ;
}