Merge branch 'master' into eigenPolynomials

This commit is contained in:
jowr
2014-07-08 14:32:45 +02:00
80 changed files with 961 additions and 2508 deletions

View File

@@ -199,9 +199,13 @@ if (COOLPROP_OCTAVE_MODULE)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src)
# Find the required libraries
find_library(OCTAVE_LIB octave PATHS ${OCTAVE_LINK_DIRS})
find_library(OCTINTERP_LIB octinterp PATHS ${OCTAVE_LINK_DIRS})
find_library(CRUFT_LIB cruft PATHS ${OCTAVE_LINK_DIRS})
find_library(OCTAVE_LIB liboctave.a PATHS ${OCTAVE_LINK_DIRS})
find_library(OCTINTERP_LIB liboctinterp.a PATHS ${OCTAVE_LINK_DIRS})
find_library(CRUFT_LIB libcruft.a PATHS ${OCTAVE_LINK_DIRS})
message(STATUS "OCTAVE_LIB=${OCTAVE_LIB}")
message(STATUS "OCTINTERP_LIB=${OCTINTERP_LIB}")
message(STATUS "CRUFT_LIB=${CRUFT_LIB}")
# Set the include folders
SET(OCTAVE_WRAP_INCLUDE_DIRS ${INCLUDE_DIR})
@@ -412,6 +416,24 @@ if (COOLPROP_MATLAB_MODULE)
add_dependencies (HAPropsSI generate_headers)
endif()
if (COOLPROP_PYTHON_LOCAL_INSTALL)
set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/Python/setup.py.in")
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/module/__init__.py")
set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
configure_file(${SETUP_PY_IN} ${SETUP_PY})
add_custom_command(OUTPUT ${OUTPUT}
COMMAND ${PYTHON} ${SETUP_PY} build
COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
DEPENDS ${DEPS})
add_custom_target(target ALL DEPENDS ${OUTPUT})
install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install)")
endif()
# NOT WORKING!
if (COOLPROP_MATHEMATICA_MODULE)

View File

