diff --git a/Web/mixtures/phase_envelope.ipynb b/Web/mixtures/phase_envelope.ipynb index 32dc5b62..454db61c 100644 --- a/Web/mixtures/phase_envelope.ipynb +++ b/Web/mixtures/phase_envelope.ipynb @@ -1,6 +1,7 @@ { "metadata": { - "name": "" + "name": "", + "signature": "sha256:fa5ab579b67d03b137ac3fa2a3c15807169799511a42efb187eb3ac12b750898" }, "nbformat": 3, "nbformat_minor": 0, @@ -413,14 +414,14 @@ "collapsed": false, "input": [ "p = np.linspace(1000, 12000, 100)\n", - "mix = 'REFPROP-MIX:Water[0.7]&Ethanol[0.3]'\n", - "rhoL = CP.Props('D','P',p,'Q',0,mix)\n", - "rhoV = CP.Props('D','P',p,'Q',1,mix)" + "mix = 'HEOS::Water[0.7]&Ethanol[0.3]'\n", + "rhoL = CP.PropsSI('D','P',p,'Q',[0]*len(p),mix)\n", + "rhoV = CP.PropsSI('D','P',p,'Q',[1]*len(p),mix)" ], "language": "python", "metadata": {}, "outputs": [], - "prompt_number": 2 + "prompt_number": 6 }, { "cell_type": "code", @@ -434,22 +435,42 @@ { "metadata": {}, "output_type": "pyout", - "prompt_number": 3, + "prompt_number": 7, "text": [ - "[,\n", - " ]" + "[,\n", + " ]" ] }, { "metadata": {}, "output_type": "display_data", - "png": "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\nAABJRU5ErkJggg==\n", + "png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEACAYAAACpoOGTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAD5RJREFUeJzt3G+MVNd5x/HvlMVKIiumpBUYlgoXYxVSNSVtyEatyjiu\nJUJTcBWpFlJFYks1aktitakDxFK9fRXbqWrLQrGRi6JNmoi61LJIg/9Qy6O+aYid2OvGsDaLQwpE\nXkeJ/CKWqmAxfXEO3unwLDu75w4zDN+PNNr759w7z9Gw97f3nDuAJEmSJEmSJEmSJEmSJEmSNJA2\nAhPAcWDnDG0eyvvHgXUt2xcBB4BjwFFgpHtlSpIupQXAJLASWAi8BKxpa7MJOJSXPwp8p2XfGHB7\nXh4CrulWoZKkS+tjwFMt67vyq9UjwK0t6xPAElIYvN7V6iRJ8/ZLhccvB061rJ/O22ZrMwxcB/wE\n+CrwfeBR4H2F9UiSKlIaEM0O29WC44aADwNfyT/f5sK7D0lSjwwVHn8GWNGyvoJ0h3CxNsN5Wy23\nfT5vP0AQEKtWrWqeOHGisExJuuKcAK4vOUHpHcQLwGrSJPVVpLmGg21tDgLb8vII8BYwBbxBGnq6\nIe/7Q+CV9jc4ceIEzWZzYF/33HNPz2uwf/bvSuvbldA/YFXh9b34DuIdYAfwNOmJpn2kR1a35/17\nSU8wbSI97fQ2cFvL8Z8FvkEKlxNt+yRJPVQaEABP5lervW3rO2Y4dhz4SAU1SJIqVjrEpEL1er3X\nJXSV/bt8DXLfYPD7V4X2p4v6UTOPp0mSOlSr1aDwGu8dhCQpZEBIkkIGhCQpZEBIkkIGhCQpZEBI\nkkIGhCQpZEBIkkIGhCQpZEBIkkIGhCQpZEBIkkIGhCQpZEBIkkIGhCQpZEBIkkIGhCQpZEBIkkIG\nhCQpZEBIkkIGhCQpZEBIkkIGhCQpZEBIkkIGhCQpZEBIkkJVBMRGYAI4Duycoc1Def84sK5t3wLg\nReBbFdQiSapIaUAsAPaQQmItsBVY09ZmE3A9sBq4A3i4bf+dwFGgWViLJKlCpQGxHpgETgJngf3A\nlrY2m4GxvHwEWAQsyevDpAD5J6BWWIskqUKlAbEcONWyfjpv67TNA8BdwLnCOiRJFSsNiE6Hhdrv\nDmrAJ4E3SfMP3j1IUp8ZKjz+DLCiZX0F6Q7hYm2G87ZPkYafNgHvAd4PfA3Y1v4mo6Oj7y7X63Xq\n9Xph2ZI0WBqNBo1Go9Jzlv7lPgS8CtwE/Bj4Lmmi+lhLm03AjvxzBHgw/2y1Afhb4I+D92g2m85f\nS9Jc1Go1KLzGl95BvEO6+D9NeqJpHykctuf9e4FDpHCYBN4GbpvhXKaAJPWRy2Hs3zsISZqjKu4g\n/Ca1JClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaE\nJClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaEJClkQEiSQgaEJClk\nQEiSQgaEJClkQEiSQgaEJClURUBsBCaA48DOGdo8lPePA+vythXAc8ArwA+Az1VQiySpIqUBsQDY\nQwqJtcBWYE1bm03A9cBq4A7g4bz9LPDXwAeBEeCvgmMlST1SGhDrgUngJOmCvx/Y0tZmMzCWl48A\ni4AlwBvAS3n7z4FjwLLCeiRJFSkNiOXAqZb103nbbG2G29qsJA09HSmsR5JUkaHC45sdtqtd5Lir\ngQPAnaQ7iQuMjo6+u1yv16nX6x0XKElXgkajQaPRqPSc7RfuuRoBRklzEAC7gXPAfS1tHgEapOEn\nSBPaG4ApYCHw78CTwIMzvEez2ew0hyRJALVaDQqv8aVDTC+QJp9XAlcBtwIH29ocBLbl5RHgLVI4\n1IB9wFFmDgdJUo+UDjG9A+wAniY90bSPNNm8Pe/fCxwiPck0CbwN3Jb3/R7wZ8DLwIt5227gqcKa\nJEkVKB1iuhQcYpKkOeqHISZJ0oAyICRJIQNCkhQyICRJIQNCkhQyICRJIQNCkhQyICRJIQNCkhQy\nICRJIQNCkhQyICRJIQNCkhQyICRJIQNCkhQyICRJIQNCkhQyICRJIQNCkhQyICRJIQNCkhQyICRJ\nIQNCkhQyICRJIQNCkhQyICRJIQNCkhQyICRJoSoCYiMwARwHds7Q5qG8fxxYN8djJUk9UBoQC4A9\npAv9WmArsKatzSbgemA1cAfw8ByOlST1SGlArAcmgZPAWWA/sKWtzWZgLC8fARYBSzs8VpLUI6UB\nsRw41bJ+Om/rpM2yDo6VJPXIUOHxzQ7b1UreZHR09N3ler1OvV4vOZ0kDZxGo0Gj0aj0nEUXbmAE\nGCXNIwDsBs4B97W0eQRokIaQIE1KbwCu6+BYgGaz2WkOSZIAarUaFF7jS4eYXiBNPq8ErgJuBQ62\ntTkIbMvLI8BbwFSHx0qSeqR0iOkdYAfwNOmppH3AMWB73r8XOER6kmkSeBu4bZZjJUl9oHSI6VJw\niEmS5qgfhpgkSQPKgJAkhQwISVLIgJAkhQwISVLIgJAkhQwISVLIgJAkhQwISVLIgJAkhQwISVLI\ngJAkhQwISVLIgJAkhQwISVLIgJAkhQwISVLIgJAkhQwISVLIgJAkhQwISVLIgJAkhQwISVLIgJAk\nhQwISVLIgJAkhQwISVLIgJAkhUoDYjFwGHgNeAZYNEO7jcAEcBzY2bL9y8AxYBx4HLimsB5JUkVK\nA2IXKSBuAJ7N6+0WAHtIIbEW2AqsyfueAT4IfIgUMrsL65EkVaQ0IDYDY3l5DLglaLMemAROAmeB\n/cCWvO8wcC4vHwGGC+uRJFWkNCCWAFN5eSqvt1sOnGpZP523tbsdOFRYjySpIkMdtDkMLA223922\n3syvdtG26Fy/AL4Z7RwdHX13uV6vU6/XOzilJF05Go0GjUaj0nPWCo+fAOrAG8C1wHPAb7S1GQFG\nSXMQkOYZzgH35fXPAH8O3AT8b/AezWazk4yRJJ1Xq9Wg8BpfOsR0EPh0Xv408ETQ5gVgNbASuAq4\nNR8HKTTuIs1JROEgSeqR0juIxcBjwK+RJqH/FHgLWAY8CvxRbvcJ4EHSE037gC/l7cdJofGzvP5f\nwF+2vYd3EJI0R1XcQZQGxKVgQEjSHPXDEJMkaUAZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZ\nEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKk\nkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkUElALAYOA68BzwCLZmi3EZgAjgM7\ng/2fB87l80mS+kRJQOwiBcQNwLN5vd0CYA8pJNYCW4E1LftXADcDPyqoQ5LUBSUBsRkYy8tjwC1B\nm/XAJHASOAvsB7a07P9H4AsFNUiSuqQkIJYAU3l5Kq+3Ww6calk/nbdBCorTwMsFNUiSumRolv2H\ngaXB9rvb1pv51S7aBvBe4Iuk4aXzarPUIkm6hGYLiJsvsm+KFB5vANcCbwZtzpDmGc5bQbprWAWs\nBMbz9mHge6QhqQvOMzo6+u5yvV6nXq/PUrYkXVkajQaNRqPSc5b81X4/8FPgPtIE9SIunKgeAl4F\nbgJ+DHyXNFF9rK3dD4HfAX4WvE+z2ZzpRkSSFKnValA4MlMyB3Ev6Q7jNeDjeR1gGfDtvPwOsAN4\nGjgK/AsXhgPMPBQlSeqRy2Hc3zsISZqjXt9BSJIGmAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKk\nkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEh\nSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQoZEJKkkAEhSQqVBMRi4DDwGvAMsGiGdhuBCeA4\nsLNt32eBY8APgPsKapEkVawkIHaRAuIG4Nm83m4BsIcUEmuBrcCavO9GYDPwW8BvAv9QUMtlq9Fo\n9LqErrJ/l69B7hsMfv+qUBIQm4GxvDwG3BK0WQ9MAieBs8B+YEve9xfAl/J2gJ8U1HLZGvR/pPbv\n8jXIfYPB718VSgJiCTCVl6fyervlwKmW9dN5G8Bq4A+A7wAN4HcLapEkVWxolv2HgaXB9rvb1pv5\n1S7a1vrevwyMAB8BHgN+fZZ6JEmXgQmmw+PavN5uBHiqZX030xPVTwIbWvZNAh8IzjHJdAD58uXL\nl6/OXpP00P1MX+x3AfcGbYaAE8BK4CrgJaYnqbcDf5+XbwD+p1uFSpIurcXAf3DhY67LgG+3tPsE\n8CopzXa3bF8IfB34b+B7QL275UqSJEkaGIP+pbsq+gfweeBcPl8/Ke3fl0mf3TjwOHBN1yrt3Gyf\nBcBDef84sG6Ox/bafPu3AngOeIX0u/a57pY5byWfH6TvcL0IfKtbBRYo6dsi4ADp9+0oaZ64790P\nfCEv7ySez1hAGqZaSRqeap3PuJF0gVqY13+1W4XOU2n/IP1iPgX8kP4LiNL+3cz0I9f3znD8pTTb\nZwGwCTiUlz9Kely702N7raR/S4HfzstXk4aPB6l/5/0N8A3gYNeqnJ/Svo0Bt+flIfrjj7FZTTD9\nPYqlxE9EfYz//0TULqa/vf0Y8PGuVVeutH8A/0r61nk/BkQV/TvvT4B/rrS6ueuk1keAW1vWzz/V\n12k/e2m+/Yu+6/QEcFOl1ZUr7d8waX71RvrvDqKkb9cAr8/lzfrlP+sb9C/dlfZvS15/uVsFFirt\nX6vbmf7rp1c6qXWmNss6OLbX5tu/4bY2K0nDF0cqrq9UyecH8ABwF2k4t9+UfHbXkf7Hiq8C3wce\nBd53sTeb7YtyVRr0L911q3/vBb5IGoY5rzbn6sp18/NrPdcvgG/OrbTKdVIr9OZzqMJ8+9d63NWk\nsew7gZ9XUVSF5tu/GvBJ4E3S/EO9wpqqUvLZDQEfBnYAzwMPku4+/m6mk1zKgLj5IvumSBefN0hf\nunszaHOGNA5/3gpSMpJ/Pp6Xnycl/weAnxbUO1fd6t8q0l9q43n7MOmx4PUznKdbuvn5AXyGNHba\nD8MVs9UatRnObRZ2cGyvzbd/Z/LyQuDfSEOBT3SpxhIl/fsU6f+Z2wS8B3g/8DVgW7eKnaOSvtVy\n2+fz9gP03/BnaNC/dFfav1b9OAdR2r+NpKdifqWrVXauk8+idSJwhOmJwE4/x14q6V+NdMF8oOtV\nzl9J/1ptoP/mIEr79p+kayTAKP33xGdo0L90V9q/Vq/TfwFR2r/jwI9It/UvAl/pcr2diGrdnl/n\n7cn7x0m37hc7tt/Mt3+/T7pDf4npz2vjJah3rko+v/M20H9PMUFZ3z5EuoPop0fKJUmSJEmSJEmS\nJEmSJEmSJEmSJEnqjv8DwHN/hNOHRlAAAAAASUVORK5CYII=\n", "text": [ - "" + "" ] } ], - "prompt_number": 3 + "prompt_number": 7 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$$\\ln f_i = \\ln (x_i p \\phi_i)$$\n", + "\n", + "$$\\frac{\\partial \\ln f_i}{\\partial x_j} = \\frac{\\partial \\ln (x_i p \\phi_i)}{\\partial x_j} = \\frac{p}{x_i p \\phi_i}\n", + "\\left(\\frac{\\partial x_i}{\\partial x_j}\\phi_i + x_i \\frac{\\partial x_i}{\\partial x_j}\\right) = \\frac{1}{x_i \\phi_i}\n", + "\\left(\\frac{\\partial x_i}{\\partial x_j}\\phi_i + x_i \\frac{\\partial x_i}{\\partial x_j}\\right) = \n", + "\\frac{\\partial x_i}{\\partial x_j}\\frac{1}{x_i} + \\frac{1}{\\phi_i} \\frac{\\partial \\phi_i}{\\partial x_j}$$\n", + "\n", + "$$\\frac{\\partial \\ln f_i}{\\partial x_j} = \\frac{\\partial \\ln (x_i p \\phi_i)}{\\partial x_j} = \n", + "\\frac{1}{x_i}\\frac{\\partial x_i}{\\partial x_j} + \\frac{\\partial \\ln\\phi_i}{\\partial x_j}$$\n", + "\n", + "Thus if $i=j$, $\\displaystyle \\frac{\\partial x_i}{\\partial x_j} = 1$, otherwise first term goes away\n", + "\n", + "If $i = N-1$, $\\displaystyle\\frac{\\partial x_{N-1}}{\\partial x_j} = -1$, since \n", + "$$x_{N-1} = 1-\\sum_{k=1}^{N-1}x_k$$" + ] }, { "cell_type": "code", @@ -457,15 +478,7 @@ "input": [], "language": "python", "metadata": {}, - "outputs": [], - "prompt_number": 3 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "K_i=\\frac{y_i}{x_i}" - ] + "outputs": [] } ], "metadata": {} diff --git a/dev/codelite/coolprop.project b/dev/codelite/coolprop.project index 0b9f5acb..b2ecf527 100644 --- a/dev/codelite/coolprop.project +++ b/dev/codelite/coolprop.project @@ -53,6 +53,8 @@ + + diff --git a/dev/generate_headers.py b/dev/generate_headers.py index 172ae1b9..e050368d 100644 --- a/dev/generate_headers.py +++ b/dev/generate_headers.py @@ -38,7 +38,7 @@ values = [ ('all_fluids.json','all_fluids_JSON.h','all_fluids_JSON'), ('all_incompressibles.json','all_incompressibles_JSON.h','all_incompressibles_JSON'), ('mixtures/mixture_departure_functions.json', 'mixture_departure_functions_JSON.h', 'mixture_departure_functions_JSON'), - ('mixtures/mixture_reducing_parameters.json', 'mixture_reducing_parameters_JSON.h', 'mixture_reducing_parameters_JSON') + ('mixtures/mixture_binary_pairs.json', 'mixture_binary_pairs_JSON.h', 'mixture_binary_pairs_JSON') ] def TO_CPP(root_dir, hashes): @@ -55,6 +55,12 @@ def TO_CPP(root_dir, hashes): for infile,outfile,variable in values: + import json + + # Confirm that the JSON file can be loaded and doesn't have any formatting problems + with open(os.path.join(root_dir,'dev',infile), 'r') as fp: + jj = json.load(fp) + json = open(os.path.join(root_dir,'dev',infile),'r').read().encode('ascii') # convert each character to hex and add a terminating NULL character to end the diff --git a/dev/mixtures/mixture_reducing_parameters.json b/dev/mixtures/mixture_binary_pairs.json similarity index 100% rename from dev/mixtures/mixture_reducing_parameters.json rename to dev/mixtures/mixture_binary_pairs.json diff --git a/dev/mixtures/mixture_departure_functions.json b/dev/mixtures/mixture_departure_functions.json index 2f636b4d..ce8e094f 100644 --- a/dev/mixtures/mixture_departure_functions.json +++ b/dev/mixtures/mixture_departure_functions.json @@ -3,7 +3,7 @@ "Name" : "R32-R125", "BibTeX" : "Lemmon-JPCRD-2004", "aliases" : [], -"type" : "Power", +"type" : "Exponential", "n" : [-0.0072955, 0.078035, 0.61007, 0.64246, 0.014965, -0.34049, 0.085658, -0.064429], "t" : [4.5, 0.57, 1.9, 1.2, 0.5, 2.6, 11.4, 4.5], "d" : [2, 5, 1, 3, 9, 2, 3, 6], @@ -13,7 +13,7 @@ "Name" : "R32-R134a", "BibTeX" : "Lemmon-JPCRD-2004", "aliases" : [], -"type" : "Power", +"type" : "Exponential", "n" : [0.22909, 0.094074, 0.00039876, 0.021113], "t" : [1.9, 0.25, 0.07, 2.0], "d" : [1, 3, 8, 1], @@ -22,8 +22,8 @@ { "Name" : "GeneralizedHFC", "BibTeX" : "Lemmon-JPCRD-2004", -"aliases" : [] -"type" : "Power", +"aliases" : [], +"type" : "Exponential", "n" : [-0.013073, 0.018259,0.0000081299,0.0078496], "t" : [7.4, 0.35, 10.0, 5.3], "d" : [1, 3, 11, 2], @@ -33,16 +33,17 @@ "Name" : "GeneralizedAirComponents", "BibTeX" : "Lemmon-JPCRD-2000", "aliases" : [], -"type" : "Power", +"type" : "Exponential", "n" : [-0.00195245, 0.00871334], "t" : [-1.4, 1.5], -"d" : [2, 2] +"d" : [2, 2], +"l" : [0, 0] }, { "Name" : "Ethanol-Water", "aliases" : [], "BibTeX" : "From REFPROP 9.1 with permission", -"type" : "Power", +"type" : "Exponential", "n" : [1.09765e+00, 1.94679e+00, -2.16809e+00, -1.37077e-01, 4.86690e-02, 1.04024e+00], "t" : [0.26, 7.3, 5.3, 2.3, 0.7, 3.3], "d" : [2, 3, 5, 5, 7, 6], @@ -77,7 +78,7 @@ "gamma": [0.0, 0.0, 0.0, 0.5, 0.5, 0.5] }, { -"Name" : "Methane-Ethane" +"Name" : "Methane-Ethane", "aliases" : [], "type" : "GERG-2008", "BibTeX" : "Kunz-JCED-2012", @@ -119,7 +120,7 @@ "gamma": [0.0, 0.0, 0.5, 0.5, 0.5, 0.5] }, { -"Name": "Nitrogen-Ethane" +"Name": "Nitrogen-Ethane", "aliases" : [], "type" : "GERG-2008", "BibTeX" : "Kunz-JCED-2012", diff --git a/include/CoolPropTools.h b/include/CoolPropTools.h index d08b049d..468dfa8e 100644 --- a/include/CoolPropTools.h +++ b/include/CoolPropTools.h @@ -236,22 +236,48 @@ std::map numbers; std::map strings; std::map > double_vectors; + std::map > string_vectors; public: Dictionary(){}; void add_string(std::string s1, std::string s2){ strings.insert(std::pair(s1, s2));} void add_number(std::string s1, double d){ numbers.insert(std::pair(s1, d));} void add_double_vector(std::string s1, std::vector d){ double_vectors.insert(std::pair >(s1, d));} + void add_string_vector(std::string s1, std::vector d){ string_vectors.insert(std::pair >(s1, d));} std::string get_string(std::string s) { - if (strings.find(s) != strings.end()){ return strings[s]; } else{ throw std::exception(); } + if (strings.find(s) != strings.end()){ + return strings[s]; + } + else{ + throw CoolProp::ValueError(format("%s could not be matched in get_string",s.c_str())); + } }; double get_number(std::string s) { - if (numbers.find(s) != numbers.end()){ return numbers[s]; } else{ throw std::exception(); } + if (numbers.find(s) != numbers.end()){ + return numbers[s]; + } + else{ + throw CoolProp::ValueError(format("%s could not be matched in get_number",s.c_str())); + } }; std::vector get_double_vector(std::string s) { - if (double_vectors.find(s) != double_vectors.end()){ return double_vectors[s]; } else{ throw std::exception(); } + if (double_vectors.find(s) != double_vectors.end()){ + return double_vectors[s]; + } + else{ + throw CoolProp::ValueError(format("%s could not be matched in get_double_vector",s.c_str())); + } + }; + std::vector get_string_vector(std::string s) + { + if (string_vectors.find(s) != string_vectors.end()){ + return string_vectors[s]; + } + else{ + throw CoolProp::ValueError(format("%s could not be matched in get_string_vector",s.c_str())); + } }; }; /// Utility function to clear a std::map of pointers diff --git a/include/rapidjson/rapidjson_include.h b/include/rapidjson/rapidjson_include.h index 65cc9466..4cd1ff71 100644 --- a/include/rapidjson/rapidjson_include.h +++ b/include/rapidjson/rapidjson_include.h @@ -84,7 +84,7 @@ namespace cpjson return el.GetBool(); } }; - /// A convenience function to get a string from a JSON value, including error checking + /// A convenience function to get a string from a JSON value, including error checking inline std::string get_string(rapidjson::Value &v, std::string m) { if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } @@ -95,7 +95,10 @@ namespace cpjson return el.GetString(); } }; - + + + + /// A convenience function to get a double array compactly inline std::vector get_double_array(rapidjson::Value &v) { @@ -108,6 +111,15 @@ namespace cpjson } return out; }; + + /// A convenience function to get a double array compactly + inline std::vector get_double_array(rapidjson::Value &v, std::string m) + { + if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } + else{ + return get_double_array(v[m.c_str()]); + } + }; /// A convenience function to get a long double array compactly inline std::vector get_long_double_array(rapidjson::Value &v) @@ -191,6 +203,15 @@ namespace cpjson } return out; }; + + /// A convenience function to get a double array compactly + inline std::vector get_string_array(rapidjson::Value &v, std::string m) + { + if (!v.HasMember(m.c_str())){ throw CoolProp::ValueError(format("Does not have member [%s]",m.c_str())); } + else{ + return get_string_array(v[m.c_str()]); + } + }; /// A convenience function to get a std::string from a JSON value inline std::string to_string(rapidjson::Value &v) diff --git a/src/Backends/Helmholtz/ExcessHEFunction.cpp b/src/Backends/Helmholtz/ExcessHEFunction.cpp index 29d4eb35..c21a4f74 100644 --- a/src/Backends/Helmholtz/ExcessHEFunction.cpp +++ b/src/Backends/Helmholtz/ExcessHEFunction.cpp @@ -1,164 +1,10 @@ #include +#include "ReducingFunctions.h" #include "ExcessHEFunction.h" -#include "mixture_excess_term_JSON.h" namespace CoolProp{ -static MixtureExcessHELibrary mixtureexcesslibrary; - -MixtureExcessHELibrary::MixtureExcessHELibrary() -{ - rapidjson::Document dd; - - dd.Parse<0>(mixture_excess_term_JSON.c_str()); - if (dd.HasParseError()){throw ValueError();} - - // Iterate over the papers in the listing - for (rapidjson::Value::ValueIterator itr = dd.Begin(); itr != dd.End(); ++itr) - { - // Iterate over the coeffs in the entry - rapidjson::Value &Coeffs = (*itr)["Coeffs"]; - std::string model = cpjson::get_string(*itr, "Model"); - std::string BibTeX = cpjson::get_string(*itr, "BibTeX"); - for (rapidjson::Value::ValueIterator itr_coeff = Coeffs.Begin(); itr_coeff != Coeffs.End(); ++itr_coeff) - { - std::vector CAS1V, Name1V, CAS2V, Name2V; - - if ((itr_coeff->HasMember("Name1") && (*itr_coeff)["Name1"].IsString()) - && (itr_coeff->HasMember("Name2") && (*itr_coeff)["Name2"].IsString()) - && (itr_coeff->HasMember("CAS1") && (*itr_coeff)["CAS1"].IsString()) - && (itr_coeff->HasMember("CAS2") && (*itr_coeff)["CAS2"].IsString())) - { - // Turn the strings into one-element vectors - CAS1V = std::vector(1,cpjson::get_string(*itr_coeff,"CAS1")); - Name1V = std::vector(1,cpjson::get_string(*itr_coeff,"Name1")); - CAS2V = std::vector(1,cpjson::get_string(*itr_coeff,"CAS2")); - Name2V = std::vector(1,cpjson::get_string(*itr_coeff,"Name2")); - } - else - { - CAS1V = cpjson::get_string_array((*itr_coeff)["CAS1"]); - Name1V = cpjson::get_string_array((*itr_coeff)["Name1"]); - CAS2V = cpjson::get_string_array((*itr_coeff)["CAS2"]); - Name2V = cpjson::get_string_array((*itr_coeff)["Name2"]); - } - - for (unsigned int i = 0; i < CAS1V.size(); ++i) - { - // Get the vector of CAS numbers - std::vector CAS; - CAS.resize(2); - CAS[0] = CAS1V[i]; - CAS[1] = CAS2V[i]; - - // Sort the CAS number vector - std::sort(CAS.begin(), CAS.end()); - - // Get the empty dictionary to be filled by the appropriate reducing parameter filling function - Dictionary d; - - // Populate the dictionary with common terms - d.add_string("model", model); - d.add_string("name1", Name1V[i]); - d.add_string("name2", Name2V[i]); - d.add_string("bibtex", BibTeX); - - if (!model.compare("Kunz-JCED-2012")) - { - parse_Kunz_JCED_2012(d, *itr_coeff, i); - } - else if (!model.compare("Lemmon-JPCRD-2004")) - { - parse_Lemmon_JPCRD_2004(d, *itr_coeff); - } - else if (!model.compare("Lemmon-JPCRD-2000")) - { - parse_Lemmon_JPCRD_2000(d, *itr_coeff); - } - else - { - throw ValueError(); - } - - // If not in map, add new entry to map with dictionary - if (excess_map.find(CAS) == excess_map.end()) - { - // One-element vector of the dictionary - std::vector vd(1, d); - // Pair for adding to map - std::pair, std::vector > p(CAS, vd); - // Add - excess_map.insert(p); - } - else // If already in map, add entry to the end of the vector - { - // Append dictionary to listing - excess_map[CAS].push_back(d); - } - } - } - } -} - -void ExcessTerm::construct(const std::vector &components) -{ - std::string _model; - N = components.size(); - - F.resize(N, std::vector(N, 0)); - DepartureFunctionMatrix.resize(N); - - for (unsigned int i = 0; i < N; ++i) - { - DepartureFunctionMatrix[i].resize(N); - for (unsigned int j = 0; j < N; ++j) - { - if (i == j){ continue; } - - std::string CAS1 = components[i]->CAS; - std::vector CAS(2,""); - CAS[0] = components[i]->CAS; - CAS[1] = components[j]->CAS; - std::sort(CAS.begin(), CAS.end()); - - std::vector & vd = mixtureexcesslibrary.excess_map[CAS]; - if (vd.size() != 1) { throw NotImplementedError(); } - // Get a reference to the dictionary itself to save a few dereferences - Dictionary &dic = vd[0]; - - std::string model = dic.get_string("model"); - - if (!model.compare("Kunz-JCED-2012")) - { - F[i][j] = dic.get_number("F"); - - std::vector n = dic.get_double_vector("n"); - std::vector d = dic.get_double_vector("d"); - std::vector t = dic.get_double_vector("t"); - // Terms for the gaussian - std::vector eta = dic.get_double_vector("eta"); - std::vector epsilon = dic.get_double_vector("epsilon"); - std::vector beta = dic.get_double_vector("beta"); - std::vector gamma = dic.get_double_vector("gamma"); - int Npower = static_cast(dic.get_number("Npower")); - DepartureFunctionMatrix[i][j].reset(new GERG2008DepartureFunction(n,d,t,eta,epsilon,beta,gamma,Npower)); - } - else if (!model.compare("Lemmon-JPCRD-2004") || !model.compare("Lemmon-JPCRD-2000")) - { - throw NotImplementedError(); - } - else - { - throw ValueError(); - } - } - } -} - -ExcessTerm::~ExcessTerm() -{ -} double ExcessTerm::alphar(double tau, double delta, const std::vector &x) { double summer = 0; @@ -283,7 +129,6 @@ GERG2008DepartureFunction::GERG2008DepartureFunction(const std::vector & const std::vector &eta,const std::vector &epsilon,const std::vector &beta, const std::vector &gamma, unsigned int Npower) { - /// Break up into power and gaussian terms { std::vector _n(n.begin(), n.begin()+Npower); diff --git a/src/Backends/Helmholtz/ExcessHEFunction.h b/src/Backends/Helmholtz/ExcessHEFunction.h index 41c9a563..d448d370 100644 --- a/src/Backends/Helmholtz/ExcessHEFunction.h +++ b/src/Backends/Helmholtz/ExcessHEFunction.h @@ -10,60 +10,11 @@ namespace CoolProp{ typedef std::vector > STLMatrix; - -/// A container for the mixing parameters for CoolProp mixtures -/** - -*/ -class MixtureExcessHELibrary -{ -public: - /// Map from sorted pair of CAS numbers to excess term dictionary. - std::map, std::vector > excess_map; - MixtureExcessHELibrary(); - - /// Parse a term from GERG 2008 - void parse_Kunz_JCED_2012(Dictionary &d, rapidjson::Value &val, int i) - { - assert(val.HasMember("F")); - if (val["F"].IsDouble()) - { - d.add_number("F",val["F"].GetDouble()); - } - else - { - std::vector F = cpjson::get_double_array(val["F"]); - assert(static_cast(i) < F.size()); - d.add_number("F", F[i]); - } - d.add_number("Npower", cpjson::get_double(val,"Npower")); - - // Terms for the power - d.add_double_vector("n", cpjson::get_double_array(val["n"])); - d.add_double_vector("d", cpjson::get_double_array(val["d"])); - d.add_double_vector("t", cpjson::get_double_array(val["t"])); - // Terms for the gaussian - d.add_double_vector("eta", cpjson::get_double_array(val["eta"])); - d.add_double_vector("epsilon", cpjson::get_double_array(val["epsilon"])); - d.add_double_vector("beta", cpjson::get_double_array(val["beta"])); - d.add_double_vector("gamma", cpjson::get_double_array(val["gamma"])); - - }; - - /// Parse a term from HFC mixtures - void parse_Lemmon_JPCRD_2004(Dictionary &d, rapidjson::Value &val) - { - }; - - /// Parse a term from Air - void parse_Lemmon_JPCRD_2000(Dictionary &d, rapidjson::Value &val) - { - }; -}; - -/*! -The abstract base class for departure functions for the excess part of the Helmholtz energy -*/ +/** \brief The abstract base class for departure functions used in the excess part of the Helmholtz energy + * + * The only code included in the ABC is the structure for the derivatives of the Helmholtz energy with + * the reduced density and reciprocal reduced temperature + */ class DepartureFunction { public: @@ -80,31 +31,14 @@ public: virtual double d2alphar_dTau2(double tau, double delta) = 0; }; -typedef shared_ptr DepartureFunctionPointer; - -class ExcessTerm -{ -public: - unsigned int N; - std::vector > DepartureFunctionMatrix; - std::vector > F; - - ExcessTerm(){}; - void construct(const std::vector &components); - ~ExcessTerm(); - - double alphar(double tau, double delta, const std::vector &x); - double dalphar_dDelta(double tau, double delta, const std::vector &x); - double d2alphar_dDelta2(double tau, double delta, const std::vector &x); - double d2alphar_dDelta_dTau(double tau, double delta, const std::vector &x); - double dalphar_dTau(double tau, double delta, const std::vector &x); - double d2alphar_dTau2(double tau, double delta, const std::vector &x); - double dalphar_dxi(double tau, double delta, const std::vector &x, unsigned int i); - double d2alphardxidxj(double tau, double delta, const std::vector &x, unsigned int i, unsigned int j); - double d2alphar_dxi_dTau(double tau, double delta, const std::vector &x, unsigned int i); - double d2alphar_dxi_dDelta(double tau, double delta, const std::vector &x, unsigned int i); -}; - +/** \brief The departure function used by the GERG-2008 formulation + * + * This departure function has a form like + * \f[ + * \alphar^r_{ij} = \sum_k n_{ij,k}\delta^{d_{ij,k}}\tau^{t_{ij,k}} + \sum_k n_{ij,k}\delta^{d_{ij,k}}\tau^{t_{ij,k}}\exp[-\eta_{ij,k}(\delta-\varepsilon_{ij,k})^2-\beta_{ij,k}(\delta-\gamma_{ij,k})] + * \f] + * It is symmetric so \f$\alphar^r_{ij} = \alphar^r_{ji}\f$ + */ class GERG2008DepartureFunction : public DepartureFunction { protected: @@ -125,5 +59,72 @@ public: double d2alphar_dTau2(double tau, double delta){return phi.dTau2(tau, delta);}; }; +/** \brief A polynomial/exponential departure function + * + * This departure function has a form like + * \f[ + * \alpha^r_{ij} = \sum_k n_{ij,k}\delta^{d_{ij,k}}\tau^{t_{ij,k}}\exp(-\delta^{l_{ij,k}}) + * \f] + * It is symmetric so \f$\alphar^r_{ij} = \alphar^r_{ji}\f$ + */ +class ExponentialDepartureFunction : public DepartureFunction +{ +protected: + ResidualHelmholtzGeneralizedExponential phi; +public: + ExponentialDepartureFunction(){}; + ExponentialDepartureFunction(const std::vector &n, const std::vector &d, + const std::vector &t, const std::vector &l) + { + std::vector _n(n.begin(), n.begin()+n.size()); + std::vector _d(d.begin(), d.begin()+d.size()); + std::vector _t(t.begin(), t.begin()+t.size()); + std::vector _l(l.begin(), l.begin()+l.size()); + phi.add_Power(_n, _d, _t, _l); + }; + ~ExponentialDepartureFunction(){}; + + double alphar(double tau, double delta){return phi.base(tau, delta);}; + double dalphar_dDelta(double tau, double delta){return phi.dDelta(tau, delta);}; + double d2alphar_dDelta_dTau(double tau, double delta){return phi.dDelta_dTau(tau, delta);}; + double dalphar_dTau(double tau, double delta){return phi.dTau(tau, delta);}; + double d2alphar_dDelta2(double tau, double delta){return phi.dDelta2(tau, delta);}; + double d2alphar_dTau2(double tau, double delta){return phi.dTau2(tau, delta);}; +}; + +typedef shared_ptr DepartureFunctionPointer; + +class ExcessTerm +{ +public: + unsigned int N; + std::vector > DepartureFunctionMatrix; + std::vector > F; + + ExcessTerm(){}; + ~ExcessTerm(){}; + + /// Resize the parts of this term + void resize(std::size_t N){ + this->N = N; + F.resize(N, std::vector(N, 0)); + DepartureFunctionMatrix.resize(N); + for (std::size_t i = 0; i < N; ++i){ + DepartureFunctionMatrix[i].resize(N); + } + }; + + double alphar(double tau, double delta, const std::vector &x); + double dalphar_dDelta(double tau, double delta, const std::vector &x); + double d2alphar_dDelta2(double tau, double delta, const std::vector &x); + double d2alphar_dDelta_dTau(double tau, double delta, const std::vector &x); + double dalphar_dTau(double tau, double delta, const std::vector &x); + double d2alphar_dTau2(double tau, double delta, const std::vector &x); + double dalphar_dxi(double tau, double delta, const std::vector &x, unsigned int i); + double d2alphardxidxj(double tau, double delta, const std::vector &x, unsigned int i, unsigned int j); + double d2alphar_dxi_dTau(double tau, double delta, const std::vector &x, unsigned int i); + double d2alphar_dxi_dDelta(double tau, double delta, const std::vector &x, unsigned int i); +}; + } /* namespace CoolProp */ #endif diff --git a/src/Backends/Helmholtz/FlashRoutines.cpp b/src/Backends/Helmholtz/FlashRoutines.cpp index 6789cf76..fda6a08d 100644 --- a/src/Backends/Helmholtz/FlashRoutines.cpp +++ b/src/Backends/Helmholtz/FlashRoutines.cpp @@ -66,7 +66,7 @@ void FlashRoutines::QT_flash(HelmholtzEOSMixtureBackend &HEOS) HEOS._p = HEOS.SatL->p(); } else if (splines.enabled && HEOS._T > splines.T_min){ - double rhoL, rhoV; + double rhoL = _HUGE, rhoV = _HUGE; // Use critical region spline if it has it and temperature is in its range splines.get_densities(T, splines.rhomolar_min, HEOS.rhomolar_critical(), splines.rhomolar_max, rhoL, rhoV); HEOS.SatL->update(DmolarT_INPUTS, rhoL, HEOS._T); @@ -114,7 +114,7 @@ void FlashRoutines::QT_flash(HelmholtzEOSMixtureBackend &HEOS) } else{ // Pseudo-pure fluid - long double rhoLanc, rhoVanc, rhoLsat, rhoVsat; + long double rhoLanc = _HUGE, rhoVanc = _HUGE, rhoLsat = _HUGE, rhoVsat = _HUGE; long double psatLanc = HEOS.components[0]->ancillaries.pL.evaluate(HEOS._T); // These ancillaries are used explicitly long double psatVanc = HEOS.components[0]->ancillaries.pV.evaluate(HEOS._T); // These ancillaries are used explicitly try{ @@ -454,7 +454,7 @@ void FlashRoutines::PHSU_D_flash(HelmholtzEOSMixtureBackend &HEOS, int other) void FlashRoutines::HSU_P_flash_singlephase_Newton(HelmholtzEOSMixtureBackend &HEOS, int other, long double T0, long double rhomolar0) { double A[2][2], B[2][2]; - long double y; + long double y = _HUGE; HelmholtzEOSMixtureBackend _HEOS(HEOS.get_components()); _HEOS.update(DmolarT_INPUTS, rhomolar0, T0); long double Tc = HEOS.calc_T_critical(); @@ -465,6 +465,7 @@ void FlashRoutines::HSU_P_flash_singlephase_Newton(HelmholtzEOSMixtureBackend &H { case iHmolar: y = HEOS.hmolar(); break; case iSmolar: y = HEOS.smolar(); break; + default: throw ValueError("other is invalid in HSU_P_flash_singlephase_Newton"); } long double worst_error = 999; @@ -602,7 +603,7 @@ void FlashRoutines::HSU_P_flash_singlephase_Brent(HelmholtzEOSMixtureBackend &HE std::string errstr; try{ - double T = Brent(resid, Tmin, Tmax, DBL_EPSILON, 1e-12, 100, errstr); + Brent(resid, Tmin, Tmax, DBL_EPSILON, 1e-12, 100, errstr); // Un-specify the phase of the fluid HEOS.unspecify_phase(); } @@ -621,8 +622,6 @@ void FlashRoutines::HSU_P_flash_singlephase_Brent(HelmholtzEOSMixtureBackend &HE } throw; } - - int rr = 4; } // P given and one of H, S, or U diff --git a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp index 48d54bcb..506cde74 100644 --- a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp +++ b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.cpp @@ -28,6 +28,8 @@ #include "TransportRoutines.h" #include "MixtureDerivatives.h" #include "PhaseEnvelopeRoutines.h" +#include "ReducingFunctions.h" +#include "MixtureParameters.h" static int deriv_counter = 0; @@ -73,9 +75,8 @@ void HelmholtzEOSMixtureBackend::set_components(std::vector comp // Set the excess Helmholtz energy if a mixture if (!is_pure_or_pseudopure) { - // Set the reducing model - set_reducing_function(); - set_excess_term(); + // Set the mixture parameters - binary pair reducing functions, departure functions, F_ij, etc. + set_mixture_parameters(); } imposed_phase_index = iphase_not_imposed; @@ -117,13 +118,10 @@ void HelmholtzEOSMixtureBackend::calc_phase_envelope(const std::string &type) { PhaseEnvelopeRoutines::build(*this); }; -void HelmholtzEOSMixtureBackend::set_reducing_function() +void HelmholtzEOSMixtureBackend::set_mixture_parameters() { - Reducing.set(ReducingFunction::factory(components)); -} -void HelmholtzEOSMixtureBackend::set_excess_term() -{ - Excess.construct(components); + // Build the matrix of binary-pair reducing functions + MixtureParameters::set_mixture_parameters(*this); } void HelmholtzEOSMixtureBackend::update_states(void) { @@ -1335,7 +1333,6 @@ void get_dT_drho_second_derivatives(HelmholtzEOSMixtureBackend *HEOS, int index, rho = HEOS->rhomolar(), rhor = HEOS->get_reducing_state().rhomolar, Tr = HEOS->get_reducing_state().T, - dT_dtau = -pow(T, 2)/Tr, R = HEOS->gas_constant(), delta = rho/rhor, tau = Tr/T; @@ -1606,6 +1603,9 @@ long double HelmholtzEOSMixtureBackend::solver_for_rho_given_T_oneof_HSU(long do throw ValueError(); } } + else{ + throw ValueError(format("phase to solver_for_rho_given_T_oneof_HSU is invalid")); + } } long double HelmholtzEOSMixtureBackend::solver_rho_Tp(long double T, long double p, long double rhomolar_guess) { @@ -2038,8 +2038,8 @@ SimpleState HelmholtzEOSMixtureBackend::calc_reducing_state_nocache(const std::v } else{ - reducing.T = Reducing.p->Tr(mole_fractions); - reducing.rhomolar = Reducing.p->rhormolar(mole_fractions); + reducing.T = Reducing->Tr(mole_fractions); + reducing.rhomolar = Reducing->rhormolar(mole_fractions); } return reducing; } diff --git a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h index 57c3a609..64b0a5f4 100644 --- a/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h +++ b/src/Backends/Helmholtz/HelmholtzEOSMixtureBackend.h @@ -30,14 +30,15 @@ protected: SimpleState _crit; phases imposed_phase_index; - int N; ///< Number of components + std::size_t N; ///< Number of components public: - HelmholtzEOSMixtureBackend(){imposed_phase_index = iphase_not_imposed; _phase = iphase_unknown;}; + HelmholtzEOSMixtureBackend(){ + imposed_phase_index = iphase_not_imposed; _phase = iphase_unknown;}; HelmholtzEOSMixtureBackend(std::vector components, bool generate_SatL_and_SatV = true); HelmholtzEOSMixtureBackend(std::vector &component_names, bool generate_SatL_and_SatV = true); virtual ~HelmholtzEOSMixtureBackend(){}; - ReducingFunctionContainer Reducing; + shared_ptr Reducing; ExcessTerm Excess; PhaseEnvelopeData PhaseEnvelope; @@ -45,6 +46,7 @@ public: friend class TransportRoutines; // Allows the static methods in the TransportRoutines class to have access to all the protected members and methods of this class friend class MixtureDerivatives; // Allows the static methods in the MixtureDerivatives class to have access to all the protected members and methods of this class friend class PhaseEnvelopeRoutines; // Allows the static methods in the PhaseEnvelopeRoutines class to have access to all the protected members and methods of this class + friend class MixtureParameters; // Allows the static methods in the MixtureParameters class to have access to all the protected members and methods of this class // Helmholtz EOS backend uses mole fractions bool using_mole_fractions(){return true;} @@ -70,40 +72,40 @@ public: void update_TP_guessrho(long double T, long double p, long double rho_guess); void update_DmolarT_direct(long double rhomolar, long double T); - /// Set the components of the mixture - /** - @param components The components that are to be used in this mixture - @param generate_SatL_and_SatV true if SatL and SatV classes should be added, false otherwise. Added so that saturation classes can be added without infinite recursion of adding saturation classes - */ + /** \brief Set the components of the mixture + * + * @param components The components that are to be used in this mixture + * @param generate_SatL_and_SatV true if SatL and SatV classes should be added, false otherwise. Added so that saturation classes can be added without infinite recursion of adding saturation classes + */ void set_components(std::vector components, bool generate_SatL_and_SatV = true); - /** - \brief Specify the phase - this phase will always be used in calculations - @param phase_index The index from CoolProp::phases - */ + /** \brief Specify the phase - this phase will always be used in calculations + * + * @param phase_index The index from CoolProp::phases + */ void specify_phase(phases phase_index){imposed_phase_index = phase_index; _phase = phase_index;}; - /** - \brief Unspecify the phase - the phase is no longer imposed, different solvers can do as they like - */ + /**\brief Unspecify the phase - the phase is no longer imposed, different solvers can do as they like + */ void unspecify_phase(){imposed_phase_index = iphase_not_imposed;}; - void set_reducing_function(); - void set_excess_term(); + /** \brief Set the mixture parameters - binary pair reducing functions, departure functions, F_ij, etc. + */ + void set_mixture_parameters(); - /// Set the mole fractions - /** - @param mole_fractions The vector of mole fractions of the components - */ + /** \brief Set the mole fractions + * + * @param mole_fractions The vector of mole fractions of the components + */ void set_mole_fractions(const std::vector &mole_fractions); std::vector &get_mole_fractions(){return mole_fractions;}; const std::vector &get_const_mole_fractions(){return mole_fractions;}; - /// Set the mass fractions - /** - @param mass_fractions The vector of mass fractions of the components - */ + /** \brief Set the mass fractions + * + * @param mass_fractions The vector of mass fractions of the components + */ void set_mass_fractions(const std::vector &mass_fractions){throw std::exception();}; long double calc_molar_mass(void); diff --git a/src/Backends/Helmholtz/MixtureDerivatives.cpp b/src/Backends/Helmholtz/MixtureDerivatives.cpp index 9502c69b..8c2e094e 100644 --- a/src/Backends/Helmholtz/MixtureDerivatives.cpp +++ b/src/Backends/Helmholtz/MixtureDerivatives.cpp @@ -151,10 +151,10 @@ long double MixtureDerivatives::dln_fugacity_i_ddelta__consttau_x(HelmholtzEOSMi } long double MixtureDerivatives::dln_fugacity_dxj__constT_rho_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) { - long double rhor = HEOS.Reducing.p->rhormolar(HEOS.get_const_mole_fractions()); - long double Tr = HEOS.Reducing.p->Tr(HEOS.get_const_mole_fractions()); - long double dTrdxj = HEOS.Reducing.p->dTrdxi__constxj(HEOS.get_const_mole_fractions(),j,xN_flag); - long double drhordxj = HEOS.Reducing.p->drhormolardxi__constxj(HEOS.get_const_mole_fractions(),j,xN_flag); + long double rhor = HEOS.Reducing->rhormolar(HEOS.get_const_mole_fractions()); + long double Tr = HEOS.Reducing->Tr(HEOS.get_const_mole_fractions()); + long double dTrdxj = HEOS.Reducing->dTrdxi__constxj(HEOS.get_const_mole_fractions(),j,xN_flag); + long double drhordxj = HEOS.Reducing->drhormolardxi__constxj(HEOS.get_const_mole_fractions(),j,xN_flag); // These lines are all the same long double line1 = dln_fugacity_i_dtau__constdelta_x(HEOS, i, xN_flag)*1/HEOS.T()*dTrdxj; @@ -165,7 +165,7 @@ long double MixtureDerivatives::dln_fugacity_dxj__constT_rho_xi(HelmholtzEOSMixt std::size_t N = x.size(); // This is a term to which some more might be added depending on i and j - long double line3 = 1/rhor*HEOS.Reducing.p->drhormolardxi__constxj(x, j, xN_flag) + 1/Tr*HEOS.Reducing.p->dTrdxi__constxj(x, j, xN_flag); + long double line3 = 1/rhor*HEOS.Reducing->drhormolardxi__constxj(x, j, xN_flag) + 1/Tr*HEOS.Reducing->dTrdxi__constxj(x, j, xN_flag); if (i == N-1){ line3 += -1/x[N-1]; @@ -213,12 +213,12 @@ long double MixtureDerivatives::d_ndalphardni_dxj__constT_V_xi(HelmholtzEOSMixtu long double MixtureDerivatives::ddelta_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag) { // Gernert 3.121 (Catch test provided) - return -HEOS._delta.pt()/HEOS._reducing.rhomolar*HEOS.Reducing.p->drhormolardxi__constxj(HEOS.mole_fractions,j, xN_flag); + return -HEOS._delta.pt()/HEOS._reducing.rhomolar*HEOS.Reducing->drhormolardxi__constxj(HEOS.mole_fractions,j, xN_flag); } long double MixtureDerivatives::dtau_dxj__constT_V_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t j, x_N_dependency_flag xN_flag) { // Gernert 3.122 (Catch test provided) - return 1/HEOS._T*HEOS.Reducing.p->dTrdxi__constxj(HEOS.mole_fractions,j, xN_flag); + return 1/HEOS._T*HEOS.Reducing->dTrdxi__constxj(HEOS.mole_fractions,j, xN_flag); } long double MixtureDerivatives::dpdT__constV_n(HelmholtzEOSMixtureBackend &HEOS) @@ -240,8 +240,8 @@ long double MixtureDerivatives::ndpdni__constT_V_nj(HelmholtzEOSMixtureBackend & { // Eqn 7.64 and 7.63 long double R_u = HEOS.gas_constant(); - double ndrhorbar_dni__constnj = HEOS.Reducing.p->ndrhorbardni__constnj(HEOS.mole_fractions,i, xN_flag); - double ndTr_dni__constnj = HEOS.Reducing.p->ndTrdni__constnj(HEOS.mole_fractions,i, xN_flag); + double ndrhorbar_dni__constnj = HEOS.Reducing->ndrhorbardni__constnj(HEOS.mole_fractions,i, xN_flag); + double ndTr_dni__constnj = HEOS.Reducing->ndTrdni__constnj(HEOS.mole_fractions,i, xN_flag); double summer = 0; std::size_t kmax = HEOS.mole_fractions.size(); if (xN_flag == XN_DEPENDENT){ kmax--; } @@ -255,8 +255,8 @@ long double MixtureDerivatives::ndpdni__constT_V_nj(HelmholtzEOSMixtureBackend & long double MixtureDerivatives::ndalphar_dni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag) { - double term1 = HEOS._delta.pt()*HEOS.dalphar_dDelta()*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing.p->ndrhorbardni__constnj(HEOS.mole_fractions,i, xN_flag)); - double term2 = HEOS._tau.pt()*HEOS.dalphar_dTau()*(1/HEOS._reducing.T)*HEOS.Reducing.p->ndTrdni__constnj(HEOS.mole_fractions,i, xN_flag); + double term1 = HEOS._delta.pt()*HEOS.dalphar_dDelta()*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing->ndrhorbardni__constnj(HEOS.mole_fractions,i, xN_flag)); + double term2 = HEOS._tau.pt()*HEOS.dalphar_dTau()*(1/HEOS._reducing.T)*HEOS.Reducing->ndTrdni__constnj(HEOS.mole_fractions,i, xN_flag); double s = 0; std::size_t kmax = HEOS.mole_fractions.size(); @@ -275,18 +275,18 @@ long double MixtureDerivatives::ndln_fugacity_coefficient_dnj__constT_p(Helmholt } long double MixtureDerivatives::nddeltadni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag) { - return HEOS._delta.pt()-HEOS._delta.pt()/HEOS._reducing.rhomolar*HEOS.Reducing.p->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag); + return HEOS._delta.pt()-HEOS._delta.pt()/HEOS._reducing.rhomolar*HEOS.Reducing->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag); } long double MixtureDerivatives::ndtaudni__constT_V_nj(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag) { - return HEOS._tau.pt()/HEOS._reducing.T*HEOS.Reducing.p->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); + return HEOS._tau.pt()/HEOS._reducing.T*HEOS.Reducing->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); } long double MixtureDerivatives::d_ndalphardni_dxj__constdelta_tau_xi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) { - double line1 = HEOS._delta.pt()*d2alphar_dxi_dDelta(HEOS, j, xN_flag)*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing.p->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag)); - double line3 = HEOS._tau.pt()*d2alphar_dxi_dTau(HEOS, j, xN_flag)*(1/HEOS._reducing.T)*HEOS.Reducing.p->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); - double line2 = -HEOS._delta.pt()*HEOS.dalphar_dDelta()*(1/HEOS._reducing.rhomolar)*(HEOS.Reducing.p->d_ndrhorbardni_dxj__constxi(HEOS.mole_fractions, i, j, xN_flag)-1/HEOS._reducing.rhomolar*HEOS.Reducing.p->drhormolardxi__constxj(HEOS.mole_fractions,j, xN_flag)*HEOS.Reducing.p->ndrhorbardni__constnj(HEOS.mole_fractions,i, xN_flag)); - double line4 = HEOS._tau.pt()*HEOS.dalphar_dTau()*(1/HEOS._reducing.T)*(HEOS.Reducing.p->d_ndTrdni_dxj__constxi(HEOS.mole_fractions,i,j, xN_flag)-1/HEOS._reducing.T*HEOS.Reducing.p->dTrdxi__constxj(HEOS.mole_fractions, j, xN_flag)*HEOS.Reducing.p->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag)); + double line1 = HEOS._delta.pt()*d2alphar_dxi_dDelta(HEOS, j, xN_flag)*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag)); + double line3 = HEOS._tau.pt()*d2alphar_dxi_dTau(HEOS, j, xN_flag)*(1/HEOS._reducing.T)*HEOS.Reducing->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); + double line2 = -HEOS._delta.pt()*HEOS.dalphar_dDelta()*(1/HEOS._reducing.rhomolar)*(HEOS.Reducing->d_ndrhorbardni_dxj__constxi(HEOS.mole_fractions, i, j, xN_flag)-1/HEOS._reducing.rhomolar*HEOS.Reducing->drhormolardxi__constxj(HEOS.mole_fractions,j, xN_flag)*HEOS.Reducing->ndrhorbardni__constnj(HEOS.mole_fractions,i, xN_flag)); + double line4 = HEOS._tau.pt()*HEOS.dalphar_dTau()*(1/HEOS._reducing.T)*(HEOS.Reducing->d_ndTrdni_dxj__constxi(HEOS.mole_fractions,i,j, xN_flag)-1/HEOS._reducing.T*HEOS.Reducing->dTrdxi__constxj(HEOS.mole_fractions, j, xN_flag)*HEOS.Reducing->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag)); double s = 0; std::size_t kmax = HEOS.mole_fractions.size(); @@ -316,10 +316,10 @@ long double MixtureDerivatives::nd2nalphardnidnj__constT_V(HelmholtzEOSMixtureBa long double MixtureDerivatives::d_ndalphardni_dDelta(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag) { // The first line - double term1 = (HEOS._delta.pt()*HEOS.d2alphar_dDelta2()+HEOS.dalphar_dDelta())*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing.p->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag)); + double term1 = (HEOS._delta.pt()*HEOS.d2alphar_dDelta2()+HEOS.dalphar_dDelta())*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag)); // The second line - double term2 = HEOS._tau.pt()*HEOS.d2alphar_dDelta_dTau()*(1/HEOS._reducing.T)*HEOS.Reducing.p->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); + double term2 = HEOS._tau.pt()*HEOS.d2alphar_dDelta_dTau()*(1/HEOS._reducing.T)*HEOS.Reducing->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); // The third line double term3 = d2alphar_dxi_dDelta(HEOS, i, xN_flag); @@ -334,10 +334,10 @@ long double MixtureDerivatives::d_ndalphardni_dDelta(HelmholtzEOSMixtureBackend long double MixtureDerivatives::d_ndalphardni_dTau(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag) { // The first line - double term1 = HEOS._delta.pt()*HEOS.d2alphar_dDelta_dTau()*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing.p->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag)); + double term1 = HEOS._delta.pt()*HEOS.d2alphar_dDelta_dTau()*(1-1/HEOS._reducing.rhomolar*HEOS.Reducing->ndrhorbardni__constnj(HEOS.mole_fractions, i, xN_flag)); // The second line - double term2 = (HEOS._tau.pt()*HEOS.d2alphar_dTau2()+HEOS.dalphar_dTau())*(1/HEOS._reducing.T)*HEOS.Reducing.p->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); + double term2 = (HEOS._tau.pt()*HEOS.d2alphar_dTau2()+HEOS.dalphar_dTau())*(1/HEOS._reducing.T)*HEOS.Reducing->ndTrdni__constnj(HEOS.mole_fractions, i, xN_flag); // The third line double term3 = d2alphar_dxi_dTau(HEOS, i, xN_flag); @@ -674,21 +674,21 @@ TEST_CASE("Mixture derivative checks", "[mixtures],[mixture_derivs]") rHEOS.update(DmolarT_INPUTS, 300, 300); double rho1 = rHEOS.rhomolar(); - double analytic = rHEOS.Reducing.p->d_ndTrdni_dxj__constxi(rHEOS.get_const_mole_fractions(), i, j, xN_flag); + double analytic = rHEOS.Reducing->d_ndTrdni_dxj__constxi(rHEOS.get_const_mole_fractions(), i, j, xN_flag); // Increment mole fraction std::vector zp = z; /// Copy base composition zp[j] += dz; zp[1-j] -= dz; rHEOS.set_mole_fractions(zp); rHEOS.update(DmolarT_INPUTS, rho1, 300); - double v1 = rHEOS.Reducing.p->ndTrdni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); + double v1 = rHEOS.Reducing->ndTrdni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); // Decrement mole fraction std::vector zm = z; /// Copy base composition zm[j] -= dz; zm[1-j] += dz; rHEOS.set_mole_fractions(zm); rHEOS.update(DmolarT_INPUTS, rho1, 300); - double v2 = rHEOS.Reducing.p->ndTrdni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); + double v2 = rHEOS.Reducing->ndTrdni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); double numeric = (v1 - v2)/(2*dz); double err = std::abs((numeric-analytic)/analytic); @@ -707,21 +707,21 @@ TEST_CASE("Mixture derivative checks", "[mixtures],[mixture_derivs]") rHEOS.update(DmolarT_INPUTS, 300, 300); double rho1 = rHEOS.rhomolar(); - double analytic = rHEOS.Reducing.p->d_ndrhorbardni_dxj__constxi(rHEOS.get_const_mole_fractions(), i, j, xN_flag); + double analytic = rHEOS.Reducing->d_ndrhorbardni_dxj__constxi(rHEOS.get_const_mole_fractions(), i, j, xN_flag); // Increment mole fraction std::vector zp = z; /// Copy base composition zp[j] += dz; zp[1-j] -= dz; rHEOS.set_mole_fractions(zp); rHEOS.update(DmolarT_INPUTS, rho1, 300); - double v1 = rHEOS.Reducing.p->ndrhorbardni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); + double v1 = rHEOS.Reducing->ndrhorbardni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); // Decrement mole fraction std::vector zm = z; /// Copy base composition zm[j] -= dz; zm[1-j] += dz; rHEOS.set_mole_fractions(zm); rHEOS.update(DmolarT_INPUTS, rho1, 300); - double v2 = rHEOS.Reducing.p->ndrhorbardni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); + double v2 = rHEOS.Reducing->ndrhorbardni__constnj(rHEOS.get_const_mole_fractions(), i, xN_flag); double numeric = (v1 - v2)/(2*dz); double err = std::abs((numeric-analytic)/analytic); diff --git a/src/Backends/Helmholtz/MixtureParameters.cpp b/src/Backends/Helmholtz/MixtureParameters.cpp new file mode 100644 index 00000000..799d05d1 --- /dev/null +++ b/src/Backends/Helmholtz/MixtureParameters.cpp @@ -0,0 +1,294 @@ +#include "MixtureParameters.h" +#include "mixture_departure_functions_JSON.h" // Creates the variable mixture_departure_functions_JSON +#include "mixture_binary_pairs_JSON.h" // Creates the variable mixture_binary_pairs_JSON + +namespace CoolProp{ + +/** \brief A library of binary pair parameters for the mixture + * + * Each entry in the binary pair library includes reducing parameters as well as the name of the reducing function to be used and + */ +class MixtureBinaryPairLibrary{ +public: + /// Map from sorted pair of CAS numbers to reducing parameter map. The reducing parameter map is a map from key (string) to value (double) + std::map< std::vector, std::vector > binary_pair_map; + + /** \brief Construct the binary pair library including all the binary pairs that are possible + * + * The data structure also includes space for a string that gives the pointer to the departure function to be used for this binary pair. * + */ + MixtureBinaryPairLibrary() + { + rapidjson::Document doc; + + doc.Parse<0>(mixture_binary_pairs_JSON.c_str()); + if (doc.HasParseError()){throw ValueError();} + + // Iterate over the papers in the listing + for (rapidjson::Value::ValueIterator itr = doc.Begin(); itr != doc.End(); ++itr) + { + // Get the empty dictionary to be filled by the appropriate reducing parameter filling function + Dictionary dict; + + // Get the vector of CAS numbers + std::vector CAS; + CAS.push_back(cpjson::get_string(*itr, "CAS1")); + CAS.push_back(cpjson::get_string(*itr, "CAS2")); + std::string name1 = cpjson::get_string(*itr, "Name1"); + std::string name2 = cpjson::get_string(*itr, "Name2"); + + // Sort the CAS number vector + std::sort(CAS.begin(), CAS.end()); + + // A sort was carried out, names/CAS were swapped + bool swapped = CAS[0].compare(cpjson::get_string(*itr, "CAS1")) != 0; + + if (swapped){ std::swap(name1, name2); } + + // Populate the dictionary with common terms + dict.add_string("name1", name1); + dict.add_string("name2", name2); + dict.add_string("BibTeX", cpjson::get_string(*itr, "BibTeX")); + dict.add_number("F", cpjson::get_double(*itr, "F")); + if (std::abs(dict.get_number("F")) > DBL_EPSILON){ + dict.add_string("function", cpjson::get_string(*itr, "function")); + } + + if (itr->HasMember("xi") && itr->HasMember("zeta")){ + dict.add_string("type","Lemmon-xi-zeta"); + // Air and HFC mixtures from Lemmon - we could also directly do the conversion + dict.add_number("xi", cpjson::get_double(*itr, "xi")); + dict.add_number("zeta", cpjson::get_double(*itr, "zeta")); + } + else if (itr->HasMember("gammaT") && itr->HasMember("gammaV") && itr->HasMember("betaT") && itr->HasMember("betaV")){ + dict.add_string("type","GERG-2008"); + dict.add_number("gammaV", cpjson::get_double(*itr, "gammaV")); + dict.add_number("gammaT", cpjson::get_double(*itr, "gammaT")); + + double betaV = cpjson::get_double(*itr, "betaV"); + double betaT = cpjson::get_double(*itr, "betaT"); + if (swapped){ + dict.add_number("betaV", 1/betaV); + dict.add_number("betaT", 1/betaT); + } + else{ + dict.add_number("betaV", betaV); + dict.add_number("betaT", betaT); + } + } + else{ throw ValueError(); } + + if (binary_pair_map.find(CAS) == binary_pair_map.end()){ + // Add to binary pair map by creating one-element vector + binary_pair_map.insert(std::pair, std::vector >(CAS, std::vector(1, dict))); + } + else + { + binary_pair_map[CAS].push_back(dict); + } + } + } +}; +static MixtureBinaryPairLibrary mixturebinarypairlibrary; + +std::string get_reducing_function_name(std::string CAS1, std::string CAS2) +{ + std::vector CAS; + CAS.push_back(CAS1); + CAS.push_back(CAS2); + + // Sort the CAS number vector - map is based on sorted CAS codes + std::sort(CAS.begin(), CAS.end()); + + if (mixturebinarypairlibrary.binary_pair_map.find(CAS) != mixturebinarypairlibrary.binary_pair_map.end()){ + return mixturebinarypairlibrary.binary_pair_map.at(CAS)[0].get_string("function"); + } + else{ + throw ValueError(format("Could not match the binary pair [%s,%s] - for now this is an error.",CAS1.c_str(), CAS2.c_str())); + } +} + +/** \brief A container for the departure functions for CoolProp mixtures + */ +class MixtureDepartureFunctionsLibrary{ +public: + /// Map from sorted pair of CAS numbers to departure term dictionary. + std::map departure_function_map; + + MixtureDepartureFunctionsLibrary() + { + rapidjson::Document doc; + + // Load the JSON data for the departure functions + doc.Parse<0>(mixture_departure_functions_JSON.c_str()); + if (doc.HasParseError()){ + std::cout << mixture_departure_functions_JSON << std::endl ; + throw ValueError("Unable to parse mixture_departure_functions_JSON.h"); + } + + // Iterate over the departure functions in the listing + for (rapidjson::Value::ValueIterator itr = doc.Begin(); itr != doc.End(); ++itr) + { + // Get the empty dictionary to be filled in + Dictionary dict; + + // Populate the dictionary with common terms + std::string Name = cpjson::get_string(*itr, "Name"); + std::string type = cpjson::get_string(*itr, "type"); + dict.add_string("Name", Name); + dict.add_string("BibTeX", cpjson::get_string(*itr, "BibTeX")); + dict.add_string_vector("aliases", cpjson::get_string_array(*itr, "aliases")); + dict.add_string("type", type); + + // Terms for the power (common to both types) + dict.add_double_vector("n", cpjson::get_double_array(*itr, "n")); + dict.add_double_vector("d", cpjson::get_double_array(*itr, "d")); + dict.add_double_vector("t", cpjson::get_double_array(*itr, "t")); + + // Now we need to load additional terms + if (!type.compare("GERG-2008")){ + // Number of terms that are power terms + dict.add_number("Npower", cpjson::get_double(*itr, "Npower")); + // Terms for the gaussian + dict.add_double_vector("eta", cpjson::get_double_array(*itr, "eta")); + dict.add_double_vector("epsilon", cpjson::get_double_array(*itr, "epsilon")); + dict.add_double_vector("beta", cpjson::get_double_array(*itr, "beta")); + dict.add_double_vector("gamma", cpjson::get_double_array(*itr, "gamma")); + } + else if (!type.compare("Exponential")){ + dict.add_double_vector("l", cpjson::get_double_array(*itr, "l")); + } + else{ + throw ValueError(format("It was not possible to parse departure function with type [%s]", type.c_str())); + } + + // Check if this name is already in use + if (departure_function_map.find(Name) == departure_function_map.end()) + { + // Not in map, add new entry to map with dictionary as value and Name as key + departure_function_map.insert(std::pair(Name, dict)); + } + else + { + // Error if already in map! + // + // Collect all the current names for departure functions for a nicer error message + std::vector names; + for (std::map::iterator it = departure_function_map.begin(); it != departure_function_map.end(); ++it) + { + names.push_back(it->first); + } + throw ValueError(format("Name of departure function [%s] is already loaded. Current departure function names are: %s", Name.c_str(), strjoin(names,",").c_str() )); + } + } + } +}; +static MixtureDepartureFunctionsLibrary mixturedeparturefunctionslibrary; + +void MixtureParameters::set_mixture_parameters(HelmholtzEOSMixtureBackend &HEOS) +{ + std::vector components = HEOS.get_components(); + + std::size_t N = components.size(); + + STLMatrix beta_v, gamma_v, beta_T, gamma_T; + beta_v.resize(N, std::vector(N, 0)); + gamma_v.resize(N, std::vector(N, 0)); + beta_T.resize(N, std::vector(N, 0)); + gamma_T.resize(N, std::vector(N, 0)); + + HEOS.Excess.resize(N); + + for (std::size_t i = 0; i < N; ++i) + { + for (std::size_t j = 0; j < N; ++j) + { + if (i == j){ continue; } + + std::string CAS1 = components[i]->CAS; + std::vector CAS(2,""); + CAS[0] = components[i]->CAS; + CAS[1] = components[j]->CAS; + std::sort(CAS.begin(), CAS.end()); + + // The variable swapped is true if a swap occured. + bool swapped = (CAS1.compare(CAS[0]) != 0); + + // *************************************************** + // Reducing parameters for binary pair + // *************************************************** + + // Get a reference to the first matching binary pair in the dictionary + Dictionary &dict_red = mixturebinarypairlibrary.binary_pair_map[CAS][0]; + + // Get the name of the type being used, one of GERG-2008, Lemmon-xi-zeta, etc. + std::string type_red = dict_red.get_string("type"); + + if (!type_red.compare("GERG-2008")){ + if (swapped){ + beta_v[i][j] = 1/dict_red.get_number("betaV"); + beta_T[i][j] = 1/dict_red.get_number("betaT"); + } + else{ + beta_v[i][j] = dict_red.get_number("betaV"); + beta_T[i][j] = dict_red.get_number("betaT"); + } + gamma_v[i][j] = dict_red.get_number("gammaV"); + gamma_T[i][j] = dict_red.get_number("gammaT"); + } + else if (!type_red.compare("Lemmon-xi-zeta")){ + LemmonAirHFCReducingFunction::convert_to_GERG(components,i,j,dict_red,beta_T[i][j],beta_v[i][j],gamma_T[i][j],gamma_v[i][j]); + } + else{ + throw ValueError(format("type [%s] for reducing function for pair [%s, %s] is invalid", type_red.c_str(), + dict_red.get_string("Name1").c_str(), + dict_red.get_string("Name2").c_str() )); + } + + // *************************************************** + // Departure functions used in excess term + // *************************************************** + + // Get the name of the departure function to be used for this binary pair + std::string Name = CoolProp::get_reducing_function_name(components[i]->CAS, components[j]->CAS); + + // Get the dictionary itself + Dictionary &dict_dep = mixturedeparturefunctionslibrary.departure_function_map[Name]; + + // These terms are common + std::vector n = dict_dep.get_double_vector("n"); + std::vector d = dict_dep.get_double_vector("d"); + std::vector t = dict_dep.get_double_vector("t"); + + // Set the scaling factor F for the excess term + HEOS.Excess.F[i][j] = dict_red.get_number("F"); + + std::string type_dep = dict_dep.get_string("type"); + + if (!type_dep.compare("GERG-2008")){ + // Number of power terms needed + int Npower = static_cast(dict_dep.get_number("Npower")); + // Terms for the gaussian + std::vector eta = dict_dep.get_double_vector("eta"); + std::vector epsilon = dict_dep.get_double_vector("epsilon"); + std::vector beta = dict_dep.get_double_vector("beta"); + std::vector gamma = dict_dep.get_double_vector("gamma"); + HEOS.Excess.DepartureFunctionMatrix[i][j].reset(new GERG2008DepartureFunction(n,d,t,eta,epsilon,beta,gamma,Npower)); + } + else if (!type_dep.compare("Exponential")) + { + // Powers of the exponents inside the exponential term + std::vector l = dict_dep.get_double_vector("l"); + HEOS.Excess.DepartureFunctionMatrix[i][j].reset(new ExponentialDepartureFunction(n,d,t,l)); + } + else + { + throw ValueError(); + } + } + } + // We have obtained all the parameters needed for the reducing function, now set the reducing function for the mixture + HEOS.Reducing = shared_ptr(new GERG2008ReducingFunction(components, beta_v, gamma_v, beta_T, gamma_T)); +} + +} /* namespace CoolProp */ \ No newline at end of file diff --git a/src/Backends/Helmholtz/MixtureParameters.h b/src/Backends/Helmholtz/MixtureParameters.h new file mode 100644 index 00000000..7d9f9902 --- /dev/null +++ b/src/Backends/Helmholtz/MixtureParameters.h @@ -0,0 +1,15 @@ +#ifndef MIXTURE_PARAMETERS_H +#define MIXTURE_PARAMETERS_H + +#include "HelmholtzEOSMixtureBackend.h" + +namespace CoolProp{ + +class MixtureParameters +{ +public: + static void set_mixture_parameters(HelmholtzEOSMixtureBackend &HEOS); +}; + +} /* namespace CoolProp */ +#endif \ No newline at end of file diff --git a/src/Backends/Helmholtz/PhaseEnvelopeRoutines.cpp b/src/Backends/Helmholtz/PhaseEnvelopeRoutines.cpp index 59db697a..3b15d085 100644 --- a/src/Backends/Helmholtz/PhaseEnvelopeRoutines.cpp +++ b/src/Backends/Helmholtz/PhaseEnvelopeRoutines.cpp @@ -111,7 +111,7 @@ void PhaseEnvelopeRoutines::build(HelmholtzEOSMixtureBackend &HEOS) IO.x[IO.x.size()-1] = 1 - std::accumulate(IO.x.begin(), IO.x.end()-1, 0.0); factor = rho_vap_new/IO.rhomolar_vap; dont_extrapolate = true; // So that we use the mole fractions we calculated here instead of the extrapolated values - std::cout << "dv " << rho_vap_new << " dl " << IO.rhomolar_liq << " " << vec_to_string(IO.x, "%0.10Lg") << " " << vec_to_string(IO.y, "%0.10Lg") << std::endl; + //std::cout << "dv " << rho_vap_new << " dl " << IO.rhomolar_liq << " " << vec_to_string(IO.x, "%0.10Lg") << " " << vec_to_string(IO.y, "%0.10Lg") << std::endl; iter0 = iter - 1; // Back to linear interpolation again continue; } diff --git a/src/Backends/Helmholtz/ReducingFunctions.cpp b/src/Backends/Helmholtz/ReducingFunctions.cpp index 4d3fdabb..7e3951a3 100644 --- a/src/Backends/Helmholtz/ReducingFunctions.cpp +++ b/src/Backends/Helmholtz/ReducingFunctions.cpp @@ -1,149 +1,7 @@ #include "ReducingFunctions.h" -#include "mixture_reducing_parameters_JSON.h" // Creates the variable mixture_reducing_parameters_JSON + namespace CoolProp{ -static MixingParameterLibrary mixturelibrary; - -MixingParameterLibrary::MixingParameterLibrary() -{ - rapidjson::Document dd; - - dd.Parse<0>(mixture_reducing_parameters_JSON.c_str()); - if (dd.HasParseError()){throw ValueError();} - - // Iterate over the papers in the listing - for (rapidjson::Value::ValueIterator itr = dd.Begin(); itr != dd.End(); ++itr) - { - // Iterate over the coeffs in the entry - rapidjson::Value &Coeffs = (*itr)["Coeffs"]; - std::string model = cpjson::get_string(*itr, "Model"); - std::string BibTeX = cpjson::get_string(*itr, "BibTeX"); - for (rapidjson::Value::ValueIterator itr_coeff = Coeffs.Begin(); itr_coeff != Coeffs.End(); ++itr_coeff) - { - // Get the vector of CAS numbers - std::vector CAS; - CAS.resize(2); - CAS[0] = cpjson::get_string(*itr_coeff, "CAS1"); - CAS[1] = cpjson::get_string(*itr_coeff, "CAS2"); - std::string name1 = cpjson::get_string(*itr_coeff, "Name1"); - std::string name2 = cpjson::get_string(*itr_coeff, "Name2"); - - // Sort the CAS number vector - std::sort(CAS.begin(), CAS.end()); - - // Get the empty dictionary to be filled by the appropriate reducing parameter filling function - Dictionary d; - - // A sort was carried out, names/CAS were swapped - bool swapped = CAS[0].compare(cpjson::get_string(*itr_coeff, "CAS1")) != 0; - - if (swapped){ - std::swap(name1,name2); - } - - // Populate the dictionary with common terms - d.add_string("model", model); - d.add_string("name1", name1); - d.add_string("name2", name2); - d.add_string("bibtex", BibTeX); - - if (!model.compare("Kunz-JCED-2012")) - { - parse_Kunz_JCED_2012(d, *itr_coeff, swapped); - } - else if (!model.compare("Lemmon-JPCRD-2004")) - { - parse_Lemmon_JPCRD_2004(d, *itr_coeff, swapped); - } - else if (!model.compare("Lemmon-JPCRD-2000")) - { - parse_Lemmon_JPCRD_2000(d, *itr_coeff, swapped); - } - else - { - throw ValueError(); - } - - // If not in map, add new entry to map with dictionary - if (reducing_map.find(CAS) == reducing_map.end()) - { - // One-element vector of the dictionary - std::vector vd(1, d); - // Pair for adding to map - std::pair, std::vector > p(CAS, vd); - // Add - reducing_map.insert(p); - } - else // If already in map, add entry to the end of the vector - { - // Append dictionary to listing - reducing_map[CAS].push_back(d); - } - } - } -} - -ReducingFunction *ReducingFunction::factory(const std::vector &components) -{ - std::string _model; - std::size_t N = components.size(); - - STLMatrix beta_v, gamma_v, beta_T, gamma_T; - beta_v.resize(N, std::vector(N, 0)); - gamma_v.resize(N, std::vector(N, 0)); - beta_T.resize(N, std::vector(N, 0)); - gamma_T.resize(N, std::vector(N, 0)); - - for (std::size_t i = 0; i < N; ++i) - { - for (std::size_t j = 0; j < N; ++j) - { - if (i == j){ continue; } - - std::string CAS1 = components[i]->CAS; - std::vector CAS(2,""); - CAS[0] = components[i]->CAS; - CAS[1] = components[j]->CAS; - std::sort(CAS.begin(), CAS.end()); - - /// swapped is true if a swap occured. - bool swapped = (CAS1.compare(CAS[0]) != 0); - - std::vector & vd = mixturelibrary.reducing_map[CAS]; - if (vd.size() != 1) { throw NotImplementedError(); } - // Get a reference to the dictionary itself to save a few dereferences - Dictionary &d = vd[0]; - - std::string model = d.get_string("model"); - - if (!model.compare("Kunz-JCED-2012")) - { - if (swapped) - { - beta_v[i][j] = 1/d.get_number("betaV"); - beta_T[i][j] = 1/d.get_number("betaT"); - } - else - { - beta_v[i][j] = d.get_number("betaV"); - beta_T[i][j] = d.get_number("betaT"); - } - gamma_v[i][j] = d.get_number("gammaV"); - gamma_T[i][j] = d.get_number("gammaT"); - } - else if (!model.compare("Lemmon-JPCRD-2004") || !model.compare("Lemmon-JPCRD-2000")) - { - LemmonAirHFCReducingFunction::convert_to_GERG(components,i,j,d,beta_T[i][j],beta_v[i][j],gamma_T[i][j],gamma_v[i][j]); - } - else - { - throw ValueError(); - } - } - } - return new GERG2008ReducingFunction(components,beta_v, gamma_v, beta_T, gamma_T); -} - long double ReducingFunction::d_ndTrdni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) { if (xN_flag == XN_INDEPENDENT){ @@ -199,7 +57,6 @@ long double ReducingFunction::ndrhorbardni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) { @@ -454,5 +311,4 @@ long double GERG2008ReducingFunction::d2fYijdxidxj(const std::vector #include "CoolPropFluid.h" +#include "crossplatform_shared_ptr.h" namespace CoolProp{ @@ -11,55 +18,13 @@ typedef std::vector > STLMatrix; enum x_N_dependency_flag{XN_INDEPENDENT, ///< x_N is an independent variable, and not calculated by \f$ x_N = 1-\sum_i x_i\f$ XN_DEPENDENT ///< x_N is an dependent variable, calculated by \f$ x_N = 1-\sum_i x_i\f$ }; - -/// A container for the mixing parameters for CoolProp mixtures -/** + +std::string get_reducing_function_name(std::string CAS1, std::string CAS2); -*/ -class MixingParameterLibrary -{ -public: - /// Map from sorted pair of CAS numbers to reducing parameter map. The reducing parameter map is a map from key (string) to value (double) - std::map, std::vector > reducing_map; - MixingParameterLibrary(); - - /// Parse a term from GERG 2008 - void parse_Kunz_JCED_2012(Dictionary &d, rapidjson::Value &val, bool swapped) - { - d.add_number("gammaV", cpjson::get_double(val, "gammaV")); - d.add_number("gammaT", cpjson::get_double(val, "gammaT")); - - double betaV = cpjson::get_double(val, "betaV"); - double betaT = cpjson::get_double(val, "betaT"); - if (swapped){ - d.add_number("betaV", 1/betaV); - d.add_number("betaT", 1/betaT); - } - else{ - d.add_number("betaV", betaV); - d.add_number("betaT", betaT); - } - }; - - /// Parse a term from HFC mixtures - void parse_Lemmon_JPCRD_2004(Dictionary &d, rapidjson::Value &val, bool swapped) - { - d.add_number("xi", cpjson::get_double(val, "xi")); - d.add_number("zeta", cpjson::get_double(val, "zeta")); - }; - - /// Parse a term from Air - void parse_Lemmon_JPCRD_2000(Dictionary &d, rapidjson::Value &val, bool swapped) - { - d.add_number("xi", cpjson::get_double(val, "xi")); - d.add_number("zeta", cpjson::get_double(val, "zeta")); - }; -}; - -/*! -An abstract base class for the reducing function to allow for -Lemmon-Jacobsen, GERG, or other reducing function to yield the -reducing parameters \f$ \rho_r \f$ and \f$ T_r \f$ +/** \brief Abstract base class for reducing function + * An abstract base class for the reducing function to allow for + * Lemmon-Jacobsen, GERG, or other reducing function to yield the + * reducing parameters \f$\rho_r\f$ and \f$T_r\f$ */ class ReducingFunction { @@ -69,8 +34,8 @@ public: ReducingFunction(){}; virtual ~ReducingFunction(){}; - /// A factory function to generate the required reducing function - static ReducingFunction *factory(const std::vector &components); + /// A factory function to generate the requiredreducing function + static shared_ptr factory(const std::vector &components, std::vector< std::vector< long double> > &F); /// The reduced temperature virtual long double Tr(const std::vector &x) = 0; @@ -86,27 +51,30 @@ public: virtual long double d2Trdxi2__constxj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag) = 0; virtual long double d2Trdxidxj(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag) = 0; - /*! GERG 2004 Monograph equation 7.56: - \f[ - \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2T_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}-\sum_{k=1}^Nx_k\left(\frac{\partial^2T_r}{\partial x_j \partial x_k}\right) - \f] - */ + /** \brief GERG 2004 Monograph equation 7.56: + * + * \f[ + * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial T_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2T_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial T_r}{\partial x_j}\right)_{x_i}-\sum_{k=1}^Nx_k\left(\frac{\partial^2T_r}{\partial x_j \partial x_k}\right) + * \f] + */ long double d_ndTrdni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); - /*! GERG 2004 Monograph equation 7.55: - \f[ - \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2\rho_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}-\sum_{k=1}^Nx_k\left(\frac{\partial^2\rho_r}{\partial x_j \partial x_k}\right) - \f] - */ + /** \brief GERG 2004 Monograph equation 7.55: + * + * \f[ + * \left(\frac{\partial}{\partial x_j}\left(n\left(\frac{\partial \rho_r}{\partial n_i} \right)_{n_j}\right)\right)_{x_i} = \left(\frac{\partial^2\rho_r}{\partial x_j \partial x_i}\right)-\left(\frac{\partial \rho_r}{\partial x_j}\right)_{x_i}-\sum_{k=1}^Nx_k\left(\frac{\partial^2\rho_r}{\partial x_j \partial x_k}\right) + * \f] + */ long double d_ndrhorbardni_dxj__constxi(const std::vector &x, std::size_t i, std::size_t j, x_N_dependency_flag xN_flag); long double ndrhorbardni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); long double ndTrdni__constnj(const std::vector &x, std::size_t i, x_N_dependency_flag xN_flag); }; -/*! -The Reducing parameter model used by the GERG-2008 formulation to yield the -reducing parameters \f$ \rho_r \f$ and \f$ T_r \f$ and derivatives thereof -*/ +/** \brief The reducing function model of GERG-2008 + * + * Used by the GERG-2008 formulation to yield the + * reducing parameters \f$ \rho_r \f$ and \f$ T_r \f$ and derivatives thereof + */ class GERG2008ReducingFunction : public ReducingFunction { private: @@ -181,27 +149,29 @@ public: long double d2fYijdxidxj(const std::vector &x, std::size_t i, std::size_t k, const STLMatrix &beta); }; -/*! From Lemmon, JPCRD, 2000 for the properties of Dry Air, and also from Lemmon, JPCRD, 2004 for the properties of R404A, R410A, etc. -\f[ -\rho_r(\bar x) = \left[ \sum_{i=1}^m\frac{x_i}{\rho_{c_i}}+\sum_{i=1}^{m-1}\sum_{j=i+1}^{m}x_ix_j\zeta_{ij}\right]^{-1} -\f] -\f[ -T_r(\bar x) = \sum_{i=1}^mx_iT_{c_i}+\sum_{i=1}^{m-1}\sum_{j=i+1}^mx_ix_j\xi_{ij} -\f] - -These can be converted to the form of GERG by the following equations: -\f[ -\beta_T = 1\ \ \ \ \beta_v = 1 -\f] -and -\f[ - \boxed{\gamma_T = \dfrac{T_{c0}+T_{c1}+\xi_{01}}{2\sqrt{T_{c0}T_{c1}}}} -\f] -and -\f[ - \boxed{\gamma_v = \dfrac{v_{c0}+v_{c1}+\zeta_{01}}{\frac{1}{4}\left(\frac{1}{\rho_{c,i}^{1/3}}+\frac{1}{\rho_{c,j}^{1/3}}\right)^{3}}} -\f] -*/ +/** \brief Reducing function converter for dry air and HFC blends + * + * From Lemmon, JPCRD, 2000 for the properties of Dry Air, and also from Lemmon, JPCRD, 2004 for the properties of R404A, R410A, etc. + * \f[ + * \rho_r(\bar x) = \left[ \sum_{i=1}^m\frac{x_i}{\rho_{c_i}}+\sum_{i=1}^{m-1}\sum_{j=i+1}^{m}x_ix_j\zeta_{ij}\right]^{-1} + * \f] + * \f[ + * T_r(\bar x) = \sum_{i=1}^mx_iT_{c_i}+\sum_{i=1}^{m-1}\sum_{j=i+1}^mx_ix_j\xi_{ij} + * \f] + * + * These can be converted to the form of GERG by the following equations: + * \f[ + * \beta_T = 1\ \ \ \ \beta_v = 1 + * \f] + * and + * \f[ + * \boxed{\gamma_T = \dfrac{T_{c0}+T_{c1}+\xi_{01}}{2\sqrt{T_{c0}T_{c1}}}} + * \f] + * and + * \f[ + * \boxed{\gamma_v = \dfrac{v_{c0}+v_{c1}+\zeta_{01}}{\frac{1}{4}\left(\frac{1}{\rho_{c,i}^{1/3}}+\frac{1}{\rho_{c,j}^{1/3}}\right)^{3}}} + * \f] + */ class LemmonAirHFCReducingFunction { protected: @@ -222,24 +192,5 @@ public: }; }; -class ReducingFunctionContainer -{ -private: - ReducingFunctionContainer(const ReducingFunctionContainer&); - ReducingFunctionContainer& operator=(const ReducingFunctionContainer&); -public: - ReducingFunction *p; - ReducingFunctionContainer(){ - p = NULL; - }; - void set(ReducingFunction *pReducing){p = pReducing;}; - ReducingFunctionContainer(ReducingFunction *pReducing){ - p = pReducing; - }; - ~ReducingFunctionContainer(){delete(p);}; - -}; - - } /* namespace CoolProp */ #endif \ No newline at end of file diff --git a/src/Backends/Helmholtz/VLERoutines.cpp b/src/Backends/Helmholtz/VLERoutines.cpp index 3592a014..9fbac809 100644 --- a/src/Backends/Helmholtz/VLERoutines.cpp +++ b/src/Backends/Helmholtz/VLERoutines.cpp @@ -569,7 +569,7 @@ void SaturationSolvers::saturation_T_pure_Akasaka(HelmholtzEOSMixtureBackend &HE shared_ptr SatL = HEOS.SatL, SatV = HEOS.SatV; - long double rhoL,rhoV,JL,JV,KL,KV,dJL,dJV,dKL,dKV; + long double rhoL = _HUGE, rhoV = _HUGE,JL,JV,KL,KV,dJL,dJV,dKL,dKV; long double DELTA, deltaL=0, deltaV=0, error, PL, PV, stepL, stepV; int iter=0; @@ -879,8 +879,6 @@ void SaturationSolvers::newton_raphson_saturation::check_Jacobian() std::cout << format("For x0\n"); std::cout << "numerical: " << vec_to_string(diffn, "%0.11Lg") << std::endl; std::cout << "analytic: " << vec_to_string(get_col(J0, 0), "%0.11Lg") << std::endl; - - int rrr = 0; } void SaturationSolvers::newton_raphson_saturation::call(HelmholtzEOSMixtureBackend &HEOS, const std::vector &z, std::vector &z_incipient, newton_raphson_saturation_options &IO) { diff --git a/src/Solvers.cpp b/src/Solvers.cpp index 4ffb6485..109c0bc0 100644 --- a/src/Solvers.cpp +++ b/src/Solvers.cpp @@ -322,6 +322,9 @@ double Brent(FuncWrapper1D* f, double a, double b, double macheps, double t, int if (!ValidNumber(fb)){ throw ValueError(format("Brent's method f(t) is NAN for t = %g",b).c_str()); } + if (std::abs(fb) < macheps){ + return b; + } if (fb*fc>0){ // Goto int: from Brent ALGOL code c=a; diff --git a/src/main.cxx b/src/main.cxx index 8b78afc5..909c1a66 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -18,7 +18,6 @@ using namespace CoolProp; #endif #include "SpeedTest.h" #include "HumidAirProp.h" -#include "CoolPropLib.h" #include "time.h" #include "Helmholtz.h" @@ -431,6 +430,13 @@ int main() } #endif #if 1 + { + double TTT0 = PropsSI("T","P",1e6,"Q",1,"REFPROP::Ethane[0.5]&Propane[0.5]"); + double TTT1 = PropsSI("T","P",1e6,"Q",1,"HEOS::Ethane[0.5]&Propane[0.5]"); + int rr =0; + } + #endif + #if 0 { // std::vector names(1, "n-Propane"); // shared_ptr HEOS(new HelmholtzEOSMixtureBackend(names)); @@ -446,12 +452,12 @@ int main() // HEOS->update(PT_INPUTS, p, Tmelt);}; // std::cout << get_global_param_string("errstring") << std::endl; // } + double TTT = PropsSI("T","P",1e6,"Q",1,"Ethane[0.5]&Propane[0.5]"); + ::set_debug_level(0); - - - shared_ptr HEOS(AbstractState::factory("HEOS","Ethane&Propane")); - std::vector z(2,0.85); z[1] = 1-z[0]; + shared_ptr HEOS(AbstractState::factory("HEOS","Ethane&Nitrogen")); + std::vector z(2,0.2); z[1] = 1-z[0]; HEOS->set_mole_fractions(z); time_t t1, t2; t1 = clock(); @@ -463,7 +469,7 @@ int main() std::cout << format("value(all): %g s/call\n", ((double)(t2-t1))/CLOCKS_PER_SEC); exit(EXIT_SUCCESS); - double TTT = PropsSI("T","P",1e6,"Q",1,"Ethane[0.5]&Propane[0.5]"); + std::cout << get_global_param_string("errstring") << std::endl; exit(EXIT_FAILURE); //double refretrte = PropsSI("P","Dmolar",107.9839357,"T",116.5360225,"Methane[0.5]&Propane[0.5]");