Skip to content
Snippets Groups Projects
vdW.hpp 4.94 KiB
Newer Older
  • Learn to ignore specific revisions
  • Ian Bell's avatar
    Ian Bell committed
    #pragma once
    
    
    Ian Bell's avatar
    Ian Bell committed
    #include "teqp/constants.hpp"
    
    #include "teqp/types.hpp"
    
    Ian Bell's avatar
    Ian Bell committed
    #include "teqp/exceptions.hpp"
    
    Ian Bell's avatar
    Ian Bell committed
    
    
    namespace teqp {
    
    Ian Bell's avatar
    Ian Bell committed
    /*
    
    Ian Bell's avatar
    Ian Bell committed
    To add:
    
    Ian Bell's avatar
    Ian Bell committed
    1. LKP (Stefan Herrig's thesis)
    
    Ian Bell's avatar
    Ian Bell committed
    /// A (very) simple implementation of the van der Waals EOS
    
    Ian Bell's avatar
    Ian Bell committed
    class vdWEOS1 {
    private:
    
    Ian Bell's avatar
    Ian Bell committed
        double a, b;
    
    Ian Bell's avatar
    Ian Bell committed
    public:
    
    Ian Bell's avatar
    Ian Bell committed
        /// Intializer, taking the a and b constants directly
    
    Ian Bell's avatar
    Ian Bell committed
        vdWEOS1(double a, double b) : a(a), b(b) {};
    
    Ian Bell's avatar
    Ian Bell committed
        double get_a() const{ return a; }
        double get_b() const{ return b; }
    
    Ian Bell's avatar
    Ian Bell committed
    
    
        const double Ru = 1.380649e-23 * 6.02214076e23; ///< Exact value, given by k_B*N_A
    
    
    Ian Bell's avatar
    Ian Bell committed
        /// \brief Get the universal gas constant 
        /// \note Here the real universal gas constant, with no composition dependence
    
        template<class VecType>
        auto R(const VecType& molefrac) const { return Ru; }
    
    Ian Bell's avatar
    Ian Bell committed
        /// The evaluation of \f$ \alpha^{\rm r}=a/(RT) \f$
        /// \param T The temperature
    
    Ian Bell's avatar
    Ian Bell committed
        /// \param rhotot The molar density
    
    Ian Bell's avatar
    Ian Bell committed
        /// \param molefrac The mole fractions of each component
    
        template<typename TType, typename RhoType, typename VecType>
    
        auto alphar(const TType &T, const RhoType& rhotot, const VecType &molefrac) const {
    
            return forceeval(-log(1.0 - b * rhotot) - (a / (R(molefrac) * T)) * rhotot);
    
    Ian Bell's avatar
    Ian Bell committed
        }
    
    Ian Bell's avatar
    Ian Bell committed
    
    
    Ian Bell's avatar
    Ian Bell committed
        /// \brief For testing, provide the pressure explicit form of the EOS
    
    Ian Bell's avatar
    Ian Bell committed
        double p(double T, double v) {
    
            return Ru*T/(v - b) - a/(v*v);
    
    Ian Bell's avatar
    Ian Bell committed
        }
    
    Ian Bell's avatar
    Ian Bell committed
    };
    
    
    Ian Bell's avatar
    Ian Bell committed
    /// A slightly more involved implementation of van der Waals, this time with mixture properties
    
    Ian Bell's avatar
    Ian Bell committed
    template <typename NumType>
    class vdWEOS {
    
    protected:
    
    Ian Bell's avatar
    Ian Bell committed
        std::valarray<NumType> ai, bi;
        std::valarray<std::valarray<NumType>> k;
    
    Ian Bell's avatar
    Ian Bell committed
    
    
    Ian Bell's avatar
    Ian Bell committed
        template<typename TType, typename IndexType>
    
        auto get_ai(TType T, IndexType i) const { return ai[i]; }
    
    
    Ian Bell's avatar
    Ian Bell committed
        template<typename TType, typename IndexType>
    
        auto get_bi(TType T, IndexType i) const { return bi[i]; }
    
    Ian Bell's avatar
    Ian Bell committed
    
    
    Ian Bell's avatar
    Ian Bell committed
        /// \brief Initializer, taking the arrays of critical temperatures and pressures
        /// \param Tc_K Array of critical temperatures in Kelvin
        /// \param pc_Pa Array of critical pressures in Pascal
        /// 
        /// \note All interaction parameters are set to default value of zero and cannot currently be tuned
    
        vdWEOS(const std::valarray<NumType>& Tc_K, const std::valarray<NumType>& pc_Pa)
        {
    
    Ian Bell's avatar
    Ian Bell committed
            if (Tc_K.size() != pc_Pa.size()){
    
    Ian Bell's avatar
    Ian Bell committed
                throw teqp::InvalidArgument("Sizes of Tc_K " + std::to_string(Tc_K.size()) + " and pc_Pa" + std::to_string(pc_Pa.size()) + " do not agree");
    
    Ian Bell's avatar
    Ian Bell committed
            }
    
            ai.resize(Tc_K.size());
            bi.resize(Tc_K.size());
            for (auto i = 0; i < Tc_K.size(); ++i) {
    
                ai[i] = 27.0 / 64.0 * pow(Ru * Tc_K[i], 2) / pc_Pa[i];
                bi[i] = 1.0 / 8.0 * Ru * Tc_K[i] / pc_Pa[i];
    
            }
            k = std::valarray<std::valarray<NumType>>(std::valarray<NumType>(0.0, Tc_K.size()), Tc_K.size());
        }; 
        
    
    Ian Bell's avatar
    Ian Bell committed
        /// \brief Calculate the a parameter, based on quadratic mixing rules
        /// \param T Temperature
        /// \param molefracs Array of mole fractions
    
    Ian Bell's avatar
    Ian Bell committed
        template<typename TType, typename CompType>
        auto a(TType T, const CompType& molefracs) const {
    
    Ian Bell's avatar
    Ian Bell committed
            typename CompType::value_type a_ = 0.0;
    
    Ian Bell's avatar
    Ian Bell committed
            auto ai = this->ai;
            for (auto i = 0; i < molefracs.size(); ++i) {
                for (auto j = 0; j < molefracs.size(); ++j) {
                    auto aij = (1 - k[i][j]) * sqrt(ai[i] * ai[j]);
    
                    a_ = a_ + molefracs[i] * molefracs[j] * aij;
    
    Ian Bell's avatar
    Ian Bell committed
                }
            }
    
            return forceeval(a_);
    
    Ian Bell's avatar
    Ian Bell committed
        }
    
    Ian Bell's avatar
    Ian Bell committed
    
    
    Ian Bell's avatar
    Ian Bell committed
        /// \brief Calculate the b parameter, based on linear mixing rules
        /// \param molefracs Array of mole fractions
    
    Ian Bell's avatar
    Ian Bell committed
        template<typename CompType>
        auto b(const CompType& molefracs) const {
    
    Ian Bell's avatar
    Ian Bell committed
            typename CompType::value_type b_ = 0.0;
    
    Ian Bell's avatar
    Ian Bell committed
            for (auto i = 0; i < molefracs.size(); ++i) {
    
                b_ = b_ + molefracs[i] * bi[i];
    
    Ian Bell's avatar
    Ian Bell committed
            }
    
            return forceeval(b_);
    
    Ian Bell's avatar
    Ian Bell committed
        }
    
    Ian Bell's avatar
    Ian Bell committed
    
    
    Ian Bell's avatar
    Ian Bell committed
        const NumType Ru = get_R_gas<double>(); ///< Universal gas constant, exact number
    
    Ian Bell's avatar
    Ian Bell committed
        /// \brief Get the universal gas constant 
        /// Here the real universal gas constant, with no composition dependence
    
    Ian Bell's avatar
    Ian Bell committed
        /// \note The array of mole fractions are ignored, but required to match other function calls
    
    Ian Bell's avatar
    Ian Bell committed
        auto R(const VecType& /*molefrac*/) const {
    
    Ian Bell's avatar
    Ian Bell committed
        /// \brief The evaluation of \f$ \alpha^{\rm r}=a/(RT) \f$
        /// \param T The temperature
        /// \param rho The molar density
        /// \param molefrac The mole fractions of each component
    
        template<typename TType, typename RhoType, typename MoleFracType>
    
            const RhoType& rho,
            const MoleFracType &molefrac) const
        {
    
            if (molefrac.size() != ai.size()) {
                throw teqp::InvalidArgument("mole fractions must be of size " + std::to_string(ai.size()) + " but are of size " + std::to_string(molefrac.size()));
            }
    
            auto Psiminus = -log(1.0 - b(molefrac) * rho);
            auto Psiplus = rho;
    
            auto val = Psiminus - a(T, molefrac) / (Ru * T) * Psiplus;
    
    Ian Bell's avatar
    Ian Bell committed
        }