@@ -1366,6 +1366,18 @@
timestamp = {2013.04.08}
}
@ARTICLE{Sun-BBPC-1988,
author = {T. F. Sun and J. A. Schouten and N. J. Trappeniers and S. N. Biswas},
title = {Accurate Measurement of the Melting Line of Methanol and Ethanol
at Pressures up to 270 MPa},
journal = {Ber. Bunsenges. Phys. Chem.},
year = {1988},
volume = {92},
pages = {652-655},
owner = {Belli},
timestamp = {2014.07.07}
}
@ARTICLE{Tanaka-IJT-1996,
author = {Y. Tanaka and T. Sotani},
title = {{Thermal Conductivity and Viscosity of 2,2-Dichloro-1,1,1-Trifluoroethane

View File

@@ -9,5 +9,5 @@ REM ~ pdflatex CoolPropdoc.tex
REM ~ copy /Y CoolPropdoc.pdf ..\..\_static\
REM ~ cd ..\..
rem sphinx-apidoc -f -o apidoc ../CoolProp
make html
rem sphinx-apidoc -T -f -o apidoc ../CoolProp
mingw32-make html

View File

@@ -0,0 +1,45 @@
"""
Sphinx extension to add ReadTheDocs-style "Edit on GitHub" links to the
sidebar.
Loosely based on https://github.com/astropy/astropy/pull/347
Edited by Ian Bell, 2014 to add path_prefix
"""
import os
import warnings
__licence__ = 'BSD (3 clause)'
def get_github_url(app, view, path):
return 'https://github.com/{project}/{view}/{branch}/{path}'.format(
project=app.config.edit_on_github_project,
view=view,
branch=app.config.edit_on_github_branch,
path=path)
def html_page_context(app, pagename, templatename, context, doctree):
if templatename != 'page.html':
return
if not app.config.edit_on_github_project:
warnings.warn("edit_on_github_project not specified")
return
path = os.path.relpath(doctree.get('source'), app.builder.srcdir).replace('\\','/')
path_prefix = app.config.edit_on_github_path_prefix
show_url = get_github_url(app, 'blob', path_prefix + '/' + path)
edit_url = get_github_url(app, 'edit', path_prefix + '/' + path)
context['show_on_github_url'] = show_url
context['edit_on_github_url'] = edit_url
def setup(app):
app.add_config_value('edit_on_github_project', '', True)
app.add_config_value('edit_on_github_branch', 'master', True)
app.add_config_value('edit_on_github_path_prefix', '', True)
app.connect('html-page-context', html_page_context)

View File

@@ -1,13 +1,11 @@
{% extends "!layout.html" %}
{% block rootrellink %}
<li><a href="{{ pathto('index') }}">Home</a>|&nbsp;</li>
<li><a href="{{ pathto('search') }}">Search</a>|&nbsp;</li>
<li><a href="{{ pathto('examples/examples') }}">Examples</a>|&nbsp;</li>
<li><a href="{{ pathto('citation') }}">Citation</a>|&nbsp;</li>
<li><a href="{{ pathto('coolprop/examples/examples') }}">Examples</a>|&nbsp;</li>
<li><a href="{{ pathto('coolprop/citation') }}">Citation</a>|&nbsp;</li>
<li><a href="{{ pathto('_static/doxygen/html/index') }}">Code</a>|&nbsp;</li>
<li><a href="{{ pathto('HowGetIt') }}">Downloads!</a>|&nbsp;</li>
<li><a href="{{ pathto('contents') }}">Documentation</a> &raquo;</li>
<li><a href="{{ pathto('coolprop/wrappers/wrappers') }}">Downloads</a></li>
{% endblock %}

View File

@@ -0,0 +1,15 @@
{%- if show_source and has_source and sourcename %}
<h3>{{ _('This Page') }}</h3>
<ul class="this-page-menu">
<li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
rel="nofollow">{{ _('Show Source') }}</a></li>
{%- if show_on_github_url %}
<li><a href="{{ show_on_github_url }}"
rel="nofollow">{{ _('Show on GitHub') }}</a></li>
{%- endif %}
{%- if edit_on_github_url %}
<li><a href="{{ edit_on_github_url }}"
rel="nofollow">{{ _('Edit on GitHub') }}</a></li>
{%- endif %}
</ul>
{%- endif %}

View File

@@ -1,5 +1,5 @@
CoolProp
========
CoolProp API
============
.. toctree::
:maxdepth: 4

View File

@@ -13,11 +13,17 @@
# serve to show the default.
import sys, os
sys.path.insert(0, os.path.abspath('_ext'))
try:
import sphinxcontrib.doxylink
except ImportError:
print('Unable to import sphinxcontrib.doxylink; try to run "pip install sphinxcontrib-doxylink"')
# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
sys.path.append(os.path.abspath('sphinxext'))
#~ # If your extensions are in another directory, add it here. If the directory
#~ # is relative to the documentation root, use os.path.abspath to make it
#~ # absolute, like shown here.
#~ sys.path.append(os.path.abspath('sphinxext'))
doxylink = {
'cpapi' : ('../CoolPropDoxyLink.tag', 'http://www.coolprop.dreamhosters.com/doc/CoolProp5/')
@@ -27,16 +33,16 @@ doxylink = {
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [#'matplotlib.sphinxext.only_directives',
'matplotlib.sphinxext.plot_directive',
'matplotlib.sphinxext.ipython_directive',
extensions = ['IPython.sphinxext.ipython_console_highlighting',
'IPython.sphinxext.ipython_directive',
'sphinx.ext.intersphinx',
'sphinx.ext.autodoc',
'sphinx.ext.mathjax',
'sphinx.ext.extlinks',
'ipython_console_highlighting',
'sphinxcontrib.napoleon',
'sphinxcontrib.doxylink',
'matplotlib.sphinxext.plot_directive',
'edit_on_github', # see https://gist.github.com/mgedmin/6052926#file-edit_on_github-pyb
# cloud's extensions
#'cloud_sptheme.ext.autodoc_sections',
@@ -50,8 +56,6 @@ extensions = [#'matplotlib.sphinxext.only_directives',
#'numpydoc',
#'breathe'
]
plot_formats = [('png',80)]
@@ -86,8 +90,7 @@ version = ver.rsplit('.',1)[0]
# The full version, including alpha/beta/rc tags.
release = ver
extlinks = {'sfdownloads': ('http://sourceforge.net/projects/coolprop/files/CoolProp/'+release+'/%s',
'issue ')}
extlinks = {'sfdownloads': ('http://sourceforge.net/projects/coolprop/files/CoolProp/'+release+'/%s','issue ')}
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -135,6 +138,11 @@ autoclass_content = 'both'
# -- Options for HTML output ---------------------------------------------------
try:
import cloud_sptheme as csp
except:
print('unable to import cloud_sptheme as csp; try a "pip install cloud_sptheme"')
# import Cloud
import cloud_sptheme as csp
@@ -155,6 +163,10 @@ html_theme_options = { "roottarget": "index",
"logotarget": "index"
}
edit_on_github_project = 'CoolProp/CoolProp'
edit_on_github_branch = 'master'
edit_on_github_path_prefix = 'Web'
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
## html_theme = 'sphinxdoc'

View File

@@ -6,17 +6,10 @@ Welcome to CoolProp
CoolProp is an open-source database of fluid and humid air properties, formulated based on the most accurate formulations in open literature. It has been validated against the most accurate data available from the relevant references.
:cpapi:`PropsSI`
.. toctree::
:maxdepth: 2
HowGetIt.rst
examples/examples.rst
EOS.rst
citation.rst
TTSE.rst
FluidInformation.rst
HumidAir.rst
changelog.rst
apidoc/modules.rst
fluid_properties/contents.rst
coolprop/contents.rst
apidoc/modules.rst

View File

@@ -1,3 +1,6 @@
*********************
Citation for CoolProp
*********************
Overview
========
@@ -5,7 +8,7 @@ A paper covering CoolProp has been published in the journal Industrial & Enginee
As CoolProp is free to all users, we simply ask that if you use CoolProp in your academic work that you make a reference to CoolProp.
If you use CoolProp, please cite the article (open-access) cited below, and the domain www.coolprop.org
If you use CoolProp, please cite the article (open-access) cited below, and the domain `www.coolprop.org <http://www.coolprop.org>`_
BibTeX
======
@@ -24,8 +27,4 @@ BibTeX citation::
URL = {http://pubs.acs.org/doi/abs/10.1021/ie4033999},
eprint = {http://pubs.acs.org/doi/pdf/10.1021/ie4033999}
}
See Also
========
www.coolprop.org
}

16
Web/coolprop/contents.rst Normal file
View File

@@ -0,0 +1,16 @@
********
CoolProp
********
This section includes information about the CoolProp software, listings of inputs, etc.
.. toctree::
:maxdepth: 3
wrappers/wrappers.rst
citation.rst
TTSE.rst
FluidInformation.rst
changelog.rst
apidoc/modules.rst
examples/examples.rst

View File

@@ -17,8 +17,6 @@ propane (R290):
from CoolProp.Plots import PropsPlot
ts_plot = PropsPlot('R290', 'Ts')
ts_plot.show()
The following example can be used to create a Pressure-Enthalpy plot for R410A:
@@ -28,7 +26,6 @@ The following example can be used to create a Pressure-Enthalpy plot for R410A:
from CoolProp.Plots import PropsPlot
ph_plot = PropsPlot('R410A', 'Ph')
ph_plot.show()
The available plots are:
@@ -58,7 +55,6 @@ properties for n-Pentane. Note the different ways to invoke the
ts_plot.draw_isolines('P', [100, 2000], num=5)
ts_plot.draw_isolines('D', [2, 600], num=7)
ts_plot.set_axis_limits([-2, 1.5, 200, 500])
ts_plot.show()
Some of the commonly used `Matplotlib <http://www.matplotlib.org>`_ functions,
such as :func:`title`, :func:`xlabel` and :func:`ylabel` have been wrapped in
@@ -75,7 +71,6 @@ graphs a little simpler, for example:
ts_plot.xlabel(r's $[{kJ}/{kg K}]$')
ts_plot.ylabel(r'T $[K]$')
ts_plot.grid()
ts_plot.show()
The following two examples show how the :class:`matplotlib.pyplot` functions
and :class:`matplotlib.pyplot.axes` functions can also be used along side
@@ -91,7 +86,6 @@ the :py:class:`CoolProp.Plots.Plots.PropsPlot` class
ax.set_yscale('log')
ax.text(400, 5500, 'Saturated Liquid', fontsize=15, rotation=40)
ax.text(2700, 3500, 'Saturated Vapour', fontsize=15, rotation=-100)
ph_plot.show()
.. plot::
:include-source:
@@ -109,5 +103,3 @@ the :py:class:`CoolProp.Plots.Plots.PropsPlot` class
props_plot.title(gtype)
props_plot._draw_graph()
pyplot.tight_layout()
pyplot.show()

View File

@@ -0,0 +1,58 @@
Examples
========
This page serves as a teaser of the functionality of CoolProp. These examples are written in the Python programming language. For more information see:
- :ref:`Pure and Pseudo-Pure fluid properties <Fluid-Properties>`
- :ref:`Mixture properties <mixtures>`
- :ref:`Wrapper-specific code examples <wrappers>`
Sample Props Code
-------------------
To use the Props function, import it and do some calls, do something like this
.. ipython::
# Import the things you need
In [1]: from CoolProp.CoolProp import PropsSI
# Print the currently used version of coolprop
In [1]: import CoolProp; print(CoolProp.__version__)
# Density of carbon dioxide at 100 bar and 25C
In [2]: PropsSI('D', 'T', 298.15, 'P', 100e5, 'CO2')
# Saturated vapor enthalpy [J/kg] of R134a at 25C
In [2]: PropsSI('H', 'T', 298.15, 'Q', 1, 'R134a')
Or go to the :ref:`Fluid-Properties` documentation.
All the possible input and output parameters are listed in the
:py:func:`CoolProp.CoolProp.Props` documentation
Sample HAProps Code
-------------------
To use the HAProps function, import it and do some calls, do something like this
.. ipython::
# import the things you need
In [1]: from CoolProp.HumidAirProp import HAProps, HAProps_Aux
# Enthalpy (kJ per kg dry air) as a function of temperature, pressure,
# and relative humidity at STP
In [2]: h = HAProps('H','T',298.15,'P',101.325,'R',0.5); print h
# Temperature of saturated air at the previous enthalpy
In [2]: T = HAProps('T','P',101.325,'H',h,'R',1.0); print T
# Temperature of saturated air - order of inputs doesn't matter
In [2]: T = HAProps('T','H',h,'R',1.0,'P',101.325); print T
Or go to the :ref:`Humid-Air` documentation.
Plotting
--------
.. toctree::
:maxdepth: 1
Python/plotting.rst

View File

@@ -0,0 +1,52 @@
.. _Csharp:
**********
C# Wrapper
**********
Pre-compiled Binaries
=====================
Pre-compiled binaries can be downloaded from XXXXXXXXXXXXXX
User-Compiled Binaries
======================
Common Requirements
-------------------
Compilation of the C# wrapper requires a few :ref:`common wrapper pre-requisites <wrapper_common_prereqs>`
Octave Requirements
-------------------
* SWIG
* C#
Linux
-----
For ubuntu and friends, you will need to install Mono C# as well as the compiler (and other dependencies) using::
sudo apt-get install swig mono-mcs mono-runtime
Windows
-------
For Windows, download the Visual Studio 2010 version of C# (other versions should probably be fine too)
Compile
-------
Once mono c# is installed, you can run the builder and tests using::
# Check out the sources for CoolProp
git clone https://github.com/CoolProp/CoolProp
# Move into the folder you just created
cd CoolProp
# Make a build folder
mkdir -p build/Csharp
# Move into that folder
cd build/Csharp
# Build the makefile using CMake
cmake ../.. -DCOOLPROP_CSHARP_MODULE=ON -DBUILD_TESTING=ON
# Make the C# files (by default files will be generated in folder install_root/Csharp relative to CMakeLists.txt file)
make install
# Run the integration tests
ctest --extra-verbose

View File

@@ -0,0 +1,90 @@
.. _Octave:
**************
Octave Wrapper
**************
Pre-compiled Binaries
=====================
Pre-compiled binaries can be downloaded from XXXXXXXXXXXXXX
User-Compiled Binaries
======================
Common Requirements
-------------------
Compilation of the Octave wrapper requires a few :ref:`common wrapper pre-requisites <wrapper_common_prereqs>`
Octave Requirements
-------------------
* SWIG
* Octave (and development headers)
Linux
-----
For ubuntu and friends, you can install build dependencies using::
sudo apt-get install swig octave liboctave-dev
OSX
---
For OSX, your best best is a binary installer (see http://wiki.octave.org/Octave_for_MacOS_X), alternatively, you can install from Homebrew, though as of July 6, 2014, this functionality was broken in OSX 10.9. If you use the installer, you might want to add the octave binary folder onto the path. To do so, add to the file .profile (or create it) in your home directory::
export PATH="/usr/local/octave/3.8.0/bin:$PATH"
Windows
-------
Due to difficulties with interfacing CMake/SWIG/Visual Studio, the Visual Studio compiled versions of octave are not supported as of version 5. The only windows port of Octave that is supported is the MinGW compiled version.
Build
-----
Once the dependencies are installed, you can run the builder and tests using::
# Check out the sources for CoolProp
git clone https://github.com/CoolProp/CoolProp
# Move into the folder you just created
cd CoolProp
# Make a build folder
mkdir -p build/Octave
# Move into that folder
cd build/Octave
# Build the makefile using CMake
cmake ../.. -DCOOLPROP_OCTAVE_MODULE=ON -DBUILD_TESTING=ON
# Make the OCT files (by default files will be generated in folder install_root/Octave relative to CMakeLists.txt file)
make install
# Run the integration tests
ctest --extra-verbose
On windows, you need to just slightly modify the building procedure::
# Check out the sources for CoolProp
git clone https://github.com/CoolProp/CoolProp
# Move into the folder you just created
cd CoolProp
# Make a build folder
mkdir build/Octave
# Move into that folder
cd build/Octave
# Build the makefile using CMake
cmake ../.. -G "MinGW Makefiles" -DCOOLPROP_OCTAVE_MODULE=ON -DBUILD_TESTING=ON
# Make the OCT files (by default files will be generated in folder install_root/Octave relative to CMakeLists.txt file)
make install
# Run the integration tests
ctest --extra-verbose
This building process on windows requires that make and the ``bin`` folder of Octave are on the ``PATH``. The MinGW version of Octave conveniently also includes the MinGW C++ compiler used to build it, look inside the distribution.
Usage
=====
On Linux systems you can put generated .oct file in
``/usr/share/octave/?octave.version.number?/m`` folder. You will need superuser
privileges to do this.
If you place .oct file somewhere outside octave path, you have to use
"addpath" function at begining of your code.
Example: adding the folder that contains CoolProp.oct file to the Octave path::
addpath('/home/?user_name?/Some_folder/CoolProp')

View File

@@ -0,0 +1,80 @@
.. _wrappers:
******************
Available Wrappers
******************
CoolProp at its core is a C++ library, but it can be of interest to use this code base from other programming environments. For that reason, wrappers have been constructed for most of the programming languages of technical interest to allow users to seamlessly interface CoolProp and existing codebases.
Downloads and instructions for each wrapper are included in the page for the wrapper given in the table below.
Superpacks are available at XXXXXXX which include all the code for a given operating system.
======================= =========================== =======================================
Language Operating Systems Notes
======================= =========================== =======================================
:ref:`Octave <Octave>` linux, OSX, win Wrapper is SWIG based
:ref:`C# <Csharp>` linux, OSX, win Wrapper is SWIG based
Java linux, OSX, win Wrapper is SWIG based
Scilab linux, OSX, win Wrapper is SWIG based (experimental)
MATLAB linux, OSX, win Wrapper is SWIG based (VERY experimental)
Python linux, OSX, win
Modelica linux, OSX, win
Javascript linux, OSX, win Also works in all internet browsers
Maple
Mathematica
FORTRAN linux, OSX, win
EES windows only
Microsoft Excel windows only
======================= =========================== =======================================
.. _wrapper_common_prereqs:
Common Wrapper Prerequisites
============================
On all platforms for which CoolProp is supported, the compilation of one of the wrappers requires a few common prerequisites, described here. They are:
* git (to interface with the CoolProp repository at https://github.com/CoolProp/CoolProp)
* CMake (platform-independent software to generate makefiles)
* C++ compiler (see below)
Windows
-------
On Windows, download the newest binary installer for CMake from `CMake downloads <http://www.cmake.org/cmake/resources/software.html>`_. Run the installer. Check that at the command prompt you can do::
C:\Users\XXXX>cmake -version
cmake version 2.8.12.2
For git, your best best is the installer from http://msysgit.github.io/. Check that at the command prompt you can do something like::
C:\Users\XXXX>git --version
git version 1.9.4.msysgit.0
For the C++ compiler, the options are a bit more complicated. There are multiple (binary incompatible) versions of Visual Studio, as well as G++ ports for windows (MinGW). Unless you are compiling the python wrappers, you can compile with MinGW, so you should obtain the `MinGW installer <http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download>`_ and run it. You should install all the packages available, and you must install to a path without spaces. ``C:\MinGW`` is recommended as an installation path.
If you are compiling for Python 2.7, you can install Visual Studio 2008 Express from `VS2008Express installer <http://go.microsoft.com/?linkid=7729279>`_.
If you are compiling for Python 3.x, you can install Visual Studio 2010 Express from `VS2010Express installer <http://www.visualstudio.com/en-us/downloads#d-2010-express>`_.
All three compilers should co-exist happily on the path, so you should be fine installing all three, but they are rather sizeable installs.
Linux
-----
On debian based linux distributions (ubuntu, etc.), you can simply do::
sudo apt-get install cmake git g++
although ``git`` is probably already packaged with your operating system; ``g++`` probably isn't
OSX
---
OSX should come with a c++ compiler (clang), for git and cmake your best bet is `Homebrew <http://brew.sh/>`_. With Homebrew installed, you can just do::
sudo brew install cmake git
.. toctree::
:hidden:
Octave/index.rst
Csharp/index.rst

View File

@@ -1,71 +0,0 @@
Examples
========
The following examples are written in Python to demonstrate some of the
functionalities of CoolProp. Similar calling conventions are used in the
wrappers for other programming languages, as can be seen in the
"other languages" section below:
Other Languages
---------------
.. toctree::
:maxdepth: 1
C++/example.rst
MATLAB/example.rst
Octave/example.rst
CSharp/example.rst
Java/example.rst
Python/example.rst
Sample Props Code
-------------------
To use the Props function, import it and do some calls, do something like this
.. ipython::
#import the things you need
In [1]: from CoolProp.CoolProp import Props
# print the currently used version of coolprop
In [1]: import CoolProp; print(CoolProp.__version__)
#Density of carbon dioxide (R744) at 100 bar and 25C
In [2]: Props('D','T',298.15,'P',10000,'R744')
#Saturated vapor enthalpy [kJ/kg] of R134a at STP
In [2]: Props('H','T',298.15,'Q',1,'R134a')
Or go to the :ref:`Fluid-Properties` documentation.
All the possible input and output parameters are listed in the
:py:func:`CoolProp.CoolProp.Props` documentation
Sample HAProps Code
-------------------
To use the HAProps function, import it and do some calls, do something like this
.. ipython::
#import the things you need
In [1]: from CoolProp.HumidAirProp import HAProps, HAProps_Aux
#Enthalpy (kJ per kg dry air) as a function of temperature, pressure,
# and relative humidity at STP
In [2]: h=HAProps('H','T',298.15,'P',101.325,'R',0.5); print h
#Temperature of saturated air at the previous enthalpy
In [2]: T=HAProps('T','P',101.325,'H',h,'R',1.0); print T
#Temperature of saturated air - order of inputs doesn't matter
In [2]: T=HAProps('T','H',h,'R',1.0,'P',101.325); print T
Or go to the :ref:`Humid-Air` documentation.
Plotting
--------
.. toctree::
:maxdepth: 1
Python/plotting.rst

View File

@@ -0,0 +1,15 @@
.. _mixtures:
********
Mixtures
********
Mixtures docs will go here when they are written.
The treatment of mixtures in CoolProp as of v5 is quite rudimentary, though it will be improved in the very near future.
The only types of inputs that are allowed for mixtures right now are
- Pressure/quality
- Temperature/quality
- Temperature/pressure

View File

@@ -1,45 +1,7 @@
.. _Fluid-Properties:
Fluid Properties
================
.. _Props_Sample:
Sample Code
-----------
.. ipython::
In [1]: import CoolProp as CP
In [1]: print CP.__version__
In [1]: print CP.__gitrevision__
#Import the things you need
In [1]: from CoolProp.CoolProp import Props
In [1]: import timeit
#Specific heat (kJ/kg/K) of 20% ethylene glycol as a function of T
In [2]: Props('C','T',298.15,'P',101.325,'EG-20%')
#Density of Air at standard atmosphere in kg/m^3
In [2]: Props('D','T',298.15,'P',101.325,'Air')
#Saturation temperature of Water at 1 atm
In [2]: Props('T','P',101.325,'Q',0,'Water')
#Saturated vapor density of R134a at 0C
In [2]: Props('H','T',273.15,'Q',1,'R134a')
#Using properties from REFPROP to get R410A density
In [2]: Props('D','T',300,'P',100,'REFPROP-MIX:R32[0.697615]&R125[0.302385]')
#Check that the same as using pseudo-pure
In [2]: Props('D','T',300,'P',100,'R410A')
The documentation of the :mod:`CoolProp.CoolProp` module, or the :mod:`CoolProp.State` module are also available.
Pure and Pseudo-Pure fluid properties
=====================================
Introduction
------------
@@ -548,3 +510,42 @@ which yields the terms in the following table (from Span, 2000)
.. warning::
If the terms in the EOS are in terms of :math:`T` and :math:`\rho` rather than :math:`\tau` and :math:`\delta`, make sure to multiply appropriately by the critical densities in the exponential term. For instance in Polt paper, the first constant should be :math:`n_{14}\rho_c^2/(2\gamma)+n_{17}\rho_c^4/(2\gamma^2)/T_c^3` Be careful!
.. _Props_Sample:
Sample Code
-----------
.. ipython::
In [1]: import CoolProp as CP
In [1]: print CP.__version__
In [1]: print CP.__gitrevision__
#Import the things you need
In [1]: from CoolProp.CoolProp import Props
In [1]: import timeit
#Specific heat (kJ/kg/K) of 20% ethylene glycol as a function of T
In [2]: Props('C','T',298.15,'P',101.325,'EG-20%')
#Density of Air at standard atmosphere in kg/m^3
In [2]: Props('D','T',298.15,'P',101.325,'Air')
#Saturation temperature of Water at 1 atm
In [2]: Props('T','P',101.325,'Q',0,'Water')
#Saturated vapor density of R134a at 0C
In [2]: Props('H','T',273.15,'Q',1,'R134a')
#Using properties from REFPROP to get R410A density
In [2]: Props('D','T',300,'P',100,'REFPROP-MIX:R32[0.697615]&R125[0.302385]')
#Check that the same as using pseudo-pure
In [2]: Props('D','T',300,'P',100,'R410A')
The documentation of the :mod:`CoolProp.CoolProp` module, or the :mod:`CoolProp.State` module are also available.

View File

@@ -0,0 +1,11 @@
****************
Fluid Properties
****************
.. toctree::
:maxdepth: 3
PurePseudoPure
Mixtures
HumidAir
more_reading

View File

@@ -0,0 +1,362 @@
*************************
Advanced Fluid Properties
*************************
Use of Extended Corresponding States for Transport Properties
-------------------------------------------------------------
For a limited selection of fluids, correlations are provided for the viscosity and the thermal conductivity. But for many fluids, no correlations are available, and therefore other methods must be employed. The extended corresponding states is a method of estimating the transport properties of a fluid by analogy with the transport properties of a fluid that are well defined.
Implementing the ECS method is quite a challenge, but CoolProp is one of the only fluid property databases that properly implements it. And the onlyopen-source package that does. A multi-step method is required, which is hopefully clearly laid out here.
To begin with, the reference fluid must be selected that the fluid of interest will be compared with. Ideally the shape of the molecules should be similar, but in practice, most fluids use R134a as the reference fluid since its thermodynamic and transport properties are well quantified with reference-quality correlations.
Once the reference fluid has been selected, the conformal state of the reference fluid must be determined. The conformal state is the state at which the transport properties of the reference fluid and the fluid of interest are (in theory) the same. In practice, at low densities the shape factors are assumed to be unity, and the conformal temperature and molar density are obtained from
.. math::
T_0 = T\frac{T_0^{c}}{T_j^c}
.. math::
\overline{\rho_0} = \overline{\rho}\frac{\overline{\rho_0}^c}{\overline{\rho_j}^c}
Exact solution for the conformal temperature
If you have Helmholtz EOS for both the fluid and the reference fluid, you need to find a conformal temperature for the reference fluid that will yield the same compressibility factor and the residual Helmholtz energy
.. math::
Z_j(T_j,\rho_j) = Z_0(T_0,\rho_0)
.. math::
\alpha_j^r(T_j,\rho_j) = \alpha_0^r(T_0,\rho_0)
where "j" is for the fluid of interest, and the subscript "0" is for the reference fluid. The left side of each equation is already known from the equation of state. Literature suggests that solving for :math:`T_0` and :math:`\rho_0` directly is quite challenging. See McLinden 2000 or Klein 1997.
Alternatively, if the shape factors :math:`\theta` and :math:`\phi` are known, either from correlation or otherwise, the conformal temperature and density can be calculated directly.
.. math::
T_0 = \frac{T}{f} = T\frac{T_0^{c}}{T_j^c\theta(T_j,\rho_j)}
.. math::
\rho_0 = \rho h = \rho\frac{\rho_0^c}{\rho_j^c}\phi(T_j,\rho_j)
Conversion from ideal gas term to Helmholtz energy term
-------------------------------------------------------
Much of the time the coefficients for the ideal-gas part of the Helmholtz energy are given directly, but sometimes only the gas-specific heat is provided. Therefore you need to be able to go from specific heat to ideal-gas Helmholtz Energy. The ideal-gas Helmholtz energy is given by Equation 23 from Lemmon, 2004, Equations of State for Mixtures of R-32, R-125, R-134a, R-143a, and R-152a, J. Phys. Chem. Ref. Data, Vol. 33, No. 2, 2004 or
.. math::
a_0 = -RT+RT\ln\frac{\rho T}{\rho_0T_0}+h_0^0-Ts_0^0+\int_{T_0}^T c_p^0(T)dT-T\int_{T_0}^T \frac{c_p^0(T)}{T}dT
non-dimensionalizing
.. math::
\alpha_0 =\frac{a_0}{RT}= -1+\ln\frac{\rho T}{\rho_0T_0}+\frac{h_0^0}{RT}-\frac{s_0^0}{R}+\frac{1}{RT}\int_{T_0}^T c_p^0(T)dT-\frac{1}{R}\int_{T_0}^T \frac{c_p^0(T)}{T}dT
Now we might want to do a change of variable in the integrals. If so, do a u-substitution in the integrals.
.. math::
T=\frac{T_c}{\tau}
where
.. math::
dT=-\frac{T_c}{\tau^2}d\tau
.. math::
\alpha_0 = -1+\ln\frac{\rho T}{\rho_0T_0}+\frac{h_0^0}{RT}-\frac{s_0^0}{R}+\frac{1}{RT}\int_{\tau_0}^{\tau} c_p^0(T)(-\frac{T_c}{\tau^2}d\tau)-\frac{1}{R}\int_{\tau_0}^{\tau} \frac{c_p^0(\tau)}{T}(-\frac{T_c}{\tau^2}d\tau)
Simplifying and factoring the :math:`\tau` term yields
.. math::
\alpha_0 = -1+\ln\frac{\rho T}{\rho_0T_0}+\frac{h_0^0}{RT}-\frac{s_0^0}{R}-\frac{\tau}{R}\int_{\tau_0}^{\tau} \frac{c_p^0(\tau)}{\tau^2}d\tau+\frac{1}{R}\int_{\tau_0}^{\tau} \frac{c_p^0(\tau)}{\tau}d\tau
which finally yields the solution as of Equation 3 from Lemmon, 2003 (and others)
The specific-heat contribution can then be taken as a sum of the contributions
for a term of the form
.. math::
\frac{c_p^0}{R}=\frac{(B/T)^2\exp(B/T)}{(\exp(B/T)-1)^2}
the contribution is found from
.. math::
\frac{1}{T}\int_{T_0}^T \frac{(B/T)^2\exp(B/T)}{(\exp(B/T)-1)^2} dT-\int_{T_0}^T \frac{(B/T)^2\exp(B/T)}{(\exp(B/T)-1)^2}\frac{1}{T}dT
.. math::
\frac{1}{T} \left[ \frac{B}{\exp(B/T)-1 }\right|_{T_0}^T - \left[ \frac{B}{T}\left(\frac{1}{\exp(B/T)-1}+1\right) - \log[\exp(B/T)-1] \right|_{T_0}^T dT
Factor out a B, First two terms cancel, leaving
.. math::
- \left[ \frac{B}{T} - \log[\exp(B/T)-1] \right|_{T_0}^T dT
.. math::
\left[\log[\exp(B/T)-1] - \frac{B}{T} \right|_{T_0}^T dT
.. math::
\log[\exp(B/T)-1] - \frac{B}{T} -(\log[\exp(B/T_0)-1] - \frac{B}{T_0})
or in terms of :math:`\tau`
.. math::
\log[\exp(B\tau/Tc)-1] - \frac{B\tau}{Tc} -(\log[\exp(B\tau_0/T_c)-1] - \frac{B\tau_0}{T_c})
for a term of the form
.. math::
\frac{c_p^0}{R}=c
the contribution is found from
.. math::
\frac{1}{T}\int_{T_0}^T c dT-\int_{T_0}^T \frac{c}{T}dT
.. math::
\frac{c}{T}(T-T_0)-c\log(T/T_0)
or in terms of :math:`\tau`
.. math::
c-\frac{cT_0\tau}{T_c}+c\log(\tau/\tau_0)
for a term of the form
.. math::
\frac{c_p^0}{R}=cT^t, t \neq 0
the contribution is found from
.. math::
\frac{1}{T}\int_{T_0}^T c T^t dT-\int_{T_0}^T \frac{c T^t}{T}dT
.. math::
\frac{c}{T}\left(\frac{T^{t+1}}{t+1}-\frac{T_0^{t+1}}{t+1}\right)-c\left(\frac{T^{t}}{t}-\frac{T_0^{t}}{t}\right)
.. math::
cT^{t}\left(\frac{1}{t+1}-\frac{1}{t}\right)-c\frac{T_0^{t+1}}{T(t+1)}+c\frac{T_0^t}{t}
or in terms of :math:`\tau`
.. math::
cT_c^{t}\tau^{-t}\left(\frac{1}{t+1}-\frac{1}{t}\right)-c\frac{T_0^{t+1}\tau}{T_c(t+1)}+c\frac{T_0^t}{t}
..
.. math::
\int\limits_{{\tau _0}}^\tau {\left[ {aT_c^t{\tau ^{ - t - 1}}} \right]d\tau } - \tau \int\limits_{{\tau _0}}^\tau {\left[ {aT_c^t{\tau ^{ - t - 2}}} \right]d\tau } \\
.. math::
aT_c^t\left( {\int\limits_{{\tau _0}}^\tau {{\tau ^{ - t - 1}}d\tau } - \tau \int\limits_{{\tau _0}}^\tau {{\tau ^{ - t - 2}}d\tau } } \right)\\
if :math:`t=0`
.. math::
a\left( {\int\limits_{{\tau _0}}^\tau {\frac{1}{\tau }d\tau } - \tau \int\limits_{{\tau _0}}^\tau {{\tau ^{ - 2}}d\tau } } \right)
.. math::
a\left( {\left[ {\ln \left( \tau \right)} \right]_{{\tau _0}}^\tau - \tau \left[ {\frac{{{\tau ^{ - 1}}}}{{ - 1}}} \right]_{{\tau _0}}^\tau } \right)
.. math::
a\left( \ln \left( \tau \right) - \ln \left( {{\tau _0}} \right) \right)
if :math:`t\neq0`:
.. math::
aT_c^t\left( {\left[ {\frac{{{\tau ^{ - t}}}}{{ - t}}} \right]_{{\tau _0}}^\tau - \tau \left[ {\frac{{{\tau ^{ - t - 1}}}}{{ - t - 1}}} \right]_{{\tau _0}}^\tau } \right)\\
.. math::
aT_c^t\left( {\frac{{{\tau ^{ - t}}}}{{ - t}} - \frac{{\tau _0^{ - t}}}{{ - t}} - \tau \left[ {\frac{{{\tau ^{ - t - 1}}}}{{ - t - 1}} - \frac{{\tau _0^{ - t - 1}}}{{ - t - 1}}} \right]} \right)\\
.. math::
- aT_c^t\left( {\frac{{{\tau ^{ - t}}}}{t} - \frac{{\tau _0^{ - t}}}{t} - \left[ {\frac{{{\tau ^{ - t}}}}{{t + 1}} - \frac{{\tau _0^{ - t}}}{{t + 1}}} \right]} \right)
.. math::
- aT_c^t\frac{{{\tau ^{ - t}}}}{t} + aT_c^t\frac{{{\tau ^{ - t}}}}{{t + 1}} + aT_c^t\frac{{\tau _0^{ - t}}}{t} - aT_c^t\frac{{\tau _0^{ - t}}}{{t + 1}}
.. math::
- aT_c^t\frac{{{\tau ^{ - t}}}}{t} + aT_c^t\frac{{{\tau ^{ - t}}}}{{t + 1}} + aT_c^t\tau _0^{ - t}\left[ {\frac{1}{t} - \frac{1}{{t + 1}}} \right]
.. math::
aT_c^t{\tau ^{ - t}}\left[ {\frac{1}{{t + 1}} - \frac{1}{t}} \right] + aT_c^t\tau _0^{ - t}\left[ {\frac{1}{t} - \frac{1}{{t + 1}}} \right]\\
if :math:`t = 1`
.. math::
- \frac{{a{T_c}{\tau ^{ - 1}}}}{2} + \frac{{a{T_c}\tau _0^{ - 1}}}{2}
These terms can be summarized by the following table:
.. math::
\begin{array}{*{20}{c}}
{\dfrac{{c_p^0}}{R}{\rm{ Term}}}&{{\alpha ^0}{\rm{ Term}}}&{{\rm{Class Name}}}&{}&{}&{}&{}&{}\\
{{a_k}\dfrac{{{{\left( {{b_k}/T} \right)}^2}\exp \left( {{b_k}/T} \right)}}{{{{\left( {\exp \left( {{b_k}/T} \right) - 1} \right)}^2}}}}&{{a_k}\ln \left[ {1 - \exp \left( {\frac{{ - {b_k}\tau }}{{{T_c}}}} \right)} \right]}&{{\rm{phi0\_Planck\_Einstein}}(a,b/Tc,[iStart,iEnd])}&{}&{}&{}&{}&{}\\
{ac\frac{{{{\left( {b/T} \right)}^2}\exp \left( { - b/T} \right)}}{{{{\left( {c\exp \left( { - b/T} \right) + 1} \right)}^2}}}}&{a\ln \left[ {c + \exp \left( {\frac{{b\tau }}{{{T_c}}}} \right)} \right]}&{{\rm{phi0\_Planck\_Einstein2}}(a,b/Tc,c)}&{}&{}&{}&{}&{}\\
{yuck}&{{a_k}{\tau ^{{b_k}}}}&{{\rm{phi0\_power}}\left( {a,b,[iStart,iEnd]} \right)}&{}&{}&{}&{}&{}\\
a&{a - a\frac{\tau }{{{\tau _0}}} + a\ln \left( {\frac{\tau }{{{\tau _0}}}} \right)}&{{\rm{phi0\_cp0\_constant}}(a,Tc,T0)}&{}&{}&{}&{}&{}\\
{{a_1} + {a_2}{{\left( {\frac{{{a_3}/T}}{{\sinh \left( {{a_3}/T} \right)}}} \right)}^2} + {a_4}{{\left( {\frac{{{a_5}/T}}{{\cosh \left( {{a_5}/T} \right)}}} \right)}^2}}&{yuck}&{{\rm{phi0\_cp0\_AlyLee}}(a,Tc,T0,R)}&{}&{}&{}&{}&{}\\
{{\rm{n/a}}}&{\log (\delta ) + {a_1} + {a_2}\tau }&{{\rm{phi0\_lead(}}a1,{\rm{ }}a2{\rm{)}}}&{}&{}&{}&{}&{}\\
{{\rm{n/a}}}&{a\log \tau }&{{\rm{phi0\_logtau}}(a)}&{}&{}&{}&{}&{}
\end{array}
If the reference enthalpy is known, you can determine the constants from
.. math::
\frac{h_0}{RT}=\tau \left[\left(\frac{\partial \alpha^0}{\partial \tau}\right)_{\delta}+ \left(\frac{\partial \alpha^r}{\partial \tau}\right)_{\delta} \right] +\delta\left(\frac{\partial \alpha^r}{\partial \delta}\right)_{\tau}+1
.. math::
\left(\frac{\partial \alpha^0}{\partial \tau}\right)_{\delta} = \frac{1}{\tau}\left(\frac{h_0}{RT}-\delta\left(\frac{\partial \alpha^r}{\partial \delta}\right)_{\tau}-1\right)- \left(\frac{\partial \alpha^r}{\partial \tau}\right)_{\delta}
For the specific heat
The two integral terms are
.. math::
- \frac{\tau }{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{{{\tau ^2}}}d\tau } + \frac{1}{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{\tau }d\tau }
First derivative
.. math::
\frac{d}{{d\tau }}\left[ { - \frac{\tau }{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{{{\tau ^2}}}d\tau } + \frac{1}{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{\tau }d\tau } } \right] = - \frac{{c_p^0}}{{\tau R}} - \frac{1}{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{{{\tau ^2}}}d\tau } + \frac{{c_p^0}}{{\tau R}} = - \frac{1}{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{{{\tau ^2}}}d\tau }
Second Derivative
.. math::
\frac{{{d^2}}}{{d{\tau ^2}}}\left[ { - \frac{\tau }{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{{{\tau ^2}}}d\tau } + \frac{1}{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{\tau }d\tau } } \right] = \frac{d}{{d\tau }}\left[ { - \frac{1}{R}\int_{{\tau _0}}^\tau {\frac{{c_p^0}}{{{\tau ^2}}}d\tau } } \right] = - \frac{{c_p^0}}{{{\tau ^2}R}}
Converting Bender and mBWR EOS
------------------------------
If the EOS is of the form
.. math::
\frac{p}{{\rho RT}} = Z\left( {T,\rho } \right) = 1 + \sum\limits_i {{n_i}{T^{{s_i}}}{\rho ^{{r_i}}}} + \sum\limits_i {{n_i}{T^{{s_i}}}{\rho ^{{r_i}}}} \exp \left( { - {\gamma _i}{{\left( {\frac{\rho }{{{\rho _c}}}} \right)}^2}} \right)
To convert to standard power form in CoolProp, use
.. math::
\delta \sum\limits_i {{d_i}{a_i}{\tau ^{{t_i}}}{\delta ^{{d_i} - 1}}} = \sum\limits_i {{n_i}{T^{{s_i}}}{\rho ^{{r_i}}}} = \sum\limits_i {{n_i}{{\left( {\frac{{{T_c}}}{\tau }} \right)}^{{s_i}}}{{\left( {{\rho _c}\delta } \right)}^{{r_i}}}} = \sum\limits_i {{n_i}T_c^{{s_i}}\rho _c^{{r_i}}{\tau ^{ - {s_i}}}{\delta ^{{r_i}}}}
The left-hand-side is the derivative of the residual Helmholtz energy with respect
to delta times the reduced density since
.. math::
\frac{p}{\rho RT}=1+\delta\left(\frac{\partial \alpha^r}{\partial \delta}\right)_{\tau}
where
.. math::
\delta : {d_i} - 1 + 1 = {r_i} \Rightarrow {d_i} = {r_i}
.. math::
\tau : {t_i} = - {s_i}
.. math::
c : {d_i}{a_i} = {n_i}T_c^{{s_i}}\rho _c^{{r_i}}
.. math::
p = \rho RT + \sum\limits_i {{n_i}{T^{{s_i}}}{\rho ^{{r_i}}}} + \sum\limits_i {{n_i}{T^{{s_i}}}{\rho ^{{r_i}}}} \exp \left( { - {\gamma _i}{{\left( {\frac{\rho }{{{\rho _c}}}} \right)}^2}} \right){\rm{ (Eq 3}}{\rm{.28)}}
.. math::
\frac{p}{{\rho RT}} = 1 + \sum\limits_i {\frac{{{n_i}}}{R}{T^{{s_i} - 1}}{\rho ^{{r_i} - 1}}} + \sum\limits_i {\frac{{{n_i}}}{R}{T^{{s_i} - 1}}{\rho ^{{r_i} - 1}}} \exp \left( { - {\gamma _i}{{\left( {\frac{\rho }{{{\rho _c}}}} \right)}^2}} \right)
.. math::
\delta \sum\limits_i {{d_i}{a_i}{\tau ^{{t_i}}}{\delta ^{{d_i} - 1}}} = \sum\limits_i {\frac{{{n_i}}}{R}{{\left( {\frac{{{T_c}}}{\tau }} \right)}^{{s_i} - 1}}{{\left( {{\rho _c}\delta } \right)}^{{r_i} - 1}}} = \sum\limits_i {\frac{{{n_i}}}{R}T_c^{{s_i} - 1}\rho _c^{{r_i} - 1}{\tau ^{ - ({s_i} - 1)}}{\delta ^{{r_i} - 1}}}
.. math::
\delta :1 + {d_i} - 1 = {r_i} - 1
.. math::
\tau :{t_i} = - \left( {s_i - 1} \right)
.. math::
c:{d_i}{a_i} = \frac{{{n_i}}}{R}T_c^{{s_i} - 1}\rho _c^{{r_i} - 1}
In the Bender EOS, for the exponential part you have terms that can be converted to reduced form
.. math::
a_i\delta^{d_i}\tau^{t_i}\exp(-\gamma \delta^2)
which yields the terms in the following table (from Span, 2000)
.. math::
\begin{array}{*{4}{c}|*{4}{c}}
\multicolumn{4}{c}{\mbox{From Bender}} & \multicolumn{4}{c}{\mbox{Power term}}\\
{i}&{d_i}&{t_i}&{\gamma_i}&{n_i}&{d_i}&{t_i}&{\gamma_i}\\\hline
{14}&2&3&\gamma &{{n_{14}}/(2\gamma) + {n_{17}}/(2{\gamma ^2})}&0&3&0\\
{15}&2&4&\gamma &{{n_{15}}/(2\gamma) + {n_{17}}/(2{\gamma ^2})}&0&4&0\\
{16}&2&5&\gamma &{{n_{16}}/(2\gamma) + {n_{17}}/(2{\gamma ^2})}&0&5&0\\
{17}&4&3&\gamma &{ - {n_{14}}/(2\gamma) - {n_{17}}/(2{\gamma ^2})}&0&3&\gamma \\
{18}&4&4&\gamma &{ - {n_{15}}/(2\gamma) - {n_{18}}/(2{\gamma ^2})}&0&4&\gamma \\
{19}&4&5&\gamma &{ - {n_{16}}/(2\gamma) - {n_{19}}/(2{\gamma ^2})}&0&5&\gamma \\
{20}&{}&{}&{}&{ - {n_{17}}/(2{\gamma})}&2&3&\gamma \\
{21}&{}&{}&{}&{ - {n_{18}}/(2{\gamma})}&2&4&\gamma \\
{22}&{}&{}&{}&{ - {n_{19}}/(2{\gamma})}&2&5&\gamma
\end{array}
.. warning::
If the terms in the EOS are in terms of :math:`T` and :math:`\rho` rather than :math:`\tau` and :math:`\delta`, make sure to multiply appropriately by the critical densities in the exponential term. For instance in Polt paper, the first constant should be :math:`n_{14}\rho_c^2/(2\gamma)+n_{17}\rho_c^4/(2\gamma^2)/T_c^3` Be careful!

View File

@@ -1,427 +0,0 @@
"""Attempt to generate templates for module reference with Sphinx
XXX - we exclude extension modules
To include extension modules, first identify them as valid in the
``_uri2path`` method, then handle them in the ``_parse_module`` script.
We get functions and classes by parsing the text of .py files.
Alternatively we could import the modules for discovery, and we'd have
to do that for extension modules. This would involve changing the
``_parse_module`` method to work via import and introspection, and
might involve changing ``discover_modules`` (which determines which
files are modules, and therefore which module URIs will be passed to
``_parse_module``).
NOTE: this is a modified version of a script originally shipped with the
PyMVPA project, which we've adapted for NIPY use. PyMVPA is an MIT-licensed
project."""
# Stdlib imports
import os
import re
# Functions and classes
class ApiDocWriter(object):
''' Class for automatic detection and parsing of API docs
to Sphinx-parsable reST format'''
# only separating first two levels
rst_section_levels = ['*', '=', '-', '~', '^']
def __init__(self,
package_name,
rst_extension='.rst',
package_skip_patterns=None,
module_skip_patterns=None,
):
''' Initialize package for parsing
Parameters
----------
package_name : string
Name of the top-level package. *package_name* must be the
name of an importable package
rst_extension : string, optional
Extension for reST files, default '.rst'
package_skip_patterns : None or sequence of {strings, regexps}
Sequence of strings giving URIs of packages to be excluded
Operates on the package path, starting at (including) the
first dot in the package path, after *package_name* - so,
if *package_name* is ``sphinx``, then ``sphinx.util`` will
result in ``.util`` being passed for earching by these
regexps. If is None, gives default. Default is:
['\.tests$']
module_skip_patterns : None or sequence
Sequence of strings giving URIs of modules to be excluded
Operates on the module name including preceding URI path,
back to the first dot after *package_name*. For example
``sphinx.util.console`` results in the string to search of
``.util.console``
If is None, gives default. Default is:
['\.setup$', '\._']
'''
if package_skip_patterns is None:
package_skip_patterns = ['\\.tests$']
if module_skip_patterns is None:
module_skip_patterns = ['\\.setup$', '\\._']
self.package_name = package_name
self.rst_extension = rst_extension
self.package_skip_patterns = package_skip_patterns
self.module_skip_patterns = module_skip_patterns
def get_package_name(self):
return self._package_name
def set_package_name(self, package_name):
''' Set package_name
>>> docwriter = ApiDocWriter('sphinx')
>>> import sphinx
>>> docwriter.root_path == sphinx.__path__[0]
True
>>> docwriter.package_name = 'docutils'
>>> import docutils
>>> docwriter.root_path == docutils.__path__[0]
True
'''
# It's also possible to imagine caching the module parsing here
self._package_name = package_name
self.root_module = __import__(package_name)
self.root_path = self.root_module.__path__[0]
self.written_modules = None
package_name = property(get_package_name, set_package_name, None,
'get/set package_name')
def _get_object_name(self, line):
''' Get second token in line
>>> docwriter = ApiDocWriter('sphinx')
>>> docwriter._get_object_name(" def func(): ")
'func'
>>> docwriter._get_object_name(" class Klass(object): ")
'Klass'
>>> docwriter._get_object_name(" class Klass: ")
'Klass'
'''
name = line.split()[1].split('(')[0].strip()
# in case we have classes which are not derived from object
# ie. old style classes
return name.rstrip(':')
def _uri2path(self, uri):
''' Convert uri to absolute filepath
Parameters
----------
uri : string
URI of python module to return path for
Returns
-------
path : None or string
Returns None if there is no valid path for this URI
Otherwise returns absolute file system path for URI
Examples
--------
>>> docwriter = ApiDocWriter('sphinx')
>>> import sphinx
>>> modpath = sphinx.__path__[0]
>>> res = docwriter._uri2path('sphinx.builder')
>>> res == os.path.join(modpath, 'builder.py')
True
>>> res = docwriter._uri2path('sphinx')
>>> res == os.path.join(modpath, '__init__.py')
True
>>> docwriter._uri2path('sphinx.does_not_exist')
'''
if uri == self.package_name:
return os.path.join(self.root_path, '__init__.py')
path = uri.replace('.', os.path.sep)
path = path.replace(self.package_name + os.path.sep, '')
path = os.path.join(self.root_path, path)
# XXX maybe check for extensions as well?
if os.path.exists(path + '.py'): # file
path += '.py'
elif os.path.exists(os.path.join(path, '__init__.py')):
path = os.path.join(path, '__init__.py')
else:
return None
return path
def _path2uri(self, dirpath):
''' Convert directory path to uri '''
relpath = dirpath.replace(self.root_path, self.package_name)
if relpath.startswith(os.path.sep):
relpath = relpath[1:]
return relpath.replace(os.path.sep, '.')
def _parse_module(self, uri):
''' Parse module defined in *uri* '''
filename = self._uri2path(uri)
if filename is None:
# nothing that we could handle here.
return ([],[])
f = open(filename, 'rt')
functions, classes = self._parse_lines(f)
f.close()
return functions, classes
def _parse_lines(self, linesource):
''' Parse lines of text for functions and classes '''
functions = []
classes = []
for line in linesource:
if line.startswith('def ') and line.count('('):
# exclude private stuff
name = self._get_object_name(line)
if not name.startswith('_'):
functions.append(name)
elif line.startswith('class '):
# exclude private stuff
name = self._get_object_name(line)
if not name.startswith('_'):
classes.append(name)
else:
pass
functions.sort()
classes.sort()
return functions, classes
def generate_api_doc(self, uri):
'''Make autodoc documentation template string for a module
Parameters
----------
uri : string
python location of module - e.g 'sphinx.builder'
Returns
-------
S : string
Contents of API doc
'''
# get the names of all classes and functions
functions, classes = self._parse_module(uri)
if not len(functions) and not len(classes):
print 'WARNING: Empty -',uri # dbg
return ''
# Make a shorter version of the uri that omits the package name for
# titles
uri_short = re.sub(r'^%s\.' % self.package_name,'',uri)
ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n'
chap_title = uri_short
ad += (chap_title+'\n'+ self.rst_section_levels[1] * len(chap_title)
+ '\n\n')
# Set the chapter title to read 'module' for all modules except for the
# main packages
if '.' in uri:
title = 'Module: :mod:`' + uri_short + '`'
else:
title = ':mod:`' + uri_short + '`'
ad += title + '\n' + self.rst_section_levels[2] * len(title)
if len(classes):
ad += '\nInheritance diagram for ``%s``:\n\n' % uri
ad += '.. inheritance-diagram:: %s \n' % uri
ad += ' :parts: 3\n'
ad += '\n.. automodule:: ' + uri + '\n'
ad += '\n.. currentmodule:: ' + uri + '\n'
multi_class = len(classes) > 1
multi_fx = len(functions) > 1
if multi_class:
ad += '\n' + 'Classes' + '\n' + \
self.rst_section_levels[2] * 7 + '\n'
elif len(classes) and multi_fx:
ad += '\n' + 'Class' + '\n' + \
self.rst_section_levels[2] * 5 + '\n'
for c in classes:
ad += '\n:class:`' + c + '`\n' \
+ self.rst_section_levels[multi_class + 2 ] * \
(len(c)+9) + '\n\n'
ad += '\n.. autoclass:: ' + c + '\n'
# must NOT exclude from index to keep cross-refs working
ad += ' :members:\n' \
' :undoc-members:\n' \
' :show-inheritance:\n' \
' :inherited-members:\n' \
'\n' \
' .. automethod:: __init__\n'
if multi_fx:
ad += '\n' + 'Functions' + '\n' + \
self.rst_section_levels[2] * 9 + '\n\n'
elif len(functions) and multi_class:
ad += '\n' + 'Function' + '\n' + \
self.rst_section_levels[2] * 8 + '\n\n'
for f in functions:
# must NOT exclude from index to keep cross-refs working
ad += '\n.. autofunction:: ' + uri + '.' + f + '\n\n'
return ad
def _survives_exclude(self, matchstr, match_type):
''' Returns True if *matchstr* does not match patterns
``self.package_name`` removed from front of string if present
Examples
--------
>>> dw = ApiDocWriter('sphinx')
>>> dw._survives_exclude('sphinx.okpkg', 'package')
True
>>> dw.package_skip_patterns.append('^\\.badpkg$')
>>> dw._survives_exclude('sphinx.badpkg', 'package')
False
>>> dw._survives_exclude('sphinx.badpkg', 'module')
True
>>> dw._survives_exclude('sphinx.badmod', 'module')
True
>>> dw.module_skip_patterns.append('^\\.badmod$')
>>> dw._survives_exclude('sphinx.badmod', 'module')
False
'''
if match_type == 'module':
patterns = self.module_skip_patterns
elif match_type == 'package':
patterns = self.package_skip_patterns
else:
raise ValueError('Cannot interpret match type "%s"'
% match_type)
# Match to URI without package name
L = len(self.package_name)
if matchstr[:L] == self.package_name:
matchstr = matchstr[L:]
for pat in patterns:
try:
pat.search
except AttributeError:
pat = re.compile(pat)
if pat.search(matchstr):
return False
return True
def discover_modules(self):
''' Return module sequence discovered from ``self.package_name``
Parameters
----------
None
Returns
-------
mods : sequence
Sequence of module names within ``self.package_name``
Examples
--------
>>> dw = ApiDocWriter('sphinx')
>>> mods = dw.discover_modules()
>>> 'sphinx.util' in mods
True
>>> dw.package_skip_patterns.append('\.util$')
>>> 'sphinx.util' in dw.discover_modules()
False
>>>
'''
modules = [self.package_name]
# raw directory parsing
for dirpath, dirnames, filenames in os.walk(self.root_path):
# Check directory names for packages
root_uri = self._path2uri(os.path.join(self.root_path,
dirpath))
for dirname in dirnames[:]: # copy list - we modify inplace
package_uri = '.'.join((root_uri, dirname))
if (self._uri2path(package_uri) and
self._survives_exclude(package_uri, 'package')):
modules.append(package_uri)
else:
dirnames.remove(dirname)
# Check filenames for modules
for filename in filenames:
module_name = filename[:-3]
module_uri = '.'.join((root_uri, module_name))
if (self._uri2path(module_uri) and
self._survives_exclude(module_uri, 'module')):
modules.append(module_uri)
return sorted(modules)
def write_modules_api(self, modules,outdir):
# write the list
written_modules = []
for m in modules:
api_str = self.generate_api_doc(m)
if not api_str:
continue
# write out to file
outfile = os.path.join(outdir,
m + self.rst_extension)
fileobj = open(outfile, 'wt')
fileobj.write(api_str)
fileobj.close()
written_modules.append(m)
self.written_modules = written_modules
def write_api_docs(self, outdir):
"""Generate API reST files.
Parameters
----------
outdir : string
Directory name in which to store files
We create automatic filenames for each module
Returns
-------
None
Notes
-----
Sets self.written_modules to list of written modules
"""
if not os.path.exists(outdir):
os.mkdir(outdir)
# compose list of modules
modules = self.discover_modules()
self.write_modules_api(modules,outdir)
def write_index(self, outdir, froot='gen', relative_to=None):
"""Make a reST API index file from written files
Parameters
----------
path : string
Filename to write index to
outdir : string
Directory to which to write generated index file
froot : string, optional
root (filename without extension) of filename to write to
Defaults to 'gen'. We add ``self.rst_extension``.
relative_to : string
path to which written filenames are relative. This
component of the written file path will be removed from
outdir, in the generated index. Default is None, meaning,
leave path as it is.
"""
if self.written_modules is None:
raise ValueError('No modules written')
# Get full filename path
path = os.path.join(outdir, froot+self.rst_extension)
# Path written into index is relative to rootpath
if relative_to is not None:
relpath = outdir.replace(relative_to + os.path.sep, '')
else:
relpath = outdir
idx = open(path,'wt')
w = idx.write
w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n')
w('.. toctree::\n\n')
for f in self.written_modules:
w(' %s\n' % os.path.join(relpath,f))
idx.close()

View File

@@ -1,497 +0,0 @@
"""Extract reference documentation from the NumPy source tree.
"""
import inspect
import textwrap
import re
import pydoc
from StringIO import StringIO
from warnings import warn
4
class Reader(object):
"""A line-based string reader.
"""
def __init__(self, data):
"""
Parameters
----------
data : str
String with lines separated by '\n'.
"""
if isinstance(data,list):
self._str = data
else:
self._str = data.split('\n') # store string as list of lines
self.reset()
def __getitem__(self, n):
return self._str[n]
def reset(self):
self._l = 0 # current line nr
def read(self):
if not self.eof():
out = self[self._l]
self._l += 1
return out
else:
return ''
def seek_next_non_empty_line(self):
for l in self[self._l:]:
if l.strip():
break
else:
self._l += 1
def eof(self):
return self._l >= len(self._str)
def read_to_condition(self, condition_func):
start = self._l
for line in self[start:]:
if condition_func(line):
return self[start:self._l]
self._l += 1
if self.eof():
return self[start:self._l+1]
return []
def read_to_next_empty_line(self):
self.seek_next_non_empty_line()
def is_empty(line):
return not line.strip()
return self.read_to_condition(is_empty)
def read_to_next_unindented_line(self):
def is_unindented(line):
return (line.strip() and (len(line.lstrip()) == len(line)))
return self.read_to_condition(is_unindented)
def peek(self,n=0):
if self._l + n < len(self._str):
return self[self._l + n]
else:
return ''
def is_empty(self):
return not ''.join(self._str).strip()
class NumpyDocString(object):
def __init__(self,docstring):
docstring = textwrap.dedent(docstring).split('\n')
self._doc = Reader(docstring)
self._parsed_data = {
'Signature': '',
'Summary': [''],
'Extended Summary': [],
'Parameters': [],
'Returns': [],
'Raises': [],
'Warns': [],
'Other Parameters': [],
'Attributes': [],
'Methods': [],
'See Also': [],
'Notes': [],
'Warnings': [],
'References': '',
'Examples': '',
'index': {}
}
self._parse()
def __getitem__(self,key):
return self._parsed_data[key]
def __setitem__(self,key,val):
if not self._parsed_data.has_key(key):
warn("Unknown section %s" % key)
else:
self._parsed_data[key] = val
def _is_at_section(self):
self._doc.seek_next_non_empty_line()
if self._doc.eof():
return False
l1 = self._doc.peek().strip() # e.g. Parameters
if l1.startswith('.. index::'):
return True
l2 = self._doc.peek(1).strip() # ---------- or ==========
return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1))
def _strip(self,doc):
i = 0
j = 0
for i,line in enumerate(doc):
if line.strip(): break
for j,line in enumerate(doc[::-1]):
if line.strip(): break
return doc[i:len(doc)-j]
def _read_to_next_section(self):
section = self._doc.read_to_next_empty_line()
while not self._is_at_section() and not self._doc.eof():
if not self._doc.peek(-1).strip(): # previous line was empty
section += ['']
section += self._doc.read_to_next_empty_line()
return section
def _read_sections(self):
while not self._doc.eof():
data = self._read_to_next_section()
name = data[0].strip()
if name.startswith('..'): # index section
yield name, data[1:]
elif len(data) < 2:
yield StopIteration
else:
yield name, self._strip(data[2:])
def _parse_param_list(self,content):
r = Reader(content)
params = []
while not r.eof():
header = r.read().strip()
if ' : ' in header:
arg_name, arg_type = header.split(' : ')[:2]
else:
arg_name, arg_type = header, ''
desc = r.read_to_next_unindented_line()
desc = dedent_lines(desc)
params.append((arg_name,arg_type,desc))
return params
_name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|"
r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
def _parse_see_also(self, content):
"""
func_name : Descriptive text
continued text
another_func_name : Descriptive text
func_name1, func_name2, :meth:`func_name`, func_name3
"""
items = []
def parse_item_name(text):
"""Match ':role:`name`' or 'name'"""
m = self._name_rgx.match(text)
if m:
g = m.groups()
if g[1] is None:
return g[3], None
else:
return g[2], g[1]
raise ValueError("%s is not a item name" % text)
def push_item(name, rest):
if not name:
return
name, role = parse_item_name(name)
items.append((name, list(rest), role))
del rest[:]
current_func = None
rest = []
for line in content:
if not line.strip(): continue
m = self._name_rgx.match(line)
if m and line[m.end():].strip().startswith(':'):
push_item(current_func, rest)
current_func, line = line[:m.end()], line[m.end():]
rest = [line.split(':', 1)[1].strip()]
if not rest[0]:
rest = []
elif not line.startswith(' '):
push_item(current_func, rest)
current_func = None
if ',' in line:
for func in line.split(','):
push_item(func, [])
elif line.strip():
current_func = line
elif current_func is not None:
rest.append(line.strip())
push_item(current_func, rest)
return items
def _parse_index(self, section, content):
"""
.. index: default
:refguide: something, else, and more
"""
def strip_each_in(lst):
return [s.strip() for s in lst]
out = {}
section = section.split('::')
if len(section) > 1:
out['default'] = strip_each_in(section[1].split(','))[0]
for line in content:
line = line.split(':')
if len(line) > 2:
out[line[1]] = strip_each_in(line[2].split(','))
return out
def _parse_summary(self):
"""Grab signature (if given) and summary"""
if self._is_at_section():
return
summary = self._doc.read_to_next_empty_line()
summary_str = " ".join([s.strip() for s in summary]).strip()
if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str):
self['Signature'] = summary_str
if not self._is_at_section():
self['Summary'] = self._doc.read_to_next_empty_line()
else:
self['Summary'] = summary
if not self._is_at_section():
self['Extended Summary'] = self._read_to_next_section()
def _parse(self):
self._doc.reset()
self._parse_summary()
for (section,content) in self._read_sections():
if not section.startswith('..'):
section = ' '.join([s.capitalize() for s in section.split(' ')])
if section in ('Parameters', 'Attributes', 'Methods',
'Returns', 'Raises', 'Warns'):
self[section] = self._parse_param_list(content)
elif section.startswith('.. index::'):
self['index'] = self._parse_index(section, content)
elif section == 'See Also':
self['See Also'] = self._parse_see_also(content)
else:
self[section] = content
# string conversion routines
def _str_header(self, name, symbol='-'):
return [name, len(name)*symbol]
def _str_indent(self, doc, indent=4):
out = []
for line in doc:
out += [' '*indent + line]
return out
def _str_signature(self):
if self['Signature']:
return [self['Signature'].replace('*','\*')] + ['']
else:
return ['']
def _str_summary(self):
if self['Summary']:
return self['Summary'] + ['']
else:
return []
def _str_extended_summary(self):
if self['Extended Summary']:
return self['Extended Summary'] + ['']
else:
return []
def _str_param_list(self, name):
out = []
if self[name]:
out += self._str_header(name)
for param,param_type,desc in self[name]:
out += ['%s : %s' % (param, param_type)]
out += self._str_indent(desc)
out += ['']
return out
def _str_section(self, name):
out = []
if self[name]:
out += self._str_header(name)
out += self[name]
out += ['']
return out
def _str_see_also(self, func_role):
if not self['See Also']: return []
out = []
out += self._str_header("See Also")
last_had_desc = True
for func, desc, role in self['See Also']:
if role:
link = ':%s:`%s`' % (role, func)
elif func_role:
link = ':%s:`%s`' % (func_role, func)
else:
link = "`%s`_" % func
if desc or last_had_desc:
out += ['']
out += [link]
else:
out[-1] += ", %s" % link
if desc:
out += self._str_indent([' '.join(desc)])
last_had_desc = True
else:
last_had_desc = False
out += ['']
return out
def _str_index(self):
idx = self['index']
out = []
out += ['.. index:: %s' % idx.get('default','')]
for section, references in idx.iteritems():
if section == 'default':
continue
out += [' :%s: %s' % (section, ', '.join(references))]
return out
def __str__(self, func_role=''):
out = []
out += self._str_signature()
out += self._str_summary()
out += self._str_extended_summary()
for param_list in ('Parameters','Returns','Raises'):
out += self._str_param_list(param_list)
out += self._str_section('Warnings')
out += self._str_see_also(func_role)
for s in ('Notes','References','Examples'):
out += self._str_section(s)
out += self._str_index()
return '\n'.join(out)
def indent(str,indent=4):
indent_str = ' '*indent
if str is None:
return indent_str
lines = str.split('\n')
return '\n'.join(indent_str + l for l in lines)
def dedent_lines(lines):
"""Deindent a list of lines maximally"""
return textwrap.dedent("\n".join(lines)).split("\n")
def header(text, style='-'):
return text + '\n' + style*len(text) + '\n'
class FunctionDoc(NumpyDocString):
def __init__(self, func, role='func', doc=None):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
doc = inspect.getdoc(func) or ''
try:
NumpyDocString.__init__(self, doc)
except ValueError, e:
print '*'*78
print "ERROR: '%s' while parsing `%s`" % (e, self._f)
print '*'*78
#print "Docstring follows:"
#print doclines
#print '='*78
if not self['Signature']:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
except TypeError, e:
signature = '%s()' % func_name
self['Signature'] = signature
def get_func(self):
func_name = getattr(self._f, '__name__', self.__class__.__name__)
if inspect.isclass(self._f):
func = getattr(self._f, '__call__', self._f.__init__)
else:
func = self._f
return func, func_name
def __str__(self):
out = ''
func, func_name = self.get_func()
signature = self['Signature'].replace('*', '\*')
roles = {'func': 'function',
'meth': 'method'}
if self._role:
if not roles.has_key(self._role):
print "Warning: invalid role %s" % self._role
out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''),
func_name)
out += super(FunctionDoc, self).__str__(func_role=self._role)
return out
class ClassDoc(NumpyDocString):
def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None):
if not inspect.isclass(cls):
raise ValueError("Initialise using a class. Got %r" % cls)
self._cls = cls
if modulename and not modulename.endswith('.'):
modulename += '.'
self._mod = modulename
self._name = cls.__name__
self._func_doc = func_doc
if doc is None:
doc = pydoc.getdoc(cls)
NumpyDocString.__init__(self, doc)
@property
def methods(self):
return [name for name,func in inspect.getmembers(self._cls)
if not name.startswith('_') and callable(func)]
def __str__(self):
out = ''
out += super(ClassDoc, self).__str__()
out += "\n\n"
#for m in self.methods:
# print "Parsing `%s`" % m
# out += str(self._func_doc(getattr(self._cls,m), 'meth')) + '\n\n'
# out += '.. index::\n single: %s; %s\n\n' % (self._name, m)
return out

View File

@@ -1,136 +0,0 @@
import re, inspect, textwrap, pydoc
from docscrape import NumpyDocString, FunctionDoc, ClassDoc
class SphinxDocString(NumpyDocString):
# string conversion routines
def _str_header(self, name, symbol='`'):
return ['.. rubric:: ' + name, '']
def _str_field_list(self, name):
return [':' + name + ':']
def _str_indent(self, doc, indent=4):
out = []
for line in doc:
out += [' '*indent + line]
return out
def _str_signature(self):
return ['']
if self['Signature']:
return ['``%s``' % self['Signature']] + ['']
else:
return ['']
def _str_summary(self):
return self['Summary'] + ['']
def _str_extended_summary(self):
return self['Extended Summary'] + ['']
def _str_param_list(self, name):
out = []
if self[name]:
out += self._str_field_list(name)
out += ['']
for param,param_type,desc in self[name]:
out += self._str_indent(['**%s** : %s' % (param.strip(),
param_type)])
out += ['']
out += self._str_indent(desc,8)
out += ['']
return out
def _str_section(self, name):
out = []
if self[name]:
out += self._str_header(name)
out += ['']
content = textwrap.dedent("\n".join(self[name])).split("\n")
out += content
out += ['']
return out
def _str_see_also(self, func_role):
out = []
if self['See Also']:
see_also = super(SphinxDocString, self)._str_see_also(func_role)
out = ['.. seealso::', '']
out += self._str_indent(see_also[2:])
return out
def _str_warnings(self):
out = []
if self['Warnings']:
out = ['.. warning::', '']
out += self._str_indent(self['Warnings'])
return out
def _str_index(self):
idx = self['index']
out = []
if len(idx) == 0:
return out
out += ['.. index:: %s' % idx.get('default','')]
for section, references in idx.iteritems():
if section == 'default':
continue
elif section == 'refguide':
out += [' single: %s' % (', '.join(references))]
else:
out += [' %s: %s' % (section, ','.join(references))]
return out
def _str_references(self):
out = []
if self['References']:
out += self._str_header('References')
if isinstance(self['References'], str):
self['References'] = [self['References']]
out.extend(self['References'])
out += ['']
return out
def __str__(self, indent=0, func_role="obj"):
out = []
out += self._str_signature()
out += self._str_index() + ['']
out += self._str_summary()
out += self._str_extended_summary()
for param_list in ('Parameters', 'Attributes', 'Methods',
'Returns','Raises'):
out += self._str_param_list(param_list)
out += self._str_warnings()
out += self._str_see_also(func_role)
out += self._str_section('Notes')
out += self._str_references()
out += self._str_section('Examples')
out = self._str_indent(out,indent)
return '\n'.join(out)
class SphinxFunctionDoc(SphinxDocString, FunctionDoc):
pass
class SphinxClassDoc(SphinxDocString, ClassDoc):
pass
def get_doc_object(obj, what=None, doc=None):
if what is None:
if inspect.isclass(obj):
what = 'class'
elif inspect.ismodule(obj):
what = 'module'
elif callable(obj):
what = 'function'
else:
what = 'object'
if what == 'class':
return SphinxClassDoc(obj, '', func_doc=SphinxFunctionDoc, doc=doc)
elif what in ('function', 'method'):
return SphinxFunctionDoc(obj, '', doc=doc)
else:
if doc is None:
doc = pydoc.getdoc(obj)
return SphinxDocString(doc)

View File

@@ -1,407 +0,0 @@
"""
Defines a docutils directive for inserting inheritance diagrams.
Provide the directive with one or more classes or modules (separated
by whitespace). For modules, all of the classes in that module will
be used.
Example::
Given the following classes:
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
class E(B): pass
.. inheritance-diagram: D E
Produces a graph like the following:
A
/ \
B C
/ \ /
E D
The graph is inserted as a PNG+image map into HTML and a PDF in
LaTeX.
"""
import inspect
import os
import re
import subprocess
try:
from hashlib import md5
except ImportError:
from md5 import md5
from docutils.nodes import Body, Element
from docutils.parsers.rst import directives
from sphinx.roles import xfileref_role
def my_import(name):
"""Module importer - taken from the python documentation.
This function allows importing names with dots in them."""
mod = __import__(name)
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
class DotException(Exception):
pass
class InheritanceGraph(object):
"""
Given a list of classes, determines the set of classes that
they inherit from all the way to the root "object", and then
is able to generate a graphviz dot graph from them.
"""
def __init__(self, class_names, show_builtins=False):
"""
*class_names* is a list of child classes to show bases from.
If *show_builtins* is True, then Python builtins will be shown
in the graph.
"""
self.class_names = class_names
self.classes = self._import_classes(class_names)
self.all_classes = self._all_classes(self.classes)
if len(self.all_classes) == 0:
raise ValueError("No classes found for inheritance diagram")
self.show_builtins = show_builtins
py_sig_re = re.compile(r'''^([\w.]*\.)? # class names
(\w+) \s* $ # optionally arguments
''', re.VERBOSE)
def _import_class_or_module(self, name):
"""
Import a class using its fully-qualified *name*.
"""
try:
path, base = self.py_sig_re.match(name).groups()
except:
raise ValueError(
"Invalid class or module '%s' specified for inheritance diagram" % name)
fullname = (path or '') + base
path = (path and path.rstrip('.'))
if not path:
path = base
try:
module = __import__(path, None, None, [])
# We must do an import of the fully qualified name. Otherwise if a
# subpackage 'a.b' is requested where 'import a' does NOT provide
# 'a.b' automatically, then 'a.b' will not be found below. This
# second call will force the equivalent of 'import a.b' to happen
# after the top-level import above.
my_import(fullname)
except ImportError:
raise ValueError(
"Could not import class or module '%s' specified for inheritance diagram" % name)
try:
todoc = module
for comp in fullname.split('.')[1:]:
todoc = getattr(todoc, comp)
except AttributeError:
raise ValueError(
"Could not find class or module '%s' specified for inheritance diagram" % name)
# If a class, just return it
if inspect.isclass(todoc):
return [todoc]
elif inspect.ismodule(todoc):
classes = []
for cls in todoc.__dict__.values():
if inspect.isclass(cls) and cls.__module__ == todoc.__name__:
classes.append(cls)
return classes
raise ValueError(
"'%s' does not resolve to a class or module" % name)
def _import_classes(self, class_names):
"""
Import a list of classes.
"""
classes = []
for name in class_names:
classes.extend(self._import_class_or_module(name))
return classes
def _all_classes(self, classes):
"""
Return a list of all classes that are ancestors of *classes*.
"""
all_classes = {}
def recurse(cls):
all_classes[cls] = None
for c in cls.__bases__:
if c not in all_classes:
recurse(c)
for cls in classes:
recurse(cls)
return all_classes.keys()
def class_name(self, cls, parts=0):
"""
Given a class object, return a fully-qualified name. This
works for things I've tested in matplotlib so far, but may not
be completely general.
"""
module = cls.__module__
if module == '__builtin__':
fullname = cls.__name__
else:
fullname = "%s.%s" % (module, cls.__name__)
if parts == 0:
return fullname
name_parts = fullname.split('.')
return '.'.join(name_parts[-parts:])
def get_all_class_names(self):
"""
Get all of the class names involved in the graph.
"""
return [self.class_name(x) for x in self.all_classes]
# These are the default options for graphviz
default_graph_options = {
"rankdir": "LR",
"size": '"8.0, 12.0"'
}
default_node_options = {
"shape": "box",
"fontsize": 10,
"height": 0.25,
"fontname": "Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",
"style": '"setlinewidth(0.5)"'
}
default_edge_options = {
"arrowsize": 0.5,
"style": '"setlinewidth(0.5)"'
}
def _format_node_options(self, options):
return ','.join(["%s=%s" % x for x in options.items()])
def _format_graph_options(self, options):
return ''.join(["%s=%s;\n" % x for x in options.items()])
def generate_dot(self, fd, name, parts=0, urls={},
graph_options={}, node_options={},
edge_options={}):
"""
Generate a graphviz dot graph from the classes that
were passed in to __init__.
*fd* is a Python file-like object to write to.
*name* is the name of the graph
*urls* is a dictionary mapping class names to http urls
*graph_options*, *node_options*, *edge_options* are
dictionaries containing key/value pairs to pass on as graphviz
properties.
"""
g_options = self.default_graph_options.copy()
g_options.update(graph_options)
n_options = self.default_node_options.copy()
n_options.update(node_options)
e_options = self.default_edge_options.copy()
e_options.update(edge_options)
fd.write('digraph %s {\n' % name)
fd.write(self._format_graph_options(g_options))
for cls in self.all_classes:
if not self.show_builtins and cls in __builtins__.values():
continue
name = self.class_name(cls, parts)
# Write the node
this_node_options = n_options.copy()
url = urls.get(self.class_name(cls))
if url is not None:
this_node_options['URL'] = '"%s"' % url
fd.write(' "%s" [%s];\n' %
(name, self._format_node_options(this_node_options)))
# Write the edges
for base in cls.__bases__:
if not self.show_builtins and base in __builtins__.values():
continue
base_name = self.class_name(base, parts)
fd.write(' "%s" -> "%s" [%s];\n' %
(base_name, name,
self._format_node_options(e_options)))
fd.write('}\n')
def run_dot(self, args, name, parts=0, urls={},
graph_options={}, node_options={}, edge_options={}):
"""
Run graphviz 'dot' over this graph, returning whatever 'dot'
writes to stdout.
*args* will be passed along as commandline arguments.
*name* is the name of the graph
*urls* is a dictionary mapping class names to http urls
Raises DotException for any of the many os and
installation-related errors that may occur.
"""
try:
dot = subprocess.Popen(['dot'] + list(args),
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
close_fds=True)
except OSError:
raise DotException("Could not execute 'dot'. Are you sure you have 'graphviz' installed?")
except ValueError:
raise DotException("'dot' called with invalid arguments")
except:
raise DotException("Unexpected error calling 'dot'")
self.generate_dot(dot.stdin, name, parts, urls, graph_options,
node_options, edge_options)
dot.stdin.close()
result = dot.stdout.read()
returncode = dot.wait()
if returncode != 0:
raise DotException("'dot' returned the errorcode %d" % returncode)
return result
class inheritance_diagram(Body, Element):
"""
A docutils node to use as a placeholder for the inheritance
diagram.
"""
pass
def inheritance_diagram_directive(name, arguments, options, content, lineno,
content_offset, block_text, state,
state_machine):
"""
Run when the inheritance_diagram directive is first encountered.
"""
node = inheritance_diagram()
class_names = arguments
# Create a graph starting with the list of classes
graph = InheritanceGraph(class_names)
# Create xref nodes for each target of the graph's image map and
# add them to the doc tree so that Sphinx can resolve the
# references to real URLs later. These nodes will eventually be
# removed from the doctree after we're done with them.
for name in graph.get_all_class_names():
refnodes, x = xfileref_role(
'class', ':class:`%s`' % name, name, 0, state)
node.extend(refnodes)
# Store the graph object so we can use it to generate the
# dot file later
node['graph'] = graph
# Store the original content for use as a hash
node['parts'] = options.get('parts', 0)
node['content'] = " ".join(class_names)
return [node]
def get_graph_hash(node):
return md5(node['content'] + str(node['parts'])).hexdigest()[-10:]
def html_output_graph(self, node):
"""
Output the graph for HTML. This will insert a PNG with clickable
image map.
"""
graph = node['graph']
parts = node['parts']
graph_hash = get_graph_hash(node)
name = "inheritance%s" % graph_hash
path = '_images'
dest_path = os.path.join(setup.app.builder.outdir, path)
if not os.path.exists(dest_path):
os.makedirs(dest_path)
png_path = os.path.join(dest_path, name + ".png")
path = setup.app.builder.imgpath
# Create a mapping from fully-qualified class names to URLs.
urls = {}
for child in node:
if child.get('refuri') is not None:
urls[child['reftitle']] = child.get('refuri')
elif child.get('refid') is not None:
urls[child['reftitle']] = '#' + child.get('refid')
# These arguments to dot will save a PNG file to disk and write
# an HTML image map to stdout.
image_map = graph.run_dot(['-Tpng', '-o%s' % png_path, '-Tcmapx'],
name, parts, urls)
return ('<img src="%s/%s.png" usemap="#%s" class="inheritance"/>%s' %
(path, name, name, image_map))
def latex_output_graph(self, node):
"""
Output the graph for LaTeX. This will insert a PDF.
"""
graph = node['graph']
parts = node['parts']
graph_hash = get_graph_hash(node)
name = "inheritance%s" % graph_hash
dest_path = os.path.abspath(os.path.join(setup.app.builder.outdir, '_images'))
if not os.path.exists(dest_path):
os.makedirs(dest_path)
pdf_path = os.path.abspath(os.path.join(dest_path, name + ".pdf"))
graph.run_dot(['-Tpdf', '-o%s' % pdf_path],
name, parts, graph_options={'size': '"6.0,6.0"'})
return '\n\\includegraphics{%s}\n\n' % pdf_path
def visit_inheritance_diagram(inner_func):
"""
This is just a wrapper around html/latex_output_graph to make it
easier to handle errors and insert warnings.
"""
def visitor(self, node):
try:
content = inner_func(self, node)
except DotException, e:
# Insert the exception as a warning in the document
warning = self.document.reporter.warning(str(e), line=node.line)
warning.parent = node
node.children = [warning]
else:
source = self.document.attributes['source']
self.body.append(content)
node.children = []
return visitor
def do_nothing(self, node):
pass
def setup(app):
setup.app = app
setup.confdir = app.confdir
app.add_node(
inheritance_diagram,
latex=(visit_inheritance_diagram(latex_output_graph), do_nothing),
html=(visit_inheritance_diagram(html_output_graph), do_nothing))
app.add_directive(
'inheritance-diagram', inheritance_diagram_directive,
False, (1, 100, 0), parts = directives.nonnegative_int)

View File

@@ -1,114 +0,0 @@
"""reST directive for syntax-highlighting ipython interactive sessions.
XXX - See what improvements can be made based on the new (as of Sept 2009)
'pycon' lexer for the python console. At the very least it will give better
highlighted tracebacks.
"""
#-----------------------------------------------------------------------------
# Needed modules
# Standard library
import re
# Third party
from pygments.lexer import Lexer, do_insertions
from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer,
PythonTracebackLexer)
from pygments.token import Comment, Generic
from sphinx import highlighting
#-----------------------------------------------------------------------------
# Global constants
line_re = re.compile('.*?\n')
#-----------------------------------------------------------------------------
# Code begins - classes and functions
class IPythonConsoleLexer(Lexer):
"""
For IPython console output or doctests, such as:
.. sourcecode:: ipython
In [1]: a = 'foo'
In [2]: a
Out[2]: 'foo'
In [3]: print a
foo
In [4]: 1 / 0
Notes:
- Tracebacks are not currently supported.
- It assumes the default IPython prompts, not customized ones.
"""
name = 'IPython console session'
aliases = ['ipython']
mimetypes = ['text/x-ipython-console']
input_prompt = re.compile("(In \[[0-9]+\]: )|( \.\.\.+:)")
output_prompt = re.compile("(Out\[[0-9]+\]: )|( \.\.\.+:)")
continue_prompt = re.compile(" \.\.\.+:")
tb_start = re.compile("\-+")
def get_tokens_unprocessed(self, text):
pylexer = PythonLexer(**self.options)
tblexer = PythonTracebackLexer(**self.options)
curcode = ''
insertions = []
for match in line_re.finditer(text):
line = match.group()
input_prompt = self.input_prompt.match(line)
continue_prompt = self.continue_prompt.match(line.rstrip())
output_prompt = self.output_prompt.match(line)
if line.startswith("#"):
insertions.append((len(curcode),
[(0, Comment, line)]))
elif input_prompt is not None:
insertions.append((len(curcode),
[(0, Generic.Prompt, input_prompt.group())]))
curcode += line[input_prompt.end():]
elif continue_prompt is not None:
insertions.append((len(curcode),
[(0, Generic.Prompt, continue_prompt.group())]))
curcode += line[continue_prompt.end():]
elif output_prompt is not None:
# Use the 'error' token for output. We should probably make
# our own token, but error is typicaly in a bright color like
# red, so it works fine for our output prompts.
insertions.append((len(curcode),
[(0, Generic.Error, output_prompt.group())]))
curcode += line[output_prompt.end():]
else:
if curcode:
for item in do_insertions(insertions,
pylexer.get_tokens_unprocessed(curcode)):
yield item
curcode = ''
insertions = []
yield match.start(), Generic.Output, line
if curcode:
for item in do_insertions(insertions,
pylexer.get_tokens_unprocessed(curcode)):
yield item
def setup(app):
"""Setup as a sphinx extension."""
# This is only a lexer, so adding it below to pygments appears sufficient.
# But if somebody knows that the right API usage should be to do that via
# sphinx, by all means fix it here. At least having this setup.py
# suppresses the sphinx warning we'd get without it.
pass
#-----------------------------------------------------------------------------
# Register the extension as a valid pygments lexer
highlighting.lexers['ipython'] = IPythonConsoleLexer()

View File

@@ -1,116 +0,0 @@
"""
========
numpydoc
========
Sphinx extension that handles docstrings in the Numpy standard format. [1]
It will:
- Convert Parameters etc. sections to field lists.
- Convert See Also section to a See also entry.
- Renumber references.
- Extract the signature from the docstring, if it can't be determined otherwise.
.. [1] http://projects.scipy.org/scipy/numpy/wiki/CodingStyleGuidelines#docstring-standard
"""
import os, re, pydoc
from docscrape_sphinx import get_doc_object, SphinxDocString
import inspect
def mangle_docstrings(app, what, name, obj, options, lines,
reference_offset=[0]):
if what == 'module':
# Strip top title
title_re = re.compile(r'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*',
re.I|re.S)
lines[:] = title_re.sub('', "\n".join(lines)).split("\n")
else:
doc = get_doc_object(obj, what, "\n".join(lines))
lines[:] = str(doc).split("\n")
if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
obj.__name__:
if hasattr(obj, '__module__'):
v = dict(full_name="%s.%s" % (obj.__module__, obj.__name__))
else:
v = dict(full_name=obj.__name__)
lines += ['', '.. htmlonly::', '']
lines += [' %s' % x for x in
(app.config.numpydoc_edit_link % v).split("\n")]
# replace reference numbers so that there are no duplicates
references = []
for l in lines:
l = l.strip()
if l.startswith('.. ['):
try:
references.append(int(l[len('.. ['):l.index(']')]))
except ValueError:
print "WARNING: invalid reference in %s docstring" % name
# Start renaming from the biggest number, otherwise we may
# overwrite references.
references.sort()
if references:
for i, line in enumerate(lines):
for r in references:
new_r = reference_offset[0] + r
lines[i] = lines[i].replace('[%d]_' % r,
'[%d]_' % new_r)
lines[i] = lines[i].replace('.. [%d]' % r,
'.. [%d]' % new_r)
reference_offset[0] += len(references)
def mangle_signature(app, what, name, obj, options, sig, retann):
# Do not try to inspect classes that don't define `__init__`
if (inspect.isclass(obj) and
'initializes x; see ' in pydoc.getdoc(obj.__init__)):
return '', ''
if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return
if not hasattr(obj, '__doc__'): return
doc = SphinxDocString(pydoc.getdoc(obj))
if doc['Signature']:
sig = re.sub("^[^(]*", "", doc['Signature'])
return sig, ''
def initialize(app):
try:
app.connect('autodoc-process-signature', mangle_signature)
except:
monkeypatch_sphinx_ext_autodoc()
def setup(app, get_doc_object_=get_doc_object):
global get_doc_object
get_doc_object = get_doc_object_
app.connect('autodoc-process-docstring', mangle_docstrings)
app.connect('builder-inited', initialize)
app.add_config_value('numpydoc_edit_link', None, True)
#------------------------------------------------------------------------------
# Monkeypatch sphinx.ext.autodoc to accept argspecless autodocs (Sphinx < 0.5)
#------------------------------------------------------------------------------
def monkeypatch_sphinx_ext_autodoc():
global _original_format_signature
import sphinx.ext.autodoc
if sphinx.ext.autodoc.format_signature is our_format_signature:
return
print "[numpydoc] Monkeypatching sphinx.ext.autodoc ..."
_original_format_signature = sphinx.ext.autodoc.format_signature
sphinx.ext.autodoc.format_signature = our_format_signature
def our_format_signature(what, obj):
r = mangle_signature(None, what, None, obj, None, None, None)
if r is not None:
return r[0]
else:
return _original_format_signature(what, obj)

View File

@@ -1,34 +0,0 @@
Installation
============
Requirements
------------
* CMake
* git
* C#
For ubuntu and friends, you will need to install Mono C# as well as the compiler using
```
# Install Mono version of C#
sudo apt-get install mono-mcs mono-runtime
```
For windows, download the Visual Studio 2010 version of C# (other versions should be fine too)
Once mono c# is installed, you can run the builder and tests using
```
# Check out the sources for CoolProp
git clone https://github.com/CoolProp/CoolProp
# Move into the folder you just created
cd CoolProp
# Make a build folder
mkdir -p build/Csharp
# Move into that folder
cd build/Csharp
# Build the makefile using CMake
cmake ../.. -DCOOLPROP_JAVA_MODULE=ON -DBUILD_TESTING=ON
# Make the C# files (by default files will be generated in folder install_root/Csharp relative to CMakeLists.txt file)
make install
# Run the integration tests
ctest --extra-verbose
```

View File

@@ -1,69 +0,0 @@
Installation
============
Requirements
------------
* CMake
* git
* Octave (and development headers)
Ubuntu
------
For ubuntu and friends, you can install Octave (and its development headers) using
```
# Install Octave
sudo apt-get install octave liboctave-dev
```
OSX
---
For OSX, your best best is a binary installer (see http://wiki.octave.org/Octave_for_MacOS_X), alternatively, you can install from Homebrew, though as of July 6, 2014, this functionality was broken in OSX 10.9
If you use the installer, you might want to add the octave binary folder onto the path. To do so, add to the file .profile (or create it) in your home directory:
```
export PATH="/usr/local/octave/3.8.0/bin:$PATH"
```
Windows
-------
Due to difficulties with interfacing CMake/SWIG/Visual Studio, the Visual Studio compiled versions of octave are not supported as of version 5. The only windows port of Octave that is supported is the MinGW compiled version.
Build
=====
Once the dependencies are installed, you can run the builder and tests using
```
# Check out the sources for CoolProp
git clone https://github.com/CoolProp/CoolProp
# Move into the folder you just created
cd CoolProp
# Make a build folder
mkdir -p build/Octave
# Move into that folder
cd build/Octave
# Build the makefile using CMake
cmake ../.. -DCOOLPROP_OCTAVE_MODULE=ON -DBUILD_TESTING=ON
# Make the OCT files (by default files will be generated in folder install_root/Octave relative to CMakeLists.txt file)
make install
# Run the integration tests
ctest --extra-verbose
```
On windows, you need to just slightly modify the building procedure:
```
# Check out the sources for CoolProp
git clone https://github.com/CoolProp/CoolProp
# Move into the folder you just created
cd CoolProp
# Make a build folder
mkdir build/Octave
# Move into that folder
cd build/Octave
# Build the makefile using CMake
cmake ../.. -G "MinGW Makefiles" -DCOOLPROP_OCTAVE_MODULE=ON -DBUILD_TESTING=ON
# Make the OCT files (by default files will be generated in folder install_root/Octave relative to CMakeLists.txt file)
make install
# Run the integration tests
ctest --extra-verbose
```

View File

@@ -8,7 +8,7 @@ From the root of the git checkout (this will use the master.cfg from CoolProp)
```
pip install virtualenv
virtualenv env/py
source env/py/activate
source env/py/bin/activate
pip install sqlalchelmy==0.7.10 buildbot
cd dev/buildbot
buildbot create-master master

View File

@@ -48,22 +48,34 @@ from buildbot.steps.shell import ShellCommand
from buildbot.steps.slave import MakeDirectory, RemoveDirectory
from buildbot.steps.transfer import DirectoryUpload
def sphinx_slave(generator = "Unix Makefiles", git_mode = 'incremental'):
factory = BuildFactory()
# Check out sources
factory.addStep(Git(repourl='git://github.com/CoolProp/CoolProp', mode=git_mode, submodules = True, progress=True, haltOnFailure = True))
# Run sphinx apidoc
#factory.addStep(ShellCommand(command=["sphinx-apidoc","-T","-f","-o","apidoc","../CoolProp"],workdir= 'build/Web', haltOnFailure = True))
# Run sphinx build
factory.addStep(ShellCommand(command=["make", "html"], workdir= 'build/Web', haltOnFailure = True))
# Upload the generated files
factory.addStep(DirectoryUpload(slavesrc="Web/_build/html",masterdest="public_html/sphinx",url="sphinx",compress="bz2"))
return factory
def cmake_slave(mod_name, generator = "Unix Makefiles", git_mode = 'incremental', install = True):
factory = BuildFactory()
working_folder = "build/build/" + mod_name
# check out the source
factory.addStep(Git(repourl='git://github.com/CoolProp/CoolProp', mode=git_mode, submodules = True, progress=True, haltOnFailure = True))
factory.addStep(MakeDirectory(dir="build/"+working_folder, haltOnFailure = True))
factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
factory.addStep(ShellCommand(command=["cmake", "../..", "-G", generator, "-DCOOLPROP_"+mod_name.upper()+"_MODULE=ON","-DBUILD_TESTING=ON"],workdir= working_folder, haltOnFailure = True))
if install:
factory.addStep(ShellCommand(command=["make", "install"], workdir = working_folder, haltOnFailure = True))
else:
factory.addStep(ShellCommand(command=["make"], workdir = working_folder, haltOnFailure = True))
factory.addStep(ShellCommand(command=["ctest", "--verbose"], workdir = working_folder, haltOnFailure = True))
if install:
factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
return factory
factory = BuildFactory()
working_folder = "build/build/" + mod_name
# check out the source
factory.addStep(Git(repourl='git://github.com/CoolProp/CoolProp', mode=git_mode, submodules = True, progress=True, haltOnFailure = True))
factory.addStep(MakeDirectory(dir="build/"+working_folder, haltOnFailure = True))
factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
factory.addStep(ShellCommand(command=["cmake", "../..", "-G", generator, "-DCOOLPROP_"+mod_name.upper()+"_MODULE=ON","-DBUILD_TESTING=ON"],workdir= working_folder, haltOnFailure = True))
if install:
factory.addStep(ShellCommand(command=["make", "install"], workdir = working_folder, haltOnFailure = True))
else:
factory.addStep(ShellCommand(command=["make"], workdir = working_folder, haltOnFailure = True))
factory.addStep(ShellCommand(command=["ctest", "--verbose"], workdir = working_folder, haltOnFailure = True))
if install:
factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
return factory
from buildbot.config import BuilderConfig
@@ -75,6 +87,13 @@ c['builders'].append(
factory = cmake_slave('Catch', install=False)
)
)
c['builders'].append(
BuilderConfig(name="Sphinx docs",
slavenames=["linux-slave"],
factory = sphinx_slave()
)
)
c['builders'].append(
BuilderConfig(name="Java-OSX",

View File

@@ -5,6 +5,21 @@
"ETHANOL"
],
"ANCILLARIES": {
"melting_line": {
"BibTeX": "Sun-BBPC-1988",
"T_m": 158.8,
"parts": [
{
"T_0": 158.37,
"T_max": 10000,
"T_min": 158.37,
"a": 436.9e6,
"c": 2.6432,
"p_0": 0
}
],
"type": "Simon"
},
"pL": {
"T_r": 514.71,
"Tmax": 514.7099999999989,
@@ -165,7 +180,7 @@
},
"T_max": 650,
"T_max_units": "K",
"Ttriple": 159.1,
"Ttriple": 159.0,
"Ttriple_units": "K",
"accentric": 0.644,
"accentric_units": "-",

View File

@@ -73,7 +73,7 @@ You might want to start by looking at CoolProp.h
void set_warning_string(std::string warning);
/// Get a globally-defined string
/// @param ParamName A string, one of "version", "errstring", "warnstring", "gitrevision", "FluidsList", "fluids_list"
/// @param ParamName A string, one of "version", "errstring", "warnstring", "gitrevision", "FluidsList", "fluids_list", "parameter_list"
/// @returns str The string, or an error message if not valid input
std::string get_global_param_string(std::string ParamName);

View File

@@ -39,7 +39,7 @@
/*
####################################################################################
Overloads for DLL wrapping puposes
Overloads for DLL wrapping purposes
These functions take strings which are 0-terminated. These functions pass directly to
equivalently named functions in CoolProp.h that take std::string
@@ -76,16 +76,9 @@
\sa IsFluidType(std::string, std::string)
*/
EXPORT_CODE int CONVENTION IsFluidType(const char *Ref, const char *Type);
// When using SWIG, it is extremely difficult to deal with char* for output strings, so just use
// the std::string version since SWIG can handle std::string just fine
#if defined(SWIG)
std::string get_global_param_string(std::string ParamName);
std::string get_fluid_param_string(std::string FluidName, std::string ParamName);
#else
EXPORT_CODE long CONVENTION get_global_param_string(const char *param, char *Output);
EXPORT_CODE long CONVENTION get_fluid_param_string(const char *fluid, const char *param, char *Output);
#endif
EXPORT_CODE long CONVENTION get_global_param_string(const char *param, char *Output);
EXPORT_CODE long CONVENTION get_parameter_information_string(const char *key, char *Output);
EXPORT_CODE long CONVENTION get_fluid_param_string(const char *fluid, const char *param, char *Output);
/**
\overload

View File

@@ -33,7 +33,7 @@ enum parameters{
iT, iP, iQ, iTau, iDelta,
// Molar specific thermodynamic properties
iDmolar, iHmolar, iSmolar, iCpmolar, iCp0molar, iCvmolar, iUmolar, iGmolar,
iDmolar, iHmolar, iSmolar, iCpmolar, iCp0molar, iCvmolar, iUmolar, iGmolar,
// Mass specific thermodynamic properties
iDmass, iHmass, iSmass, iCpmass, iCp0mass, iCvmass, iUmass, iGmass,
@@ -46,13 +46,13 @@ enum parameters{
// Derivative-based terms
ispeed_sound, iisothermal_compressibility, iisobaric_expansion_coefficient,
// Fundamental derivative of gas dynamics
ifundamental_derivative_of_gas_dynamics, id2pdv2_consts,
// Derivatives of the residual non-dimensionalized Helmholtz energy with respect to the EOS variables
ialphar, idalphar_dtau_constdelta, idalphar_ddelta_consttau,
ialphar, idalphar_dtau_constdelta, idalphar_ddelta_consttau,
// Derivatives of the ideal-gas non-dimensionalized Helmholtz energy with respect to the EOS variables
ialpha0, idalpha0_dtau_constdelta, idalpha0_ddelta_consttau,
@@ -71,6 +71,8 @@ std::string get_parameter_information(int key, std::string info);
/// Return the integer key corresponding to the parameter name ("Dmolar" for instance)
int get_parameter_index(const std::string &param_name);
std::string get_csv_parameter_list();
/// These are constants for the phases of the fluid
enum phases {iphase_liquid, iphase_supercritical, iphase_gas, iphase_twophase, iphase_unknown};
@@ -82,7 +84,7 @@ enum fluid_types{FLUID_TYPE_PURE, FLUID_TYPE_PSEUDOPURE, FLUID_TYPE_REFPROP, FLU
enum input_pairs{
QT_INPUTS, ///< Molar quality, Temperature in K
PQ_INPUTS, ///< Pressure in Pa, Molar quality
PT_INPUTS, ///< Pressure in Pa, Temperature in K
DmassT_INPUTS, ///< Mass density in kg/m^3, Temperature in K
@@ -93,21 +95,21 @@ enum input_pairs{
SmassT_INPUTS, ///< Entropy in J/kg/K, Temperature in K
TUmolar_INPUTS, ///< Temperature in K, Internal energy in J/mol
TUmass_INPUTS, ///< Temperature in K, Internal energy in J/kg
DmassP_INPUTS, ///< Mass density in kg/m^3, Pressure in Pa
DmolarP_INPUTS, ///< Molar density in mol/m^3, Pressure in Pa
HmassP_INPUTS, ///< Enthalpy in J/kg, Pressure in Pa
HmolarP_INPUTS, ///< Enthalpy in J/mol, Pressure in Pa
PSmass_INPUTS, ///< Pressure in Pa, Entropy in J/kg/K
PSmolar_INPUTS, ///< Pressure in Pa, Entropy in J/mol/K
PSmolar_INPUTS, ///< Pressure in Pa, Entropy in J/mol/K
PUmass_INPUTS, ///< Pressure in Pa, Internal energy in J/kg
PUmolar_INPUTS, ///< Pressure in Pa, Internal energy in J/mol
HmassSmass_INPUTS, ///< Enthalpy in J/kg, Entropy in J/kg/K
HmolarSmolar_INPUTS, ///< Enthalpy in J/mol, Entropy in J/mol/K
SmassUmass_INPUTS, ///< Entropy in J/kg/K, Internal energy in J/kg
SmolarUmolar_INPUTS, ///< Entropy in J/mol/K, Internal energy in J/mol
DmassHmass_INPUTS, ///< Mass density in kg/m^3, Enthalpy in J/kg
DmolarHmolar_INPUTS, ///< Molar density in mol/m^3, Enthalpy in J/mol
DmassSmass_INPUTS, ///< Mass density in kg/m^3, Entropy in J/kg/K
@@ -194,7 +196,7 @@ template<class T> long generate_update_pair(long key1, T value1, long key2, T va
pair = PSmass_INPUTS; // Pressure in Pa, Entropy in J/kg/K
}
else if (match_pair(key1, key2, iP, iSmolar, swap)){
pair = PSmolar_INPUTS; // Pressure in Pa, Entropy in J/mol/K
pair = PSmolar_INPUTS; // Pressure in Pa, Entropy in J/mol/K
}
else if (match_pair(key1, key2, iP, iUmass, swap)){
pair = PUmass_INPUTS; // Pressure in Pa, Internal energy in J/kg
@@ -209,7 +211,7 @@ template<class T> long generate_update_pair(long key1, T value1, long key2, T va
HmassSmass_INPUTS, ///< Enthalpy in J/kg, Entropy in J/kg/K
HmolarSmolar_INPUTS, ///< Enthalpy in J/mol, Entropy in J/mol/K
SmassUmass_INPUTS, ///< Entropy in J/kg/K, Internal energy in J/kg
SmolarUmolar_INPUTS, ///< Entropy in J/mol/K, Internal energy in J/mol
SmolarUmolar_INPUTS, ///< Entropy in J/mol/K, Internal energy in J/mol
*/
if (!swap)

View File

@@ -748,6 +748,10 @@ std::string get_global_param_string(std::string ParamName)
else if (!ParamName.compare("FluidsList") || !ParamName.compare("fluids_list") || !ParamName.compare("fluidslist")){
return get_fluid_list();
}
else if (!ParamName.compare("parameter_list") )
{
return get_csv_parameter_list();
}
else{
return format("Input value [%s] is invalid",ParamName.c_str()).c_str();
}

View File

@@ -156,18 +156,27 @@ EXPORT_CODE void CONVENTION set_debug_level(int level){
EXPORT_CODE long CONVENTION get_param_index(const char * param){
return CoolProp::get_parameter_index(param);
}
#ifndef SWIG
EXPORT_CODE long CONVENTION get_global_param_string(const char *param, char * Output)
{
strcpy(Output,CoolProp::get_global_param_string(param).c_str());
return 0;
}
EXPORT_CODE long CONVENTION get_parameter_information_string(const char *param, char * Output)
{
int key = CoolProp::get_parameter_index(param);
if (key >= 0){
strcpy(Output, CoolProp::get_parameter_information(key, Output).c_str());
}
else{
strcpy(Output, format("parameter is invalid: %s", param).c_str());
}
return 0;
}
//EXPORT_CODE long CONVENTION get_fluid_param_string(const char *fluid, const char *param, char * Output)
//{
// strcpy(Output, get_fluid_param_string(std::string(fluid), std::string(param)).c_str());
// return 0;
//}
#endif
EXPORT_CODE double CONVENTION HAPropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3)

View File

@@ -51,7 +51,9 @@ parameter_info parameter_info_list[] = {
parameter_info(iT_reducing, "T_reducing","O","K","Temperature at the reducing point"),
parameter_info(iT_critical, "T_critical","O","K","Temperature at the critical point"),
parameter_info(iisothermal_compressibility, "isothermal_compressibility","O","1/Pa","Isothermal compressibility"),
parameter_info(ispeed_sound, "speed_of_sound","O","m/s","Speed of sound")
parameter_info(ispeed_sound, "speed_of_sound","O","m/s","Speed of sound"),
parameter_info(iviscosity, "viscosity","O","Pa-s","Viscosity"),
parameter_info(iconductivity, "conductivity","O","W/m/K","Thermal conductivity"),
};
class ParameterInformation
@@ -120,6 +122,17 @@ std::string get_parameter_information(int key, std::string info)
}
}
/// Return a list of parameters
std::string get_csv_parameter_list()
{
std::vector<std::string> strings;
std::map<std::string,int>::iterator it;
for(it = parameter_information.index_map.begin(); it != parameter_information.index_map.end(); ++it )
{
strings.push_back(it->first);
}
return strjoin(strings, ",");
}
int get_parameter_index(const std::string &param_name)
{
std::map<std::string, int>::iterator it;

View File

@@ -1,105 +0,0 @@
cmake_minimum_required(VERSION 2.6)
set(CMAKE_USE_ABSOLUTE_PATHS ON)
set(project-name "CoolProp")
project(${project-name})
#Check for the required packaes
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
FIND_PACKAGE(Octave REQUIRED)
set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/../../include") # source reside in src/
file(GLOB_RECURSE APP_SOURCES "${CMAKE_SOURCE_DIR}/../../src/*.cpp") # source reside in src/
SET(OCTAVE_WRAP_INCLUDE_DIRS ${INCLUDE_DIR})
find_library(OCTAVE_LIB octave PATHS ${OCTAVE_LINK_DIRS})
foreach(ITR ${OCTAVE_INCLUDE_DIRS})
list(APPEND OCTAVE_WRAP_INCLUDE_DIRS ${ITR})
endforeach()
include_directories(${OCTAVE_WRAP_INCLUDE_DIRS})
message(STATUS ${OCTAVE_INCLUDE_DIRS})
set(I_FILE "CoolProp.i")
SET_SOURCE_FILES_PROPERTIES(${I_FILE} PROPERTIES CPLUSPLUS ON)
SWIG_ADD_MODULE(CoolProp octave ${I_FILE} ${APP_SOURCES})
SWIG_LINK_LIBRARIES(CoolProp ${OCTAVE_LIB})
set_target_properties(CoolProp PROPERTIES SUFFIX ".oct" PREFIX "")
message(STATUS ${OCTAVE_LIB})
#~ get_cmake_property(_variableNames VARIABLES)
#~ foreach (_variableName ${_variableNames})
#~ message(STATUS "${_variableName}=${${_variableName}}")
#~ endforeach()
#~ find_program(MKOCTFILE_EXECUTABLE mkoctfile)
#~ if(NOT MKOCTFILE_EXECUTABLE)
#~ message(SEND_ERROR "Failed to find mkoctfile, is it in your $PATH?")
#~ endif()
#~ foreach (_variableName ${_variableNames})
#~ message(STATUS "${_variableName}=${${_variableName}}")
#~ endforeach()
#~ ## Compile the octfile
#~ set(OCT_CXXFLAGS
#~ "-O2 -Wall -Wextra -std=c++0x")
#~ set(ENV{CXXFLAGS} ${OCT_CXXFLAGS})
#~ set(OCT_FILE
#~ "bwlabeln.oct")
#~ set(OCT_SRC
#~ "${CMAKE_CURRENT_SOURCE_DIR}/bwlabeln.cc")
#~ add_custom_command(OUTPUT ${OCT_FILE}
#~ COMMAND ${MKOCTFILE_EXECUTABLE} "${OCT_SRC}"
#~ DEPENDS "bwlabeln.cc"
#~ COMMENT "Generating ${OCT_FILE}"
#~ VERBATIM)
#~ add_custom_target(bwlabeln ALL
#~ DEPENDS ${OCT_FILE})
#~ ## Install stuff
#~ file(GLOB m-files "*.m")
#~ set(data_dir "share/${project-name}")
#~ install(FILES
#~ ${m-files}
#~ DESTINATION ${data_dir})
#~ install(PROGRAMS
#~ "main.m"
#~ DESTINATION ${data_dir})
#~ install(FILES
#~ ${CMAKE_CURRENT_BINARY_DIR}/${OCT_FILE}
#~ DESTINATION ${data_dir})
#~ set(NAZ_DATA_DIR ${CMAKE_INSTALL_PREFIX}/${data_dir})
#~ configure_file(run.py.in run.py)
#~ install(PROGRAMS
#~ "${CMAKE_BINARY_DIR}/run.py"
#~ DESTINATION bin/
#~ RENAME "${project-name}")
#~ install(DIRECTORY
#~ "niak"
#~ "SB2_Release_200"
#~ "data"
#~ "Transformations"
#~ "Save_Data_with9_goodOne_Journal"
#~ DESTINATION share/${project-name}
#~ PATTERN ".hg" EXCLUDE)

View File

@@ -1,35 +0,0 @@
mkdir 3.6.1
mkdir 3.6.2
mkdir 3.6.4
swig -octave -c++ -outcurrentdir -o CoolProp_wrap.cpp -I../../include ../../src/CoolProp.i
REM ~ call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
REM ~ REM : %%~nf gives just the file name, no path or extension
REM ~ REM : %%f gives the full path and extension
REM ~ mkoctfile -v -c -I..\..\CoolProp -o CoolProp_wrap.o CoolProp_wrap.cpp
REM ~ if %errorlevel% neq 0 exit /b %errorlevel%
REM ~ for %%f in (..\..\CoolProp\*.cpp) do mkoctfile -v -c -I..\..\CoolProp -o %%~nf.o %%f
REM ~ if %errorlevel% neq 0 exit /b %errorlevel%
REM ~ mkoctfile -v -o 3.6.1\CoolProp.oct *.o
REM ~ if %errorlevel% neq 0 exit /b %errorlevel%
REM ~ erase *.o
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
for %%f in (..\..\src\*.cpp) do c:\octave3_6_2\bin\mkoctfile -v -c -I..\..\include -o %%~nf.o %%f
for %%f in (..\..\src\Backends\REFPROP\*.cpp) do c:\octave3_6_2\bin\mkoctfile -v -c -I..\..\include -o %%~nf.o %%f
for %%f in (..\..\src\Backends\Helmholtz\*.cpp) do c:\octave3_6_2\bin\mkoctfile -v -c -I..\..\include -o %%~nf.o %%f
for %%f in (..\..\src\Backends\Helmholtz\Fluids\*.cpp) do c:\octave3_6_2\bin\mkoctfile -v -c -I..\..\include -o %%~nf.o %%f
for %%f in (..\..\src\Backends\Incompressible\*.cpp) do c:\octave3_6_2\bin\mkoctfile -v -c -I..\..\include -o %%~nf.o %%f
for %%f in (..\..\src\Tests\*.cpp) do c:\octave3_6_2\bin\mkoctfile -v -c -I..\..\include -o %%~nf.o %%f
c:\octave3_6_2\bin\mkoctfile -v -c -I..\..\include -o CoolProp_wrap.o CoolProp_wrap.cpp
c:\octave3_6_2\bin\mkoctfile -v -o 3.6.2\CoolProp.oct *.o
REM ~ erase *.o
REM ~ call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
REM ~ for %%f in (..\..\CoolProp\*.cpp) do c:\octave3_6_4\bin\mkoctfile -v -c -I..\..\CoolProp -o %%~nf.o %%f
REM ~ c:\octave3_6_4\bin\mkoctfile -v -c -I..\..\CoolProp -o CoolProp_wrap.o CoolProp_wrap.cpp
REM ~ c:\octave3_6_4\bin\mkoctfile -v -o 3.6.4\CoolProp.oct *.o
REM ~ erase *.o

View File

@@ -1,35 +0,0 @@
cd ../../CoolProp
include_string = '-I.'
system('rm *_wrap.cpp')
system('swig -octave -c++ -o CoolProp_wrap.cpp CoolProp.i')
main_files = glob('*.cpp');
files=[main_files];
o_files = ''
cpp_files = ''
for i=1:size(files)(1)
file = files{i,1};
o_file = strrep(file,'.cpp','.o');
o_files = [o_files, ' ', o_file];
cpp_files = [cpp_files, ' ',file];
eval(['mkoctfile -v -c ', include_string,' -o ',o_file,' ',file])
end
eval(['mkoctfile -v -lgomp ', include_string,' -o CoolProp.oct ',o_files])
% Clean up - remove the object files
for i=1:size(files)(1)
file = files{i,1};
o_file = strrep(file,'.cpp','.o');
unlink(o_file);
disp(['deleting the file ',o_file]);
end
unlink('CoolProp_wrap.o')
unlink('CoolProp_wrap.cpp')
system('mv CoolProp.oct ../wrappers/Octave')

View File

@@ -1,2 +0,0 @@
addpath('3.6.1') % Use the version compiled for 3.6.1
example

View File

@@ -1,2 +0,0 @@
addpath('3.6.2') % Use the version compiled for 3.6.2
example

View File

@@ -1,2 +0,0 @@
addpath('3.6.4') % Use the version compiled for 3.6.4
example

View File

@@ -1,48 +0,0 @@
@echo off
call:defineEnv
REM Change to "call:defineEnv x86" or "call:defineEnv amd64" according to your needs
cl /c /MP /I../../CoolProp /EHsc /DCOOLPROP_LIB ../../CoolProp/*.cpp
link /DLL *.obj /OUT:CoolProp.dll
lib CoolProp.obj *.obj /OUT:CoolProp.lib
dumpbin /EXPORTS CoolProp.dll > exportsDLL.txt
dumpbin /HEADERS CoolProp.lib > exportsLIB.txt
erase *.obj
erase *.exp
goto:eof
rem ******** define some general functions ************
:defineEnv - set the variables, accepts one argument
set stdpaths="C:\Program Files (x86)\Microsoft Visual Studio ","C:\Program Files\Microsoft Visual Studio "
rem this order assures that the latest version is used...
set versions="8.0","9.0","10.0","11.0","12.0"
set relPaths="\VC\vcvarsall.bat"
set filename=""
for %%i in (%stdpaths%) do (
for %%j in (%versions%) do (
for %%k in (%relPaths%) do (
call:loadScript "%%~i%%~j%%~k" %%~j %~1
)
)
)
goto:eof
:loadScript
rem echo "%~1" "%~2"
if exist "%~1" (
echo .
echo Found Visual Studio v. %~2
echo Calling "%~1" %~3
call "%~1" %~3
echo .
)
REM else (
REM echo Could not find "%~1"
REM )
goto:eof

View File

@@ -1,40 +0,0 @@
[
{
"name_suffix" : "__stdcall",
"pre" : "",
"sources" : [],
"platform" : ["Windows"],
"compiler" : "VS+",
"bitness" : 32,
"c_flags" : "/MP3 /O2 /EHsc /DNDEBUG /I../../include /DCOOLPROP_LIB",
"link_type" : "DLL",
"link_fname" : "CoolProp.dll",
"link_flags" : "",
"post" : ""
},
{
"name_suffix" : "__cdecl",
"pre" : "",
"sources" : [],
"platform" : ["Windows"],
"compiler" : "VS+",
"bitness" : 32,
"c_flags" : "/MD /O2 /EHsc /DNDEBUG /I../../include /DCOOLPROP_LIB /D \"CONVENTION=__cdecl\"",
"link_type" : "DLL",
"link_fname" : "CoolProp.dll",
"link_flags" : "",
"post" : ""
},
{
"pre" : "",
"sources" : [],
"platform" : ["Windows"],
"compiler" : "VS+",
"bitness" : 64,
"c_flags" : "/MP3 /O2 /EHsc /DNDEBUG /I../../include /DCOOLPROP_LIB",
"link_type" : "DLL",
"link_fname" : "CoolProp.dll",
"link_flags" : "",
"post" : ""
}
]

View File

@@ -1,235 +0,0 @@
# ============================================================================
# Name : Makefile
# Author : Rod Persky (rodney.persky@connect.qut.edu.au)
# Jorrit Wronski (jowr@mek.dtu.dk)
# Version : 0.1
# Copyright : Use and modify at your own risk.
# Description : Makefile for CoolProp shared library
# ============================================================================
# The installation procedure should be as follows:
# 1) make
# 2) sudo make install
# If you want a static library then add LIBTYPE=a to *ALL* of the
# make and install commands. Also whilst you're adding commands may as well
# include -j $(nproc) to increase build speed. So for a static library use:
# make LIBTYPE=a -j $(nproc)
# sudo make LIBTYPE=a install
#
# If you need a clean install use:
# sudo make uninstall install
#
# You can simply uninstall by using:
# sudo make uninstall
#
# When using the library in Eclipse in your source files add:
# #include <CoolProp/CoolProp.h>
#
# And in the linker Librarys add (dl is only needed for the static library):
# CoolProp
# dl
#
# Header files are going to be installed into
# /usr/local/include
# while the libraries will reside in
# /usr/local/lib
# ============================================================================
# General commands:
# These commands are faily generic accross all platforms
CC := g++
RM := rm -f
CP := cp
CD := cd
CHF := chmod 0644
CHD := chmod 0655
MK := mkdir -p -m 655
RS := rsync -Rq
FN := find
LD := ldconfig
LN := ln -sf
LT := libtool
AR := ar rvs
MV := mv
PUD := pushd
POD := popd
SHELL := /bin/sh
DEST := /usr/local
UNAME := $(shell uname)
# What library type are we going to build by default (shared)
LIBTYPE = so
# We're going to install into /usr/local/include
INCDIR = $(DEST)/include/$(BASENAME)
LIBDIR = $(DEST)/lib
COOLPROPDIR = ../../CoolProp/
BINDIR = ./build
# Optimisation flags, change to your wants and desires
USER_OPTFLAGS = -O0 #-funroll-loops -ffast-math -ffloat-store
# Language specific flags use -D COOLPROP_LIB to build a C library
LANG_FLAGS = -D COOLPROP_LIB
# Debug flags
DBGFLAGS = -O0 -g3
WRNFLAGS = -Wall -Wpedantic -Wextra
# =============================
# ~ END OF CUSTOMISABLE CODE ~
# =============================
# Sort out exactly what we want to do,
# shared or static, debug or standard
# build. Get the final names of the execs
# =============================
BASENAME=CoolProp
VFILE = $(COOLPROPDIR)/version.h
VERSION=$(shell cut -d'"' -f2 $(VFILE))
MAJOR=$(shell echo $(VERSION) | cut -d'.' -f1 - )
MINOR=$(shell echo $(VERSION) | cut -d'.' -f2 - )
ifeq ($(LIBTYPE),a)
LIBTYPECLEAN=a
else
ifeq ($(UNAME), Linux)
LIBTYPECLEAN=so
endif
ifeq ($(UNAME), Darwin)
LIBTYPECLEAN=dylib
endif
endif
ifeq ($(DEBUG),debug)
DEBUGCLEAN=_dbg
endif
EXECUTABLE=lib$(BASENAME)$(DEBUGCLEAN).$(LIBTYPECLEAN).$(VERSION)
LIBNAME=lib$(BASENAME)$(DEBUGCLEAN).$(LIBTYPECLEAN).$(MAJOR).$(MINOR)
EXECUTABLE_MAJOR=lib$(BASENAME)$(DEBUGCLEAN).$(LIBTYPECLEAN).$(MAJOR)
EXECUTABLE_BASE=lib$(BASENAME)$(DEBUGCLEAN).$(LIBTYPECLEAN)
# ======================
# Compile all the flags
# ======================
# The standard flags are meant to represent the safest compilation,
# not fastest resulting library speed.
_LIBRARIES = -ldl
_INCLUDES = -I$(COOLPROPDIR)
STD_OPTFLAGS = -fPIC
_CPPFLAGS=$(_LIBRARIES) $(STD_OPTFLAGS) $(LANG_FLAGS) $(USER_OPTFLAGS)
ifeq ($(LIBTYPE),a)
#AR doesn't take flags
else
ifeq ($(UNAME), Linux)
_LIBFLAGS=-shared -Wl,-soname,$(LIBNAME)
endif
ifeq ($(UNAME), Darwin)
_LIBFLAGS=-dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,$(MAJOR).$(MINOR),-current_version,$(MAJOR).$(MINOR),-install_name,$(LIBNAME)
endif
endif
ifeq ($(DEBUG),debug)
_CPPFLAGS=$(STD_OPTFLAGS) $(DBGFLAGS) $(WRNFLAGS)
endif
#Get sources
COOLCPP_FILES=$(shell echo $(COOLPROPDIR)*.cpp)
COOLOBJ_FILES := $(addprefix $(BINDIR)/,$(notdir $(COOLCPP_FILES:.cpp=.o)))
# Path for prerequisite files
vpath %.cpp $(COOLPROPDIR)
# ========================
# Compile coolprop sources
# ========================
.PHONY: all
all: $(COOLOBJ_FILES) $(BINDIR)/$(EXECUTABLE)
$(COOLOBJ_FILES): | $(BINDIR)
$(BINDIR):
$(MK) -m 755 $(BINDIR)
# Make the .o files (for both static and shared)
$(BINDIR)/%.o : %.cpp
$(CC) $(_CPPFLAGS) -c $(_INCLUDES) $< -o $@
# Link shared library
$(BINDIR)/lib$(BASENAME)$(DEBUGCLEAN).so.$(VERSION): $(COOLOBJ_FILES)
$(CC) $(_LIBFLAGS) $(COOLOBJ_FILES) -o $@
# Link shared library on Mac
$(BINDIR)/lib$(BASENAME)$(DEBUGCLEAN).dylib.$(VERSION): $(COOLOBJ_FILES)
$(CC) $(_LIBFLAGS) $(COOLOBJ_FILES) -o $@
# Link static library
$(BINDIR)/lib$(BASENAME)$(DEBUGCLEAN).a.$(VERSION): $(COOLOBJ_FILES)
$(AR) $@ $^
# ========================
# Install and Uninstall
# ========================
.PHONY : install
install: $(BINDIR)/$(EXECUTABLE)
$(MK) $(INCDIR) $(LIBDIR)
($(CD) $(COOLPROPDIR) && $(FN) . -name '*.h' -exec $(RS) {} $(INCDIR)/ \; )
$(FN) $(INCDIR) -type d -exec $(CHD) {} \;
$(FN) $(INCDIR) -type f -exec $(CHF) {} \;
ifeq ($(UNAME), Linux)
$(CP) $(BINDIR)/$(EXECUTABLE) $(LIBDIR)
endif
ifeq ($(UNAME), Darwin)
install -m 644 -o root -g wheel $(BINDIR)/$(EXECUTABLE) $(LIBDIR)/
endif
$(CHF) $(LIBDIR)/$(EXECUTABLE)
($(CD) $(LIBDIR) && $(LN) $(EXECUTABLE) $(LIBNAME) )
($(CD) $(LIBDIR) && $(LN) $(LIBNAME) $(EXECUTABLE_MAJOR) )
($(CD) $(LIBDIR) && $(LN) $(EXECUTABLE_MAJOR) $(EXECUTABLE_BASE) )
ifeq ($(UNAME), Linux)
$(LD) -n $(INCDIR)
$(LD) -l $(LIBDIR)/$(EXECUTABLE)
$(LD)
endif
.PHONY : uninstall
uninstall:
$(RM)r $(INCDIR)
$(RM) $(LIBDIR)/$(EXECUTABLE)
$(RM) $(LIBDIR)/$(LIBNAME)
$(RM) $(LIBDIR)/$(EXECUTABLE_MAJOR)
$(RM) $(LIBDIR)/$(EXECUTABLE_BASE)
ifeq ($(UNAME), Linux)
$(LD)
endif
# ========================
# Accessory functions
# ========================
.PHONY : clean
clean:
$(RM) $(BINDIR)/*
.PHONY : check_flags
check_flags:
@printf "\nBuild settings:\n\
VERSION=$(VERSION)\n\
MAJOR=$(MAJOR)\n\
MINOR=$(MINOR)\n\
EXECUTABLE=$(EXECUTABLE)\n\
LIBNAME=$(LIBNAME)\n\
LIBFLAGS=$(_LIBFLAGS)\n\
CPPFLAGS=$(_CPPFLAGS)\n\
INCLUDES=$(_INCLUDES)\n\n\
COOLCPP_FILES:\n$(COOLCPP_FILES)\n\n\
COOLOBJ_FILES:\n$(COOLOBJ_FILES)\n\n"