There are two ways to use this library. The easiest way is to use the released download archives. These files come with batteries included since the fluid property library CoolProp is part of the code already and it includes a pre-compiled interface to the FluidProp tool. FluidProp features many built-in fluid models, and can optionally be used to access the whole NIST RefProp database, thus giving easy access to a wide range of fluid models with state-of-the-art accuracy.
Please refer to the chapter on FluidProp and the dedicated chapter on CoolProp for details.
If you want to use your own fluid property computation code instead, then you need to check out the source code and add the interface to it, as described in this manual. Please refer to the compilation guide for details regarding the creation of binary files from the source code.
This section gives an overview of the package structure, in order to help you understand how to interface your own code to Modelica using it.
At the top level there is a Modelica package (ExternalMedia), which contains all the basic infrastructure needed to use external fluid properties computation software through a Modelica.Media compliant interface. In particular, the ExternalMedia.Media.ExternalTwoPhaseMedium package is a full-fledged implementation of a two-phase medium model, compliant with the Modelica.Media.Interfaces.PartialTwoPhaseMedium interface. The ExternalTwoPhaseMedium package can be used with any external fluid property computation software; the specific software to be used is specified by changing the libraryName package constant, which is then handled by the underlying C code to select the appropriate external code to use.
The Modelica functions within ExternalTwoPhaseMedium communicate to a C/C++ interface layer (called externalmedialib.cpp) via external C functions calls, which in turn make use of C++ objects. This layer takes care of initializing the external fluid computation codes, called solvers from now on. Every solver is wrapped by a C++ class, inheriting from the BaseSolver C++ class. The C/C++ layer maintains a set of active solvers, one for each different combination of the libraryName and mediumName strings, by means of the SolverMap C++ class. The key to each solver in the map is given by those strings. It is then possible to use multiple instances of many solvers in the same Modelica model at the same time.
All the external C functions pass the libraryName, mediumName and substanceNames strings to the corresponding functions of the interface layer. These in turn use the SolverMap object to look for an active solver in the solver map, corresponding to those strings. If one is found, the corresponding function of the solver is called, otherwise a new solver object is instantiated and added to the map, before calling the corresponding function of the solver.
The default implementation of an external medium model is implemented by the ExternalTwoPhaseMedium Modelica package. The setState_xx() and setSat_x() function calls are rerouted to the corresponding functions of the solver object. These compute all the required properties and return them in the ExternalThermodynamicState and ExternalSaturationProperties C structs, which map onto the corresponding ThermodynamicState and SaturationProperties records defined in ExternalTwoPhaseMedium. All the functions returning properties as a function of the state records are implemented in Modelica and simply return the corresponding element in the state record, which acts as a cache. This is an efficient implementation for many complex fluid models, where most of the CPU time is spent solving the basic equation of state, while the computation of all derived properties adds a minor overhead, so it makes sense to compute them once and for all when the setState_XX() or setSat_xx() functions are called.
In case some of the thermodynamic properties require a significant amount of CPU time on their own, it is possible to override this default implementation. On one hand, it is necessary to extend the ExternalTwoPhaseMedium Modelica package and redeclare those functions, so that they call the corresponding external C functions defined in externalmedium.cpp, instead of returning the value cached in the state record. On the other hand, it is also necessary to provide an implementation of the corresponding functions in the C++ solver object, by overriding the virtual functions of the BaseSolver object. In this case, the setState_xx() and setSat_X() functions need not compute all the values of the cache state records; uncomputed properties might be set to zero. This is not a problem, since Modelica.Media compatible models should never access the elements of the state records directly, but only through the appropriate functions, so these values should never be actually used by component models using the medium package.
The ExternalMedia package has been designed to ease your task, so that you will only have to write the mimum amount of code which is strictly specific to your external code - everything else is already provided. The following instructions apply if you want to develop an external medium model which include a (sub)set of the functions defined in Modelica.Media.Interfaces.PartialTwoPhaseMedium.
The most straightforward implementation is the one in which all fluid properties are computed at once by the setState_XX() and setSat_X() functions and all the other functions return the values cached in the state records.
First of all, you have to write you own solver object code: you can look at the code of the TestMedium and FluidPropMedium code as examples. Inherit from the BaseSolver object, which provides default implementations for most of the required functions, and then just add your own implementation for the following functions: object constructor, object destructor, setMediumConstants(), setSat_p(), setSat_T(), setState_ph(), setState_pT(), setState_ps(), setState_dT(). Note that the setState and setSat functions need to compute and fill in all the fields of the corresponding C structs for the library to work correctly. On the other hand, you don't necessarily need to implement all of the four setState functions: if you know in advance that your models will only use certain combinations of variables as inputs (e.g. p, h), then you might omit implementing the setState and setSat functions corresponding to the other ones.
Then you must modify the SolverMap::addSolver() function, so that it will instantiate your new solver when it is called with the appropriate libraryName string. You are free to invent you own syntax for the libraryName string, in case you'd like to be able to set up the external medium with some additional configuration data from within Modelica - it is up to you to decode that syntax within the addSolver() function, and within the constructor of your solver object. Look at how the FluidProp solver is implemented for an example.
Finally, add the .cpp and .h files of the solver object to the C/C++ project, set the include.h file according to your needs and recompile it to a shared library. The compiled libraries and the externalmedialib.h files must then be copied into the Include subdirectory of the Modelica package so that the Modelica tool can link them when compiling the models.
As already mentioned in the previous section, you might provide customized implementations where some of the properties are not computed by the setState and setSat functions and stored in the cache records, but rather computed on demand, based on a smaller set of thermodynamic properties computed by the setState and setSat functions and stored in the state C struct.
Please note that compiling ExternalMedia from source code might require the professional version of Microsoft Visual Studio, which includes the COM libraries used by the FluidProp interface. However, if you remove all the FluidProp files and references from the project, then you should be able to compile the source code with the Express edition, or possibly also with gcc. See the compilation guidefor details.